From python-3000-checkins at python.org Sun Jun 1 05:53:03 2008 From: python-3000-checkins at python.org (alexandre.vassalotti) Date: Sun, 1 Jun 2008 05:53:03 +0200 (CEST) Subject: [Python-3000-checkins] r63843 - python/branches/py3k/Include/dictobject.h Message-ID: <20080601035303.891851E4009@bag.python.org> Author: alexandre.vassalotti Date: Sun Jun 1 05:53:03 2008 New Revision: 63843 Log: Added missing prototype for PyDict_GetItemWithError(). Modified: python/branches/py3k/Include/dictobject.h Modified: python/branches/py3k/Include/dictobject.h ============================================================================== --- python/branches/py3k/Include/dictobject.h (original) +++ python/branches/py3k/Include/dictobject.h Sun Jun 1 05:53:03 2008 @@ -109,6 +109,7 @@ PyAPI_FUNC(PyObject *) PyDict_New(void); PyAPI_FUNC(PyObject *) PyDict_GetItem(PyObject *mp, PyObject *key); +PyAPI_FUNC(PyObject *) PyDict_GetItemWithError(PyObject *mp, PyObject *key); PyAPI_FUNC(int) PyDict_SetItem(PyObject *mp, PyObject *key, PyObject *item); PyAPI_FUNC(int) PyDict_DelItem(PyObject *mp, PyObject *key); PyAPI_FUNC(void) PyDict_Clear(PyObject *mp); From python-3000-checkins at python.org Sun Jun 1 06:00:19 2008 From: python-3000-checkins at python.org (alexandre.vassalotti) Date: Sun, 1 Jun 2008 06:00:19 +0200 (CEST) Subject: [Python-3000-checkins] r63844 - python/branches/py3k/Doc/c-api/dict.rst Message-ID: <20080601040019.5D3851E400A@bag.python.org> Author: alexandre.vassalotti Date: Sun Jun 1 06:00:18 2008 New Revision: 63844 Log: Added documentation for PyDict_GetItemWithError(). Modified: python/branches/py3k/Doc/c-api/dict.rst Modified: python/branches/py3k/Doc/c-api/dict.rst ============================================================================== --- python/branches/py3k/Doc/c-api/dict.rst (original) +++ python/branches/py3k/Doc/c-api/dict.rst Sun Jun 1 06:00:18 2008 @@ -98,6 +98,12 @@ Return the object from dictionary *p* which has a key *key*. Return *NULL* if the key *key* is not present, but *without* setting an exception. +.. cfunction:: PyObject* PyDict_GetItemWithError(PyObject *p, PyObject *key) + + Variant of :cfunc:`PyDict_GetItem` that does not suppress + exceptions. Return *NULL* **with** an exception set if an exception + occurred. Return *NULL* **without** an exception set if the key + wasn't present. .. cfunction:: PyObject* PyDict_GetItemString(PyObject *p, const char *key) From python-3000-checkins at python.org Sun Jun 1 06:16:28 2008 From: python-3000-checkins at python.org (alexandre.vassalotti) Date: Sun, 1 Jun 2008 06:16:28 +0200 (CEST) Subject: [Python-3000-checkins] r63845 - python/branches/py3k/Doc/c-api/dict.rst Message-ID: <20080601041628.660DA1E4009@bag.python.org> Author: alexandre.vassalotti Date: Sun Jun 1 06:16:28 2008 New Revision: 63845 Log: Whitespace nits. Modified: python/branches/py3k/Doc/c-api/dict.rst Modified: python/branches/py3k/Doc/c-api/dict.rst ============================================================================== --- python/branches/py3k/Doc/c-api/dict.rst (original) +++ python/branches/py3k/Doc/c-api/dict.rst Sun Jun 1 06:16:28 2008 @@ -98,6 +98,7 @@ Return the object from dictionary *p* which has a key *key*. Return *NULL* if the key *key* is not present, but *without* setting an exception. + .. cfunction:: PyObject* PyDict_GetItemWithError(PyObject *p, PyObject *key) Variant of :cfunc:`PyDict_GetItem` that does not suppress @@ -105,6 +106,7 @@ occurred. Return *NULL* **without** an exception set if the key wasn't present. + .. cfunction:: PyObject* PyDict_GetItemString(PyObject *p, const char *key) This is the same as :cfunc:`PyDict_GetItem`, but *key* is specified as a From python-3000-checkins at python.org Sun Jun 1 09:22:10 2008 From: python-3000-checkins at python.org (martin.v.loewis) Date: Sun, 1 Jun 2008 09:22:10 +0200 (CEST) Subject: [Python-3000-checkins] r63847 - python/branches/py3k Message-ID: <20080601072210.7D8491E4009@bag.python.org> Author: martin.v.loewis Date: Sun Jun 1 09:22:10 2008 New Revision: 63847 Log: Blocked revisions 63846 via svnmerge ........ r63846 | martin.v.loewis | 2008-06-01 09:20:46 +0200 (So, 01 Jun 2008) | 2 lines New environment variable PYTHONIOENCODING. ........ Modified: python/branches/py3k/ (props changed) From python-3000-checkins at python.org Sun Jun 1 10:32:41 2008 From: python-3000-checkins at python.org (martin.v.loewis) Date: Sun, 1 Jun 2008 10:32:41 +0200 (CEST) Subject: [Python-3000-checkins] r63850 - python/branches/py3k Message-ID: <20080601083241.CDDFE1E4009@bag.python.org> Author: martin.v.loewis Date: Sun Jun 1 10:32:41 2008 New Revision: 63850 Log: Blocked revisions 63848-63849 via svnmerge ........ r63848 | martin.v.loewis | 2008-06-01 10:06:17 +0200 (So, 01 Jun 2008) | 2 lines Move sys_stream and sys_isatty out of the have-langinfo block. ........ r63849 | martin.v.loewis | 2008-06-01 10:19:02 +0200 (So, 01 Jun 2008) | 2 lines Typo: encoding -> codeset. ........ Modified: python/branches/py3k/ (props changed) From python-3000-checkins at python.org Sun Jun 1 20:50:38 2008 From: python-3000-checkins at python.org (benjamin.peterson) Date: Sun, 1 Jun 2008 20:50:38 +0200 (CEST) Subject: [Python-3000-checkins] r63862 - in python/branches/py3k: Misc/NEWS Tools/README Message-ID: <20080601185038.D5D0E1E4016@bag.python.org> Author: benjamin.peterson Date: Sun Jun 1 20:50:38 2008 New Revision: 63862 Log: add notes about the removal of bgen Modified: python/branches/py3k/Misc/NEWS python/branches/py3k/Tools/README Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sun Jun 1 20:50:38 2008 @@ -143,6 +143,8 @@ - The test.test_support module has been renamed to test.support. +- The bgen tool has been removed + Build ----- Modified: python/branches/py3k/Tools/README ============================================================================== --- python/branches/py3k/Tools/README (original) +++ python/branches/py3k/Tools/README Sun Jun 1 20:50:38 2008 @@ -7,9 +7,6 @@ be run either as a command-line script, or as a Tkinter application. -bgen Generate complete extension modules from a - description. Still under development! - compiler Tools used to maintain the compiler package in the standard library. From python-3000-checkins at python.org Sun Jun 1 21:04:01 2008 From: python-3000-checkins at python.org (benjamin.peterson) Date: Sun, 1 Jun 2008 21:04:01 +0200 (CEST) Subject: [Python-3000-checkins] r63864 - python/branches/py3k Message-ID: <20080601190401.C42851E400A@bag.python.org> Author: benjamin.peterson Date: Sun Jun 1 21:04:01 2008 New Revision: 63864 Log: Blocked revisions 63863 via svnmerge ........ r63863 | benjamin.peterson | 2008-06-01 14:01:25 -0500 (Sun, 01 Jun 2008) | 2 lines add a warning about bgen being removed ........ Modified: python/branches/py3k/ (props changed) From python-3000-checkins at python.org Sun Jun 1 21:24:43 2008 From: python-3000-checkins at python.org (georg.brandl) Date: Sun, 1 Jun 2008 21:24:43 +0200 (CEST) Subject: [Python-3000-checkins] r63866 - python/branches/py3k Message-ID: <20080601192443.C38FD1E400A@bag.python.org> Author: georg.brandl Date: Sun Jun 1 21:24:43 2008 New Revision: 63866 Log: Blocked revisions 63861 via svnmerge ........ r63861 | robert.schuppenies | 2008-06-01 19:11:09 +0200 (Sun, 01 Jun 2008) | 2 lines Fix test_sys. ........ Modified: python/branches/py3k/ (props changed) From python-3000-checkins at python.org Sun Jun 1 21:25:33 2008 From: python-3000-checkins at python.org (georg.brandl) Date: Sun, 1 Jun 2008 21:25:33 +0200 (CEST) Subject: [Python-3000-checkins] r63867 - python/branches/py3k/Misc/NEWS Message-ID: <20080601192533.3B94A1E400C@bag.python.org> Author: georg.brandl Date: Sun Jun 1 21:25:32 2008 New Revision: 63867 Log: Add proper heading for tools entry. Modified: python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sun Jun 1 21:25:32 2008 @@ -143,7 +143,10 @@ - The test.test_support module has been renamed to test.support. -- The bgen tool has been removed +Tools/Demos +----------- + +- The bgen tool has been removed. Build ----- From python-3000-checkins at python.org Sun Jun 1 22:16:08 2008 From: python-3000-checkins at python.org (benjamin.peterson) Date: Sun, 1 Jun 2008 22:16:08 +0200 (CEST) Subject: [Python-3000-checkins] r63869 - in python/branches/py3k/Doc/library: gensuitemodule.rst miniaeframe.rst Message-ID: <20080601201608.5938B1E401B@bag.python.org> Author: benjamin.peterson Date: Sun Jun 1 22:16:07 2008 New Revision: 63869 Log: remove mac module docs missed in the first round Removed: python/branches/py3k/Doc/library/gensuitemodule.rst python/branches/py3k/Doc/library/miniaeframe.rst Deleted: python/branches/py3k/Doc/library/gensuitemodule.rst ============================================================================== --- python/branches/py3k/Doc/library/gensuitemodule.rst Sun Jun 1 22:16:07 2008 +++ (empty file) @@ -1,61 +0,0 @@ - -:mod:`gensuitemodule` --- Generate OSA stub packages -==================================================== - -.. module:: gensuitemodule - :platform: Mac - :synopsis: Create a stub package from an OSA dictionary -.. sectionauthor:: Jack Jansen -.. moduleauthor:: Jack Jansen - -The :mod:`gensuitemodule` module creates a Python package implementing stub code -for the AppleScript suites that are implemented by a specific application, -according to its AppleScript dictionary. - -It is usually invoked by the user through the :program:`PythonIDE`, but it can -also be run as a script from the command line (pass :option:`--help` for help on -the options) or imported from Python code. For an example of its use see -:file:`Mac/scripts/genallsuites.py` in a source distribution, which generates -the stub packages that are included in the standard library. - -It defines the following public functions: - - -.. function:: is_scriptable(application) - - Returns true if ``application``, which should be passed as a pathname, appears - to be scriptable. Take the return value with a grain of salt: :program:`Internet - Explorer` appears not to be scriptable but definitely is. - - -.. function:: processfile(application[, output, basepkgname, edit_modnames, creatorsignature, dump, verbose]) - - Create a stub package for ``application``, which should be passed as a full - pathname. For a :file:`.app` bundle this is the pathname to the bundle, not to - the executable inside the bundle; for an unbundled CFM application you pass the - filename of the application binary. - - This function asks the application for its OSA terminology resources, decodes - these resources and uses the resultant data to create the Python code for the - package implementing the client stubs. - - ``output`` is the pathname where the resulting package is stored, if not - specified a standard "save file as" dialog is presented to the user. - ``basepkgname`` is the base package on which this package will build, and - defaults to :mod:`StdSuites`. Only when generating :mod:`StdSuites` itself do - you need to specify this. ``edit_modnames`` is a dictionary that can be used to - change modulenames that are too ugly after name mangling. ``creator_signature`` - can be used to override the 4-char creator code, which is normally obtained from - the :file:`PkgInfo` file in the package or from the CFM file creator signature. - When ``dump`` is given it should refer to a file object, and ``processfile`` - will stop after decoding the resources and dump the Python representation of the - terminology resources to this file. ``verbose`` should also be a file object, - and specifying it will cause ``processfile`` to tell you what it is doing. - - -.. function:: processfile_fromresource(application[, output, basepkgname, edit_modnames, creatorsignature, dump, verbose]) - - This function does the same as ``processfile``, except that it uses a different - method to get the terminology resources. It opens ``application`` as a resource - file and reads all ``"aete"`` and ``"aeut"`` resources from this file. - Deleted: python/branches/py3k/Doc/library/miniaeframe.rst ============================================================================== --- python/branches/py3k/Doc/library/miniaeframe.rst Sun Jun 1 22:16:07 2008 +++ (empty file) @@ -1,68 +0,0 @@ - -:mod:`MiniAEFrame` --- Open Scripting Architecture server support -================================================================= - -.. module:: MiniAEFrame - :platform: Mac - :synopsis: Support to act as an Open Scripting Architecture (OSA) server ("Apple Events"). - - -.. index:: - single: Open Scripting Architecture - single: AppleEvents - module: FrameWork - -The module :mod:`MiniAEFrame` provides a framework for an application that can -function as an Open Scripting Architecture (OSA) server, i.e. receive and -process AppleEvents. It can be used in conjunction with :mod:`FrameWork` or -standalone. As an example, it is used in :program:`PythonCGISlave`. - -The :mod:`MiniAEFrame` module defines the following classes: - - -.. class:: AEServer() - - A class that handles AppleEvent dispatch. Your application should subclass this - class together with either :class:`MiniApplication` or - :class:`FrameWork.Application`. Your :meth:`__init__` method should call the - :meth:`__init__` method for both classes. - - -.. class:: MiniApplication() - - A class that is more or less compatible with :class:`FrameWork.Application` but - with less functionality. Its event loop supports the apple menu, command-dot and - AppleEvents; other events are passed on to the Python interpreter and/or Sioux. - Useful if your application wants to use :class:`AEServer` but does not provide - its own windows, etc. - - -.. _aeserver-objects: - -AEServer Objects ----------------- - - -.. method:: AEServer.installaehandler(classe, type, callback) - - Installs an AppleEvent handler. *classe* and *type* are the four-character OSA - Class and Type designators, ``'****'`` wildcards are allowed. When a matching - AppleEvent is received the parameters are decoded and your callback is invoked. - - -.. method:: AEServer.callback(_object, **kwargs) - - Your callback is called with the OSA Direct Object as first positional - parameter. The other parameters are passed as keyword arguments, with the - 4-character designator as name. Three extra keyword parameters are passed: - ``_class`` and ``_type`` are the Class and Type designators and ``_attributes`` - is a dictionary with the AppleEvent attributes. - - The return value of your method is packed with :func:`aetools.packevent` and - sent as reply. - -Note that there are some serious problems with the current design. AppleEvents -which have non-identifier 4-character designators for arguments are not -implementable, and it is not possible to return an error to the originator. This -will be addressed in a future release. - From python-3000-checkins at python.org Sun Jun 1 23:05:19 2008 From: python-3000-checkins at python.org (georg.brandl) Date: Sun, 1 Jun 2008 23:05:19 +0200 (CEST) Subject: [Python-3000-checkins] r63872 - in python/branches/py3k: Doc/Makefile Doc/README.txt Doc/tools/sphinxext/pyspecific.py Lib/pydoc.py Lib/pydoc_topics.py Message-ID: <20080601210519.EBF131E400A@bag.python.org> Author: georg.brandl Date: Sun Jun 1 23:05:17 2008 New Revision: 63872 Log: Merged revisions 63871 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r63871 | georg.brandl | 2008-06-01 22:33:55 +0200 (Sun, 01 Jun 2008) | 3 lines Generate pydoc's topic help from the reST docs via Sphinx' new text writer. ........ Added: python/branches/py3k/Lib/pydoc_topics.py - copied, changed from r63871, /python/trunk/Lib/pydoc_topics.py Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/Makefile python/branches/py3k/Doc/README.txt python/branches/py3k/Doc/tools/sphinxext/pyspecific.py python/branches/py3k/Lib/pydoc.py Modified: python/branches/py3k/Doc/Makefile ============================================================================== --- python/branches/py3k/Doc/Makefile (original) +++ python/branches/py3k/Doc/Makefile Sun Jun 1 23:05:17 2008 @@ -93,6 +93,11 @@ @echo "Testing of doctests in the sources finished, look at the " \ "results in build/doctest/output.txt" +pydoc-topics: BUILDER = pydoc-topics +pydoc-topics: build + @echo "Building finished; now copy build/pydoc-topics/pydoc_topics.py " \ + "into the Lib/ directory" + clean: -rm -rf build/* -rm -rf tools/sphinx Modified: python/branches/py3k/Doc/README.txt ============================================================================== --- python/branches/py3k/Doc/README.txt (original) +++ python/branches/py3k/Doc/README.txt Sun Jun 1 23:05:17 2008 @@ -67,6 +67,11 @@ * "coverage", which builds a coverage overview for standard library modules and C API. + * "pydoc-topics", which builds a Python module containing a dictionary + with plain text documentation for the labels defined in + `tools/sphinxext/pyspecific.py` -- pydoc needs these to show topic + and keyword help. + A "make update" updates the Subversion checkouts in `tools/`. Modified: python/branches/py3k/Doc/tools/sphinxext/pyspecific.py ============================================================================== --- python/branches/py3k/Doc/tools/sphinxext/pyspecific.py (original) +++ python/branches/py3k/Doc/tools/sphinxext/pyspecific.py Sun Jun 1 23:05:17 2008 @@ -20,5 +20,69 @@ return [refnode], [] +# Support for building "topic help" for pydoc + +pydoc_topic_labels = [ + 'assert', 'assignment', 'atom-identifiers', 'atom-literals', + 'attribute-access', 'attribute-references', 'augassign', 'binary', + 'bitwise', 'bltin-code-objects', 'bltin-ellipsis-object', + 'bltin-file-objects', 'bltin-null-object', 'bltin-type-objects', 'booleans', + 'break', 'callable-types', 'calls', 'class', 'comparisons', 'compound', + 'context-managers', 'continue', 'conversions', 'customization', 'debugger', + 'del', 'dict', 'dynamic-features', 'else', 'exceptions', 'execmodel', + 'exprlists', 'floating', 'for', 'formatstrings', 'function', 'global', + 'id-classes', 'identifiers', 'if', 'imaginary', 'import', 'in', 'integers', + 'lambda', 'lists', 'naming', 'numbers', 'numeric-types', 'objects', + 'operator-summary', 'pass', 'power', 'raise', 'return', 'sequence-types', + 'shifting', 'slicings', 'specialattrs', 'specialnames', 'string-methods', + 'strings', 'subscriptions', 'truth', 'try', 'types', 'typesfunctions', + 'typesmapping', 'typesmethods', 'typesmodules', 'typesseq', + 'typesseq-mutable', 'unary', 'while', 'with', 'yield' +] + +from os import path +from time import asctime +from pprint import pformat +from docutils.io import StringOutput +from docutils.utils import new_document +from sphinx.builder import Builder +from sphinx.textwriter import TextWriter + +class PydocTopicsBuilder(Builder): + name = 'pydoc-topics' + + def init(self): + self.topics = {} + + def get_outdated_docs(self): + return 'all pydoc topics' + + def get_target_uri(self, docname, typ=None): + return '' # no URIs + + def write(self, *ignored): + writer = TextWriter(self) + for label in self.status_iterator(pydoc_topic_labels, 'building topics... '): + if label not in self.env.labels: + self.warn('label %r not in documentation' % label) + continue + docname, labelid, sectname = self.env.labels[label] + doctree = self.env.get_and_resolve_doctree(docname, self) + document = new_document('
') + document.append(doctree.ids[labelid]) + destination = StringOutput(encoding='utf-8') + writer.write(document, destination) + self.topics[label] = str(writer.output) + + def finish(self): + f = open(path.join(self.outdir, 'pydoc_topics.py'), 'w') + try: + f.write('# Autogenerated by Sphinx on %s\n' % asctime()) + f.write('topics = ' + pformat(self.topics) + '\n') + finally: + f.close() + + def setup(app): app.add_role('issue', issue_role) + app.add_builder(PydocTopicsBuilder) Modified: python/branches/py3k/Lib/pydoc.py ============================================================================== --- python/branches/py3k/Lib/pydoc.py (original) +++ python/branches/py3k/Lib/pydoc.py Sun Jun 1 23:05:17 2008 @@ -1524,141 +1524,141 @@ return class Helper: + + # These dictionaries map a topic name to either an alias, or a tuple + # (label, seealso-items). The "label" is the label of the corresponding + # section in the .rst file under Doc/ and an index into the dictionary + # in pydoc_topics.py. + # + # CAUTION: if you change one of these dictionaries, be sure to adapt the + # list of needed labels in Doc/tools/sphinxext/pyspecific.py and + # regenerate the pydoc_topics.py file by running + # make pydoc-topics + # in Doc/ and copying the output file into the Lib/ directory. + keywords = { 'and': 'BOOLEAN', 'as': 'with', - 'assert': ('ref/assert', ''), - 'break': ('ref/break', 'while for'), - 'class': ('ref/class', 'CLASSES SPECIALMETHODS'), - 'continue': ('ref/continue', 'while for'), - 'def': ('ref/function', ''), - 'del': ('ref/del', 'BASICMETHODS'), + 'assert': ('assert', ''), + 'break': ('break', 'while for'), + 'class': ('class', 'CLASSES SPECIALMETHODS'), + 'continue': ('continue', 'while for'), + 'def': ('function', ''), + 'del': ('del', 'BASICMETHODS'), 'elif': 'if', - 'else': ('ref/if', 'while for'), - 'except': 'try', - 'exec': ('ref/exec', ''), - 'finally': 'try', - 'for': ('ref/for', 'break continue while'), - 'from': 'import', - 'global': ('ref/global', 'NAMESPACES'), - 'if': ('ref/if', 'TRUTHVALUE'), - 'import': ('ref/import', 'MODULES'), - 'in': ('ref/comparisons', 'SEQUENCEMETHODS2'), + 'else': ('else', 'while for'), + 'except': 'except', + 'finally': 'finally', + 'for': ('for', 'break continue while'), + 'from': 'from', + 'global': ('global', 'NAMESPACES'), + 'if': ('if', 'TRUTHVALUE'), + 'import': ('import', 'MODULES'), + 'in': ('in', 'SEQUENCEMETHODS2'), 'is': 'COMPARISON', - 'lambda': ('ref/lambdas', 'FUNCTIONS'), + 'lambda': ('lambda', 'FUNCTIONS'), 'not': 'BOOLEAN', 'or': 'BOOLEAN', - 'pass': ('ref/pass', ''), - 'print': ('ref/print', ''), - 'raise': ('ref/raise', 'EXCEPTIONS'), - 'return': ('ref/return', 'FUNCTIONS'), - 'try': ('ref/try', 'EXCEPTIONS'), - 'while': ('ref/while', 'break continue if TRUTHVALUE'), - 'with': ('ref/with', 'CONTEXTMANAGERS EXCEPTIONS yield'), - 'yield': ('ref/yield', ''), + 'pass': ('pass', ''), + 'raise': ('raise', 'EXCEPTIONS'), + 'return': ('return', 'FUNCTIONS'), + 'try': ('try', 'EXCEPTIONS'), + 'while': ('while', 'break continue if TRUTHVALUE'), + 'with': ('with', 'CONTEXTMANAGERS EXCEPTIONS yield'), + 'yield': ('yield', ''), } topics = { - 'TYPES': ('ref/types', 'STRINGS UNICODE NUMBERS SEQUENCES MAPPINGS FUNCTIONS CLASSES MODULES FILES inspect'), - 'STRINGS': ('ref/strings', 'str UNICODE SEQUENCES STRINGMETHODS FORMATTING TYPES'), - 'STRINGMETHODS': ('lib/string-methods', 'STRINGS FORMATTING'), - 'FORMATTING': ('lib/typesseq-strings', 'OPERATORS'), - 'UNICODE': ('ref/strings', 'encodings unicode SEQUENCES STRINGMETHODS FORMATTING TYPES'), - 'NUMBERS': ('ref/numbers', 'INTEGER FLOAT COMPLEX TYPES'), - 'INTEGER': ('ref/integers', 'int range'), - 'FLOAT': ('ref/floating', 'float math'), - 'COMPLEX': ('ref/imaginary', 'complex cmath'), - 'SEQUENCES': ('lib/typesseq', 'STRINGMETHODS FORMATTING range LISTS'), + 'TYPES': ('types', 'STRINGS UNICODE NUMBERS SEQUENCES MAPPINGS ' + 'FUNCTIONS CLASSES MODULES FILES inspect'), + 'STRINGS': ('strings', 'str UNICODE SEQUENCES STRINGMETHODS ' + 'FORMATTING TYPES'), + 'STRINGMETHODS': ('string-methods', 'STRINGS FORMATTING'), + 'FORMATTING': ('formatstrings', 'OPERATORS'), + 'UNICODE': ('strings', 'encodings unicode SEQUENCES STRINGMETHODS ' + 'FORMATTING TYPES'), + 'NUMBERS': ('numbers', 'INTEGER FLOAT COMPLEX TYPES'), + 'INTEGER': ('integers', 'int range'), + 'FLOAT': ('floating', 'float math'), + 'COMPLEX': ('imaginary', 'complex cmath'), + 'SEQUENCES': ('typesseq', 'STRINGMETHODS FORMATTING range LISTS'), 'MAPPINGS': 'DICTIONARIES', - 'FUNCTIONS': ('lib/typesfunctions', 'def TYPES'), - 'METHODS': ('lib/typesmethods', 'class def CLASSES TYPES'), - 'CODEOBJECTS': ('lib/bltin-code-objects', 'compile FUNCTIONS TYPES'), - 'TYPEOBJECTS': ('lib/bltin-type-objects', 'types TYPES'), + 'FUNCTIONS': ('typesfunctions', 'def TYPES'), + 'METHODS': ('typesmethods', 'class def CLASSES TYPES'), + 'CODEOBJECTS': ('bltin-code-objects', 'compile FUNCTIONS TYPES'), + 'TYPEOBJECTS': ('bltin-type-objects', 'types TYPES'), 'FRAMEOBJECTS': 'TYPES', 'TRACEBACKS': 'TYPES', - 'NONE': ('lib/bltin-null-object', ''), - 'ELLIPSIS': ('lib/bltin-ellipsis-object', 'SLICINGS'), - 'FILES': ('lib/bltin-file-objects', ''), - 'SPECIALATTRIBUTES': ('lib/specialattrs', ''), - 'CLASSES': ('ref/types', 'class SPECIALMETHODS PRIVATENAMES'), - 'MODULES': ('lib/typesmodules', 'import'), + 'NONE': ('bltin-null-object', ''), + 'ELLIPSIS': ('bltin-ellipsis-object', 'SLICINGS'), + 'FILES': ('bltin-file-objects', ''), + 'SPECIALATTRIBUTES': ('specialattrs', ''), + 'CLASSES': ('types', 'class SPECIALMETHODS PRIVATENAMES'), + 'MODULES': ('typesmodules', 'import'), 'PACKAGES': 'import', - 'EXPRESSIONS': ('ref/summary', 'lambda or and not in is BOOLEAN COMPARISON BITWISE SHIFTING BINARY FORMATTING POWER UNARY ATTRIBUTES SUBSCRIPTS SLICINGS CALLS TUPLES LISTS DICTIONARIES'), + 'EXPRESSIONS': ('operator-summary', 'lambda or and not in is BOOLEAN ' + 'COMPARISON BITWISE SHIFTING BINARY FORMATTING POWER ' + 'UNARY ATTRIBUTES SUBSCRIPTS SLICINGS CALLS TUPLES ' + 'LISTS DICTIONARIES'), 'OPERATORS': 'EXPRESSIONS', 'PRECEDENCE': 'EXPRESSIONS', - 'OBJECTS': ('ref/objects', 'TYPES'), - 'SPECIALMETHODS': ('ref/specialnames', 'BASICMETHODS ATTRIBUTEMETHODS CALLABLEMETHODS SEQUENCEMETHODS1 MAPPINGMETHODS SEQUENCEMETHODS2 NUMBERMETHODS CLASSES'), - 'BASICMETHODS': ('ref/customization', 'cmp hash repr str SPECIALMETHODS'), - 'ATTRIBUTEMETHODS': ('ref/attribute-access', 'ATTRIBUTES SPECIALMETHODS'), - 'CALLABLEMETHODS': ('ref/callable-types', 'CALLS SPECIALMETHODS'), - 'SEQUENCEMETHODS1': ('ref/sequence-types', 'SEQUENCES SEQUENCEMETHODS2 SPECIALMETHODS'), - 'SEQUENCEMETHODS2': ('ref/sequence-methods', 'SEQUENCES SEQUENCEMETHODS1 SPECIALMETHODS'), - 'MAPPINGMETHODS': ('ref/sequence-types', 'MAPPINGS SPECIALMETHODS'), - 'NUMBERMETHODS': ('ref/numeric-types', 'NUMBERS AUGMENTEDASSIGNMENT SPECIALMETHODS'), - 'EXECUTION': ('ref/execmodel', 'NAMESPACES DYNAMICFEATURES EXCEPTIONS'), - 'NAMESPACES': ('ref/naming', 'global ASSIGNMENT DELETION DYNAMICFEATURES'), - 'DYNAMICFEATURES': ('ref/dynamic-features', ''), + 'OBJECTS': ('objects', 'TYPES'), + 'SPECIALMETHODS': ('specialnames', 'BASICMETHODS ATTRIBUTEMETHODS ' + 'CALLABLEMETHODS SEQUENCEMETHODS1 MAPPINGMETHODS ' + 'SEQUENCEMETHODS2 NUMBERMETHODS CLASSES'), + 'BASICMETHODS': ('customization', 'cmp hash repr str SPECIALMETHODS'), + 'ATTRIBUTEMETHODS': ('attribute-access', 'ATTRIBUTES SPECIALMETHODS'), + 'CALLABLEMETHODS': ('callable-types', 'CALLS SPECIALMETHODS'), + 'SEQUENCEMETHODS': ('sequence-types', 'SEQUENCES SEQUENCEMETHODS2 ' + 'SPECIALMETHODS'), + 'MAPPINGMETHODS': ('sequence-types', 'MAPPINGS SPECIALMETHODS'), + 'NUMBERMETHODS': ('numeric-types', 'NUMBERS AUGMENTEDASSIGNMENT ' + 'SPECIALMETHODS'), + 'EXECUTION': ('execmodel', 'NAMESPACES DYNAMICFEATURES EXCEPTIONS'), + 'NAMESPACES': ('naming', 'global ASSIGNMENT DELETION DYNAMICFEATURES'), + 'DYNAMICFEATURES': ('dynamic-features', ''), 'SCOPING': 'NAMESPACES', 'FRAMES': 'NAMESPACES', - 'EXCEPTIONS': ('ref/exceptions', 'try except finally raise'), - 'COERCIONS': ('ref/coercion-rules','CONVERSIONS'), - 'CONVERSIONS': ('ref/conversions', 'COERCIONS'), - 'IDENTIFIERS': ('ref/identifiers', 'keywords SPECIALIDENTIFIERS'), - 'SPECIALIDENTIFIERS': ('ref/id-classes', ''), - 'PRIVATENAMES': ('ref/atom-identifiers', ''), - 'LITERALS': ('ref/atom-literals', 'STRINGS NUMBERS TUPLELITERALS LISTLITERALS DICTIONARYLITERALS'), + 'EXCEPTIONS': ('exceptions', 'try except finally raise'), + 'CONVERSIONS': ('conversions', ''), + 'IDENTIFIERS': ('identifiers', 'keywords SPECIALIDENTIFIERS'), + 'SPECIALIDENTIFIERS': ('id-classes', ''), + 'PRIVATENAMES': ('atom-identifiers', ''), + 'LITERALS': ('atom-literals', 'STRINGS NUMBERS TUPLELITERALS ' + 'LISTLITERALS DICTIONARYLITERALS'), 'TUPLES': 'SEQUENCES', - 'TUPLELITERALS': ('ref/exprlists', 'TUPLES LITERALS'), - 'LISTS': ('lib/typesseq-mutable', 'LISTLITERALS'), - 'LISTLITERALS': ('ref/lists', 'LISTS LITERALS'), - 'DICTIONARIES': ('lib/typesmapping', 'DICTIONARYLITERALS'), - 'DICTIONARYLITERALS': ('ref/dict', 'DICTIONARIES LITERALS'), - 'ATTRIBUTES': ('ref/attribute-references', 'getattr hasattr setattr ATTRIBUTEMETHODS'), - 'SUBSCRIPTS': ('ref/subscriptions', 'SEQUENCEMETHODS1'), - 'SLICINGS': ('ref/slicings', 'SEQUENCEMETHODS2'), - 'CALLS': ('ref/calls', 'EXPRESSIONS'), - 'POWER': ('ref/power', 'EXPRESSIONS'), - 'UNARY': ('ref/unary', 'EXPRESSIONS'), - 'BINARY': ('ref/binary', 'EXPRESSIONS'), - 'SHIFTING': ('ref/shifting', 'EXPRESSIONS'), - 'BITWISE': ('ref/bitwise', 'EXPRESSIONS'), - 'COMPARISON': ('ref/comparisons', 'EXPRESSIONS BASICMETHODS'), - 'BOOLEAN': ('ref/Booleans', 'EXPRESSIONS TRUTHVALUE'), + 'TUPLELITERALS': ('exprlists', 'TUPLES LITERALS'), + 'LISTS': ('typesseq-mutable', 'LISTLITERALS'), + 'LISTLITERALS': ('lists', 'LISTS LITERALS'), + 'DICTIONARIES': ('typesmapping', 'DICTIONARYLITERALS'), + 'DICTIONARYLITERALS': ('dict', 'DICTIONARIES LITERALS'), + 'ATTRIBUTES': ('attribute-references', 'getattr hasattr setattr ATTRIBUTEMETHODS'), + 'SUBSCRIPTS': ('subscriptions', 'SEQUENCEMETHODS1'), + 'SLICINGS': ('slicings', 'SEQUENCEMETHODS2'), + 'CALLS': ('calls', 'EXPRESSIONS'), + 'POWER': ('power', 'EXPRESSIONS'), + 'UNARY': ('unary', 'EXPRESSIONS'), + 'BINARY': ('binary', 'EXPRESSIONS'), + 'SHIFTING': ('shifting', 'EXPRESSIONS'), + 'BITWISE': ('bitwise', 'EXPRESSIONS'), + 'COMPARISON': ('comparisons', 'EXPRESSIONS BASICMETHODS'), + 'BOOLEAN': ('booleans', 'EXPRESSIONS TRUTHVALUE'), 'ASSERTION': 'assert', - 'ASSIGNMENT': ('ref/assignment', 'AUGMENTEDASSIGNMENT'), - 'AUGMENTEDASSIGNMENT': ('ref/augassign', 'NUMBERMETHODS'), + 'ASSIGNMENT': ('assignment', 'AUGMENTEDASSIGNMENT'), + 'AUGMENTEDASSIGNMENT': ('augassign', 'NUMBERMETHODS'), 'DELETION': 'del', - 'PRINTING': 'print', 'RETURNING': 'return', 'IMPORTING': 'import', 'CONDITIONAL': 'if', - 'LOOPING': ('ref/compound', 'for while break continue'), - 'TRUTHVALUE': ('lib/truth', 'if while and or not BASICMETHODS'), - 'DEBUGGING': ('lib/module-pdb', 'pdb'), - 'CONTEXTMANAGERS': ('ref/context-managers', 'with'), + 'LOOPING': ('compound', 'for while break continue'), + 'TRUTHVALUE': ('truth', 'if while and or not BASICMETHODS'), + 'DEBUGGING': ('debugger', 'pdb'), + 'CONTEXTMANAGERS': ('context-managers', 'with'), } def __init__(self, input, output): self.input = input self.output = output - self.docdir = None - execdir = os.path.dirname(sys.executable) - homedir = os.environ.get('PYTHONHOME') - join = os.path.join - for dir in [os.environ.get('PYTHONDOCS'), - homedir and os.path.join(homedir, 'doc'), - join(execdir, 'doc'), # for Windows - join(sys.prefix, 'doc/python-docs-' + sys.version.split()[0]), - join(sys.prefix, 'doc/python-' + sys.version.split()[0]), - join(sys.prefix, 'doc/python-docs-' + sys.version[:3]), - join(sys.prefix, 'doc/python-' + sys.version[:3]), - join(sys.prefix, 'Resources/English.lproj/Documentation')]: - if dir and os.path.isdir(join(dir, 'lib')): - self.docdir = dir - break - if dir and os.path.isdir(join(dir, 'html', 'lib')): - self.docdir = join(dir, 'html') - break def __repr__(self): if inspect.stack()[1][3] == '?': @@ -1760,14 +1760,12 @@ self.list(self.topics.keys()) def showtopic(self, topic): - if not self.docdir: + try: + import pydoc_topics + except ImportError: self.output.write(''' -Sorry, topic and keyword documentation is not available because the Python -HTML documentation files could not be found. If you have installed them, -please set the environment variable PYTHONDOCS to indicate their location. - -On the Microsoft Windows operating system, the files can be built by -running "hh -decompile . PythonNN.chm" in the C:\PythonNN\Doc> directory. +Sorry, topic and keyword documentation is not available because the +module "pydoc_topics" could not be found. ''') return target = self.topics.get(topic, self.keywords.get(topic)) @@ -1777,31 +1775,15 @@ if type(target) is type(''): return self.showtopic(target) - filename, xrefs = target - filename = self.docdir + '/' + filename + '.html' + label, xrefs = target try: - file = open(filename) - except: - self.output.write('could not read docs from %s\n' % filename) + doc = pydoc_topics.topics[label] + except KeyError: + self.output.write('no documentation found for %s\n' % repr(topic)) return - - divpat = re.compile(']*navigat.*?', re.I | re.S) - addrpat = re.compile('.*?', re.I | re.S) - document = re.sub(addrpat, '', re.sub(divpat, '', file.read())) - file.close() - - import htmllib, formatter, io - buffer = io.StringIO() - parser = htmllib.HTMLParser( - formatter.AbstractFormatter(formatter.DumbWriter(buffer))) - parser.start_table = parser.do_p - parser.end_table = lambda parser=parser: parser.do_p({}) - parser.start_tr = parser.do_br - parser.start_td = parser.start_th = lambda a, b=buffer: b.write('\t') - parser.feed(document) - buffer = replace(buffer.getvalue(), '\xa0', ' ', '\n', '\n ') - pager(' ' + buffer.strip() + '\n') + pager(doc.strip() + '\n') if xrefs: + import io, formatter buffer = io.StringIO() formatter.DumbWriter(buffer).send_flowing_data( 'Related help topics: ' + ', '.join(xrefs.split()) + '\n') Copied: python/branches/py3k/Lib/pydoc_topics.py (from r63871, /python/trunk/Lib/pydoc_topics.py) ============================================================================== --- /python/trunk/Lib/pydoc_topics.py (original) +++ python/branches/py3k/Lib/pydoc_topics.py Sun Jun 1 23:05:17 2008 @@ -1,83 +1,78 @@ -# Autogenerated by Sphinx on Sun Jun 1 22:23:15 2008 -topics = {'assert': u'\nThe ``assert`` statement\n************************\n\nAssert statements are a convenient way to insert debugging assertions\ninto a program:\n\n assert_stmt ::= "assert" expression ["," expression]\n\nThe simple form, ``assert expression``, is equivalent to\n\n if __debug__:\n if not expression: raise AssertionError\n\nThe extended form, ``assert expression1, expression2``, is equivalent\nto\n\n if __debug__:\n if not expression1: raise AssertionError, expression2\n\nThese equivalences assume that ``__debug__`` and ``AssertionError``\nrefer to the built-in variables with those names. In the current\nimplementation, the built-in variable ``__debug__`` is ``True`` under\nnormal circumstances, ``False`` when optimization is requested\n(command line option -O). The current code generator emits no code\nfor an assert statement when optimization is requested at compile\ntime. Note that it is unnecessary to include the source code for the\nexpression that failed in the error message; it will be displayed as\npart of the stack trace.\n\nAssignments to ``__debug__`` are illegal. The value for the built-in\nvariable is determined when the interpreter starts.\n', - 'assignment': u'\nAssignment statements\n*********************\n\nAssignment statements are used to (re)bind names to values and to\nmodify attributes or items of mutable objects:\n\n assignment_stmt ::= (target_list "=")+ (expression_list | yield_expression)\n target_list ::= target ("," target)* [","]\n target ::= identifier\n | "(" target_list ")"\n | "[" target_list "]"\n | attributeref\n | subscription\n | slicing\n\n(See section *Primaries* for the syntax definitions for the last three\nsymbols.)\n\nAn assignment statement evaluates the expression list (remember that\nthis can be a single expression or a comma-separated list, the latter\nyielding a tuple) and assigns the single resulting object to each of\nthe target lists, from left to right.\n\nAssignment is defined recursively depending on the form of the target\n(list). When a target is part of a mutable object (an attribute\nreference, subscription or slicing), the mutable object must\nultimately perform the assignment and decide about its validity, and\nmay raise an exception if the assignment is unacceptable. The rules\nobserved by various types and the exceptions raised are given with the\ndefinition of the object types (see section *The standard type\nhierarchy*).\n\nAssignment of an object to a target list is recursively defined as\nfollows.\n\n* If the target list is a single target: The object is assigned to\n that target.\n\n* If the target list is a comma-separated list of targets: The object\n must be a sequence with the same number of items as there are\n targets in the target list, and the items are assigned, from left to\n right, to the corresponding targets. (This rule is relaxed as of\n Python 1.5; in earlier versions, the object had to be a tuple.\n Since strings are sequences, an assignment like ``a, b = "xy"`` is\n now legal as long as the string has the right length.)\n\nAssignment of an object to a single target is recursively defined as\nfollows.\n\n* If the target is an identifier (name):\n\n * If the name does not occur in a ``global`` statement in the\n current code block: the name is bound to the object in the current\n local namespace.\n\n * Otherwise: the name is bound to the object in the current global\n namespace.\n\n The name is rebound if it was already bound. This may cause the\n reference count for the object previously bound to the name to reach\n zero, causing the object to be deallocated and its destructor (if it\n has one) to be called.\n\n* If the target is a target list enclosed in parentheses or in square\n brackets: The object must be a sequence with the same number of\n items as there are targets in the target list, and its items are\n assigned, from left to right, to the corresponding targets.\n\n* If the target is an attribute reference: The primary expression in\n the reference is evaluated. It should yield an object with\n assignable attributes; if this is not the case, ``TypeError`` is\n raised. That object is then asked to assign the assigned object to\n the given attribute; if it cannot perform the assignment, it raises\n an exception (usually but not necessarily ``AttributeError``).\n\n* If the target is a subscription: The primary expression in the\n reference is evaluated. It should yield either a mutable sequence\n object (such as a list) or a mapping object (such as a dictionary).\n Next, the subscript expression is evaluated.\n\n If the primary is a mutable sequence object (such as a list), the\n subscript must yield a plain integer. If it is negative, the\n sequence\'s length is added to it. The resulting value must be a\n nonnegative integer less than the sequence\'s length, and the\n sequence is asked to assign the assigned object to its item with\n that index. If the index is out of range, ``IndexError`` is raised\n (assignment to a subscripted sequence cannot add new items to a\n list).\n\n If the primary is a mapping object (such as a dictionary), the\n subscript must have a type compatible with the mapping\'s key type,\n and the mapping is then asked to create a key/datum pair which maps\n the subscript to the assigned object. This can either replace an\n existing key/value pair with the same key value, or insert a new\n key/value pair (if no key with the same value existed).\n\n* If the target is a slicing: The primary expression in the reference\n is evaluated. It should yield a mutable sequence object (such as a\n list). The assigned object should be a sequence object of the same\n type. Next, the lower and upper bound expressions are evaluated,\n insofar they are present; defaults are zero and the sequence\'s\n length. The bounds should evaluate to (small) integers. If either\n bound is negative, the sequence\'s length is added to it. The\n resulting bounds are clipped to lie between zero and the sequence\'s\n length, inclusive. Finally, the sequence object is asked to replace\n the slice with the items of the assigned sequence. The length of\n the slice may be different from the length of the assigned sequence,\n thus changing the length of the target sequence, if the object\n allows it.\n\n(In the current implementation, the syntax for targets is taken to be\nthe same as for expressions, and invalid syntax is rejected during the\ncode generation phase, causing less detailed error messages.)\n\nWARNING: Although the definition of assignment implies that overlaps\nbetween the left-hand side and the right-hand side are \'safe\' (for\nexample ``a, b = b, a`` swaps two variables), overlaps *within* the\ncollection of assigned-to variables are not safe! For instance, the\nfollowing program prints ``[0, 2]``:\n\n x = [0, 1]\n i = 0\n i, x[i] = 1, 2\n print x\n\n\nAugmented assignment statements\n===============================\n\nAugmented assignment is the combination, in a single statement, of a\nbinary operation and an assignment statement:\n\n augmented_assignment_stmt ::= target augop (expression_list | yield_expression)\n augop ::= "+=" | "-=" | "*=" | "/=" | "%=" | "**="\n | ">>=" | "<<=" | "&=" | "^=" | "|="\n\n(See section *Primaries* for the syntax definitions for the last three\nsymbols.)\n\nAn augmented assignment evaluates the target (which, unlike normal\nassignment statements, cannot be an unpacking) and the expression\nlist, performs the binary operation specific to the type of assignment\non the two operands, and assigns the result to the original target.\nThe target is only evaluated once.\n\nAn augmented assignment expression like ``x += 1`` can be rewritten as\n``x = x + 1`` to achieve a similar, but not exactly equal effect. In\nthe augmented version, ``x`` is only evaluated once. Also, when\npossible, the actual operation is performed *in-place*, meaning that\nrather than creating a new object and assigning that to the target,\nthe old object is modified instead.\n\nWith the exception of assigning to tuples and multiple targets in a\nsingle statement, the assignment done by augmented assignment\nstatements is handled the same way as normal assignments. Similarly,\nwith the exception of the possible *in-place* behavior, the binary\noperation performed by augmented assignment is the same as the normal\nbinary operations.\n\nFor targets which are attribute references, the initial value is\nretrieved with a ``getattr()`` and the result is assigned with a\n``setattr()``. Notice that the two methods do not necessarily refer\nto the same variable. When ``getattr()`` refers to a class variable,\n``setattr()`` still writes to an instance variable. For example:\n\n class A:\n x = 3 # class variable\n a = A()\n a.x += 1 # writes a.x as 4 leaving A.x as 3\n', - 'atom-identifiers': u'\nIdentifiers (Names)\n*******************\n\nAn identifier occurring as an atom is a name. See section\n*Identifiers and keywords* for lexical definition and section *Naming\nand binding* for documentation of naming and binding.\n\nWhen the name is bound to an object, evaluation of the atom yields\nthat object. When a name is not bound, an attempt to evaluate it\nraises a ``NameError`` exception.\n\n**Private name mangling:** When an identifier that textually occurs in\na class definition begins with two or more underscore characters and\ndoes not end in two or more underscores, it is considered a *private\nname* of that class. Private names are transformed to a longer form\nbefore code is generated for them. The transformation inserts the\nclass name in front of the name, with leading underscores removed, and\na single underscore inserted in front of the class name. For example,\nthe identifier ``__spam`` occurring in a class named ``Ham`` will be\ntransformed to ``_Ham__spam``. This transformation is independent of\nthe syntactical context in which the identifier is used. If the\ntransformed name is extremely long (longer than 255 characters),\nimplementation defined truncation may happen. If the class name\nconsists only of underscores, no transformation is done.\n', - 'atom-literals': u"\nLiterals\n********\n\nPython supports string literals and various numeric literals:\n\n literal ::= stringliteral | integer | longinteger\n | floatnumber | imagnumber\n\nEvaluation of a literal yields an object of the given type (string,\ninteger, long integer, floating point number, complex number) with the\ngiven value. The value may be approximated in the case of floating\npoint and imaginary (complex) literals. See section *Literals* for\ndetails.\n\nAll literals correspond to immutable data types, and hence the\nobject's identity is less important than its value. Multiple\nevaluations of literals with the same value (either the same\noccurrence in the program text or a different occurrence) may obtain\nthe same object or a different object with the same value.\n", - 'attribute-access': u'\nCustomizing attribute access\n****************************\n\nThe following methods can be defined to customize the meaning of\nattribute access (use of, assignment to, or deletion of ``x.name``)\nfor class instances.\n\nobject.__getattr__(self, name)\n\n Called when an attribute lookup has not found the attribute in the\n usual places (i.e. it is not an instance attribute nor is it found\n in the class tree for ``self``). ``name`` is the attribute name.\n This method should return the (computed) attribute value or raise\n an ``AttributeError`` exception.\n\n Note that if the attribute is found through the normal mechanism,\n ``__getattr__()`` is not called. (This is an intentional asymmetry\n between ``__getattr__()`` and ``__setattr__()``.) This is done both\n for efficiency reasons and because otherwise ``__setattr__()``\n would have no way to access other attributes of the instance. Note\n that at least for instance variables, you can fake total control by\n not inserting any values in the instance attribute dictionary (but\n instead inserting them in another object). See the\n ``__getattribute__()`` method below for a way to actually get total\n control in new-style classes.\n\nobject.__setattr__(self, name, value)\n\n Called when an attribute assignment is attempted. This is called\n instead of the normal mechanism (i.e. store the value in the\n instance dictionary). *name* is the attribute name, *value* is the\n value to be assigned to it.\n\n If ``__setattr__()`` wants to assign to an instance attribute, it\n should not simply execute ``self.name = value`` --- this would\n cause a recursive call to itself. Instead, it should insert the\n value in the dictionary of instance attributes, e.g.,\n ``self.__dict__[name] = value``. For new-style classes, rather\n than accessing the instance dictionary, it should call the base\n class method with the same name, for example,\n ``object.__setattr__(self, name, value)``.\n\nobject.__delattr__(self, name)\n\n Like ``__setattr__()`` but for attribute deletion instead of\n assignment. This should only be implemented if ``del obj.name`` is\n meaningful for the object.\n\n\nMore attribute access for new-style classes\n===========================================\n\nThe following methods only apply to new-style classes.\n\nobject.__getattribute__(self, name)\n\n Called unconditionally to implement attribute accesses for\n instances of the class. If the class also defines\n ``__getattr__()``, the latter will not be called unless\n ``__getattribute__()`` either calls it explicitly or raises an\n ``AttributeError``. This method should return the (computed)\n attribute value or raise an ``AttributeError`` exception. In order\n to avoid infinite recursion in this method, its implementation\n should always call the base class method with the same name to\n access any attributes it needs, for example,\n ``object.__getattribute__(self, name)``.\n\n\nImplementing Descriptors\n========================\n\nThe following methods only apply when an instance of the class\ncontaining the method (a so-called *descriptor* class) appears in the\nclass dictionary of another new-style class, known as the *owner*\nclass. In the examples below, "the attribute" refers to the attribute\nwhose name is the key of the property in the owner class\'\n``__dict__``. Descriptors can only be implemented as new-style\nclasses themselves.\n\nobject.__get__(self, instance, owner)\n\n Called to get the attribute of the owner class (class attribute\n access) or of an instance of that class (instance attribute\n access). *owner* is always the owner class, while *instance* is the\n instance that the attribute was accessed through, or ``None`` when\n the attribute is accessed through the *owner*. This method should\n return the (computed) attribute value or raise an\n ``AttributeError`` exception.\n\nobject.__set__(self, instance, value)\n\n Called to set the attribute on an instance *instance* of the owner\n class to a new value, *value*.\n\nobject.__delete__(self, instance)\n\n Called to delete the attribute on an instance *instance* of the\n owner class.\n\n\nInvoking Descriptors\n====================\n\nIn general, a descriptor is an object attribute with "binding\nbehavior", one whose attribute access has been overridden by methods\nin the descriptor protocol: ``__get__()``, ``__set__()``, and\n``__delete__()``. If any of those methods are defined for an object,\nit is said to be a descriptor.\n\nThe default behavior for attribute access is to get, set, or delete\nthe attribute from an object\'s dictionary. For instance, ``a.x`` has a\nlookup chain starting with ``a.__dict__[\'x\']``, then\n``type(a).__dict__[\'x\']``, and continuing through the base classes of\n``type(a)`` excluding metaclasses.\n\nHowever, if the looked-up value is an object defining one of the\ndescriptor methods, then Python may override the default behavior and\ninvoke the descriptor method instead. Where this occurs in the\nprecedence chain depends on which descriptor methods were defined and\nhow they were called. Note that descriptors are only invoked for new\nstyle objects or classes (ones that subclass ``object()`` or\n``type()``).\n\nThe starting point for descriptor invocation is a binding, ``a.x``.\nHow the arguments are assembled depends on ``a``:\n\nDirect Call\n The simplest and least common call is when user code directly\n invokes a descriptor method: ``x.__get__(a)``.\n\nInstance Binding\n If binding to a new-style object instance, ``a.x`` is transformed\n into the call: ``type(a).__dict__[\'x\'].__get__(a, type(a))``.\n\nClass Binding\n If binding to a new-style class, ``A.x`` is transformed into the\n call: ``A.__dict__[\'x\'].__get__(None, A)``.\n\nSuper Binding\n If ``a`` is an instance of ``super``, then the binding ``super(B,\n obj).m()`` searches ``obj.__class__.__mro__`` for the base class\n ``A`` immediately preceding ``B`` and then invokes the descriptor\n with the call: ``A.__dict__[\'m\'].__get__(obj, A)``.\n\nFor instance bindings, the precedence of descriptor invocation depends\non the which descriptor methods are defined. Normally, data\ndescriptors define both ``__get__()`` and ``__set__()``, while non-\ndata descriptors have just the ``__get__()`` method. Data descriptors\nalways override a redefinition in an instance dictionary. In\ncontrast, non-data descriptors can be overridden by instances. [3]\n\nPython methods (including ``staticmethod()`` and ``classmethod()``)\nare implemented as non-data descriptors. Accordingly, instances can\nredefine and override methods. This allows individual instances to\nacquire behaviors that differ from other instances of the same class.\n\nThe ``property()`` function is implemented as a data descriptor.\nAccordingly, instances cannot override the behavior of a property.\n\n\n__slots__\n=========\n\nBy default, instances of both old and new-style classes have a\ndictionary for attribute storage. This wastes space for objects\nhaving very few instance variables. The space consumption can become\nacute when creating large numbers of instances.\n\nThe default can be overridden by defining *__slots__* in a new-style\nclass definition. The *__slots__* declaration takes a sequence of\ninstance variables and reserves just enough space in each instance to\nhold a value for each variable. Space is saved because *__dict__* is\nnot created for each instance.\n\n__slots__\n\n This class variable can be assigned a string, iterable, or sequence\n of strings with variable names used by instances. If defined in a\n new-style class, *__slots__* reserves space for the declared\n variables and prevents the automatic creation of *__dict__* and\n *__weakref__* for each instance.\n\n Added in version 2.2.\n\nNotes on using *__slots__*\n\n* Without a *__dict__* variable, instances cannot be assigned new\n variables not listed in the *__slots__* definition. Attempts to\n assign to an unlisted variable name raises ``AttributeError``. If\n dynamic assignment of new variables is desired, then add\n ``\'__dict__\'`` to the sequence of strings in the *__slots__*\n declaration.\n\n Changed in version 2.3: Previously, adding ``\'__dict__\'`` to the\n *__slots__* declaration would not enable the assignment of new\n attributes not specifically listed in the sequence of instance\n variable names.\n\n* Without a *__weakref__* variable for each instance, classes defining\n *__slots__* do not support weak references to its instances. If weak\n reference support is needed, then add ``\'__weakref__\'`` to the\n sequence of strings in the *__slots__* declaration.\n\n Changed in version 2.3: Previously, adding ``\'__weakref__\'`` to the\n *__slots__* declaration would not enable support for weak\n references.\n\n* *__slots__* are implemented at the class level by creating\n descriptors (*Implementing Descriptors*) for each variable name. As\n a result, class attributes cannot be used to set default values for\n instance variables defined by *__slots__*; otherwise, the class\n attribute would overwrite the descriptor assignment.\n\n* If a class defines a slot also defined in a base class, the instance\n variable defined by the base class slot is inaccessible (except by\n retrieving its descriptor directly from the base class). This\n renders the meaning of the program undefined. In the future, a\n check may be added to prevent this.\n\n* The action of a *__slots__* declaration is limited to the class\n where it is defined. As a result, subclasses will have a *__dict__*\n unless they also define *__slots__*.\n\n* *__slots__* do not work for classes derived from "variable-length"\n built-in types such as ``long``, ``str`` and ``tuple``.\n\n* Any non-string iterable may be assigned to *__slots__*. Mappings may\n also be used; however, in the future, special meaning may be\n assigned to the values corresponding to each key.\n\n* *__class__* assignment works only if both classes have the same\n *__slots__*.\n\n Changed in version 2.6: Previously, *__class__* assignment raised an\n error if either new or old class had *__slots__*.\n', - 'attribute-references': u'\nAttribute references\n********************\n\nAn attribute reference is a primary followed by a period and a name:\n\n attributeref ::= primary "." identifier\n\nThe primary must evaluate to an object of a type that supports\nattribute references, e.g., a module, list, or an instance. This\nobject is then asked to produce the attribute whose name is the\nidentifier. If this attribute is not available, the exception\n``AttributeError`` is raised. Otherwise, the type and value of the\nobject produced is determined by the object. Multiple evaluations of\nthe same attribute reference may yield different objects.\n', - 'augassign': u'\nAugmented assignment statements\n*******************************\n\nAugmented assignment is the combination, in a single statement, of a\nbinary operation and an assignment statement:\n\n augmented_assignment_stmt ::= target augop (expression_list | yield_expression)\n augop ::= "+=" | "-=" | "*=" | "/=" | "%=" | "**="\n | ">>=" | "<<=" | "&=" | "^=" | "|="\n\n(See section *Primaries* for the syntax definitions for the last three\nsymbols.)\n\nAn augmented assignment evaluates the target (which, unlike normal\nassignment statements, cannot be an unpacking) and the expression\nlist, performs the binary operation specific to the type of assignment\non the two operands, and assigns the result to the original target.\nThe target is only evaluated once.\n\nAn augmented assignment expression like ``x += 1`` can be rewritten as\n``x = x + 1`` to achieve a similar, but not exactly equal effect. In\nthe augmented version, ``x`` is only evaluated once. Also, when\npossible, the actual operation is performed *in-place*, meaning that\nrather than creating a new object and assigning that to the target,\nthe old object is modified instead.\n\nWith the exception of assigning to tuples and multiple targets in a\nsingle statement, the assignment done by augmented assignment\nstatements is handled the same way as normal assignments. Similarly,\nwith the exception of the possible *in-place* behavior, the binary\noperation performed by augmented assignment is the same as the normal\nbinary operations.\n\nFor targets which are attribute references, the initial value is\nretrieved with a ``getattr()`` and the result is assigned with a\n``setattr()``. Notice that the two methods do not necessarily refer\nto the same variable. When ``getattr()`` refers to a class variable,\n``setattr()`` still writes to an instance variable. For example:\n\n class A:\n x = 3 # class variable\n a = A()\n a.x += 1 # writes a.x as 4 leaving A.x as 3\n', - 'binary': u'\nBinary arithmetic operations\n****************************\n\nThe binary arithmetic operations have the conventional priority\nlevels. Note that some of these operations also apply to certain non-\nnumeric types. Apart from the power operator, there are only two\nlevels, one for multiplicative operators and one for additive\noperators:\n\n m_expr ::= u_expr | m_expr "*" u_expr | m_expr "//" u_expr | m_expr "/" u_expr\n | m_expr "%" u_expr\n a_expr ::= m_expr | a_expr "+" m_expr | a_expr "-" m_expr\n\nThe ``*`` (multiplication) operator yields the product of its\narguments. The arguments must either both be numbers, or one argument\nmust be an integer (plain or long) and the other must be a sequence.\nIn the former case, the numbers are converted to a common type and\nthen multiplied together. In the latter case, sequence repetition is\nperformed; a negative repetition factor yields an empty sequence.\n\nThe ``/`` (division) and ``//`` (floor division) operators yield the\nquotient of their arguments. The numeric arguments are first\nconverted to a common type. Plain or long integer division yields an\ninteger of the same type; the result is that of mathematical division\nwith the \'floor\' function applied to the result. Division by zero\nraises the ``ZeroDivisionError`` exception.\n\nThe ``%`` (modulo) operator yields the remainder from the division of\nthe first argument by the second. The numeric arguments are first\nconverted to a common type. A zero right argument raises the\n``ZeroDivisionError`` exception. The arguments may be floating point\nnumbers, e.g., ``3.14%0.7`` equals ``0.34`` (since ``3.14`` equals\n``4*0.7 + 0.34``.) The modulo operator always yields a result with\nthe same sign as its second operand (or zero); the absolute value of\nthe result is strictly smaller than the absolute value of the second\noperand [2].\n\nThe integer division and modulo operators are connected by the\nfollowing identity: ``x == (x/y)*y + (x%y)``. Integer division and\nmodulo are also connected with the built-in function ``divmod()``:\n``divmod(x, y) == (x/y, x%y)``. These identities don\'t hold for\nfloating point numbers; there similar identities hold approximately\nwhere ``x/y`` is replaced by ``floor(x/y)`` or ``floor(x/y) - 1`` [3].\n\nIn addition to performing the modulo operation on numbers, the ``%``\noperator is also overloaded by string and unicode objects to perform\nstring formatting (also known as interpolation). The syntax for string\nformatting is described in the Python Library Reference, section\n*String Formatting Operations*.\n\nDeprecated in version 2.3: The floor division operator, the modulo\noperator, and the ``divmod()`` function are no longer defined for\ncomplex numbers. Instead, convert to a floating point number using\nthe ``abs()`` function if appropriate.\n\nThe ``+`` (addition) operator yields the sum of its arguments. The\narguments must either both be numbers or both sequences of the same\ntype. In the former case, the numbers are converted to a common type\nand then added together. In the latter case, the sequences are\nconcatenated.\n\nThe ``-`` (subtraction) operator yields the difference of its\narguments. The numeric arguments are first converted to a common\ntype.\n', - 'bitwise': u'\nBinary bitwise operations\n*************************\n\nEach of the three bitwise operations has a different priority level:\n\n and_expr ::= shift_expr | and_expr "&" shift_expr\n xor_expr ::= and_expr | xor_expr "^" and_expr\n or_expr ::= xor_expr | or_expr "|" xor_expr\n\nThe ``&`` operator yields the bitwise AND of its arguments, which must\nbe plain or long integers. The arguments are converted to a common\ntype.\n\nThe ``^`` operator yields the bitwise XOR (exclusive OR) of its\narguments, which must be plain or long integers. The arguments are\nconverted to a common type.\n\nThe ``|`` operator yields the bitwise (inclusive) OR of its arguments,\nwhich must be plain or long integers. The arguments are converted to\na common type.\n', - 'bltin-code-objects': u'\nCode Objects\n************\n\nCode objects are used by the implementation to represent "pseudo-\ncompiled" executable Python code such as a function body. They differ\nfrom function objects because they don\'t contain a reference to their\nglobal execution environment. Code objects are returned by the built-\nin ``compile()`` function and can be extracted from function objects\nthrough their ``func_code`` attribute. See also the ``code`` module.\n\nA code object can be executed or evaluated by passing it (instead of a\nsource string) to the ``exec`` statement or the built-in ``eval()``\nfunction.\n\nSee *The standard type hierarchy* for more information.\n', - 'bltin-ellipsis-object': u'\nThe Ellipsis Object\n*******************\n\nThis object is used by extended slice notation (see *Slicings*). It\nsupports no special operations. There is exactly one ellipsis object,\nnamed ``Ellipsis`` (a built-in name).\n\nIt is written as ``Ellipsis``.\n', - 'bltin-file-objects': u'\nFile Objects\n************\n\nFile objects are implemented using C\'s ``stdio`` package and can be\ncreated with the built-in ``open()`` function. File objects are also\nreturned by some other built-in functions and methods, such as\n``os.popen()`` and ``os.fdopen()`` and the ``makefile()`` method of\nsocket objects. Temporary files can be created using the ``tempfile``\nmodule, and high-level file operations such as copying, moving, and\ndeleting files and directories can be achieved with the ``shutil``\nmodule.\n\nWhen a file operation fails for an I/O-related reason, the exception\n``IOError`` is raised. This includes situations where the operation\nis not defined for some reason, like ``seek()`` on a tty device or\nwriting a file opened for reading.\n\nFiles have the following methods:\n\nfile.close()\n\n Close the file. A closed file cannot be read or written any more.\n Any operation which requires that the file be open will raise a\n ``ValueError`` after the file has been closed. Calling ``close()``\n more than once is allowed.\n\n As of Python 2.5, you can avoid having to call this method\n explicitly if you use the ``with`` statement. For example, the\n following code will automatically close *f* when the ``with`` block\n is exited:\n\n from __future__ import with_statement\n\n with open("hello.txt") as f:\n for line in f:\n print line\n\n In older versions of Python, you would have needed to do this to\n get the same effect:\n\n f = open("hello.txt")\n try:\n for line in f:\n print line\n finally:\n f.close()\n\n Note: Not all "file-like" types in Python support use as a context\n manager for the ``with`` statement. If your code is intended to\n work with any file-like object, you can use the function\n ``contextlib.closing()`` instead of using the object directly.\n\nfile.flush()\n\n Flush the internal buffer, like ``stdio``\'s ``fflush``. This may\n be a no-op on some file-like objects.\n\nfile.fileno()\n\n Return the integer "file descriptor" that is used by the underlying\n implementation to request I/O operations from the operating system.\n This can be useful for other, lower level interfaces that use file\n descriptors, such as the ``fcntl`` module or ``os.read()`` and\n friends.\n\n Note: File-like objects which do not have a real file descriptor should\n *not* provide this method!\n\nfile.isatty()\n\n Return ``True`` if the file is connected to a tty(-like) device,\n else ``False``.\n\n Note: If a file-like object is not associated with a real file, this\n method should *not* be implemented.\n\nfile.next()\n\n A file object is its own iterator, for example ``iter(f)`` returns\n *f* (unless *f* is closed). When a file is used as an iterator,\n typically in a ``for`` loop (for example, ``for line in f: print\n line``), the ``next()`` method is called repeatedly. This method\n returns the next input line, or raises ``StopIteration`` when EOF\n is hit when the file is open for reading (behavior is undefined\n when the file is open for writing). In order to make a ``for``\n loop the most efficient way of looping over the lines of a file (a\n very common operation), the ``next()`` method uses a hidden read-\n ahead buffer. As a consequence of using a read-ahead buffer,\n combining ``next()`` with other file methods (like ``readline()``)\n does not work right. However, using ``seek()`` to reposition the\n file to an absolute position will flush the read-ahead buffer.\n\n Added in version 2.3.\n\nfile.read([size])\n\n Read at most *size* bytes from the file (less if the read hits EOF\n before obtaining *size* bytes). If the *size* argument is negative\n or omitted, read all data until EOF is reached. The bytes are\n returned as a string object. An empty string is returned when EOF\n is encountered immediately. (For certain files, like ttys, it\n makes sense to continue reading after an EOF is hit.) Note that\n this method may call the underlying C function ``fread`` more than\n once in an effort to acquire as close to *size* bytes as possible.\n Also note that when in non-blocking mode, less data than what was\n requested may be returned, even if no *size* parameter was given.\n\nfile.readline([size])\n\n Read one entire line from the file. A trailing newline character\n is kept in the string (but may be absent when a file ends with an\n incomplete line). [6] If the *size* argument is present and non-\n negative, it is a maximum byte count (including the trailing\n newline) and an incomplete line may be returned. An empty string is\n returned *only* when EOF is encountered immediately.\n\n Note: Unlike ``stdio``\'s ``fgets``, the returned string contains null\n characters (``\'\\0\'``) if they occurred in the input.\n\nfile.readlines([sizehint])\n\n Read until EOF using ``readline()`` and return a list containing\n the lines thus read. If the optional *sizehint* argument is\n present, instead of reading up to EOF, whole lines totalling\n approximately *sizehint* bytes (possibly after rounding up to an\n internal buffer size) are read. Objects implementing a file-like\n interface may choose to ignore *sizehint* if it cannot be\n implemented, or cannot be implemented efficiently.\n\nfile.xreadlines()\n\n This method returns the same thing as ``iter(f)``.\n\n Added in version 2.1.\n\n Deprecated in version 2.3: Use ``for line in file`` instead.\n\nfile.seek(offset[, whence])\n\n Set the file\'s current position, like ``stdio``\'s ``fseek``. The\n *whence* argument is optional and defaults to ``os.SEEK_SET`` or\n ``0`` (absolute file positioning); other values are ``os.SEEK_CUR``\n or ``1`` (seek relative to the current position) and\n ``os.SEEK_END`` or ``2`` (seek relative to the file\'s end). There\n is no return value.\n\n For example, ``f.seek(2, os.SEEK_CUR)`` advances the position by\n two and ``f.seek(-3, os.SEEK_END)`` sets the position to the third\n to last.\n\n Note that if the file is opened for appending (mode ``\'a\'`` or\n ``\'a+\'``), any ``seek()`` operations will be undone at the next\n write. If the file is only opened for writing in append mode (mode\n ``\'a\'``), this method is essentially a no-op, but it remains useful\n for files opened in append mode with reading enabled (mode\n ``\'a+\'``). If the file is opened in text mode (without ``\'b\'``),\n only offsets returned by ``tell()`` are legal. Use of other\n offsets causes undefined behavior.\n\n Note that not all file objects are seekable.\n\n Changed in version 2.6: Passing float values as offset has been\n deprecated.\n\nfile.tell()\n\n Return the file\'s current position, like ``stdio``\'s ``ftell``.\n\n Note: On Windows, ``tell()`` can return illegal values (after an\n ``fgets``) when reading files with Unix-style line-endings. Use\n binary mode (``\'rb\'``) to circumvent this problem.\n\nfile.truncate([size])\n\n Truncate the file\'s size. If the optional *size* argument is\n present, the file is truncated to (at most) that size. The size\n defaults to the current position. The current file position is not\n changed. Note that if a specified size exceeds the file\'s current\n size, the result is platform-dependent: possibilities include that\n the file may remain unchanged, increase to the specified size as if\n zero-filled, or increase to the specified size with undefined new\n content. Availability: Windows, many Unix variants.\n\nfile.write(str)\n\n Write a string to the file. There is no return value. Due to\n buffering, the string may not actually show up in the file until\n the ``flush()`` or ``close()`` method is called.\n\nfile.writelines(sequence)\n\n Write a sequence of strings to the file. The sequence can be any\n iterable object producing strings, typically a list of strings.\n There is no return value. (The name is intended to match\n ``readlines()``; ``writelines()`` does not add line separators.)\n\nFiles support the iterator protocol. Each iteration returns the same\nresult as ``file.readline()``, and iteration ends when the\n``readline()`` method returns an empty string.\n\nFile objects also offer a number of other interesting attributes.\nThese are not required for file-like objects, but should be\nimplemented if they make sense for the particular object.\n\nfile.closed\n\n bool indicating the current state of the file object. This is a\n read-only attribute; the ``close()`` method changes the value. It\n may not be available on all file-like objects.\n\nfile.encoding\n\n The encoding that this file uses. When Unicode strings are written\n to a file, they will be converted to byte strings using this\n encoding. In addition, when the file is connected to a terminal,\n the attribute gives the encoding that the terminal is likely to use\n (that information might be incorrect if the user has misconfigured\n the terminal). The attribute is read-only and may not be present\n on all file-like objects. It may also be ``None``, in which case\n the file uses the system default encoding for converting Unicode\n strings.\n\n Added in version 2.3.\n\nfile.errors\n\n The Unicode error handler used to along with the encoding.\n\n Added in version 2.6.\n\nfile.mode\n\n The I/O mode for the file. If the file was created using the\n ``open()`` built-in function, this will be the value of the *mode*\n parameter. This is a read-only attribute and may not be present on\n all file-like objects.\n\nfile.name\n\n If the file object was created using ``open()``, the name of the\n file. Otherwise, some string that indicates the source of the file\n object, of the form ``<...>``. This is a read-only attribute and\n may not be present on all file-like objects.\n\nfile.newlines\n\n If Python was built with the *--with-universal-newlines* option to\n **configure** (the default) this read-only attribute exists, and\n for files opened in universal newline read mode it keeps track of\n the types of newlines encountered while reading the file. The\n values it can take are ``\'\\r\'``, ``\'\\n\'``, ``\'\\r\\n\'``, ``None``\n (unknown, no newlines read yet) or a tuple containing all the\n newline types seen, to indicate that multiple newline conventions\n were encountered. For files not opened in universal newline read\n mode the value of this attribute will be ``None``.\n\nfile.softspace\n\n Boolean that indicates whether a space character needs to be\n printed before another value when using the ``print`` statement.\n Classes that are trying to simulate a file object should also have\n a writable ``softspace`` attribute, which should be initialized to\n zero. This will be automatic for most classes implemented in\n Python (care may be needed for objects that override attribute\n access); types implemented in C will have to provide a writable\n ``softspace`` attribute.\n\n Note: This attribute is not used to control the ``print`` statement,\n but to allow the implementation of ``print`` to keep track of its\n internal state.\n', - 'bltin-null-object': u"\nThe Null Object\n***************\n\nThis object is returned by functions that don't explicitly return a\nvalue. It supports no special operations. There is exactly one null\nobject, named ``None`` (a built-in name).\n\nIt is written as ``None``.\n", - 'bltin-type-objects': u"\nType Objects\n************\n\nType objects represent the various object types. An object's type is\naccessed by the built-in function ``type()``. There are no special\noperations on types. The standard module ``types`` defines names for\nall standard built-in types.\n\nTypes are written like this: ````.\n", - 'booleans': u'\nBoolean operations\n******************\n\nBoolean operations have the lowest priority of all Python operations:\n\n expression ::= conditional_expression | lambda_form\n old_expression ::= or_test | old_lambda_form\n conditional_expression ::= or_test ["if" or_test "else" expression]\n or_test ::= and_test | or_test "or" and_test\n and_test ::= not_test | and_test "and" not_test\n not_test ::= comparison | "not" not_test\n\nIn the context of Boolean operations, and also when expressions are\nused by control flow statements, the following values are interpreted\nas false: ``False``, ``None``, numeric zero of all types, and empty\nstrings and containers (including strings, tuples, lists,\ndictionaries, sets and frozensets). All other values are interpreted\nas true.\n\nThe operator ``not`` yields ``True`` if its argument is false,\n``False`` otherwise.\n\nThe expression ``x if C else y`` first evaluates *C* (*not* *x*); if\n*C* is true, *x* is evaluated and its value is returned; otherwise,\n*y* is evaluated and its value is returned.\n\nAdded in version 2.5.\n\nThe expression ``x and y`` first evaluates *x*; if *x* is false, its\nvalue is returned; otherwise, *y* is evaluated and the resulting value\nis returned.\n\nThe expression ``x or y`` first evaluates *x*; if *x* is true, its\nvalue is returned; otherwise, *y* is evaluated and the resulting value\nis returned.\n\n(Note that neither ``and`` nor ``or`` restrict the value and type they\nreturn to ``False`` and ``True``, but rather return the last evaluated\nargument. This is sometimes useful, e.g., if ``s`` is a string that\nshould be replaced by a default value if it is empty, the expression\n``s or \'foo\'`` yields the desired value. Because ``not`` has to\ninvent a value anyway, it does not bother to return a value of the\nsame type as its argument, so e.g., ``not \'foo\'`` yields ``False``,\nnot ``\'\'``.)\n', - 'break': u'\nThe ``break`` statement\n***********************\n\n break_stmt ::= "break"\n\n``break`` may only occur syntactically nested in a ``for`` or\n``while`` loop, but not nested in a function or class definition\nwithin that loop.\n\nIt terminates the nearest enclosing loop, skipping the optional\n``else`` clause if the loop has one.\n\nIf a ``for`` loop is terminated by ``break``, the loop control target\nkeeps its current value.\n\nWhen ``break`` passes control out of a ``try`` statement with a\n``finally`` clause, that ``finally`` clause is executed before really\nleaving the loop.\n', - 'callable-types': u'\nEmulating callable objects\n**************************\n\nobject.__call__(self[, args...])\n\n Called when the instance is "called" as a function; if this method\n is defined, ``x(arg1, arg2, ...)`` is a shorthand for\n ``x.__call__(arg1, arg2, ...)``.\n', - 'calls': u'\nCalls\n*****\n\nA call calls a callable object (e.g., a function) with a possibly\nempty series of arguments:\n\n call ::= primary "(" [argument_list [","]\n | expression genexpr_for] ")"\n argument_list ::= positional_arguments ["," keyword_arguments]\n ["," "*" expression]\n ["," "**" expression]\n | keyword_arguments ["," "*" expression]\n ["," "**" expression]\n | "*" expression ["," "**" expression]\n | "**" expression\n positional_arguments ::= expression ("," expression)*\n keyword_arguments ::= keyword_item ("," keyword_item)*\n keyword_item ::= identifier "=" expression\n\nA trailing comma may be present after the positional and keyword\narguments but does not affect the semantics.\n\nThe primary must evaluate to a callable object (user-defined\nfunctions, built-in functions, methods of built-in objects, class\nobjects, methods of class instances, and certain class instances\nthemselves are callable; extensions may define additional callable\nobject types). All argument expressions are evaluated before the call\nis attempted. Please refer to section *Function definitions* for the\nsyntax of formal parameter lists.\n\nIf keyword arguments are present, they are first converted to\npositional arguments, as follows. First, a list of unfilled slots is\ncreated for the formal parameters. If there are N positional\narguments, they are placed in the first N slots. Next, for each\nkeyword argument, the identifier is used to determine the\ncorresponding slot (if the identifier is the same as the first formal\nparameter name, the first slot is used, and so on). If the slot is\nalready filled, a ``TypeError`` exception is raised. Otherwise, the\nvalue of the argument is placed in the slot, filling it (even if the\nexpression is ``None``, it fills the slot). When all arguments have\nbeen processed, the slots that are still unfilled are filled with the\ncorresponding default value from the function definition. (Default\nvalues are calculated, once, when the function is defined; thus, a\nmutable object such as a list or dictionary used as default value will\nbe shared by all calls that don\'t specify an argument value for the\ncorresponding slot; this should usually be avoided.) If there are any\nunfilled slots for which no default value is specified, a\n``TypeError`` exception is raised. Otherwise, the list of filled\nslots is used as the argument list for the call.\n\nNote: An implementation may provide builtin functions whose positional\n parameters do not have names, even if they are \'named\' for the\n purpose of documentation, and which therefore cannot be supplied by\n keyword. In CPython, this is the case for functions implemented in\n C that use ``PyArg_ParseTuple`` to parse their arguments.\n\nIf there are more positional arguments than there are formal parameter\nslots, a ``TypeError`` exception is raised, unless a formal parameter\nusing the syntax ``*identifier`` is present; in this case, that formal\nparameter receives a tuple containing the excess positional arguments\n(or an empty tuple if there were no excess positional arguments).\n\nIf any keyword argument does not correspond to a formal parameter\nname, a ``TypeError`` exception is raised, unless a formal parameter\nusing the syntax ``**identifier`` is present; in this case, that\nformal parameter receives a dictionary containing the excess keyword\narguments (using the keywords as keys and the argument values as\ncorresponding values), or a (new) empty dictionary if there were no\nexcess keyword arguments.\n\nIf the syntax ``*expression`` appears in the function call,\n``expression`` must evaluate to a sequence. Elements from this\nsequence are treated as if they were additional positional arguments;\nif there are positional arguments *x1*,...,*xN* , and ``expression``\nevaluates to a sequence *y1*,...,*yM*, this is equivalent to a call\nwith M+N positional arguments *x1*,...,*xN*,*y1*,...,*yM*.\n\nA consequence of this is that although the ``*expression`` syntax\nappears *after* any keyword arguments, it is processed *before* the\nkeyword arguments (and the ``**expression`` argument, if any -- see\nbelow). So:\n\n >>> def f(a, b):\n ... print a, b\n ...\n >>> f(b=1, *(2,))\n 2 1\n >>> f(a=1, *(2,))\n Traceback (most recent call last):\n File "", line 1, in ?\n TypeError: f() got multiple values for keyword argument \'a\'\n >>> f(1, *(2,))\n 1 2\n\nIt is unusual for both keyword arguments and the ``*expression``\nsyntax to be used in the same call, so in practice this confusion does\nnot arise.\n\nIf the syntax ``**expression`` appears in the function call,\n``expression`` must evaluate to a mapping, the contents of which are\ntreated as additional keyword arguments. In the case of a keyword\nappearing in both ``expression`` and as an explicit keyword argument,\na ``TypeError`` exception is raised.\n\nFormal parameters using the syntax ``*identifier`` or ``**identifier``\ncannot be used as positional argument slots or as keyword argument\nnames. Formal parameters using the syntax ``(sublist)`` cannot be\nused as keyword argument names; the outermost sublist corresponds to a\nsingle unnamed argument slot, and the argument value is assigned to\nthe sublist using the usual tuple assignment rules after all other\nparameter processing is done.\n\nA call always returns some value, possibly ``None``, unless it raises\nan exception. How this value is computed depends on the type of the\ncallable object.\n\nIf it is---\n\na user-defined function:\n The code block for the function is executed, passing it the\n argument list. The first thing the code block will do is bind the\n formal parameters to the arguments; this is described in section\n *Function definitions*. When the code block executes a ``return``\n statement, this specifies the return value of the function call.\n\na built-in function or method:\n The result is up to the interpreter; see *Built-in Functions* for\n the descriptions of built-in functions and methods.\n\na class object:\n A new instance of that class is returned.\n\na class instance method:\n The corresponding user-defined function is called, with an argument\n list that is one longer than the argument list of the call: the\n instance becomes the first argument.\n\na class instance:\n The class must define a ``__call__()`` method; the effect is then\n the same as if that method was called.\n', - 'class': u'\nClass definitions\n*****************\n\nA class definition defines a class object (see section *The standard\ntype hierarchy*):\n\n classdef ::= "class" classname [inheritance] ":" suite\n inheritance ::= "(" [expression_list] ")"\n classname ::= identifier\n\nA class definition is an executable statement. It first evaluates the\ninheritance list, if present. Each item in the inheritance list\nshould evaluate to a class object or class type which allows\nsubclassing. The class\'s suite is then executed in a new execution\nframe (see section *Naming and binding*), using a newly created local\nnamespace and the original global namespace. (Usually, the suite\ncontains only function definitions.) When the class\'s suite finishes\nexecution, its execution frame is discarded but its local namespace is\nsaved. A class object is then created using the inheritance list for\nthe base classes and the saved local namespace for the attribute\ndictionary. The class name is bound to this class object in the\noriginal local namespace.\n\n**Programmer\'s note:** Variables defined in the class definition are\nclass variables; they are shared by all instances. To create instance\nvariables, they can be set in a method with ``self.name = value``.\nBoth class and instance variables are accessible through the notation\n"``self.name``", and an instance variable hides a class variable with\nthe same name when accessed in this way. Class variables can be used\nas defaults for instance variables, but using mutable values there can\nlead to unexpected results. For *new-style class*es, descriptors can\nbe used to create instance variables with different implementation\ndetails.\n\nClass definitions, like function definitions, may be wrapped by one or\nmore *decorator* expressions. The evaluation rules for the decorator\nexpressions are the same as for functions. The result must be a class\nobject, which is then bound to the class name.\n\n-[ Footnotes ]-\n\n[1] The exception is propagated to the invocation stack only if there\n is no ``finally`` clause that negates the exception.\n\n[2] Currently, control "flows off the end" except in the case of an\n exception or the execution of a ``return``, ``continue``, or\n ``break`` statement.\n', - 'coercion-rules': u"\nCoercion rules\n**************\n\nThis section used to document the rules for coercion. As the language\nhas evolved, the coercion rules have become hard to document\nprecisely; documenting what one version of one particular\nimplementation does is undesirable. Instead, here are some informal\nguidelines regarding coercion. In Python 3.0, coercion will not be\nsupported.\n\n* If the left operand of a % operator is a string or Unicode object,\n no coercion takes place and the string formatting operation is\n invoked instead.\n\n* It is no longer recommended to define a coercion operation. Mixed-\n mode operations on types that don't define coercion pass the\n original arguments to the operation.\n\n* New-style classes (those derived from ``object``) never invoke the\n ``__coerce__()`` method in response to a binary operator; the only\n time ``__coerce__()`` is invoked is when the built-in function\n ``coerce()`` is called.\n\n* For most intents and purposes, an operator that returns\n ``NotImplemented`` is treated the same as one that is not\n implemented at all.\n\n* Below, ``__op__()`` and ``__rop__()`` are used to signify the\n generic method names corresponding to an operator; ``__iop__()`` is\n used for the corresponding in-place operator. For example, for the\n operator '``+``', ``__add__()`` and ``__radd__()`` are used for the\n left and right variant of the binary operator, and ``__iadd__()``\n for the in-place variant.\n\n* For objects *x* and *y*, first ``x.__op__(y)`` is tried. If this is\n not implemented or returns ``NotImplemented``, ``y.__rop__(x)`` is\n tried. If this is also not implemented or returns\n ``NotImplemented``, a ``TypeError`` exception is raised. But see\n the following exception:\n\n* Exception to the previous item: if the left operand is an instance\n of a built-in type or a new-style class, and the right operand is an\n instance of a proper subclass of that type or class and overrides\n the base's ``__rop__()`` method, the right operand's ``__rop__()``\n method is tried *before* the left operand's ``__op__()`` method.\n\n This is done so that a subclass can completely override binary\n operators. Otherwise, the left operand's ``__op__()`` method would\n always accept the right operand: when an instance of a given class\n is expected, an instance of a subclass of that class is always\n acceptable.\n\n* When either operand type defines a coercion, this coercion is called\n before that type's ``__op__()`` or ``__rop__()`` method is called,\n but no sooner. If the coercion returns an object of a different\n type for the operand whose coercion is invoked, part of the process\n is redone using the new object.\n\n* When an in-place operator (like '``+=``') is used, if the left\n operand implements ``__iop__()``, it is invoked without any\n coercion. When the operation falls back to ``__op__()`` and/or\n ``__rop__()``, the normal coercion rules apply.\n\n* In *x*``+``*y*, if *x* is a sequence that implements sequence\n concatenation, sequence concatenation is invoked.\n\n* In *x*``*``*y*, if one operator is a sequence that implements\n sequence repetition, and the other is an integer (``int`` or\n ``long``), sequence repetition is invoked.\n\n* Rich comparisons (implemented by methods ``__eq__()`` and so on)\n never use coercion. Three-way comparison (implemented by\n ``__cmp__()``) does use coercion under the same conditions as other\n binary operations use it.\n\n* In the current implementation, the built-in numeric types ``int``,\n ``long`` and ``float`` do not use coercion; the type ``complex``\n however does use it. The difference can become apparent when\n subclassing these types. Over time, the type ``complex`` may be\n fixed to avoid coercion. All these types implement a\n ``__coerce__()`` method, for use by the built-in ``coerce()``\n function.\n", - 'comparisons': u'\nComparisons\n***********\n\nUnlike C, all comparison operations in Python have the same priority,\nwhich is lower than that of any arithmetic, shifting or bitwise\noperation. Also unlike C, expressions like ``a < b < c`` have the\ninterpretation that is conventional in mathematics:\n\n comparison ::= or_expr ( comp_operator or_expr )*\n comp_operator ::= "<" | ">" | "==" | ">=" | "<=" | "<>" | "!="\n | "is" ["not"] | ["not"] "in"\n\nComparisons yield boolean values: ``True`` or ``False``.\n\nComparisons can be chained arbitrarily, e.g., ``x < y <= z`` is\nequivalent to ``x < y and y <= z``, except that ``y`` is evaluated\nonly once (but in both cases ``z`` is not evaluated at all when ``x <\ny`` is found to be false).\n\nFormally, if *a*, *b*, *c*, ..., *y*, *z* are expressions and *op1*,\n*op2*, ..., *opN* are comparison operators, then ``a op1 b op2 c ... y\nopN z`` is equivalent to ``a op1 b and b op2 c and ... y opN z``,\nexcept that each expression is evaluated at most once.\n\nNote that ``a op1 b op2 c`` doesn\'t imply any kind of comparison\nbetween *a* and *c*, so that, e.g., ``x < y > z`` is perfectly legal\n(though perhaps not pretty).\n\nThe forms ``<>`` and ``!=`` are equivalent; for consistency with C,\n``!=`` is preferred; where ``!=`` is mentioned below ``<>`` is also\naccepted. The ``<>`` spelling is considered obsolescent.\n\nThe operators ``<``, ``>``, ``==``, ``>=``, ``<=``, and ``!=`` compare\nthe values of two objects. The objects need not have the same type.\nIf both are numbers, they are converted to a common type. Otherwise,\nobjects of different types *always* compare unequal, and are ordered\nconsistently but arbitrarily. You can control comparison behavior of\nobjects of non-builtin types by defining a ``__cmp__`` method or rich\ncomparison methods like ``__gt__``, described in section *Special\nmethod names*.\n\n(This unusual definition of comparison was used to simplify the\ndefinition of operations like sorting and the ``in`` and ``not in``\noperators. In the future, the comparison rules for objects of\ndifferent types are likely to change.)\n\nComparison of objects of the same type depends on the type:\n\n* Numbers are compared arithmetically.\n\n* Strings are compared lexicographically using the numeric equivalents\n (the result of the built-in function ``ord()``) of their characters.\n Unicode and 8-bit strings are fully interoperable in this behavior.\n [4]\n\n* Tuples and lists are compared lexicographically using comparison of\n corresponding elements. This means that to compare equal, each\n element must compare equal and the two sequences must be of the same\n type and have the same length.\n\n If not equal, the sequences are ordered the same as their first\n differing elements. For example, ``cmp([1,2,x], [1,2,y])`` returns\n the same as ``cmp(x,y)``. If the corresponding element does not\n exist, the shorter sequence is ordered first (for example, ``[1,2] <\n [1,2,3]``).\n\n* Mappings (dictionaries) compare equal if and only if their sorted\n (key, value) lists compare equal. [5] Outcomes other than equality\n are resolved consistently, but are not otherwise defined. [6]\n\n* Most other objects of builtin types compare unequal unless they are\n the same object; the choice whether one object is considered smaller\n or larger than another one is made arbitrarily but consistently\n within one execution of a program.\n\nThe operators ``in`` and ``not in`` test for collection membership.\n``x in s`` evaluates to true if *x* is a member of the collection *s*,\nand false otherwise. ``x not in s`` returns the negation of ``x in\ns``. The collection membership test has traditionally been bound to\nsequences; an object is a member of a collection if the collection is\na sequence and contains an element equal to that object. However, it\nmake sense for many other object types to support membership tests\nwithout being a sequence. In particular, dictionaries (for keys) and\nsets support membership testing.\n\nFor the list and tuple types, ``x in y`` is true if and only if there\nexists an index *i* such that ``x == y[i]`` is true.\n\nFor the Unicode and string types, ``x in y`` is true if and only if\n*x* is a substring of *y*. An equivalent test is ``y.find(x) != -1``.\nNote, *x* and *y* need not be the same type; consequently, ``u\'ab\' in\n\'abc\'`` will return ``True``. Empty strings are always considered to\nbe a substring of any other string, so ``"" in "abc"`` will return\n``True``.\n\nChanged in version 2.3: Previously, *x* was required to be a string of\nlength ``1``.\n\nFor user-defined classes which define the ``__contains__()`` method,\n``x in y`` is true if and only if ``y.__contains__(x)`` is true.\n\nFor user-defined classes which do not define ``__contains__()`` and do\ndefine ``__getitem__()``, ``x in y`` is true if and only if there is a\nnon-negative integer index *i* such that ``x == y[i]``, and all lower\ninteger indices do not raise ``IndexError`` exception. (If any other\nexception is raised, it is as if ``in`` raised that exception).\n\nThe operator ``not in`` is defined to have the inverse true value of\n``in``.\n\nThe operators ``is`` and ``is not`` test for object identity: ``x is\ny`` is true if and only if *x* and *y* are the same object. ``x is\nnot y`` yields the inverse truth value.\n', - 'compound': u'\nCompound statements\n*******************\n\nCompound statements contain (groups of) other statements; they affect\nor control the execution of those other statements in some way. In\ngeneral, compound statements span multiple lines, although in simple\nincarnations a whole compound statement may be contained in one line.\n\nThe ``if``, ``while`` and ``for`` statements implement traditional\ncontrol flow constructs. ``try`` specifies exception handlers and/or\ncleanup code for a group of statements. Function and class\ndefinitions are also syntactically compound statements.\n\nCompound statements consist of one or more \'clauses.\' A clause\nconsists of a header and a \'suite.\' The clause headers of a\nparticular compound statement are all at the same indentation level.\nEach clause header begins with a uniquely identifying keyword and ends\nwith a colon. A suite is a group of statements controlled by a\nclause. A suite can be one or more semicolon-separated simple\nstatements on the same line as the header, following the header\'s\ncolon, or it can be one or more indented statements on subsequent\nlines. Only the latter form of suite can contain nested compound\nstatements; the following is illegal, mostly because it wouldn\'t be\nclear to which ``if`` clause a following ``else`` clause would belong:\n\n if test1: if test2: print x\n\nAlso note that the semicolon binds tighter than the colon in this\ncontext, so that in the following example, either all or none of the\n``print`` statements are executed:\n\n if x < y < z: print x; print y; print z\n\nSummarizing:\n\n compound_stmt ::= if_stmt\n | while_stmt\n | for_stmt\n | try_stmt\n | with_stmt\n | funcdef\n | classdef\n | decorated\n suite ::= stmt_list NEWLINE | NEWLINE INDENT statement+ DEDENT\n statement ::= stmt_list NEWLINE | compound_stmt\n stmt_list ::= simple_stmt (";" simple_stmt)* [";"]\n\nNote that statements always end in a ``NEWLINE`` possibly followed by\na ``DEDENT``. Also note that optional continuation clauses always\nbegin with a keyword that cannot start a statement, thus there are no\nambiguities (the \'dangling ``else``\' problem is solved in Python by\nrequiring nested ``if`` statements to be indented).\n\nThe formatting of the grammar rules in the following sections places\neach clause on a separate line for clarity.\n\n\nThe ``if`` statement\n====================\n\nThe ``if`` statement is used for conditional execution:\n\n if_stmt ::= "if" expression ":" suite\n ( "elif" expression ":" suite )*\n ["else" ":" suite]\n\nIt selects exactly one of the suites by evaluating the expressions one\nby one until one is found to be true (see section *Boolean operations*\nfor the definition of true and false); then that suite is executed\n(and no other part of the ``if`` statement is executed or evaluated).\nIf all expressions are false, the suite of the ``else`` clause, if\npresent, is executed.\n\n\nThe ``while`` statement\n=======================\n\nThe ``while`` statement is used for repeated execution as long as an\nexpression is true:\n\n while_stmt ::= "while" expression ":" suite\n ["else" ":" suite]\n\nThis repeatedly tests the expression and, if it is true, executes the\nfirst suite; if the expression is false (which may be the first time\nit is tested) the suite of the ``else`` clause, if present, is\nexecuted and the loop terminates.\n\nA ``break`` statement executed in the first suite terminates the loop\nwithout executing the ``else`` clause\'s suite. A ``continue``\nstatement executed in the first suite skips the rest of the suite and\ngoes back to testing the expression.\n\n\nThe ``for`` statement\n=====================\n\nThe ``for`` statement is used to iterate over the elements of a\nsequence (such as a string, tuple or list) or other iterable object:\n\n for_stmt ::= "for" target_list "in" expression_list ":" suite\n ["else" ":" suite]\n\nThe expression list is evaluated once; it should yield an iterable\nobject. An iterator is created for the result of the\n``expression_list``. The suite is then executed once for each item\nprovided by the iterator, in the order of ascending indices. Each\nitem in turn is assigned to the target list using the standard rules\nfor assignments, and then the suite is executed. When the items are\nexhausted (which is immediately when the sequence is empty), the suite\nin the ``else`` clause, if present, is executed, and the loop\nterminates.\n\nA ``break`` statement executed in the first suite terminates the loop\nwithout executing the ``else`` clause\'s suite. A ``continue``\nstatement executed in the first suite skips the rest of the suite and\ncontinues with the next item, or with the ``else`` clause if there was\nno next item.\n\nThe suite may assign to the variable(s) in the target list; this does\nnot affect the next item assigned to it.\n\nThe target list is not deleted when the loop is finished, but if the\nsequence is empty, it will not have been assigned to at all by the\nloop. Hint: the built-in function ``range()`` returns a sequence of\nintegers suitable to emulate the effect of Pascal\'s ``for i := a to b\ndo``; e.g., ``range(3)`` returns the list ``[0, 1, 2]``.\n\nWarning: There is a subtlety when the sequence is being modified by the loop\n (this can only occur for mutable sequences, i.e. lists). An internal\n counter is used to keep track of which item is used next, and this\n is incremented on each iteration. When this counter has reached the\n length of the sequence the loop terminates. This means that if the\n suite deletes the current (or a previous) item from the sequence,\n the next item will be skipped (since it gets the index of the\n current item which has already been treated). Likewise, if the\n suite inserts an item in the sequence before the current item, the\n current item will be treated again the next time through the loop.\n This can lead to nasty bugs that can be avoided by making a\n temporary copy using a slice of the whole sequence, e.g.,\n\n for x in a[:]:\n if x < 0: a.remove(x)\n\n\nThe ``try`` statement\n=====================\n\nThe ``try`` statement specifies exception handlers and/or cleanup code\nfor a group of statements:\n\n try_stmt ::= try1_stmt | try2_stmt\n try1_stmt ::= "try" ":" suite\n ("except" [expression ["," target]] ":" suite)+\n ["else" ":" suite]\n ["finally" ":" suite]\n try2_stmt ::= "try" ":" suite\n "finally" ":" suite\n\nChanged in version 2.5: In previous versions of Python,\n``try``...``except``...``finally`` did not work. ``try``...``except``\nhad to be nested in ``try``...``finally``.\n\nThe ``except`` clause(s) specify one or more exception handlers. When\nno exception occurs in the ``try`` clause, no exception handler is\nexecuted. When an exception occurs in the ``try`` suite, a search for\nan exception handler is started. This search inspects the except\nclauses in turn until one is found that matches the exception. An\nexpression-less except clause, if present, must be last; it matches\nany exception. For an except clause with an expression, that\nexpression is evaluated, and the clause matches the exception if the\nresulting object is "compatible" with the exception. An object is\ncompatible with an exception if it is the class or a base class of the\nexception object, a tuple containing an item compatible with the\nexception, or, in the (deprecated) case of string exceptions, is the\nraised string itself (note that the object identities must match, i.e.\nit must be the same string object, not just a string with the same\nvalue).\n\nIf no except clause matches the exception, the search for an exception\nhandler continues in the surrounding code and on the invocation stack.\n[1]\n\nIf the evaluation of an expression in the header of an except clause\nraises an exception, the original search for a handler is canceled and\na search starts for the new exception in the surrounding code and on\nthe call stack (it is treated as if the entire ``try`` statement\nraised the exception).\n\nWhen a matching except clause is found, the exception is assigned to\nthe target specified in that except clause, if present, and the except\nclause\'s suite is executed. All except clauses must have an\nexecutable block. When the end of this block is reached, execution\ncontinues normally after the entire try statement. (This means that\nif two nested handlers exist for the same exception, and the exception\noccurs in the try clause of the inner handler, the outer handler will\nnot handle the exception.)\n\nBefore an except clause\'s suite is executed, details about the\nexception are assigned to three variables in the ``sys`` module:\n``sys.exc_type`` receives the object identifying the exception;\n``sys.exc_value`` receives the exception\'s parameter;\n``sys.exc_traceback`` receives a traceback object (see section *The\nstandard type hierarchy*) identifying the point in the program where\nthe exception occurred. These details are also available through the\n``sys.exc_info()`` function, which returns a tuple ``(exc_type,\nexc_value, exc_traceback)``. Use of the corresponding variables is\ndeprecated in favor of this function, since their use is unsafe in a\nthreaded program. As of Python 1.5, the variables are restored to\ntheir previous values (before the call) when returning from a function\nthat handled an exception.\n\nThe optional ``else`` clause is executed if and when control flows off\nthe end of the ``try`` clause. [2] Exceptions in the ``else`` clause\nare not handled by the preceding ``except`` clauses.\n\nIf ``finally`` is present, it specifies a \'cleanup\' handler. The\n``try`` clause is executed, including any ``except`` and ``else``\nclauses. If an exception occurs in any of the clauses and is not\nhandled, the exception is temporarily saved. The ``finally`` clause is\nexecuted. If there is a saved exception, it is re-raised at the end\nof the ``finally`` clause. If the ``finally`` clause raises another\nexception or executes a ``return`` or ``break`` statement, the saved\nexception is lost. The exception information is not available to the\nprogram during execution of the ``finally`` clause.\n\nWhen a ``return``, ``break`` or ``continue`` statement is executed in\nthe ``try`` suite of a ``try``...``finally`` statement, the\n``finally`` clause is also executed \'on the way out.\' A ``continue``\nstatement is illegal in the ``finally`` clause. (The reason is a\nproblem with the current implementation --- this restriction may be\nlifted in the future).\n\nAdditional information on exceptions can be found in section\n*Exceptions*, and information on using the ``raise`` statement to\ngenerate exceptions may be found in section *The raise statement*.\n\n\nThe ``with`` statement\n======================\n\nAdded in version 2.5.\n\nThe ``with`` statement is used to wrap the execution of a block with\nmethods defined by a context manager (see section *With Statement\nContext Managers*). This allows common\n``try``...``except``...``finally`` usage patterns to be encapsulated\nfor convenient reuse.\n\n with_stmt ::= "with" expression ["as" target] ":" suite\n\nThe execution of the ``with`` statement proceeds as follows:\n\n1. The context expression is evaluated to obtain a context manager.\n\n2. The context manager\'s ``__enter__()`` method is invoked.\n\n3. If a target was included in the ``with`` statement, the return\n value from ``__enter__()`` is assigned to it.\n\n Note: The ``with`` statement guarantees that if the ``__enter__()``\n method returns without an error, then ``__exit__()`` will always\n be called. Thus, if an error occurs during the assignment to the\n target list, it will be treated the same as an error occurring\n within the suite would be. See step 5 below.\n\n4. The suite is executed.\n\n5. The context manager\'s ``__exit__()`` method is invoked. If an\n exception caused the suite to be exited, its type, value, and\n traceback are passed as arguments to ``__exit__()``. Otherwise,\n three ``None`` arguments are supplied.\n\n If the suite was exited due to an exception, and the return value\n from the ``__exit__()`` method was false, the exception is\n reraised. If the return value was true, the exception is\n suppressed, and execution continues with the statement following\n the ``with`` statement.\n\n If the suite was exited for any reason other than an exception, the\n return value from ``__exit__()`` is ignored, and execution proceeds\n at the normal location for the kind of exit that was taken.\n\nNote: In Python 2.5, the ``with`` statement is only allowed when the\n ``with_statement`` feature has been enabled. It is always enabled\n in Python 2.6.\n\nSee also:\n\n **PEP 0343** - The "with" statement\n The specification, background, and examples for the Python\n ``with`` statement.\n\n\nFunction definitions\n====================\n\nA function definition defines a user-defined function object (see\nsection *The standard type hierarchy*):\n\n decorated ::= decorators (classdef | funcdef)\n decorators ::= decorator+\n decorator ::= "@" dotted_name ["(" [argument_list [","]] ")"] NEWLINE\n funcdef ::= "def" funcname "(" [parameter_list] ")" ":" suite\n dotted_name ::= identifier ("." identifier)*\n parameter_list ::= (defparameter ",")*\n ( "*" identifier [, "**" identifier]\n | "**" identifier\n | defparameter [","] )\n defparameter ::= parameter ["=" expression]\n sublist ::= parameter ("," parameter)* [","]\n parameter ::= identifier | "(" sublist ")"\n funcname ::= identifier\n\nA function definition is an executable statement. Its execution binds\nthe function name in the current local namespace to a function object\n(a wrapper around the executable code for the function). This\nfunction object contains a reference to the current global namespace\nas the global namespace to be used when the function is called.\n\nThe function definition does not execute the function body; this gets\nexecuted only when the function is called.\n\nA function definition may be wrapped by one or more *decorator*\nexpressions. Decorator expressions are evaluated when the function is\ndefined, in the scope that contains the function definition. The\nresult must be a callable, which is invoked with the function object\nas the only argument. The returned value is bound to the function name\ninstead of the function object. Multiple decorators are applied in\nnested fashion. For example, the following code:\n\n @f1(arg)\n @f2\n def func(): pass\n\nis equivalent to:\n\n def func(): pass\n func = f1(arg)(f2(func))\n\nWhen one or more top-level parameters have the form *parameter* ``=``\n*expression*, the function is said to have "default parameter values."\nFor a parameter with a default value, the corresponding argument may\nbe omitted from a call, in which case the parameter\'s default value is\nsubstituted. If a parameter has a default value, all following\nparameters must also have a default value --- this is a syntactic\nrestriction that is not expressed by the grammar.\n\n**Default parameter values are evaluated when the function definition\nis executed.** This means that the expression is evaluated once, when\nthe function is defined, and that that same "pre-computed" value is\nused for each call. This is especially important to understand when a\ndefault parameter is a mutable object, such as a list or a dictionary:\nif the function modifies the object (e.g. by appending an item to a\nlist), the default value is in effect modified. This is generally not\nwhat was intended. A way around this is to use ``None`` as the\ndefault, and explicitly test for it in the body of the function, e.g.:\n\n def whats_on_the_telly(penguin=None):\n if penguin is None:\n penguin = []\n penguin.append("property of the zoo")\n return penguin\n\nFunction call semantics are described in more detail in section\n*Calls*. A function call always assigns values to all parameters\nmentioned in the parameter list, either from position arguments, from\nkeyword arguments, or from default values. If the form\n"``*identifier``" is present, it is initialized to a tuple receiving\nany excess positional parameters, defaulting to the empty tuple. If\nthe form "``**identifier``" is present, it is initialized to a new\ndictionary receiving any excess keyword arguments, defaulting to a new\nempty dictionary.\n\nIt is also possible to create anonymous functions (functions not bound\nto a name), for immediate use in expressions. This uses lambda forms,\ndescribed in section *Expression lists*. Note that the lambda form is\nmerely a shorthand for a simplified function definition; a function\ndefined in a "``def``" statement can be passed around or assigned to\nanother name just like a function defined by a lambda form. The\n"``def``" form is actually more powerful since it allows the execution\nof multiple statements.\n\n**Programmer\'s note:** Functions are first-class objects. A "``def``"\nform executed inside a function definition defines a local function\nthat can be returned or passed around. Free variables used in the\nnested function can access the local variables of the function\ncontaining the def. See section *Naming and binding* for details.\n\n\nClass definitions\n=================\n\nA class definition defines a class object (see section *The standard\ntype hierarchy*):\n\n classdef ::= "class" classname [inheritance] ":" suite\n inheritance ::= "(" [expression_list] ")"\n classname ::= identifier\n\nA class definition is an executable statement. It first evaluates the\ninheritance list, if present. Each item in the inheritance list\nshould evaluate to a class object or class type which allows\nsubclassing. The class\'s suite is then executed in a new execution\nframe (see section *Naming and binding*), using a newly created local\nnamespace and the original global namespace. (Usually, the suite\ncontains only function definitions.) When the class\'s suite finishes\nexecution, its execution frame is discarded but its local namespace is\nsaved. A class object is then created using the inheritance list for\nthe base classes and the saved local namespace for the attribute\ndictionary. The class name is bound to this class object in the\noriginal local namespace.\n\n**Programmer\'s note:** Variables defined in the class definition are\nclass variables; they are shared by all instances. To create instance\nvariables, they can be set in a method with ``self.name = value``.\nBoth class and instance variables are accessible through the notation\n"``self.name``", and an instance variable hides a class variable with\nthe same name when accessed in this way. Class variables can be used\nas defaults for instance variables, but using mutable values there can\nlead to unexpected results. For *new-style class*es, descriptors can\nbe used to create instance variables with different implementation\ndetails.\n\nClass definitions, like function definitions, may be wrapped by one or\nmore *decorator* expressions. The evaluation rules for the decorator\nexpressions are the same as for functions. The result must be a class\nobject, which is then bound to the class name.\n\n-[ Footnotes ]-\n\n[1] The exception is propagated to the invocation stack only if there\n is no ``finally`` clause that negates the exception.\n\n[2] Currently, control "flows off the end" except in the case of an\n exception or the execution of a ``return``, ``continue``, or\n ``break`` statement.\n', - 'context-managers': u'\nWith Statement Context Managers\n*******************************\n\nAdded in version 2.5.\n\nA *context manager* is an object that defines the runtime context to\nbe established when executing a ``with`` statement. The context\nmanager handles the entry into, and the exit from, the desired runtime\ncontext for the execution of the block of code. Context managers are\nnormally invoked using the ``with`` statement (described in section\n*The with statement*), but can also be used by directly invoking their\nmethods.\n\nTypical uses of context managers include saving and restoring various\nkinds of global state, locking and unlocking resources, closing opened\nfiles, etc.\n\nFor more information on context managers, see *Context Manager Types*.\n\nobject.__enter__(self)\n\n Enter the runtime context related to this object. The ``with``\n statement will bind this method\'s return value to the target(s)\n specified in the ``as`` clause of the statement, if any.\n\nobject.__exit__(self, exc_type, exc_value, traceback)\n\n Exit the runtime context related to this object. The parameters\n describe the exception that caused the context to be exited. If the\n context was exited without an exception, all three arguments will\n be ``None``.\n\n If an exception is supplied, and the method wishes to suppress the\n exception (i.e., prevent it from being propagated), it should\n return a true value. Otherwise, the exception will be processed\n normally upon exit from this method.\n\n Note that ``__exit__()`` methods should not reraise the passed-in\n exception; this is the caller\'s responsibility.\n\nSee also:\n\n **PEP 0343** - The "with" statement\n The specification, background, and examples for the Python\n ``with`` statement.\n\n-[ Footnotes ]-\n\n[1] Since Python 2.2, a gradual merging of types and classes has been\n started that makes this and a few other assertions made in this\n manual not 100% accurate and complete: for example, it *is* now\n possible in some cases to change an object\'s type, under certain\n controlled conditions. Until this manual undergoes extensive\n revision, it must now be taken as authoritative only regarding\n "classic classes", that are still the default, for compatibility\n purposes, in Python 2.2 and 2.3. For more information, see\n http://www.python.org/doc/newstyle/.\n\n[2] This, and other statements, are only roughly true for instances of\n new-style classes.\n\n[3] A descriptor can define any combination of ``__get__()``,\n ``__set__()`` and ``__delete__()``. If it does not define\n ``__get__()``, then accessing the attribute even on an instance\n will return the descriptor object itself. If the descriptor\n defines ``__set__()`` and/or ``__delete__()``, it is a data\n descriptor; if it defines neither, it is a non-data descriptor.\n\n[4] For operands of the same type, it is assumed that if the non-\n reflected method (such as ``__add__()``) fails the operation is\n not supported, which is why the reflected method is not called.\n', - 'continue': u'\nThe ``continue`` statement\n**************************\n\n continue_stmt ::= "continue"\n\n``continue`` may only occur syntactically nested in a ``for`` or\n``while`` loop, but not nested in a function or class definition or\n``finally`` clause within that loop. It continues with the next cycle\nof the nearest enclosing loop.\n\nWhen ``continue`` passes control out of a ``try`` statement with a\n``finally`` clause, that ``finally`` clause is executed before really\nstarting the next loop cycle.\n', - 'conversions': u'\nArithmetic conversions\n**********************\n\nWhen a description of an arithmetic operator below uses the phrase\n"the numeric arguments are converted to a common type," the arguments\nare coerced using the coercion rules listed at *Coercion rules*. If\nboth arguments are standard numeric types, the following coercions are\napplied:\n\n* If either argument is a complex number, the other is converted to\n complex;\n\n* otherwise, if either argument is a floating point number, the other\n is converted to floating point;\n\n* otherwise, if either argument is a long integer, the other is\n converted to long integer;\n\n* otherwise, both must be plain integers and no conversion is\n necessary.\n\nSome additional rules apply for certain operators (e.g., a string left\nargument to the \'%\' operator). Extensions can define their own\ncoercions.\n', - 'customization': u'\nBasic customization\n*******************\n\nobject.__new__(cls[, ...])\n\n Called to create a new instance of class *cls*. ``__new__()`` is a\n static method (special-cased so you need not declare it as such)\n that takes the class of which an instance was requested as its\n first argument. The remaining arguments are those passed to the\n object constructor expression (the call to the class). The return\n value of ``__new__()`` should be the new object instance (usually\n an instance of *cls*).\n\n Typical implementations create a new instance of the class by\n invoking the superclass\'s ``__new__()`` method using\n ``super(currentclass, cls).__new__(cls[, ...])`` with appropriate\n arguments and then modifying the newly-created instance as\n necessary before returning it.\n\n If ``__new__()`` returns an instance of *cls*, then the new\n instance\'s ``__init__()`` method will be invoked like\n ``__init__(self[, ...])``, where *self* is the new instance and the\n remaining arguments are the same as were passed to ``__new__()``.\n\n If ``__new__()`` does not return an instance of *cls*, then the new\n instance\'s ``__init__()`` method will not be invoked.\n\n ``__new__()`` is intended mainly to allow subclasses of immutable\n types (like int, str, or tuple) to customize instance creation. It\n is also commonly overridden in custom metaclasses in order to\n customize class creation.\n\nobject.__init__(self[, ...])\n\n Called when the instance is created. The arguments are those\n passed to the class constructor expression. If a base class has an\n ``__init__()`` method, the derived class\'s ``__init__()`` method,\n if any, must explicitly call it to ensure proper initialization of\n the base class part of the instance; for example:\n ``BaseClass.__init__(self, [args...])``. As a special constraint\n on constructors, no value may be returned; doing so will cause a\n ``TypeError`` to be raised at runtime.\n\nobject.__del__(self)\n\n Called when the instance is about to be destroyed. This is also\n called a destructor. If a base class has a ``__del__()`` method,\n the derived class\'s ``__del__()`` method, if any, must explicitly\n call it to ensure proper deletion of the base class part of the\n instance. Note that it is possible (though not recommended!) for\n the ``__del__()`` method to postpone destruction of the instance by\n creating a new reference to it. It may then be called at a later\n time when this new reference is deleted. It is not guaranteed that\n ``__del__()`` methods are called for objects that still exist when\n the interpreter exits.\n\n Note: ``del x`` doesn\'t directly call ``x.__del__()`` --- the former\n decrements the reference count for ``x`` by one, and the latter\n is only called when ``x``\'s reference count reaches zero. Some\n common situations that may prevent the reference count of an\n object from going to zero include: circular references between\n objects (e.g., a doubly-linked list or a tree data structure with\n parent and child pointers); a reference to the object on the\n stack frame of a function that caught an exception (the traceback\n stored in ``sys.exc_traceback`` keeps the stack frame alive); or\n a reference to the object on the stack frame that raised an\n unhandled exception in interactive mode (the traceback stored in\n ``sys.last_traceback`` keeps the stack frame alive). The first\n situation can only be remedied by explicitly breaking the cycles;\n the latter two situations can be resolved by storing ``None`` in\n ``sys.exc_traceback`` or ``sys.last_traceback``. Circular\n references which are garbage are detected when the option cycle\n detector is enabled (it\'s on by default), but can only be cleaned\n up if there are no Python-level ``__del__()`` methods involved.\n Refer to the documentation for the ``gc`` module for more\n information about how ``__del__()`` methods are handled by the\n cycle detector, particularly the description of the ``garbage``\n value.\n\n Warning: Due to the precarious circumstances under which ``__del__()``\n methods are invoked, exceptions that occur during their execution\n are ignored, and a warning is printed to ``sys.stderr`` instead.\n Also, when ``__del__()`` is invoked in response to a module being\n deleted (e.g., when execution of the program is done), other\n globals referenced by the ``__del__()`` method may already have\n been deleted. For this reason, ``__del__()`` methods should do\n the absolute minimum needed to maintain external invariants.\n Starting with version 1.5, Python guarantees that globals whose\n name begins with a single underscore are deleted from their\n module before other globals are deleted; if no other references\n to such globals exist, this may help in assuring that imported\n modules are still available at the time when the ``__del__()``\n method is called.\n\nobject.__repr__(self)\n\n Called by the ``repr()`` built-in function and by string\n conversions (reverse quotes) to compute the "official" string\n representation of an object. If at all possible, this should look\n like a valid Python expression that could be used to recreate an\n object with the same value (given an appropriate environment). If\n this is not possible, a string of the form ``<...some useful\n description...>`` should be returned. The return value must be a\n string object. If a class defines ``__repr__()`` but not\n ``__str__()``, then ``__repr__()`` is also used when an "informal"\n string representation of instances of that class is required.\n\n This is typically used for debugging, so it is important that the\n representation is information-rich and unambiguous.\n\nobject.__str__(self)\n\n Called by the ``str()`` built-in function and by the ``print``\n statement to compute the "informal" string representation of an\n object. This differs from ``__repr__()`` in that it does not have\n to be a valid Python expression: a more convenient or concise\n representation may be used instead. The return value must be a\n string object.\n\nobject.__lt__(self, other)\nobject.__le__(self, other)\nobject.__eq__(self, other)\nobject.__ne__(self, other)\nobject.__gt__(self, other)\nobject.__ge__(self, other)\n\n Added in version 2.1.\n\n These are the so-called "rich comparison" methods, and are called\n for comparison operators in preference to ``__cmp__()`` below. The\n correspondence between operator symbols and method names is as\n follows: ``xy`` call ``x.__ne__(y)``, ``x>y`` calls ``x.__gt__(y)``, and\n ``x>=y`` calls ``x.__ge__(y)``.\n\n A rich comparison method may return the singleton\n ``NotImplemented`` if it does not implement the operation for a\n given pair of arguments. By convention, ``False`` and ``True`` are\n returned for a successful comparison. However, these methods can\n return any value, so if the comparison operator is used in a\n Boolean context (e.g., in the condition of an ``if`` statement),\n Python will call ``bool()`` on the value to determine if the result\n is true or false.\n\n There are no implied relationships among the comparison operators.\n The truth of ``x==y`` does not imply that ``x!=y`` is false.\n Accordingly, when defining ``__eq__()``, one should also define\n ``__ne__()`` so that the operators will behave as expected. See\n the paragraph on ``__hash__()`` for some important notes on\n creating *hashable* objects which support custom comparison\n operations and are usable as dictionary keys.\n\n There are no swapped-argument versions of these methods (to be used\n when the left argument does not support the operation but the right\n argument does); rather, ``__lt__()`` and ``__gt__()`` are each\n other\'s reflection, ``__le__()`` and ``__ge__()`` are each other\'s\n reflection, and ``__eq__()`` and ``__ne__()`` are their own\n reflection.\n\n Arguments to rich comparison methods are never coerced.\n\nobject.__cmp__(self, other)\n\n Called by comparison operations if rich comparison (see above) is\n not defined. Should return a negative integer if ``self < other``,\n zero if ``self == other``, a positive integer if ``self > other``.\n If no ``__cmp__()``, ``__eq__()`` or ``__ne__()`` operation is\n defined, class instances are compared by object identity\n ("address"). See also the description of ``__hash__()`` for some\n important notes on creating *hashable* objects which support custom\n comparison operations and are usable as dictionary keys. (Note: the\n restriction that exceptions are not propagated by ``__cmp__()`` has\n been removed since Python 1.5.)\n\nobject.__rcmp__(self, other)\n\n Changed in version 2.1: No longer supported.\n\nobject.__hash__(self)\n\n Called for the key object for dictionary operations, and by the\n built-in function ``hash()``. Should return an integer usable as a\n hash value for dictionary operations. The only required property\n is that objects which compare equal have the same hash value; it is\n advised to somehow mix together (e.g., using exclusive or) the hash\n values for the components of the object that also play a part in\n comparison of objects.\n\n If a class does not define a ``__cmp__()`` or ``__eq__()`` method\n it should not define a ``__hash__()`` operation either; if it\n defines ``__cmp__()`` or ``__eq__()`` but not ``__hash__()``, its\n instances will not be usable as dictionary keys. If a class\n defines mutable objects and implements a ``__cmp__()`` or\n ``__eq__()`` method, it should not implement ``__hash__()``, since\n the dictionary implementation requires that a key\'s hash value is\n immutable (if the object\'s hash value changes, it will be in the\n wrong hash bucket).\n\n User-defined classes have ``__cmp__()`` and ``__hash__()`` methods\n by default; with them, all objects compare unequal and\n ``x.__hash__()`` returns ``id(x)``.\n\n Changed in version 2.5: ``__hash__()`` may now also return a long\n integer object; the 32-bit integer is then derived from the hash of\n that object.\n\nobject.__nonzero__(self)\n\n Called to implement truth value testing, and the built-in operation\n ``bool()``; should return ``False`` or ``True``, or their integer\n equivalents ``0`` or ``1``. When this method is not defined,\n ``__len__()`` is called, if it is defined (see below). If a class\n defines neither ``__len__()`` nor ``__nonzero__()``, all its\n instances are considered true.\n\nobject.__unicode__(self)\n\n Called to implement ``unicode()`` builtin; should return a Unicode\n object. When this method is not defined, string conversion is\n attempted, and the result of string conversion is converted to\n Unicode using the system default encoding.\n', - 'debugger': u'\n``pdb`` --- The Python Debugger\n*******************************\n\nThe module ``pdb`` defines an interactive source code debugger for\nPython programs. It supports setting (conditional) breakpoints and\nsingle stepping at the source line level, inspection of stack frames,\nsource code listing, and evaluation of arbitrary Python code in the\ncontext of any stack frame. It also supports post-mortem debugging\nand can be called under program control.\n\nThe debugger is extensible --- it is actually defined as the class\n``Pdb``. This is currently undocumented but easily understood by\nreading the source. The extension interface uses the modules ``bdb``\n(undocumented) and ``cmd``.\n\nThe debugger\'s prompt is ``(Pdb)``. Typical usage to run a program\nunder control of the debugger is:\n\n >>> import pdb\n >>> import mymodule\n >>> pdb.run(\'mymodule.test()\')\n > (0)?()\n (Pdb) continue\n > (1)?()\n (Pdb) continue\n NameError: \'spam\'\n > (1)?()\n (Pdb)\n\n``pdb.py`` can also be invoked as a script to debug other scripts.\nFor example:\n\n python -m pdb myscript.py\n\nWhen invoked as a script, pdb will automatically enter post-mortem\ndebugging if the program being debugged exits abnormally. After post-\nmortem debugging (or after normal exit of the program), pdb will\nrestart the program. Automatic restarting preserves pdb\'s state (such\nas breakpoints) and in most cases is more useful than quitting the\ndebugger upon program\'s exit.\n\nAdded in version 2.4: Restarting post-mortem behavior added.\n\nTypical usage to inspect a crashed program is:\n\n >>> import pdb\n >>> import mymodule\n >>> mymodule.test()\n Traceback (most recent call last):\n File "", line 1, in ?\n File "./mymodule.py", line 4, in test\n test2()\n File "./mymodule.py", line 3, in test2\n print spam\n NameError: spam\n >>> pdb.pm()\n > ./mymodule.py(3)test2()\n -> print spam\n (Pdb)\n\nThe module defines the following functions; each enters the debugger\nin a slightly different way:\n\npdb.run(statement[, globals[, locals]])\n\n Execute the *statement* (given as a string) under debugger control.\n The debugger prompt appears before any code is executed; you can\n set breakpoints and type ``continue``, or you can step through the\n statement using ``step`` or ``next`` (all these commands are\n explained below). The optional *globals* and *locals* arguments\n specify the environment in which the code is executed; by default\n the dictionary of the module ``__main__`` is used. (See the\n explanation of the ``exec`` statement or the ``eval()`` built-in\n function.)\n\npdb.runeval(expression[, globals[, locals]])\n\n Evaluate the *expression* (given as a string) under debugger\n control. When ``runeval()`` returns, it returns the value of the\n expression. Otherwise this function is similar to ``run()``.\n\npdb.runcall(function[, argument, ...])\n\n Call the *function* (a function or method object, not a string)\n with the given arguments. When ``runcall()`` returns, it returns\n whatever the function call returned. The debugger prompt appears\n as soon as the function is entered.\n\npdb.set_trace()\n\n Enter the debugger at the calling stack frame. This is useful to\n hard-code a breakpoint at a given point in a program, even if the\n code is not otherwise being debugged (e.g. when an assertion\n fails).\n\npdb.post_mortem([traceback])\n\n Enter post-mortem debugging of the given *traceback* object. If no\n *traceback* is given, it uses the one of the exception that is\n currently being handled (an exception must be being handled if the\n default is to be used).\n\npdb.pm()\n\n Enter post-mortem debugging of the traceback found in\n ``sys.last_traceback``.\n', - 'del': u'\nThe ``del`` statement\n*********************\n\n del_stmt ::= "del" target_list\n\nDeletion is recursively defined very similar to the way assignment is\ndefined. Rather that spelling it out in full details, here are some\nhints.\n\nDeletion of a target list recursively deletes each target, from left\nto right.\n\nDeletion of a name removes the binding of that name from the local or\nglobal namespace, depending on whether the name occurs in a ``global``\nstatement in the same code block. If the name is unbound, a\n``NameError`` exception will be raised.\n\nIt is illegal to delete a name from the local namespace if it occurs\nas a free variable in a nested block.\n\nDeletion of attribute references, subscriptions and slicings is passed\nto the primary object involved; deletion of a slicing is in general\nequivalent to assignment of an empty slice of the right type (but even\nthis is determined by the sliced object).\n', - 'dict': u'\nDictionary displays\n*******************\n\nA dictionary display is a possibly empty series of key/datum pairs\nenclosed in curly braces:\n\n dict_display ::= "{" [key_datum_list] "}"\n key_datum_list ::= key_datum ("," key_datum)* [","]\n key_datum ::= expression ":" expression\n\nA dictionary display yields a new dictionary object.\n\nThe key/datum pairs are evaluated from left to right to define the\nentries of the dictionary: each key object is used as a key into the\ndictionary to store the corresponding datum.\n\nRestrictions on the types of the key values are listed earlier in\nsection *The standard type hierarchy*. (To summarize, the key type\nshould be *hashable*, which excludes all mutable objects.) Clashes\nbetween duplicate keys are not detected; the last datum (textually\nrightmost in the display) stored for a given key value prevails.\n', - 'dynamic-features': u'\nInteraction with dynamic features\n*********************************\n\nThere are several cases where Python statements are illegal when used\nin conjunction with nested scopes that contain free variables.\n\nIf a variable is referenced in an enclosing scope, it is illegal to\ndelete the name. An error will be reported at compile time.\n\nIf the wild card form of import --- ``import *`` --- is used in a\nfunction and the function contains or is a nested block with free\nvariables, the compiler will raise a ``SyntaxError``.\n\nIf ``exec`` is used in a function and the function contains or is a\nnested block with free variables, the compiler will raise a\n``SyntaxError`` unless the exec explicitly specifies the local\nnamespace for the ``exec``. (In other words, ``exec obj`` would be\nillegal, but ``exec obj in ns`` would be legal.)\n\nThe ``eval()``, ``execfile()``, and ``input()`` functions and the\n``exec`` statement do not have access to the full environment for\nresolving names. Names may be resolved in the local and global\nnamespaces of the caller. Free variables are not resolved in the\nnearest enclosing namespace, but in the global namespace. [1] The\n``exec`` statement and the ``eval()`` and ``execfile()`` functions\nhave optional arguments to override the global and local namespace.\nIf only one namespace is specified, it is used for both.\n', - 'else': u'\nThe ``if`` statement\n********************\n\nThe ``if`` statement is used for conditional execution:\n\n if_stmt ::= "if" expression ":" suite\n ( "elif" expression ":" suite )*\n ["else" ":" suite]\n\nIt selects exactly one of the suites by evaluating the expressions one\nby one until one is found to be true (see section *Boolean operations*\nfor the definition of true and false); then that suite is executed\n(and no other part of the ``if`` statement is executed or evaluated).\nIf all expressions are false, the suite of the ``else`` clause, if\npresent, is executed.\n', - 'exceptions': u'\nExceptions\n**********\n\nExceptions are a means of breaking out of the normal flow of control\nof a code block in order to handle errors or other exceptional\nconditions. An exception is *raised* at the point where the error is\ndetected; it may be *handled* by the surrounding code block or by any\ncode block that directly or indirectly invoked the code block where\nthe error occurred.\n\nThe Python interpreter raises an exception when it detects a run-time\nerror (such as division by zero). A Python program can also\nexplicitly raise an exception with the ``raise`` statement. Exception\nhandlers are specified with the ``try`` ... ``except`` statement. The\n``finally`` clause of such a statement can be used to specify cleanup\ncode which does not handle the exception, but is executed whether an\nexception occurred or not in the preceding code.\n\nPython uses the "termination" model of error handling: an exception\nhandler can find out what happened and continue execution at an outer\nlevel, but it cannot repair the cause of the error and retry the\nfailing operation (except by re-entering the offending piece of code\nfrom the top).\n\nWhen an exception is not handled at all, the interpreter terminates\nexecution of the program, or returns to its interactive main loop. In\neither case, it prints a stack backtrace, except when the exception is\n``SystemExit``.\n\nExceptions are identified by class instances. The ``except`` clause\nis selected depending on the class of the instance: it must reference\nthe class of the instance or a base class thereof. The instance can\nbe received by the handler and can carry additional information about\nthe exceptional condition.\n\nExceptions can also be identified by strings, in which case the\n``except`` clause is selected by object identity. An arbitrary value\ncan be raised along with the identifying string which can be passed to\nthe handler.\n\nWarning: Messages to exceptions are not part of the Python API. Their\n contents may change from one version of Python to the next without\n warning and should not be relied on by code which will run under\n multiple versions of the interpreter.\n\nSee also the description of the ``try`` statement in section *The try\nstatement* and ``raise`` statement in section *The raise statement*.\n\n-[ Footnotes ]-\n\n[1] This limitation occurs because the code that is executed by these\n operations is not available at the time the module is compiled.\n', - 'exec': u'\nThe ``exec`` statement\n**********************\n\n exec_stmt ::= "exec" or_expr ["in" expression ["," expression]]\n\nThis statement supports dynamic execution of Python code. The first\nexpression should evaluate to either a string, an open file object, or\na code object. If it is a string, the string is parsed as a suite of\nPython statements which is then executed (unless a syntax error\noccurs). If it is an open file, the file is parsed until EOF and\nexecuted. If it is a code object, it is simply executed. In all\ncases, the code that\'s executed is expected to be valid as file input\n(see section *File input*). Be aware that the ``return`` and\n``yield`` statements may not be used outside of function definitions\neven within the context of code passed to the ``exec`` statement.\n\nIn all cases, if the optional parts are omitted, the code is executed\nin the current scope. If only the first expression after ``in`` is\nspecified, it should be a dictionary, which will be used for both the\nglobal and the local variables. If two expressions are given, they\nare used for the global and local variables, respectively. If\nprovided, *locals* can be any mapping object.\n\nChanged in version 2.4: Formerly, *locals* was required to be a\ndictionary.\n\nAs a side effect, an implementation may insert additional keys into\nthe dictionaries given besides those corresponding to variable names\nset by the executed code. For example, the current implementation may\nadd a reference to the dictionary of the built-in module\n``__builtin__`` under the key ``__builtins__`` (!).\n\n**Programmer\'s hints:** dynamic evaluation of expressions is supported\nby the built-in function ``eval()``. The built-in functions\n``globals()`` and ``locals()`` return the current global and local\ndictionary, respectively, which may be useful to pass around for use\nby ``exec``.\n', - 'execmodel': u'\nExecution model\n***************\n\n\nNaming and binding\n==================\n\n*Names* refer to objects. Names are introduced by name binding\noperations. Each occurrence of a name in the program text refers to\nthe *binding* of that name established in the innermost function block\ncontaining the use.\n\nA *block* is a piece of Python program text that is executed as a\nunit. The following are blocks: a module, a function body, and a class\ndefinition. Each command typed interactively is a block. A script\nfile (a file given as standard input to the interpreter or specified\non the interpreter command line the first argument) is a code block.\nA script command (a command specified on the interpreter command line\nwith the \'**-c**\' option) is a code block. The file read by the\nbuilt-in function ``execfile()`` is a code block. The string argument\npassed to the built-in function ``eval()`` and to the ``exec``\nstatement is a code block. The expression read and evaluated by the\nbuilt-in function ``input()`` is a code block.\n\nA code block is executed in an *execution frame*. A frame contains\nsome administrative information (used for debugging) and determines\nwhere and how execution continues after the code block\'s execution has\ncompleted.\n\nA *scope* defines the visibility of a name within a block. If a local\nvariable is defined in a block, its scope includes that block. If the\ndefinition occurs in a function block, the scope extends to any blocks\ncontained within the defining one, unless a contained block introduces\na different binding for the name. The scope of names defined in a\nclass block is limited to the class block; it does not extend to the\ncode blocks of methods -- this includes generator expressions since\nthey are implemented using a function scope. This means that the\nfollowing will fail:\n\n class A:\n a = 42\n b = list(a + i for i in range(10))\n\nWhen a name is used in a code block, it is resolved using the nearest\nenclosing scope. The set of all such scopes visible to a code block\nis called the block\'s *environment*.\n\nIf a name is bound in a block, it is a local variable of that block.\nIf a name is bound at the module level, it is a global variable. (The\nvariables of the module code block are local and global.) If a\nvariable is used in a code block but not defined there, it is a *free\nvariable*.\n\nWhen a name is not found at all, a ``NameError`` exception is raised.\nIf the name refers to a local variable that has not been bound, a\n``UnboundLocalError`` exception is raised. ``UnboundLocalError`` is a\nsubclass of ``NameError``.\n\nThe following constructs bind names: formal parameters to functions,\n``import`` statements, class and function definitions (these bind the\nclass or function name in the defining block), and targets that are\nidentifiers if occurring in an assignment, ``for`` loop header, or in\nthe second position of an ``except`` clause header. The ``import``\nstatement of the form "``from ...import *``" binds all names defined\nin the imported module, except those beginning with an underscore.\nThis form may only be used at the module level.\n\nA target occurring in a ``del`` statement is also considered bound for\nthis purpose (though the actual semantics are to unbind the name). It\nis illegal to unbind a name that is referenced by an enclosing scope;\nthe compiler will report a ``SyntaxError``.\n\nEach assignment or import statement occurs within a block defined by a\nclass or function definition or at the module level (the top-level\ncode block).\n\nIf a name binding operation occurs anywhere within a code block, all\nuses of the name within the block are treated as references to the\ncurrent block. This can lead to errors when a name is used within a\nblock before it is bound. This rule is subtle. Python lacks\ndeclarations and allows name binding operations to occur anywhere\nwithin a code block. The local variables of a code block can be\ndetermined by scanning the entire text of the block for name binding\noperations.\n\nIf the global statement occurs within a block, all uses of the name\nspecified in the statement refer to the binding of that name in the\ntop-level namespace. Names are resolved in the top-level namespace by\nsearching the global namespace, i.e. the namespace of the module\ncontaining the code block, and the builtin namespace, the namespace of\nthe module ``__builtin__``. The global namespace is searched first.\nIf the name is not found there, the builtin namespace is searched.\nThe global statement must precede all uses of the name.\n\nThe built-in namespace associated with the execution of a code block\nis actually found by looking up the name ``__builtins__`` in its\nglobal namespace; this should be a dictionary or a module (in the\nlatter case the module\'s dictionary is used). By default, when in the\n``__main__`` module, ``__builtins__`` is the built-in module\n``__builtin__`` (note: no \'s\'); when in any other module,\n``__builtins__`` is an alias for the dictionary of the ``__builtin__``\nmodule itself. ``__builtins__`` can be set to a user-created\ndictionary to create a weak form of restricted execution.\n\nNote: Users should not touch ``__builtins__``; it is strictly an\n implementation detail. Users wanting to override values in the\n built-in namespace should ``import`` the ``__builtin__`` (no \'s\')\n module and modify its attributes appropriately.\n\nThe namespace for a module is automatically created the first time a\nmodule is imported. The main module for a script is always called\n``__main__``.\n\nThe global statement has the same scope as a name binding operation in\nthe same block. If the nearest enclosing scope for a free variable\ncontains a global statement, the free variable is treated as a global.\n\nA class definition is an executable statement that may use and define\nnames. These references follow the normal rules for name resolution.\nThe namespace of the class definition becomes the attribute dictionary\nof the class. Names defined at the class scope are not visible in\nmethods.\n\n\nInteraction with dynamic features\n---------------------------------\n\nThere are several cases where Python statements are illegal when used\nin conjunction with nested scopes that contain free variables.\n\nIf a variable is referenced in an enclosing scope, it is illegal to\ndelete the name. An error will be reported at compile time.\n\nIf the wild card form of import --- ``import *`` --- is used in a\nfunction and the function contains or is a nested block with free\nvariables, the compiler will raise a ``SyntaxError``.\n\nIf ``exec`` is used in a function and the function contains or is a\nnested block with free variables, the compiler will raise a\n``SyntaxError`` unless the exec explicitly specifies the local\nnamespace for the ``exec``. (In other words, ``exec obj`` would be\nillegal, but ``exec obj in ns`` would be legal.)\n\nThe ``eval()``, ``execfile()``, and ``input()`` functions and the\n``exec`` statement do not have access to the full environment for\nresolving names. Names may be resolved in the local and global\nnamespaces of the caller. Free variables are not resolved in the\nnearest enclosing namespace, but in the global namespace. [1] The\n``exec`` statement and the ``eval()`` and ``execfile()`` functions\nhave optional arguments to override the global and local namespace.\nIf only one namespace is specified, it is used for both.\n\n\nExceptions\n==========\n\nExceptions are a means of breaking out of the normal flow of control\nof a code block in order to handle errors or other exceptional\nconditions. An exception is *raised* at the point where the error is\ndetected; it may be *handled* by the surrounding code block or by any\ncode block that directly or indirectly invoked the code block where\nthe error occurred.\n\nThe Python interpreter raises an exception when it detects a run-time\nerror (such as division by zero). A Python program can also\nexplicitly raise an exception with the ``raise`` statement. Exception\nhandlers are specified with the ``try`` ... ``except`` statement. The\n``finally`` clause of such a statement can be used to specify cleanup\ncode which does not handle the exception, but is executed whether an\nexception occurred or not in the preceding code.\n\nPython uses the "termination" model of error handling: an exception\nhandler can find out what happened and continue execution at an outer\nlevel, but it cannot repair the cause of the error and retry the\nfailing operation (except by re-entering the offending piece of code\nfrom the top).\n\nWhen an exception is not handled at all, the interpreter terminates\nexecution of the program, or returns to its interactive main loop. In\neither case, it prints a stack backtrace, except when the exception is\n``SystemExit``.\n\nExceptions are identified by class instances. The ``except`` clause\nis selected depending on the class of the instance: it must reference\nthe class of the instance or a base class thereof. The instance can\nbe received by the handler and can carry additional information about\nthe exceptional condition.\n\nExceptions can also be identified by strings, in which case the\n``except`` clause is selected by object identity. An arbitrary value\ncan be raised along with the identifying string which can be passed to\nthe handler.\n\nWarning: Messages to exceptions are not part of the Python API. Their\n contents may change from one version of Python to the next without\n warning and should not be relied on by code which will run under\n multiple versions of the interpreter.\n\nSee also the description of the ``try`` statement in section *The try\nstatement* and ``raise`` statement in section *The raise statement*.\n\n-[ Footnotes ]-\n\n[1] This limitation occurs because the code that is executed by these\n operations is not available at the time the module is compiled.\n', - 'exprlists': u'\nExpression lists\n****************\n\n expression_list ::= expression ( "," expression )* [","]\n\nAn expression list containing at least one comma yields a tuple. The\nlength of the tuple is the number of expressions in the list. The\nexpressions are evaluated from left to right.\n\nThe trailing comma is required only to create a single tuple (a.k.a. a\n*singleton*); it is optional in all other cases. A single expression\nwithout a trailing comma doesn\'t create a tuple, but rather yields the\nvalue of that expression. (To create an empty tuple, use an empty pair\nof parentheses: ``()``.)\n', - 'floating': u'\nFloating point literals\n***********************\n\nFloating point literals are described by the following lexical\ndefinitions:\n\n floatnumber ::= pointfloat | exponentfloat\n pointfloat ::= [intpart] fraction | intpart "."\n exponentfloat ::= (intpart | pointfloat) exponent\n intpart ::= digit+\n fraction ::= "." digit+\n exponent ::= ("e" | "E") ["+" | "-"] digit+\n\nNote that the integer and exponent parts of floating point numbers can\nlook like octal integers, but are interpreted using radix 10. For\nexample, ``077e010`` is legal, and denotes the same number as\n``77e10``. The allowed range of floating point literals is\nimplementation-dependent. Some examples of floating point literals:\n\n 3.14 10. .001 1e100 3.14e-10 0e0\n\nNote that numeric literals do not include a sign; a phrase like ``-1``\nis actually an expression composed of the unary operator ``-`` and the\nliteral ``1``.\n', - 'for': u'\nThe ``for`` statement\n*********************\n\nThe ``for`` statement is used to iterate over the elements of a\nsequence (such as a string, tuple or list) or other iterable object:\n\n for_stmt ::= "for" target_list "in" expression_list ":" suite\n ["else" ":" suite]\n\nThe expression list is evaluated once; it should yield an iterable\nobject. An iterator is created for the result of the\n``expression_list``. The suite is then executed once for each item\nprovided by the iterator, in the order of ascending indices. Each\nitem in turn is assigned to the target list using the standard rules\nfor assignments, and then the suite is executed. When the items are\nexhausted (which is immediately when the sequence is empty), the suite\nin the ``else`` clause, if present, is executed, and the loop\nterminates.\n\nA ``break`` statement executed in the first suite terminates the loop\nwithout executing the ``else`` clause\'s suite. A ``continue``\nstatement executed in the first suite skips the rest of the suite and\ncontinues with the next item, or with the ``else`` clause if there was\nno next item.\n\nThe suite may assign to the variable(s) in the target list; this does\nnot affect the next item assigned to it.\n\nThe target list is not deleted when the loop is finished, but if the\nsequence is empty, it will not have been assigned to at all by the\nloop. Hint: the built-in function ``range()`` returns a sequence of\nintegers suitable to emulate the effect of Pascal\'s ``for i := a to b\ndo``; e.g., ``range(3)`` returns the list ``[0, 1, 2]``.\n\nWarning: There is a subtlety when the sequence is being modified by the loop\n (this can only occur for mutable sequences, i.e. lists). An internal\n counter is used to keep track of which item is used next, and this\n is incremented on each iteration. When this counter has reached the\n length of the sequence the loop terminates. This means that if the\n suite deletes the current (or a previous) item from the sequence,\n the next item will be skipped (since it gets the index of the\n current item which has already been treated). Likewise, if the\n suite inserts an item in the sequence before the current item, the\n current item will be treated again the next time through the loop.\n This can lead to nasty bugs that can be avoided by making a\n temporary copy using a slice of the whole sequence, e.g.,\n\n for x in a[:]:\n if x < 0: a.remove(x)\n', - 'formatstrings': u'\nFormat String Syntax\n********************\n\nThe ``str.format()`` method and the ``Formatter`` class share the same\nsyntax for format strings (although in the case of ``Formatter``,\nsubclasses can define their own format string syntax.)\n\nFormat strings contain "replacement fields" surrounded by curly braces\n``{}``. Anything that is not contained in braces is considered literal\ntext, which is copied unchanged to the output. If you need to include\na brace character in the literal text, it can be escaped by doubling:\n``{{`` and ``}}``.\n\nThe grammar for a replacement field is as follows:\n\n replacement_field ::= "{" field_name ["!" conversion] [":" format_spec] "}"\n field_name ::= (identifier | integer) ("." attribute_name | "[" element_index "]")*\n attribute_name ::= identifier\n element_index ::= integer\n conversion ::= "r" | "s"\n format_spec ::= \n\nIn less formal terms, the replacement field starts with a\n*field_name*, which can either be a number (for a positional\nargument), or an identifier (for keyword arguments). Following this\nis an optional *conversion* field, which is preceded by an exclamation\npoint ``\'!\'``, and a *format_spec*, which is preceded by a colon\n``\':\'``.\n\nThe *field_name* itself begins with either a number or a keyword. If\nit\'s a number, it refers to a positional argument, and if it\'s a\nkeyword it refers to a named keyword argument. This can be followed\nby any number of index or attribute expressions. An expression of the\nform ``\'.name\'`` selects the named attribute using ``getattr()``,\nwhile an expression of the form ``\'[index]\'`` does an index lookup\nusing ``__getitem__()``.\n\nSome simple format string examples:\n\n "First, thou shalt count to {0}" # References first positional argument\n "My quest is {name}" # References keyword argument \'name\'\n "Weight in tons {0.weight}" # \'weight\' attribute of first positional arg\n "Units destroyed: {players[0]}" # First element of keyword argument \'players\'.\n\nThe *conversion* field causes a type coercion before formatting.\nNormally, the job of formatting a value is done by the\n``__format__()`` method of the value itself. However, in some cases\nit is desirable to force a type to be formatted as a string,\noverriding its own definition of formatting. By converting the value\nto a string before calling ``__format__()``, the normal formatting\nlogic is bypassed.\n\nTwo conversion flags are currently supported: ``\'!s\'`` which calls\n``str()`` on the value, and ``\'!r\'`` which calls ``repr()``.\n\nSome examples:\n\n "Harold\'s a clever {0!s}" # Calls str() on the argument first\n "Bring out the holy {name!r}" # Calls repr() on the argument first\n\nThe *format_spec* field contains a specification of how the value\nshould be presented, including such details as field width, alignment,\npadding, decimal precision and so on. Each value type can define it\'s\nown "formatting mini-language" or interpretation of the *format_spec*.\n\nMost built-in types support a common formatting mini-language, which\nis described in the next section.\n\nA *format_spec* field can also include nested replacement fields\nwithin it. These nested replacement fields can contain only a field\nname; conversion flags and format specifications are not allowed. The\nreplacement fields within the format_spec are substituted before the\n*format_spec* string is interpreted. This allows the formatting of a\nvalue to be dynamically specified.\n\nFor example, suppose you wanted to have a replacement field whose\nfield width is determined by another variable:\n\n "A man with two {0:{1}}".format("noses", 10)\n\nThis would first evaluate the inner replacement field, making the\nformat string effectively:\n\n "A man with two {0:10}"\n\nThen the outer replacement field would be evaluated, producing:\n\n "noses "\n\nWhich is subsitituted into the string, yielding:\n\n "A man with two noses "\n\n(The extra space is because we specified a field width of 10, and\nbecause left alignment is the default for strings.)\n\n\nFormat Specification Mini-Language\n==================================\n\n"Format specifications" are used within replacement fields contained\nwithin a format string to define how individual values are presented\n(see *Format String Syntax*.) They can also be passed directly to the\nbuiltin ``format()`` function. Each formattable type may define how\nthe format specification is to be interpreted.\n\nMost built-in types implement the following options for format\nspecifications, although some of the formatting options are only\nsupported by the numeric types.\n\nA general convention is that an empty format string (``""``) produces\nthe same result as if you had called ``str()`` on the value.\n\nThe general form of a *standard format specifier* is:\n\n format_spec ::= [[fill]align][sign][0][width][.precision][type]\n fill ::= \n align ::= "<" | ">" | "=" | "^"\n sign ::= "+" | "-" | " "\n width ::= integer\n precision ::= integer\n type ::= "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g" | "G" | "n" | "o" | "x" | "X" | "%"\n\nThe *fill* character can be any character other than \'}\' (which\nsignifies the end of the field). The presence of a fill character is\nsignaled by the *next* character, which must be one of the alignment\noptions. If the second character of *format_spec* is not a valid\nalignment option, then it is assumed that both the fill character and\nthe alignment option are absent.\n\nThe meaning of the various alignment options is as follows:\n\n +-----------+------------------------------------------------------------+\n | Option | Meaning |\n +===========+============================================================+\n | ``\'<\'`` | Forces the field to be left-aligned within the available |\n | | space (This is the default.) |\n +-----------+------------------------------------------------------------+\n | ``\'>\'`` | Forces the field to be right-aligned within the available |\n | | space. |\n +-----------+------------------------------------------------------------+\n | ``\'=\'`` | Forces the padding to be placed after the sign (if any) |\n | | but before the digits. This is used for printing fields |\n | | in the form \'+000000120\'. This alignment option is only |\n | | valid for numeric types. |\n +-----------+------------------------------------------------------------+\n | ``\'^\'`` | Forces the field to be centered within the available |\n | | space. |\n +-----------+------------------------------------------------------------+\n\nNote that unless a minimum field width is defined, the field width\nwill always be the same size as the data to fill it, so that the\nalignment option has no meaning in this case.\n\nThe *sign* option is only valid for number types, and can be one of\nthe following:\n\n +-----------+------------------------------------------------------------+\n | Option | Meaning |\n +===========+============================================================+\n | ``\'+\'`` | indicates that a sign should be used for both positive as |\n | | well as negative numbers. |\n +-----------+------------------------------------------------------------+\n | ``\'-\'`` | indicates that a sign should be used only for negative |\n | | numbers (this is the default behavior). |\n +-----------+------------------------------------------------------------+\n | space | indicates that a leading space should be used on positive |\n | | numbers, and a minus sign on negative numbers. |\n +-----------+------------------------------------------------------------+\n\n*width* is a decimal integer defining the minimum field width. If not\nspecified, then the field width will be determined by the content.\n\nIf the *width* field is preceded by a zero (``\'0\'``) character, this\nenables zero-padding. This is equivalent to an *alignment* type of\n``\'=\'`` and a *fill* character of ``\'0\'``.\n\nThe *precision* is a decimal number indicating how many digits should\nbe displayed after the decimal point for a floating point value. For\nnon-number types the field indicates the maximum field size - in other\nwords, how many characters will be used from the field content. The\n*precision* is ignored for integer values.\n\nFinally, the *type* determines how the data should be presented.\n\nThe available integer presentation types are:\n\n +-----------+------------------------------------------------------------+\n | Type | Meaning |\n +===========+============================================================+\n | ``\'b\'`` | Binary. Outputs the number in base 2. |\n +-----------+------------------------------------------------------------+\n | ``\'c\'`` | Character. Converts the integer to the corresponding |\n | | unicode character before printing. |\n +-----------+------------------------------------------------------------+\n | ``\'d\'`` | Decimal Integer. Outputs the number in base 10. |\n +-----------+------------------------------------------------------------+\n | ``\'o\'`` | Octal format. Outputs the number in base 8. |\n +-----------+------------------------------------------------------------+\n | ``\'x\'`` | Hex format. Outputs the number in base 16, using lower- |\n | | case letters for the digits above 9. |\n +-----------+------------------------------------------------------------+\n | ``\'X\'`` | Hex format. Outputs the number in base 16, using upper- |\n | | case letters for the digits above 9. |\n +-----------+------------------------------------------------------------+\n | ``\'n\'`` | Number. This is the same as ``\'d\'``, except that it uses |\n | | the current locale setting to insert the appropriate |\n | | number separator characters. |\n +-----------+------------------------------------------------------------+\n | None | the same as ``\'d\'`` |\n +-----------+------------------------------------------------------------+\n\nThe available presentation types for floating point and decimal values\nare:\n\n +-----------+------------------------------------------------------------+\n | Type | Meaning |\n +===========+============================================================+\n | ``\'e\'`` | Exponent notation. Prints the number in scientific |\n | | notation using the letter \'e\' to indicate the exponent. |\n +-----------+------------------------------------------------------------+\n | ``\'E\'`` | Exponent notation. Same as ``\'e\'`` except it uses an upper |\n | | case \'E\' as the separator character. |\n +-----------+------------------------------------------------------------+\n | ``\'f\'`` | Fixed point. Displays the number as a fixed-point number. |\n +-----------+------------------------------------------------------------+\n | ``\'F\'`` | Fixed point. Same as ``\'f\'``. |\n +-----------+------------------------------------------------------------+\n | ``\'g\'`` | General format. This prints the number as a fixed-point |\n | | number, unless the number is too large, in which case it |\n | | switches to ``\'e\'`` exponent notation. |\n +-----------+------------------------------------------------------------+\n | ``\'G\'`` | General format. Same as ``\'g\'`` except switches to ``\'E\'`` |\n | | if the number gets to large. |\n +-----------+------------------------------------------------------------+\n | ``\'n\'`` | Number. This is the same as ``\'g\'``, except that it uses |\n | | the current locale setting to insert the appropriate |\n | | number separator characters. |\n +-----------+------------------------------------------------------------+\n | ``\'%\'`` | Percentage. Multiplies the number by 100 and displays in |\n | | fixed (``\'f\'``) format, followed by a percent sign. |\n +-----------+------------------------------------------------------------+\n | None | the same as ``\'g\'`` |\n +-----------+------------------------------------------------------------+\n', - 'function': u'\nFunction definitions\n********************\n\nA function definition defines a user-defined function object (see\nsection *The standard type hierarchy*):\n\n decorated ::= decorators (classdef | funcdef)\n decorators ::= decorator+\n decorator ::= "@" dotted_name ["(" [argument_list [","]] ")"] NEWLINE\n funcdef ::= "def" funcname "(" [parameter_list] ")" ":" suite\n dotted_name ::= identifier ("." identifier)*\n parameter_list ::= (defparameter ",")*\n ( "*" identifier [, "**" identifier]\n | "**" identifier\n | defparameter [","] )\n defparameter ::= parameter ["=" expression]\n sublist ::= parameter ("," parameter)* [","]\n parameter ::= identifier | "(" sublist ")"\n funcname ::= identifier\n\nA function definition is an executable statement. Its execution binds\nthe function name in the current local namespace to a function object\n(a wrapper around the executable code for the function). This\nfunction object contains a reference to the current global namespace\nas the global namespace to be used when the function is called.\n\nThe function definition does not execute the function body; this gets\nexecuted only when the function is called.\n\nA function definition may be wrapped by one or more *decorator*\nexpressions. Decorator expressions are evaluated when the function is\ndefined, in the scope that contains the function definition. The\nresult must be a callable, which is invoked with the function object\nas the only argument. The returned value is bound to the function name\ninstead of the function object. Multiple decorators are applied in\nnested fashion. For example, the following code:\n\n @f1(arg)\n @f2\n def func(): pass\n\nis equivalent to:\n\n def func(): pass\n func = f1(arg)(f2(func))\n\nWhen one or more top-level parameters have the form *parameter* ``=``\n*expression*, the function is said to have "default parameter values."\nFor a parameter with a default value, the corresponding argument may\nbe omitted from a call, in which case the parameter\'s default value is\nsubstituted. If a parameter has a default value, all following\nparameters must also have a default value --- this is a syntactic\nrestriction that is not expressed by the grammar.\n\n**Default parameter values are evaluated when the function definition\nis executed.** This means that the expression is evaluated once, when\nthe function is defined, and that that same "pre-computed" value is\nused for each call. This is especially important to understand when a\ndefault parameter is a mutable object, such as a list or a dictionary:\nif the function modifies the object (e.g. by appending an item to a\nlist), the default value is in effect modified. This is generally not\nwhat was intended. A way around this is to use ``None`` as the\ndefault, and explicitly test for it in the body of the function, e.g.:\n\n def whats_on_the_telly(penguin=None):\n if penguin is None:\n penguin = []\n penguin.append("property of the zoo")\n return penguin\n\nFunction call semantics are described in more detail in section\n*Calls*. A function call always assigns values to all parameters\nmentioned in the parameter list, either from position arguments, from\nkeyword arguments, or from default values. If the form\n"``*identifier``" is present, it is initialized to a tuple receiving\nany excess positional parameters, defaulting to the empty tuple. If\nthe form "``**identifier``" is present, it is initialized to a new\ndictionary receiving any excess keyword arguments, defaulting to a new\nempty dictionary.\n\nIt is also possible to create anonymous functions (functions not bound\nto a name), for immediate use in expressions. This uses lambda forms,\ndescribed in section *Expression lists*. Note that the lambda form is\nmerely a shorthand for a simplified function definition; a function\ndefined in a "``def``" statement can be passed around or assigned to\nanother name just like a function defined by a lambda form. The\n"``def``" form is actually more powerful since it allows the execution\nof multiple statements.\n\n**Programmer\'s note:** Functions are first-class objects. A "``def``"\nform executed inside a function definition defines a local function\nthat can be returned or passed around. Free variables used in the\nnested function can access the local variables of the function\ncontaining the def. See section *Naming and binding* for details.\n', - 'global': u'\nThe ``global`` statement\n************************\n\n global_stmt ::= "global" identifier ("," identifier)*\n\nThe ``global`` statement is a declaration which holds for the entire\ncurrent code block. It means that the listed identifiers are to be\ninterpreted as globals. It would be impossible to assign to a global\nvariable without ``global``, although free variables may refer to\nglobals without being declared global.\n\nNames listed in a ``global`` statement must not be used in the same\ncode block textually preceding that ``global`` statement.\n\nNames listed in a ``global`` statement must not be defined as formal\nparameters or in a ``for`` loop control target, ``class`` definition,\nfunction definition, or ``import`` statement.\n\n(The current implementation does not enforce the latter two\nrestrictions, but programs should not abuse this freedom, as future\nimplementations may enforce them or silently change the meaning of the\nprogram.)\n\n**Programmer\'s note:** the ``global`` is a directive to the parser.\nIt applies only to code parsed at the same time as the ``global``\nstatement. In particular, a ``global`` statement contained in an\n``exec`` statement does not affect the code block *containing* the\n``exec`` statement, and code contained in an ``exec`` statement is\nunaffected by ``global`` statements in the code containing the\n``exec`` statement. The same applies to the ``eval()``,\n``execfile()`` and ``compile()`` functions.\n', - 'id-classes': u'\nReserved classes of identifiers\n*******************************\n\nCertain classes of identifiers (besides keywords) have special\nmeanings. These classes are identified by the patterns of leading and\ntrailing underscore characters:\n\n``_*``\n Not imported by ``from module import *``. The special identifier\n ``_`` is used in the interactive interpreter to store the result of\n the last evaluation; it is stored in the ``__builtin__`` module.\n When not in interactive mode, ``_`` has no special meaning and is\n not defined. See section *The import statement*.\n\n Note: The name ``_`` is often used in conjunction with\n internationalization; refer to the documentation for the\n ``gettext`` module for more information on this convention.\n\n``__*__``\n System-defined names. These names are defined by the interpreter\n and its implementation (including the standard library);\n applications should not expect to define additional names using\n this convention. The set of names of this class defined by Python\n may be extended in future versions. See section *Special method\n names*.\n\n``__*``\n Class-private names. Names in this category, when used within the\n context of a class definition, are re-written to use a mangled form\n to help avoid name clashes between "private" attributes of base and\n derived classes. See section *Identifiers (Names)*.\n', - 'identifiers': u'\nIdentifiers and keywords\n************************\n\nIdentifiers (also referred to as *names*) are described by the\nfollowing lexical definitions:\n\n identifier ::= (letter|"_") (letter | digit | "_")*\n letter ::= lowercase | uppercase\n lowercase ::= "a"..."z"\n uppercase ::= "A"..."Z"\n digit ::= "0"..."9"\n\nIdentifiers are unlimited in length. Case is significant.\n\n\nKeywords\n========\n\nThe following identifiers are used as reserved words, or *keywords* of\nthe language, and cannot be used as ordinary identifiers. They must\nbe spelled exactly as written here:\n\n and del from not while\n as elif global or with\n assert else if pass yield\n break except import print\n class exec in raise\n continue finally is return\n def for lambda try\n\nChanged in version 2.4: ``None`` became a constant and is now\nrecognized by the compiler as a name for the built-in object ``None``.\nAlthough it is not a keyword, you cannot assign a different object to\nit.\n\nChanged in version 2.5: Both ``as`` and ``with`` are only recognized\nwhen the ``with_statement`` future feature has been enabled. It will\nalways be enabled in Python 2.6. See section *The with statement* for\ndetails. Note that using ``as`` and ``with`` as identifiers will\nalways issue a warning, even when the ``with_statement`` future\ndirective is not in effect.\n\n\nReserved classes of identifiers\n===============================\n\nCertain classes of identifiers (besides keywords) have special\nmeanings. These classes are identified by the patterns of leading and\ntrailing underscore characters:\n\n``_*``\n Not imported by ``from module import *``. The special identifier\n ``_`` is used in the interactive interpreter to store the result of\n the last evaluation; it is stored in the ``__builtin__`` module.\n When not in interactive mode, ``_`` has no special meaning and is\n not defined. See section *The import statement*.\n\n Note: The name ``_`` is often used in conjunction with\n internationalization; refer to the documentation for the\n ``gettext`` module for more information on this convention.\n\n``__*__``\n System-defined names. These names are defined by the interpreter\n and its implementation (including the standard library);\n applications should not expect to define additional names using\n this convention. The set of names of this class defined by Python\n may be extended in future versions. See section *Special method\n names*.\n\n``__*``\n Class-private names. Names in this category, when used within the\n context of a class definition, are re-written to use a mangled form\n to help avoid name clashes between "private" attributes of base and\n derived classes. See section *Identifiers (Names)*.\n', - 'if': u'\nThe ``if`` statement\n********************\n\nThe ``if`` statement is used for conditional execution:\n\n if_stmt ::= "if" expression ":" suite\n ( "elif" expression ":" suite )*\n ["else" ":" suite]\n\nIt selects exactly one of the suites by evaluating the expressions one\nby one until one is found to be true (see section *Boolean operations*\nfor the definition of true and false); then that suite is executed\n(and no other part of the ``if`` statement is executed or evaluated).\nIf all expressions are false, the suite of the ``else`` clause, if\npresent, is executed.\n', - 'imaginary': u'\nImaginary literals\n******************\n\nImaginary literals are described by the following lexical definitions:\n\n imagnumber ::= (floatnumber | intpart) ("j" | "J")\n\nAn imaginary literal yields a complex number with a real part of 0.0.\nComplex numbers are represented as a pair of floating point numbers\nand have the same restrictions on their range. To create a complex\nnumber with a nonzero real part, add a floating point number to it,\ne.g., ``(3+4j)``. Some examples of imaginary literals:\n\n 3.14j 10.j 10j .001j 1e100j 3.14e-10j\n', - 'import': u'\nThe ``import`` statement\n************************\n\n import_stmt ::= "import" module ["as" name] ( "," module ["as" name] )*\n | "from" relative_module "import" identifier ["as" name]\n ( "," identifier ["as" name] )*\n | "from" relative_module "import" "(" identifier ["as" name]\n ( "," identifier ["as" name] )* [","] ")"\n | "from" module "import" "*"\n module ::= (identifier ".")* identifier\n relative_module ::= "."* module | "."+\n name ::= identifier\n\nImport statements are executed in two steps: (1) find a module, and\ninitialize it if necessary; (2) define a name or names in the local\nnamespace (of the scope where the ``import`` statement occurs). The\nfirst form (without ``from``) repeats these steps for each identifier\nin the list. The form with ``from`` performs step (1) once, and then\nperforms step (2) repeatedly.\n\nIn this context, to "initialize" a built-in or extension module means\nto call an initialization function that the module must provide for\nthe purpose (in the reference implementation, the function\'s name is\nobtained by prepending string "init" to the module\'s name); to\n"initialize" a Python-coded module means to execute the module\'s body.\n\nThe system maintains a table of modules that have been or are being\ninitialized, indexed by module name. This table is accessible as\n``sys.modules``. When a module name is found in this table, step (1)\nis finished. If not, a search for a module definition is started.\nWhen a module is found, it is loaded. Details of the module searching\nand loading process are implementation and platform specific. It\ngenerally involves searching for a "built-in" module with the given\nname and then searching a list of locations given as ``sys.path``.\n\nIf a built-in module is found, its built-in initialization code is\nexecuted and step (1) is finished. If no matching file is found,\n``ImportError`` is raised. If a file is found, it is parsed, yielding\nan executable code block. If a syntax error occurs, ``SyntaxError``\nis raised. Otherwise, an empty module of the given name is created\nand inserted in the module table, and then the code block is executed\nin the context of this module. Exceptions during this execution\nterminate step (1).\n\nWhen step (1) finishes without raising an exception, step (2) can\nbegin.\n\nThe first form of ``import`` statement binds the module name in the\nlocal namespace to the module object, and then goes on to import the\nnext identifier, if any. If the module name is followed by ``as``,\nthe name following ``as`` is used as the local name for the module.\n\nThe ``from`` form does not bind the module name: it goes through the\nlist of identifiers, looks each one of them up in the module found in\nstep (1), and binds the name in the local namespace to the object thus\nfound. As with the first form of ``import``, an alternate local name\ncan be supplied by specifying "``as`` localname". If a name is not\nfound, ``ImportError`` is raised. If the list of identifiers is\nreplaced by a star (``\'*\'``), all public names defined in the module\nare bound in the local namespace of the ``import`` statement..\n\nThe *public names* defined by a module are determined by checking the\nmodule\'s namespace for a variable named ``__all__``; if defined, it\nmust be a sequence of strings which are names defined or imported by\nthat module. The names given in ``__all__`` are all considered public\nand are required to exist. If ``__all__`` is not defined, the set of\npublic names includes all names found in the module\'s namespace which\ndo not begin with an underscore character (``\'_\'``). ``__all__``\nshould contain the entire public API. It is intended to avoid\naccidentally exporting items that are not part of the API (such as\nlibrary modules which were imported and used within the module).\n\nThe ``from`` form with ``*`` may only occur in a module scope. If the\nwild card form of import --- ``import *`` --- is used in a function\nand the function contains or is a nested block with free variables,\nthe compiler will raise a ``SyntaxError``.\n\n**Hierarchical module names:** when the module names contains one or\nmore dots, the module search path is carried out differently. The\nsequence of identifiers up to the last dot is used to find a\n"package"; the final identifier is then searched inside the package.\nA package is generally a subdirectory of a directory on ``sys.path``\nthat has a file ``__init__.py``. [XXX Can\'t be bothered to spell this\nout right now; see the URL\nhttp://www.python.org/doc/essays/packages.html for more details, also\nabout how the module search works from inside a package.]\n\nThe built-in function ``__import__()`` is provided to support\napplications that determine which modules need to be loaded\ndynamically; refer to *Built-in Functions* for additional information.\n\n\nFuture statements\n=================\n\nA *future statement* is a directive to the compiler that a particular\nmodule should be compiled using syntax or semantics that will be\navailable in a specified future release of Python. The future\nstatement is intended to ease migration to future versions of Python\nthat introduce incompatible changes to the language. It allows use of\nthe new features on a per-module basis before the release in which the\nfeature becomes standard.\n\n future_statement ::= "from" "__future__" "import" feature ["as" name]\n ("," feature ["as" name])*\n | "from" "__future__" "import" "(" feature ["as" name]\n ("," feature ["as" name])* [","] ")"\n feature ::= identifier\n name ::= identifier\n\nA future statement must appear near the top of the module. The only\nlines that can appear before a future statement are:\n\n* the module docstring (if any),\n\n* comments,\n\n* blank lines, and\n\n* other future statements.\n\nThe features recognized by Python 2.5 are ``absolute_import``,\n``division``, ``generators``, ``nested_scopes`` and\n``with_statement``. ``generators`` and ``nested_scopes`` are\nredundant in Python version 2.3 and above because they are always\nenabled.\n\nA future statement is recognized and treated specially at compile\ntime: Changes to the semantics of core constructs are often\nimplemented by generating different code. It may even be the case\nthat a new feature introduces new incompatible syntax (such as a new\nreserved word), in which case the compiler may need to parse the\nmodule differently. Such decisions cannot be pushed off until\nruntime.\n\nFor any given release, the compiler knows which feature names have\nbeen defined, and raises a compile-time error if a future statement\ncontains a feature not known to it.\n\nThe direct runtime semantics are the same as for any import statement:\nthere is a standard module ``__future__``, described later, and it\nwill be imported in the usual way at the time the future statement is\nexecuted.\n\nThe interesting runtime semantics depend on the specific feature\nenabled by the future statement.\n\nNote that there is nothing special about the statement:\n\n import __future__ [as name]\n\nThat is not a future statement; it\'s an ordinary import statement with\nno special semantics or syntax restrictions.\n\nCode compiled by an ``exec`` statement or calls to the builtin\nfunctions ``compile()`` and ``execfile()`` that occur in a module\n``M`` containing a future statement will, by default, use the new\nsyntax or semantics associated with the future statement. This can,\nstarting with Python 2.2 be controlled by optional arguments to\n``compile()`` --- see the documentation of that function for details.\n\nA future statement typed at an interactive interpreter prompt will\ntake effect for the rest of the interpreter session. If an\ninterpreter is started with the *-i* option, is passed a script name\nto execute, and the script includes a future statement, it will be in\neffect in the interactive session started after the script is\nexecuted.\n', - 'in': u'\nComparisons\n***********\n\nUnlike C, all comparison operations in Python have the same priority,\nwhich is lower than that of any arithmetic, shifting or bitwise\noperation. Also unlike C, expressions like ``a < b < c`` have the\ninterpretation that is conventional in mathematics:\n\n comparison ::= or_expr ( comp_operator or_expr )*\n comp_operator ::= "<" | ">" | "==" | ">=" | "<=" | "<>" | "!="\n | "is" ["not"] | ["not"] "in"\n\nComparisons yield boolean values: ``True`` or ``False``.\n\nComparisons can be chained arbitrarily, e.g., ``x < y <= z`` is\nequivalent to ``x < y and y <= z``, except that ``y`` is evaluated\nonly once (but in both cases ``z`` is not evaluated at all when ``x <\ny`` is found to be false).\n\nFormally, if *a*, *b*, *c*, ..., *y*, *z* are expressions and *op1*,\n*op2*, ..., *opN* are comparison operators, then ``a op1 b op2 c ... y\nopN z`` is equivalent to ``a op1 b and b op2 c and ... y opN z``,\nexcept that each expression is evaluated at most once.\n\nNote that ``a op1 b op2 c`` doesn\'t imply any kind of comparison\nbetween *a* and *c*, so that, e.g., ``x < y > z`` is perfectly legal\n(though perhaps not pretty).\n\nThe forms ``<>`` and ``!=`` are equivalent; for consistency with C,\n``!=`` is preferred; where ``!=`` is mentioned below ``<>`` is also\naccepted. The ``<>`` spelling is considered obsolescent.\n\nThe operators ``<``, ``>``, ``==``, ``>=``, ``<=``, and ``!=`` compare\nthe values of two objects. The objects need not have the same type.\nIf both are numbers, they are converted to a common type. Otherwise,\nobjects of different types *always* compare unequal, and are ordered\nconsistently but arbitrarily. You can control comparison behavior of\nobjects of non-builtin types by defining a ``__cmp__`` method or rich\ncomparison methods like ``__gt__``, described in section *Special\nmethod names*.\n\n(This unusual definition of comparison was used to simplify the\ndefinition of operations like sorting and the ``in`` and ``not in``\noperators. In the future, the comparison rules for objects of\ndifferent types are likely to change.)\n\nComparison of objects of the same type depends on the type:\n\n* Numbers are compared arithmetically.\n\n* Strings are compared lexicographically using the numeric equivalents\n (the result of the built-in function ``ord()``) of their characters.\n Unicode and 8-bit strings are fully interoperable in this behavior.\n [4]\n\n* Tuples and lists are compared lexicographically using comparison of\n corresponding elements. This means that to compare equal, each\n element must compare equal and the two sequences must be of the same\n type and have the same length.\n\n If not equal, the sequences are ordered the same as their first\n differing elements. For example, ``cmp([1,2,x], [1,2,y])`` returns\n the same as ``cmp(x,y)``. If the corresponding element does not\n exist, the shorter sequence is ordered first (for example, ``[1,2] <\n [1,2,3]``).\n\n* Mappings (dictionaries) compare equal if and only if their sorted\n (key, value) lists compare equal. [5] Outcomes other than equality\n are resolved consistently, but are not otherwise defined. [6]\n\n* Most other objects of builtin types compare unequal unless they are\n the same object; the choice whether one object is considered smaller\n or larger than another one is made arbitrarily but consistently\n within one execution of a program.\n\nThe operators ``in`` and ``not in`` test for collection membership.\n``x in s`` evaluates to true if *x* is a member of the collection *s*,\nand false otherwise. ``x not in s`` returns the negation of ``x in\ns``. The collection membership test has traditionally been bound to\nsequences; an object is a member of a collection if the collection is\na sequence and contains an element equal to that object. However, it\nmake sense for many other object types to support membership tests\nwithout being a sequence. In particular, dictionaries (for keys) and\nsets support membership testing.\n\nFor the list and tuple types, ``x in y`` is true if and only if there\nexists an index *i* such that ``x == y[i]`` is true.\n\nFor the Unicode and string types, ``x in y`` is true if and only if\n*x* is a substring of *y*. An equivalent test is ``y.find(x) != -1``.\nNote, *x* and *y* need not be the same type; consequently, ``u\'ab\' in\n\'abc\'`` will return ``True``. Empty strings are always considered to\nbe a substring of any other string, so ``"" in "abc"`` will return\n``True``.\n\nChanged in version 2.3: Previously, *x* was required to be a string of\nlength ``1``.\n\nFor user-defined classes which define the ``__contains__()`` method,\n``x in y`` is true if and only if ``y.__contains__(x)`` is true.\n\nFor user-defined classes which do not define ``__contains__()`` and do\ndefine ``__getitem__()``, ``x in y`` is true if and only if there is a\nnon-negative integer index *i* such that ``x == y[i]``, and all lower\ninteger indices do not raise ``IndexError`` exception. (If any other\nexception is raised, it is as if ``in`` raised that exception).\n\nThe operator ``not in`` is defined to have the inverse true value of\n``in``.\n\nThe operators ``is`` and ``is not`` test for object identity: ``x is\ny`` is true if and only if *x* and *y* are the same object. ``x is\nnot y`` yields the inverse truth value.\n', - 'integers': u'\nInteger and long integer literals\n*********************************\n\nInteger and long integer literals are described by the following\nlexical definitions:\n\n longinteger ::= integer ("l" | "L")\n integer ::= decimalinteger | octinteger | hexinteger\n decimalinteger ::= nonzerodigit digit* | "0"\n octinteger ::= "0" octdigit+\n hexinteger ::= "0" ("x" | "X") hexdigit+\n nonzerodigit ::= "1"..."9"\n octdigit ::= "0"..."7"\n hexdigit ::= digit | "a"..."f" | "A"..."F"\n\nAlthough both lower case ``\'l\'`` and upper case ``\'L\'`` are allowed as\nsuffix for long integers, it is strongly recommended to always use\n``\'L\'``, since the letter ``\'l\'`` looks too much like the digit\n``\'1\'``.\n\nPlain integer literals that are above the largest representable plain\ninteger (e.g., 2147483647 when using 32-bit arithmetic) are accepted\nas if they were long integers instead. [1] There is no limit for long\ninteger literals apart from what can be stored in available memory.\n\nSome examples of plain integer literals (first row) and long integer\nliterals (second and third rows):\n\n 7 2147483647 0177\n 3L 79228162514264337593543950336L 0377L 0x100000000L\n 79228162514264337593543950336 0xdeadbeef\n', - 'lambda': u'\nExpression lists\n****************\n\n expression_list ::= expression ( "," expression )* [","]\n\nAn expression list containing at least one comma yields a tuple. The\nlength of the tuple is the number of expressions in the list. The\nexpressions are evaluated from left to right.\n\nThe trailing comma is required only to create a single tuple (a.k.a. a\n*singleton*); it is optional in all other cases. A single expression\nwithout a trailing comma doesn\'t create a tuple, but rather yields the\nvalue of that expression. (To create an empty tuple, use an empty pair\nof parentheses: ``()``.)\n', - 'lists': u'\nList displays\n*************\n\nA list display is a possibly empty series of expressions enclosed in\nsquare brackets:\n\n list_display ::= "[" [expression_list | list_comprehension] "]"\n list_comprehension ::= expression list_for\n list_for ::= "for" target_list "in" old_expression_list [list_iter]\n old_expression_list ::= old_expression [("," old_expression)+ [","]]\n list_iter ::= list_for | list_if\n list_if ::= "if" old_expression [list_iter]\n\nA list display yields a new list object. Its contents are specified\nby providing either a list of expressions or a list comprehension.\nWhen a comma-separated list of expressions is supplied, its elements\nare evaluated from left to right and placed into the list object in\nthat order. When a list comprehension is supplied, it consists of a\nsingle expression followed by at least one ``for`` clause and zero or\nmore ``for`` or ``if`` clauses. In this case, the elements of the new\nlist are those that would be produced by considering each of the\n``for`` or ``if`` clauses a block, nesting from left to right, and\nevaluating the expression to produce a list element each time the\ninnermost block is reached [1].\n', - 'naming': u'\nNaming and binding\n******************\n\n*Names* refer to objects. Names are introduced by name binding\noperations. Each occurrence of a name in the program text refers to\nthe *binding* of that name established in the innermost function block\ncontaining the use.\n\nA *block* is a piece of Python program text that is executed as a\nunit. The following are blocks: a module, a function body, and a class\ndefinition. Each command typed interactively is a block. A script\nfile (a file given as standard input to the interpreter or specified\non the interpreter command line the first argument) is a code block.\nA script command (a command specified on the interpreter command line\nwith the \'**-c**\' option) is a code block. The file read by the\nbuilt-in function ``execfile()`` is a code block. The string argument\npassed to the built-in function ``eval()`` and to the ``exec``\nstatement is a code block. The expression read and evaluated by the\nbuilt-in function ``input()`` is a code block.\n\nA code block is executed in an *execution frame*. A frame contains\nsome administrative information (used for debugging) and determines\nwhere and how execution continues after the code block\'s execution has\ncompleted.\n\nA *scope* defines the visibility of a name within a block. If a local\nvariable is defined in a block, its scope includes that block. If the\ndefinition occurs in a function block, the scope extends to any blocks\ncontained within the defining one, unless a contained block introduces\na different binding for the name. The scope of names defined in a\nclass block is limited to the class block; it does not extend to the\ncode blocks of methods -- this includes generator expressions since\nthey are implemented using a function scope. This means that the\nfollowing will fail:\n\n class A:\n a = 42\n b = list(a + i for i in range(10))\n\nWhen a name is used in a code block, it is resolved using the nearest\nenclosing scope. The set of all such scopes visible to a code block\nis called the block\'s *environment*.\n\nIf a name is bound in a block, it is a local variable of that block.\nIf a name is bound at the module level, it is a global variable. (The\nvariables of the module code block are local and global.) If a\nvariable is used in a code block but not defined there, it is a *free\nvariable*.\n\nWhen a name is not found at all, a ``NameError`` exception is raised.\nIf the name refers to a local variable that has not been bound, a\n``UnboundLocalError`` exception is raised. ``UnboundLocalError`` is a\nsubclass of ``NameError``.\n\nThe following constructs bind names: formal parameters to functions,\n``import`` statements, class and function definitions (these bind the\nclass or function name in the defining block), and targets that are\nidentifiers if occurring in an assignment, ``for`` loop header, or in\nthe second position of an ``except`` clause header. The ``import``\nstatement of the form "``from ...import *``" binds all names defined\nin the imported module, except those beginning with an underscore.\nThis form may only be used at the module level.\n\nA target occurring in a ``del`` statement is also considered bound for\nthis purpose (though the actual semantics are to unbind the name). It\nis illegal to unbind a name that is referenced by an enclosing scope;\nthe compiler will report a ``SyntaxError``.\n\nEach assignment or import statement occurs within a block defined by a\nclass or function definition or at the module level (the top-level\ncode block).\n\nIf a name binding operation occurs anywhere within a code block, all\nuses of the name within the block are treated as references to the\ncurrent block. This can lead to errors when a name is used within a\nblock before it is bound. This rule is subtle. Python lacks\ndeclarations and allows name binding operations to occur anywhere\nwithin a code block. The local variables of a code block can be\ndetermined by scanning the entire text of the block for name binding\noperations.\n\nIf the global statement occurs within a block, all uses of the name\nspecified in the statement refer to the binding of that name in the\ntop-level namespace. Names are resolved in the top-level namespace by\nsearching the global namespace, i.e. the namespace of the module\ncontaining the code block, and the builtin namespace, the namespace of\nthe module ``__builtin__``. The global namespace is searched first.\nIf the name is not found there, the builtin namespace is searched.\nThe global statement must precede all uses of the name.\n\nThe built-in namespace associated with the execution of a code block\nis actually found by looking up the name ``__builtins__`` in its\nglobal namespace; this should be a dictionary or a module (in the\nlatter case the module\'s dictionary is used). By default, when in the\n``__main__`` module, ``__builtins__`` is the built-in module\n``__builtin__`` (note: no \'s\'); when in any other module,\n``__builtins__`` is an alias for the dictionary of the ``__builtin__``\nmodule itself. ``__builtins__`` can be set to a user-created\ndictionary to create a weak form of restricted execution.\n\nNote: Users should not touch ``__builtins__``; it is strictly an\n implementation detail. Users wanting to override values in the\n built-in namespace should ``import`` the ``__builtin__`` (no \'s\')\n module and modify its attributes appropriately.\n\nThe namespace for a module is automatically created the first time a\nmodule is imported. The main module for a script is always called\n``__main__``.\n\nThe global statement has the same scope as a name binding operation in\nthe same block. If the nearest enclosing scope for a free variable\ncontains a global statement, the free variable is treated as a global.\n\nA class definition is an executable statement that may use and define\nnames. These references follow the normal rules for name resolution.\nThe namespace of the class definition becomes the attribute dictionary\nof the class. Names defined at the class scope are not visible in\nmethods.\n\n\nInteraction with dynamic features\n=================================\n\nThere are several cases where Python statements are illegal when used\nin conjunction with nested scopes that contain free variables.\n\nIf a variable is referenced in an enclosing scope, it is illegal to\ndelete the name. An error will be reported at compile time.\n\nIf the wild card form of import --- ``import *`` --- is used in a\nfunction and the function contains or is a nested block with free\nvariables, the compiler will raise a ``SyntaxError``.\n\nIf ``exec`` is used in a function and the function contains or is a\nnested block with free variables, the compiler will raise a\n``SyntaxError`` unless the exec explicitly specifies the local\nnamespace for the ``exec``. (In other words, ``exec obj`` would be\nillegal, but ``exec obj in ns`` would be legal.)\n\nThe ``eval()``, ``execfile()``, and ``input()`` functions and the\n``exec`` statement do not have access to the full environment for\nresolving names. Names may be resolved in the local and global\nnamespaces of the caller. Free variables are not resolved in the\nnearest enclosing namespace, but in the global namespace. [1] The\n``exec`` statement and the ``eval()`` and ``execfile()`` functions\nhave optional arguments to override the global and local namespace.\nIf only one namespace is specified, it is used for both.\n', - 'numbers': u"\nNumeric literals\n****************\n\nThere are four types of numeric literals: plain integers, long\nintegers, floating point numbers, and imaginary numbers. There are no\ncomplex literals (complex numbers can be formed by adding a real\nnumber and an imaginary number).\n\nNote that numeric literals do not include a sign; a phrase like ``-1``\nis actually an expression composed of the unary operator '``-``' and\nthe literal ``1``.\n", - 'numeric-types': u'\nEmulating numeric types\n***********************\n\nThe following methods can be defined to emulate numeric objects.\nMethods corresponding to operations that are not supported by the\nparticular kind of number implemented (e.g., bitwise operations for\nnon-integral numbers) should be left undefined.\n\nobject.__add__(self, other)\nobject.__sub__(self, other)\nobject.__mul__(self, other)\nobject.__floordiv__(self, other)\nobject.__mod__(self, other)\nobject.__divmod__(self, other)\nobject.__pow__(self, other[, modulo])\nobject.__lshift__(self, other)\nobject.__rshift__(self, other)\nobject.__and__(self, other)\nobject.__xor__(self, other)\nobject.__or__(self, other)\n\n These methods are called to implement the binary arithmetic\n operations (``+``, ``-``, ``*``, ``//``, ``%``, ``divmod()``,\n ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``, ``|``). For\n instance, to evaluate the expression *x*``+``*y*, where *x* is an\n instance of a class that has an ``__add__()`` method,\n ``x.__add__(y)`` is called. The ``__divmod__()`` method should be\n the equivalent to using ``__floordiv__()`` and ``__mod__()``; it\n should not be related to ``__truediv__()`` (described below). Note\n that ``__pow__()`` should be defined to accept an optional third\n argument if the ternary version of the built-in ``pow()`` function\n is to be supported.\n\n If one of those methods does not support the operation with the\n supplied arguments, it should return ``NotImplemented``.\n\nobject.__div__(self, other)\nobject.__truediv__(self, other)\n\n The division operator (``/``) is implemented by these methods. The\n ``__truediv__()`` method is used when ``__future__.division`` is in\n effect, otherwise ``__div__()`` is used. If only one of these two\n methods is defined, the object will not support division in the\n alternate context; ``TypeError`` will be raised instead.\n\nobject.__radd__(self, other)\nobject.__rsub__(self, other)\nobject.__rmul__(self, other)\nobject.__rdiv__(self, other)\nobject.__rtruediv__(self, other)\nobject.__rfloordiv__(self, other)\nobject.__rmod__(self, other)\nobject.__rdivmod__(self, other)\nobject.__rpow__(self, other)\nobject.__rlshift__(self, other)\nobject.__rrshift__(self, other)\nobject.__rand__(self, other)\nobject.__rxor__(self, other)\nobject.__ror__(self, other)\n\n These methods are called to implement the binary arithmetic\n operations (``+``, ``-``, ``*``, ``/``, ``%``, ``divmod()``,\n ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``, ``|``) with\n reflected (swapped) operands. These functions are only called if\n the left operand does not support the corresponding operation and\n the operands are of different types. [4] For instance, to evaluate\n the expression *x*``-``*y*, where *y* is an instance of a class\n that has an ``__rsub__()`` method, ``y.__rsub__(x)`` is called if\n ``x.__sub__(y)`` returns *NotImplemented*.\n\n Note that ternary ``pow()`` will not try calling ``__rpow__()``\n (the coercion rules would become too complicated).\n\n Note: If the right operand\'s type is a subclass of the left operand\'s\n type and that subclass provides the reflected method for the\n operation, this method will be called before the left operand\'s\n non-reflected method. This behavior allows subclasses to\n override their ancestors\' operations.\n\nobject.__iadd__(self, other)\nobject.__isub__(self, other)\nobject.__imul__(self, other)\nobject.__idiv__(self, other)\nobject.__itruediv__(self, other)\nobject.__ifloordiv__(self, other)\nobject.__imod__(self, other)\nobject.__ipow__(self, other[, modulo])\nobject.__ilshift__(self, other)\nobject.__irshift__(self, other)\nobject.__iand__(self, other)\nobject.__ixor__(self, other)\nobject.__ior__(self, other)\n\n These methods are called to implement the augmented arithmetic\n operations (``+=``, ``-=``, ``*=``, ``/=``, ``//=``, ``%=``,\n ``**=``, ``<<=``, ``>>=``, ``&=``, ``^=``, ``|=``). These methods\n should attempt to do the operation in-place (modifying *self*) and\n return the result (which could be, but does not have to be,\n *self*). If a specific method is not defined, the augmented\n operation falls back to the normal methods. For instance, to\n evaluate the expression *x*``+=``*y*, where *x* is an instance of a\n class that has an ``__iadd__()`` method, ``x.__iadd__(y)`` is\n called. If *x* is an instance of a class that does not define a\n ``__iadd__()`` method, ``x.__add__(y)`` and ``y.__radd__(x)`` are\n considered, as with the evaluation of *x*``+``*y*.\n\nobject.__neg__(self)\nobject.__pos__(self)\nobject.__abs__(self)\nobject.__invert__(self)\n\n Called to implement the unary arithmetic operations (``-``, ``+``,\n ``abs()`` and ``~``).\n\nobject.__complex__(self)\nobject.__int__(self)\nobject.__long__(self)\nobject.__float__(self)\n\n Called to implement the built-in functions ``complex()``,\n ``int()``, ``long()``, and ``float()``. Should return a value of\n the appropriate type.\n\nobject.__oct__(self)\nobject.__hex__(self)\n\n Called to implement the built-in functions ``oct()`` and ``hex()``.\n Should return a string value.\n\nobject.__index__(self)\n\n Called to implement ``operator.index()``. Also called whenever\n Python needs an integer object (such as in slicing). Must return\n an integer (int or long).\n\n Added in version 2.5.\n\nobject.__coerce__(self, other)\n\n Called to implement "mixed-mode" numeric arithmetic. Should either\n return a 2-tuple containing *self* and *other* converted to a\n common numeric type, or ``None`` if conversion is impossible. When\n the common type would be the type of ``other``, it is sufficient to\n return ``None``, since the interpreter will also ask the other\n object to attempt a coercion (but sometimes, if the implementation\n of the other type cannot be changed, it is useful to do the\n conversion to the other type here). A return value of\n ``NotImplemented`` is equivalent to returning ``None``.\n', - 'objects': u'\nObjects, values and types\n*************************\n\n*Objects* are Python\'s abstraction for data. All data in a Python\nprogram is represented by objects or by relations between objects. (In\na sense, and in conformance to Von Neumann\'s model of a "stored\nprogram computer," code is also represented by objects.)\n\nEvery object has an identity, a type and a value. An object\'s\n*identity* never changes once it has been created; you may think of it\nas the object\'s address in memory. The \'``is``\' operator compares the\nidentity of two objects; the ``id()`` function returns an integer\nrepresenting its identity (currently implemented as its address). An\nobject\'s *type* is also unchangeable. [1] An object\'s type determines\nthe operations that the object supports (e.g., "does it have a\nlength?") and also defines the possible values for objects of that\ntype. The ``type()`` function returns an object\'s type (which is an\nobject itself). The *value* of some objects can change. Objects\nwhose value can change are said to be *mutable*; objects whose value\nis unchangeable once they are created are called *immutable*. (The\nvalue of an immutable container object that contains a reference to a\nmutable object can change when the latter\'s value is changed; however\nthe container is still considered immutable, because the collection of\nobjects it contains cannot be changed. So, immutability is not\nstrictly the same as having an unchangeable value, it is more subtle.)\nAn object\'s mutability is determined by its type; for instance,\nnumbers, strings and tuples are immutable, while dictionaries and\nlists are mutable.\n\nObjects are never explicitly destroyed; however, when they become\nunreachable they may be garbage-collected. An implementation is\nallowed to postpone garbage collection or omit it altogether --- it is\na matter of implementation quality how garbage collection is\nimplemented, as long as no objects are collected that are still\nreachable. (Implementation note: the current implementation uses a\nreference-counting scheme with (optional) delayed detection of\ncyclically linked garbage, which collects most objects as soon as they\nbecome unreachable, but is not guaranteed to collect garbage\ncontaining circular references. See the documentation of the ``gc``\nmodule for information on controlling the collection of cyclic\ngarbage.)\n\nNote that the use of the implementation\'s tracing or debugging\nfacilities may keep objects alive that would normally be collectable.\nAlso note that catching an exception with a \'``try``...``except``\'\nstatement may keep objects alive.\n\nSome objects contain references to "external" resources such as open\nfiles or windows. It is understood that these resources are freed\nwhen the object is garbage-collected, but since garbage collection is\nnot guaranteed to happen, such objects also provide an explicit way to\nrelease the external resource, usually a ``close()`` method. Programs\nare strongly recommended to explicitly close such objects. The\n\'``try``...``finally``\' statement provides a convenient way to do\nthis.\n\nSome objects contain references to other objects; these are called\n*containers*. Examples of containers are tuples, lists and\ndictionaries. The references are part of a container\'s value. In\nmost cases, when we talk about the value of a container, we imply the\nvalues, not the identities of the contained objects; however, when we\ntalk about the mutability of a container, only the identities of the\nimmediately contained objects are implied. So, if an immutable\ncontainer (like a tuple) contains a reference to a mutable object, its\nvalue changes if that mutable object is changed.\n\nTypes affect almost all aspects of object behavior. Even the\nimportance of object identity is affected in some sense: for immutable\ntypes, operations that compute new values may actually return a\nreference to any existing object with the same type and value, while\nfor mutable objects this is not allowed. E.g., after ``a = 1; b =\n1``, ``a`` and ``b`` may or may not refer to the same object with the\nvalue one, depending on the implementation, but after ``c = []; d =\n[]``, ``c`` and ``d`` are guaranteed to refer to two different,\nunique, newly created empty lists. (Note that ``c = d = []`` assigns\nthe same object to both ``c`` and ``d``.)\n', - 'operator-summary': u'\nSummary\n*******\n\nThe following table summarizes the operator precedences in Python,\nfrom lowest precedence (least binding) to highest precedence (most\nbinding). Operators in the same box have the same precedence. Unless\nthe syntax is explicitly given, operators are binary. Operators in\nthe same box group left to right (except for comparisons, including\ntests, which all have the same precedence and chain from left to right\n--- see section *Comparisons* --- and exponentiation, which groups\nfrom right to left).\n\n+-------------------------------------------------+---------------------------------------+\n| Operator | Description |\n+=================================================+=======================================+\n| ``lambda`` | Lambda expression |\n+-------------------------------------------------+---------------------------------------+\n| ``or`` | Boolean OR |\n+-------------------------------------------------+---------------------------------------+\n| ``and`` | Boolean AND |\n+-------------------------------------------------+---------------------------------------+\n| ``not`` *x* | Boolean NOT |\n+-------------------------------------------------+---------------------------------------+\n| ``in``, ``not`` ``in`` | Membership tests |\n+-------------------------------------------------+---------------------------------------+\n| ``is``, ``is not`` | Identity tests |\n+-------------------------------------------------+---------------------------------------+\n| ``<``, ``<=``, ``>``, ``>=``, ``<>``, ``!=``, | Comparisons |\n| ``==`` | |\n+-------------------------------------------------+---------------------------------------+\n| ``|`` | Bitwise OR |\n+-------------------------------------------------+---------------------------------------+\n| ``^`` | Bitwise XOR |\n+-------------------------------------------------+---------------------------------------+\n| ``&`` | Bitwise AND |\n+-------------------------------------------------+---------------------------------------+\n| ``<<``, ``>>`` | Shifts |\n+-------------------------------------------------+---------------------------------------+\n| ``+``, ``-`` | Addition and subtraction |\n+-------------------------------------------------+---------------------------------------+\n| ``*``, ``/``, ``%`` | Multiplication, division, remainder |\n+-------------------------------------------------+---------------------------------------+\n| ``+x``, ``-x`` | Positive, negative |\n+-------------------------------------------------+---------------------------------------+\n| ``~x`` | Bitwise not |\n+-------------------------------------------------+---------------------------------------+\n| ``**`` | Exponentiation |\n+-------------------------------------------------+---------------------------------------+\n| ``x.attribute`` | Attribute reference |\n+-------------------------------------------------+---------------------------------------+\n| ``x[index]`` | Subscription |\n+-------------------------------------------------+---------------------------------------+\n| ``x[index:index]`` | Slicing |\n+-------------------------------------------------+---------------------------------------+\n| ``f(arguments...)`` | Function call |\n+-------------------------------------------------+---------------------------------------+\n| ``(expressions...)`` | Binding or tuple display |\n+-------------------------------------------------+---------------------------------------+\n| ``[expressions...]`` | List display |\n+-------------------------------------------------+---------------------------------------+\n| ``{key:datum...}`` | Dictionary display |\n+-------------------------------------------------+---------------------------------------+\n| ```expressions...``` | String conversion |\n+-------------------------------------------------+---------------------------------------+\n\n-[ Footnotes ]-\n\n[1] In Python 2.3 and later releases, a list comprehension "leaks" the\n control variables of each ``for`` it contains into the containing\n scope. However, this behavior is deprecated, and relying on it\n will not work in Python 3.0\n\n[2] While ``abs(x%y) < abs(y)`` is true mathematically, for floats it\n may not be true numerically due to roundoff. For example, and\n assuming a platform on which a Python float is an IEEE 754 double-\n precision number, in order that ``-1e-100 % 1e100`` have the same\n sign as ``1e100``, the computed result is ``-1e-100 + 1e100``,\n which is numerically exactly equal to ``1e100``. Function\n ``fmod()`` in the ``math`` module returns a result whose sign\n matches the sign of the first argument instead, and so returns\n ``-1e-100`` in this case. Which approach is more appropriate\n depends on the application.\n\n[3] If x is very close to an exact integer multiple of y, it\'s\n possible for ``floor(x/y)`` to be one larger than ``(x-x%y)/y``\n due to rounding. In such cases, Python returns the latter result,\n in order to preserve that ``divmod(x,y)[0] * y + x % y`` be very\n close to ``x``.\n\n[4] While comparisons between unicode strings make sense at the byte\n level, they may be counter-intuitive to users. For example, the\n strings ``u"\\u00C7"`` and ``u"\\u0043\\u0327"`` compare differently,\n even though they both represent the same unicode character (LATIN\n CAPTITAL LETTER C WITH CEDILLA). To compare strings in a human\n recognizable way, compare using ``unicodedata.normalize()``.\n\n[5] The implementation computes this efficiently, without constructing\n lists or sorting.\n\n[6] Earlier versions of Python used lexicographic comparison of the\n sorted (key, value) lists, but this was very expensive for the\n common case of comparing for equality. An even earlier version of\n Python compared dictionaries by identity only, but this caused\n surprises because people expected to be able to test a dictionary\n for emptiness by comparing it to ``{}``.\n', - 'pass': u'\nThe ``pass`` statement\n**********************\n\n pass_stmt ::= "pass"\n\n``pass`` is a null operation --- when it is executed, nothing happens.\nIt is useful as a placeholder when a statement is required\nsyntactically, but no code needs to be executed, for example:\n\n def f(arg): pass # a function that does nothing (yet)\n\n class C: pass # a class with no methods (yet)\n', - 'power': u'\nThe power operator\n******************\n\nThe power operator binds more tightly than unary operators on its\nleft; it binds less tightly than unary operators on its right. The\nsyntax is:\n\n power ::= primary ["**" u_expr]\n\nThus, in an unparenthesized sequence of power and unary operators, the\noperators are evaluated from right to left (this does not constrain\nthe evaluation order for the operands): ``-1**2`` results in ``-1``.\n\nThe power operator has the same semantics as the built-in ``pow()``\nfunction, when called with two arguments: it yields its left argument\nraised to the power of its right argument. The numeric arguments are\nfirst converted to a common type. The result type is that of the\narguments after coercion.\n\nWith mixed operand types, the coercion rules for binary arithmetic\noperators apply. For int and long int operands, the result has the\nsame type as the operands (after coercion) unless the second argument\nis negative; in that case, all arguments are converted to float and a\nfloat result is delivered. For example, ``10**2`` returns ``100``, but\n``10**-2`` returns ``0.01``. (This last feature was added in Python\n2.2. In Python 2.1 and before, if both arguments were of integer types\nand the second argument was negative, an exception was raised).\n\nRaising ``0.0`` to a negative power results in a\n``ZeroDivisionError``. Raising a negative number to a fractional power\nresults in a ``ValueError``.\n', - 'print': u'\nThe ``print`` statement\n***********************\n\n print_stmt ::= "print" ([expression ("," expression)* [","]\n | ">>" expression [("," expression)+ [","])\n\n``print`` evaluates each expression in turn and writes the resulting\nobject to standard output (see below). If an object is not a string,\nit is first converted to a string using the rules for string\nconversions. The (resulting or original) string is then written. A\nspace is written before each object is (converted and) written, unless\nthe output system believes it is positioned at the beginning of a\nline. This is the case (1) when no characters have yet been written\nto standard output, (2) when the last character written to standard\noutput is ``\'\\n\'``, or (3) when the last write operation on standard\noutput was not a ``print`` statement. (In some cases it may be\nfunctional to write an empty string to standard output for this\nreason.)\n\nNote: Objects which act like file objects but which are not the built-in\n file objects often do not properly emulate this aspect of the file\n object\'s behavior, so it is best not to rely on this.\n\nA ``\'\\n\'`` character is written at the end, unless the ``print``\nstatement ends with a comma. This is the only action if the statement\ncontains just the keyword ``print``.\n\nStandard output is defined as the file object named ``stdout`` in the\nbuilt-in module ``sys``. If no such object exists, or if it does not\nhave a ``write()`` method, a ``RuntimeError`` exception is raised.\n\n``print`` also has an extended form, defined by the second portion of\nthe syntax described above. This form is sometimes referred to as\n"``print`` chevron." In this form, the first expression after the\n``>>`` must evaluate to a "file-like" object, specifically an object\nthat has a ``write()`` method as described above. With this extended\nform, the subsequent expressions are printed to this file object. If\nthe first expression evaluates to ``None``, then ``sys.stdout`` is\nused as the file for output.\n', - 'raise': u'\nThe ``raise`` statement\n***********************\n\n raise_stmt ::= "raise" [expression ["," expression ["," expression]]]\n\nIf no expressions are present, ``raise`` re-raises the last exception\nthat was active in the current scope. If no exception is active in\nthe current scope, a ``TypeError`` exception is raised indicating that\nthis is an error (if running under IDLE, a ``Queue.Empty`` exception\nis raised instead).\n\nOtherwise, ``raise`` evaluates the expressions to get three objects,\nusing ``None`` as the value of omitted expressions. The first two\nobjects are used to determine the *type* and *value* of the exception.\n\nIf the first object is an instance, the type of the exception is the\nclass of the instance, the instance itself is the value, and the\nsecond object must be ``None``.\n\nIf the first object is a class, it becomes the type of the exception.\nThe second object is used to determine the exception value: If it is\nan instance of the class, the instance becomes the exception value. If\nthe second object is a tuple, it is used as the argument list for the\nclass constructor; if it is ``None``, an empty argument list is used,\nand any other object is treated as a single argument to the\nconstructor. The instance so created by calling the constructor is\nused as the exception value.\n\nIf a third object is present and not ``None``, it must be a traceback\nobject (see section *The standard type hierarchy*), and it is\nsubstituted instead of the current location as the place where the\nexception occurred. If the third object is present and not a\ntraceback object or ``None``, a ``TypeError`` exception is raised.\nThe three-expression form of ``raise`` is useful to re-raise an\nexception transparently in an except clause, but ``raise`` with no\nexpressions should be preferred if the exception to be re-raised was\nthe most recently active exception in the current scope.\n\nAdditional information on exceptions can be found in section\n*Exceptions*, and information about handling exceptions is in section\n*The try statement*.\n', - 'return': u'\nThe ``return`` statement\n************************\n\n return_stmt ::= "return" [expression_list]\n\n``return`` may only occur syntactically nested in a function\ndefinition, not within a nested class definition.\n\nIf an expression list is present, it is evaluated, else ``None`` is\nsubstituted.\n\n``return`` leaves the current function call with the expression list\n(or ``None``) as return value.\n\nWhen ``return`` passes control out of a ``try`` statement with a\n``finally`` clause, that ``finally`` clause is executed before really\nleaving the function.\n\nIn a generator function, the ``return`` statement is not allowed to\ninclude an **expression_list**. In that context, a bare ``return``\nindicates that the generator is done and will cause ``StopIteration``\nto be raised.\n', - 'sequence-methods': u'\nAdditional methods for emulation of sequence types\n**************************************************\n\nThe following optional methods can be defined to further emulate\nsequence objects. Immutable sequences methods should at most only\ndefine ``__getslice__()``; mutable sequences might define all three\nmethods.\n\nobject.__getslice__(self, i, j)\n\n Deprecated in version 2.0: Support slice objects as parameters to\n the ``__getitem__()`` method. (However, built-in types in CPython\n currently still implement ``__getslice__()``. Therefore, you have\n to override it in derived classes when implementing slicing.)\n\n Called to implement evaluation of ``self[i:j]``. The returned\n object should be of the same type as *self*. Note that missing *i*\n or *j* in the slice expression are replaced by zero or\n ``sys.maxint``, respectively. If negative indexes are used in the\n slice, the length of the sequence is added to that index. If the\n instance does not implement the ``__len__()`` method, an\n ``AttributeError`` is raised. No guarantee is made that indexes\n adjusted this way are not still negative. Indexes which are\n greater than the length of the sequence are not modified. If no\n ``__getslice__()`` is found, a slice object is created instead, and\n passed to ``__getitem__()`` instead.\n\nobject.__setslice__(self, i, j, sequence)\n\n Called to implement assignment to ``self[i:j]``. Same notes for *i*\n and *j* as for ``__getslice__()``.\n\n This method is deprecated. If no ``__setslice__()`` is found, or\n for extended slicing of the form ``self[i:j:k]``, a slice object is\n created, and passed to ``__setitem__()``, instead of\n ``__setslice__()`` being called.\n\nobject.__delslice__(self, i, j)\n\n Called to implement deletion of ``self[i:j]``. Same notes for *i*\n and *j* as for ``__getslice__()``. This method is deprecated. If no\n ``__delslice__()`` is found, or for extended slicing of the form\n ``self[i:j:k]``, a slice object is created, and passed to\n ``__delitem__()``, instead of ``__delslice__()`` being called.\n\nNotice that these methods are only invoked when a single slice with a\nsingle colon is used, and the slice method is available. For slice\noperations involving extended slice notation, or in absence of the\nslice methods, ``__getitem__()``, ``__setitem__()`` or\n``__delitem__()`` is called with a slice object as argument.\n\nThe following example demonstrate how to make your program or module\ncompatible with earlier versions of Python (assuming that methods\n``__getitem__()``, ``__setitem__()`` and ``__delitem__()`` support\nslice objects as arguments):\n\n class MyClass:\n ...\n def __getitem__(self, index):\n ...\n def __setitem__(self, index, value):\n ...\n def __delitem__(self, index):\n ...\n\n if sys.version_info < (2, 0):\n # They won\'t be defined if version is at least 2.0 final\n\n def __getslice__(self, i, j):\n return self[max(0, i):max(0, j):]\n def __setslice__(self, i, j, seq):\n self[max(0, i):max(0, j):] = seq\n def __delslice__(self, i, j):\n del self[max(0, i):max(0, j):]\n ...\n\nNote the calls to ``max()``; these are necessary because of the\nhandling of negative indices before the ``__*slice__()`` methods are\ncalled. When negative indexes are used, the ``__*item__()`` methods\nreceive them as provided, but the ``__*slice__()`` methods get a\n"cooked" form of the index values. For each negative index value, the\nlength of the sequence is added to the index before calling the method\n(which may still result in a negative index); this is the customary\nhandling of negative indexes by the built-in sequence types, and the\n``__*item__()`` methods are expected to do this as well. However,\nsince they should already be doing that, negative indexes cannot be\npassed in; they must be constrained to the bounds of the sequence\nbefore being passed to the ``__*item__()`` methods. Calling ``max(0,\ni)`` conveniently returns the proper value.\n', - 'sequence-types': u"\nEmulating container types\n*************************\n\nThe following methods can be defined to implement container objects.\nContainers usually are sequences (such as lists or tuples) or mappings\n(like dictionaries), but can represent other containers as well. The\nfirst set of methods is used either to emulate a sequence or to\nemulate a mapping; the difference is that for a sequence, the\nallowable keys should be the integers *k* for which ``0 <= k < N``\nwhere *N* is the length of the sequence, or slice objects, which\ndefine a range of items. (For backwards compatibility, the method\n``__getslice__()`` (see below) can also be defined to handle simple,\nbut not extended slices.) It is also recommended that mappings provide\nthe methods ``keys()``, ``values()``, ``items()``, ``has_key()``,\n``get()``, ``clear()``, ``setdefault()``, ``iterkeys()``,\n``itervalues()``, ``iteritems()``, ``pop()``, ``popitem()``,\n``copy()``, and ``update()`` behaving similar to those for Python's\nstandard dictionary objects. The ``UserDict`` module provides a\n``DictMixin`` class to help create those methods from a base set of\n``__getitem__()``, ``__setitem__()``, ``__delitem__()``, and\n``keys()``. Mutable sequences should provide methods ``append()``,\n``count()``, ``index()``, ``extend()``, ``insert()``, ``pop()``,\n``remove()``, ``reverse()`` and ``sort()``, like Python standard list\nobjects. Finally, sequence types should implement addition (meaning\nconcatenation) and multiplication (meaning repetition) by defining the\nmethods ``__add__()``, ``__radd__()``, ``__iadd__()``, ``__mul__()``,\n``__rmul__()`` and ``__imul__()`` described below; they should not\ndefine ``__coerce__()`` or other numerical operators. It is\nrecommended that both mappings and sequences implement the\n``__contains__()`` method to allow efficient use of the ``in``\noperator; for mappings, ``in`` should be equivalent of ``has_key()``;\nfor sequences, it should search through the values. It is further\nrecommended that both mappings and sequences implement the\n``__iter__()`` method to allow efficient iteration through the\ncontainer; for mappings, ``__iter__()`` should be the same as\n``iterkeys()``; for sequences, it should iterate through the values.\n\nobject.__len__(self)\n\n Called to implement the built-in function ``len()``. Should return\n the length of the object, an integer ``>=`` 0. Also, an object\n that doesn't define a ``__nonzero__()`` method and whose\n ``__len__()`` method returns zero is considered to be false in a\n Boolean context.\n\nobject.__getitem__(self, key)\n\n Called to implement evaluation of ``self[key]``. For sequence\n types, the accepted keys should be integers and slice objects.\n Note that the special interpretation of negative indexes (if the\n class wishes to emulate a sequence type) is up to the\n ``__getitem__()`` method. If *key* is of an inappropriate type,\n ``TypeError`` may be raised; if of a value outside the set of\n indexes for the sequence (after any special interpretation of\n negative values), ``IndexError`` should be raised. For mapping\n types, if *key* is missing (not in the container), ``KeyError``\n should be raised.\n\n Note: ``for`` loops expect that an ``IndexError`` will be raised for\n illegal indexes to allow proper detection of the end of the\n sequence.\n\nobject.__setitem__(self, key, value)\n\n Called to implement assignment to ``self[key]``. Same note as for\n ``__getitem__()``. This should only be implemented for mappings if\n the objects support changes to the values for keys, or if new keys\n can be added, or for sequences if elements can be replaced. The\n same exceptions should be raised for improper *key* values as for\n the ``__getitem__()`` method.\n\nobject.__delitem__(self, key)\n\n Called to implement deletion of ``self[key]``. Same note as for\n ``__getitem__()``. This should only be implemented for mappings if\n the objects support removal of keys, or for sequences if elements\n can be removed from the sequence. The same exceptions should be\n raised for improper *key* values as for the ``__getitem__()``\n method.\n\nobject.__iter__(self)\n\n This method is called when an iterator is required for a container.\n This method should return a new iterator object that can iterate\n over all the objects in the container. For mappings, it should\n iterate over the keys of the container, and should also be made\n available as the method ``iterkeys()``.\n\n Iterator objects also need to implement this method; they are\n required to return themselves. For more information on iterator\n objects, see *Iterator Types*.\n\nobject.__reversed__(self)\n\n Called (if present) by the ``reversed()`` builtin to implement\n reverse iteration. It should return a new iterator object that\n iterates over all the objects in the container in reverse order.\n\n If the ``__reversed__()`` method is not provided, the\n ``reversed()`` builtin will fall back to using the sequence\n protocol (``__len__()`` and ``__getitem__()``). Objects should\n normally only provide ``__reversed__()`` if they do not support the\n sequence protocol and an efficient implementation of reverse\n iteration is possible.\n\n Added in version 2.6.\n\nThe membership test operators (``in`` and ``not in``) are normally\nimplemented as an iteration through a sequence. However, container\nobjects can supply the following special method with a more efficient\nimplementation, which also does not require the object be a sequence.\n\nobject.__contains__(self, item)\n\n Called to implement membership test operators. Should return true\n if *item* is in *self*, false otherwise. For mapping objects, this\n should consider the keys of the mapping rather than the values or\n the key-item pairs.\n", - 'shifting': u'\nShifting operations\n*******************\n\nThe shifting operations have lower priority than the arithmetic\noperations:\n\n shift_expr ::= a_expr | shift_expr ( "<<" | ">>" ) a_expr\n\nThese operators accept plain or long integers as arguments. The\narguments are converted to a common type. They shift the first\nargument to the left or right by the number of bits given by the\nsecond argument.\n\nA right shift by *n* bits is defined as division by ``pow(2, n)``. A\nleft shift by *n* bits is defined as multiplication with ``pow(2,\nn)``. Negative shift counts raise a ``ValueError`` exception.\n', - 'slicings': u'\nSlicings\n********\n\nA slicing selects a range of items in a sequence object (e.g., a\nstring, tuple or list). Slicings may be used as expressions or as\ntargets in assignment or ``del`` statements. The syntax for a\nslicing:\n\n slicing ::= simple_slicing | extended_slicing\n simple_slicing ::= primary "[" short_slice "]"\n extended_slicing ::= primary "[" slice_list "]"\n slice_list ::= slice_item ("," slice_item)* [","]\n slice_item ::= expression | proper_slice | ellipsis\n proper_slice ::= short_slice | long_slice\n short_slice ::= [lower_bound] ":" [upper_bound]\n long_slice ::= short_slice ":" [stride]\n lower_bound ::= expression\n upper_bound ::= expression\n stride ::= expression\n ellipsis ::= "..."\n\nThere is ambiguity in the formal syntax here: anything that looks like\nan expression list also looks like a slice list, so any subscription\ncan be interpreted as a slicing. Rather than further complicating the\nsyntax, this is disambiguated by defining that in this case the\ninterpretation as a subscription takes priority over the\ninterpretation as a slicing (this is the case if the slice list\ncontains no proper slice nor ellipses). Similarly, when the slice\nlist has exactly one short slice and no trailing comma, the\ninterpretation as a simple slicing takes priority over that as an\nextended slicing.\n\nThe semantics for a simple slicing are as follows. The primary must\nevaluate to a sequence object. The lower and upper bound expressions,\nif present, must evaluate to plain integers; defaults are zero and the\n``sys.maxint``, respectively. If either bound is negative, the\nsequence\'s length is added to it. The slicing now selects all items\nwith index *k* such that ``i <= k < j`` where *i* and *j* are the\nspecified lower and upper bounds. This may be an empty sequence. It\nis not an error if *i* or *j* lie outside the range of valid indexes\n(such items don\'t exist so they aren\'t selected).\n\nThe semantics for an extended slicing are as follows. The primary\nmust evaluate to a mapping object, and it is indexed with a key that\nis constructed from the slice list, as follows. If the slice list\ncontains at least one comma, the key is a tuple containing the\nconversion of the slice items; otherwise, the conversion of the lone\nslice item is the key. The conversion of a slice item that is an\nexpression is that expression. The conversion of an ellipsis slice\nitem is the built-in ``Ellipsis`` object. The conversion of a proper\nslice is a slice object (see section *The standard type hierarchy*)\nwhose ``start``, ``stop`` and ``step`` attributes are the values of\nthe expressions given as lower bound, upper bound and stride,\nrespectively, substituting ``None`` for missing expressions.\n', - 'specialattrs': u"\nSpecial Attributes\n******************\n\nThe implementation adds a few special read-only attributes to several\nobject types, where they are relevant. Some of these are not reported\nby the ``dir()`` built-in function.\n\nobject.__dict__\n\n A dictionary or other mapping object used to store an object's\n (writable) attributes.\n\nobject.__methods__\n\n Deprecated in version 2.2: Use the built-in function ``dir()`` to\n get a list of an object's attributes. This attribute is no longer\n available.\n\nobject.__members__\n\n Deprecated in version 2.2: Use the built-in function ``dir()`` to\n get a list of an object's attributes. This attribute is no longer\n available.\n\ninstance.__class__\n\n The class to which a class instance belongs.\n\nclass.__bases__\n\n The tuple of base classes of a class object. If there are no base\n classes, this will be an empty tuple.\n\nclass.__name__\n\n The name of the class or type.\n\n-[ Footnotes ]-\n\n[1] Additional information on these special methods may be found in\n the Python Reference Manual (*Basic customization*).\n\n[2] As a consequence, the list ``[1, 2]`` is considered equal to\n ``[1.0, 2.0]``, and similarly for tuples.\n\n[3] They must have since the parser can't tell the type of the\n operands.\n\n[4] To format only a tuple you should therefore provide a singleton\n tuple whose only element is the tuple to be formatted.\n\n[5] These numbers are fairly arbitrary. They are intended to avoid\n printing endless strings of meaningless digits without hampering\n correct use and without having to know the exact precision of\n floating point values on a particular machine.\n\n[6] The advantage of leaving the newline on is that returning an empty\n string is then an unambiguous EOF indication. It is also possible\n (in cases where it might matter, for example, if you want to make\n an exact copy of a file while scanning its lines) to tell whether\n the last line of a file ended in a newline or not (yes this\n happens!).\n", - 'specialnames': u'\nSpecial method names\n********************\n\nA class can implement certain operations that are invoked by special\nsyntax (such as arithmetic operations or subscripting and slicing) by\ndefining methods with special names. This is Python\'s approach to\n*operator overloading*, allowing classes to define their own behavior\nwith respect to language operators. For instance, if a class defines\na method named ``__getitem__()``, and ``x`` is an instance of this\nclass, then ``x[i]`` is equivalent [2] to ``x.__getitem__(i)``.\nExcept where mentioned, attempts to execute an operation raise an\nexception when no appropriate method is defined.\n\nFor new-style classes, special methods are only guaranteed to work if\ndefined in an object\'s class, not in the object\'s instance dictionary.\nThat explains why this won\'t work:\n\n >>> class C:\n ... pass\n ...\n >>> c = C()\n >>> c.__len__ = lambda: 5\n >>> len(c)\n Traceback (most recent call last):\n File "", line 1, in \n TypeError: object of type \'C\' has no len()\n\nWhen implementing a class that emulates any built-in type, it is\nimportant that the emulation only be implemented to the degree that it\nmakes sense for the object being modelled. For example, some\nsequences may work well with retrieval of individual elements, but\nextracting a slice may not make sense. (One example of this is the\n``NodeList`` interface in the W3C\'s Document Object Model.)\n\n\nBasic customization\n===================\n\nobject.__new__(cls[, ...])\n\n Called to create a new instance of class *cls*. ``__new__()`` is a\n static method (special-cased so you need not declare it as such)\n that takes the class of which an instance was requested as its\n first argument. The remaining arguments are those passed to the\n object constructor expression (the call to the class). The return\n value of ``__new__()`` should be the new object instance (usually\n an instance of *cls*).\n\n Typical implementations create a new instance of the class by\n invoking the superclass\'s ``__new__()`` method using\n ``super(currentclass, cls).__new__(cls[, ...])`` with appropriate\n arguments and then modifying the newly-created instance as\n necessary before returning it.\n\n If ``__new__()`` returns an instance of *cls*, then the new\n instance\'s ``__init__()`` method will be invoked like\n ``__init__(self[, ...])``, where *self* is the new instance and the\n remaining arguments are the same as were passed to ``__new__()``.\n\n If ``__new__()`` does not return an instance of *cls*, then the new\n instance\'s ``__init__()`` method will not be invoked.\n\n ``__new__()`` is intended mainly to allow subclasses of immutable\n types (like int, str, or tuple) to customize instance creation. It\n is also commonly overridden in custom metaclasses in order to\n customize class creation.\n\nobject.__init__(self[, ...])\n\n Called when the instance is created. The arguments are those\n passed to the class constructor expression. If a base class has an\n ``__init__()`` method, the derived class\'s ``__init__()`` method,\n if any, must explicitly call it to ensure proper initialization of\n the base class part of the instance; for example:\n ``BaseClass.__init__(self, [args...])``. As a special constraint\n on constructors, no value may be returned; doing so will cause a\n ``TypeError`` to be raised at runtime.\n\nobject.__del__(self)\n\n Called when the instance is about to be destroyed. This is also\n called a destructor. If a base class has a ``__del__()`` method,\n the derived class\'s ``__del__()`` method, if any, must explicitly\n call it to ensure proper deletion of the base class part of the\n instance. Note that it is possible (though not recommended!) for\n the ``__del__()`` method to postpone destruction of the instance by\n creating a new reference to it. It may then be called at a later\n time when this new reference is deleted. It is not guaranteed that\n ``__del__()`` methods are called for objects that still exist when\n the interpreter exits.\n\n Note: ``del x`` doesn\'t directly call ``x.__del__()`` --- the former\n decrements the reference count for ``x`` by one, and the latter\n is only called when ``x``\'s reference count reaches zero. Some\n common situations that may prevent the reference count of an\n object from going to zero include: circular references between\n objects (e.g., a doubly-linked list or a tree data structure with\n parent and child pointers); a reference to the object on the\n stack frame of a function that caught an exception (the traceback\n stored in ``sys.exc_traceback`` keeps the stack frame alive); or\n a reference to the object on the stack frame that raised an\n unhandled exception in interactive mode (the traceback stored in\n ``sys.last_traceback`` keeps the stack frame alive). The first\n situation can only be remedied by explicitly breaking the cycles;\n the latter two situations can be resolved by storing ``None`` in\n ``sys.exc_traceback`` or ``sys.last_traceback``. Circular\n references which are garbage are detected when the option cycle\n detector is enabled (it\'s on by default), but can only be cleaned\n up if there are no Python-level ``__del__()`` methods involved.\n Refer to the documentation for the ``gc`` module for more\n information about how ``__del__()`` methods are handled by the\n cycle detector, particularly the description of the ``garbage``\n value.\n\n Warning: Due to the precarious circumstances under which ``__del__()``\n methods are invoked, exceptions that occur during their execution\n are ignored, and a warning is printed to ``sys.stderr`` instead.\n Also, when ``__del__()`` is invoked in response to a module being\n deleted (e.g., when execution of the program is done), other\n globals referenced by the ``__del__()`` method may already have\n been deleted. For this reason, ``__del__()`` methods should do\n the absolute minimum needed to maintain external invariants.\n Starting with version 1.5, Python guarantees that globals whose\n name begins with a single underscore are deleted from their\n module before other globals are deleted; if no other references\n to such globals exist, this may help in assuring that imported\n modules are still available at the time when the ``__del__()``\n method is called.\n\nobject.__repr__(self)\n\n Called by the ``repr()`` built-in function and by string\n conversions (reverse quotes) to compute the "official" string\n representation of an object. If at all possible, this should look\n like a valid Python expression that could be used to recreate an\n object with the same value (given an appropriate environment). If\n this is not possible, a string of the form ``<...some useful\n description...>`` should be returned. The return value must be a\n string object. If a class defines ``__repr__()`` but not\n ``__str__()``, then ``__repr__()`` is also used when an "informal"\n string representation of instances of that class is required.\n\n This is typically used for debugging, so it is important that the\n representation is information-rich and unambiguous.\n\nobject.__str__(self)\n\n Called by the ``str()`` built-in function and by the ``print``\n statement to compute the "informal" string representation of an\n object. This differs from ``__repr__()`` in that it does not have\n to be a valid Python expression: a more convenient or concise\n representation may be used instead. The return value must be a\n string object.\n\nobject.__lt__(self, other)\nobject.__le__(self, other)\nobject.__eq__(self, other)\nobject.__ne__(self, other)\nobject.__gt__(self, other)\nobject.__ge__(self, other)\n\n Added in version 2.1.\n\n These are the so-called "rich comparison" methods, and are called\n for comparison operators in preference to ``__cmp__()`` below. The\n correspondence between operator symbols and method names is as\n follows: ``xy`` call ``x.__ne__(y)``, ``x>y`` calls ``x.__gt__(y)``, and\n ``x>=y`` calls ``x.__ge__(y)``.\n\n A rich comparison method may return the singleton\n ``NotImplemented`` if it does not implement the operation for a\n given pair of arguments. By convention, ``False`` and ``True`` are\n returned for a successful comparison. However, these methods can\n return any value, so if the comparison operator is used in a\n Boolean context (e.g., in the condition of an ``if`` statement),\n Python will call ``bool()`` on the value to determine if the result\n is true or false.\n\n There are no implied relationships among the comparison operators.\n The truth of ``x==y`` does not imply that ``x!=y`` is false.\n Accordingly, when defining ``__eq__()``, one should also define\n ``__ne__()`` so that the operators will behave as expected. See\n the paragraph on ``__hash__()`` for some important notes on\n creating *hashable* objects which support custom comparison\n operations and are usable as dictionary keys.\n\n There are no swapped-argument versions of these methods (to be used\n when the left argument does not support the operation but the right\n argument does); rather, ``__lt__()`` and ``__gt__()`` are each\n other\'s reflection, ``__le__()`` and ``__ge__()`` are each other\'s\n reflection, and ``__eq__()`` and ``__ne__()`` are their own\n reflection.\n\n Arguments to rich comparison methods are never coerced.\n\nobject.__cmp__(self, other)\n\n Called by comparison operations if rich comparison (see above) is\n not defined. Should return a negative integer if ``self < other``,\n zero if ``self == other``, a positive integer if ``self > other``.\n If no ``__cmp__()``, ``__eq__()`` or ``__ne__()`` operation is\n defined, class instances are compared by object identity\n ("address"). See also the description of ``__hash__()`` for some\n important notes on creating *hashable* objects which support custom\n comparison operations and are usable as dictionary keys. (Note: the\n restriction that exceptions are not propagated by ``__cmp__()`` has\n been removed since Python 1.5.)\n\nobject.__rcmp__(self, other)\n\n Changed in version 2.1: No longer supported.\n\nobject.__hash__(self)\n\n Called for the key object for dictionary operations, and by the\n built-in function ``hash()``. Should return an integer usable as a\n hash value for dictionary operations. The only required property\n is that objects which compare equal have the same hash value; it is\n advised to somehow mix together (e.g., using exclusive or) the hash\n values for the components of the object that also play a part in\n comparison of objects.\n\n If a class does not define a ``__cmp__()`` or ``__eq__()`` method\n it should not define a ``__hash__()`` operation either; if it\n defines ``__cmp__()`` or ``__eq__()`` but not ``__hash__()``, its\n instances will not be usable as dictionary keys. If a class\n defines mutable objects and implements a ``__cmp__()`` or\n ``__eq__()`` method, it should not implement ``__hash__()``, since\n the dictionary implementation requires that a key\'s hash value is\n immutable (if the object\'s hash value changes, it will be in the\n wrong hash bucket).\n\n User-defined classes have ``__cmp__()`` and ``__hash__()`` methods\n by default; with them, all objects compare unequal and\n ``x.__hash__()`` returns ``id(x)``.\n\n Changed in version 2.5: ``__hash__()`` may now also return a long\n integer object; the 32-bit integer is then derived from the hash of\n that object.\n\nobject.__nonzero__(self)\n\n Called to implement truth value testing, and the built-in operation\n ``bool()``; should return ``False`` or ``True``, or their integer\n equivalents ``0`` or ``1``. When this method is not defined,\n ``__len__()`` is called, if it is defined (see below). If a class\n defines neither ``__len__()`` nor ``__nonzero__()``, all its\n instances are considered true.\n\nobject.__unicode__(self)\n\n Called to implement ``unicode()`` builtin; should return a Unicode\n object. When this method is not defined, string conversion is\n attempted, and the result of string conversion is converted to\n Unicode using the system default encoding.\n\n\nCustomizing attribute access\n============================\n\nThe following methods can be defined to customize the meaning of\nattribute access (use of, assignment to, or deletion of ``x.name``)\nfor class instances.\n\nobject.__getattr__(self, name)\n\n Called when an attribute lookup has not found the attribute in the\n usual places (i.e. it is not an instance attribute nor is it found\n in the class tree for ``self``). ``name`` is the attribute name.\n This method should return the (computed) attribute value or raise\n an ``AttributeError`` exception.\n\n Note that if the attribute is found through the normal mechanism,\n ``__getattr__()`` is not called. (This is an intentional asymmetry\n between ``__getattr__()`` and ``__setattr__()``.) This is done both\n for efficiency reasons and because otherwise ``__setattr__()``\n would have no way to access other attributes of the instance. Note\n that at least for instance variables, you can fake total control by\n not inserting any values in the instance attribute dictionary (but\n instead inserting them in another object). See the\n ``__getattribute__()`` method below for a way to actually get total\n control in new-style classes.\n\nobject.__setattr__(self, name, value)\n\n Called when an attribute assignment is attempted. This is called\n instead of the normal mechanism (i.e. store the value in the\n instance dictionary). *name* is the attribute name, *value* is the\n value to be assigned to it.\n\n If ``__setattr__()`` wants to assign to an instance attribute, it\n should not simply execute ``self.name = value`` --- this would\n cause a recursive call to itself. Instead, it should insert the\n value in the dictionary of instance attributes, e.g.,\n ``self.__dict__[name] = value``. For new-style classes, rather\n than accessing the instance dictionary, it should call the base\n class method with the same name, for example,\n ``object.__setattr__(self, name, value)``.\n\nobject.__delattr__(self, name)\n\n Like ``__setattr__()`` but for attribute deletion instead of\n assignment. This should only be implemented if ``del obj.name`` is\n meaningful for the object.\n\n\nMore attribute access for new-style classes\n-------------------------------------------\n\nThe following methods only apply to new-style classes.\n\nobject.__getattribute__(self, name)\n\n Called unconditionally to implement attribute accesses for\n instances of the class. If the class also defines\n ``__getattr__()``, the latter will not be called unless\n ``__getattribute__()`` either calls it explicitly or raises an\n ``AttributeError``. This method should return the (computed)\n attribute value or raise an ``AttributeError`` exception. In order\n to avoid infinite recursion in this method, its implementation\n should always call the base class method with the same name to\n access any attributes it needs, for example,\n ``object.__getattribute__(self, name)``.\n\n\nImplementing Descriptors\n------------------------\n\nThe following methods only apply when an instance of the class\ncontaining the method (a so-called *descriptor* class) appears in the\nclass dictionary of another new-style class, known as the *owner*\nclass. In the examples below, "the attribute" refers to the attribute\nwhose name is the key of the property in the owner class\'\n``__dict__``. Descriptors can only be implemented as new-style\nclasses themselves.\n\nobject.__get__(self, instance, owner)\n\n Called to get the attribute of the owner class (class attribute\n access) or of an instance of that class (instance attribute\n access). *owner* is always the owner class, while *instance* is the\n instance that the attribute was accessed through, or ``None`` when\n the attribute is accessed through the *owner*. This method should\n return the (computed) attribute value or raise an\n ``AttributeError`` exception.\n\nobject.__set__(self, instance, value)\n\n Called to set the attribute on an instance *instance* of the owner\n class to a new value, *value*.\n\nobject.__delete__(self, instance)\n\n Called to delete the attribute on an instance *instance* of the\n owner class.\n\n\nInvoking Descriptors\n--------------------\n\nIn general, a descriptor is an object attribute with "binding\nbehavior", one whose attribute access has been overridden by methods\nin the descriptor protocol: ``__get__()``, ``__set__()``, and\n``__delete__()``. If any of those methods are defined for an object,\nit is said to be a descriptor.\n\nThe default behavior for attribute access is to get, set, or delete\nthe attribute from an object\'s dictionary. For instance, ``a.x`` has a\nlookup chain starting with ``a.__dict__[\'x\']``, then\n``type(a).__dict__[\'x\']``, and continuing through the base classes of\n``type(a)`` excluding metaclasses.\n\nHowever, if the looked-up value is an object defining one of the\ndescriptor methods, then Python may override the default behavior and\ninvoke the descriptor method instead. Where this occurs in the\nprecedence chain depends on which descriptor methods were defined and\nhow they were called. Note that descriptors are only invoked for new\nstyle objects or classes (ones that subclass ``object()`` or\n``type()``).\n\nThe starting point for descriptor invocation is a binding, ``a.x``.\nHow the arguments are assembled depends on ``a``:\n\nDirect Call\n The simplest and least common call is when user code directly\n invokes a descriptor method: ``x.__get__(a)``.\n\nInstance Binding\n If binding to a new-style object instance, ``a.x`` is transformed\n into the call: ``type(a).__dict__[\'x\'].__get__(a, type(a))``.\n\nClass Binding\n If binding to a new-style class, ``A.x`` is transformed into the\n call: ``A.__dict__[\'x\'].__get__(None, A)``.\n\nSuper Binding\n If ``a`` is an instance of ``super``, then the binding ``super(B,\n obj).m()`` searches ``obj.__class__.__mro__`` for the base class\n ``A`` immediately preceding ``B`` and then invokes the descriptor\n with the call: ``A.__dict__[\'m\'].__get__(obj, A)``.\n\nFor instance bindings, the precedence of descriptor invocation depends\non the which descriptor methods are defined. Normally, data\ndescriptors define both ``__get__()`` and ``__set__()``, while non-\ndata descriptors have just the ``__get__()`` method. Data descriptors\nalways override a redefinition in an instance dictionary. In\ncontrast, non-data descriptors can be overridden by instances. [3]\n\nPython methods (including ``staticmethod()`` and ``classmethod()``)\nare implemented as non-data descriptors. Accordingly, instances can\nredefine and override methods. This allows individual instances to\nacquire behaviors that differ from other instances of the same class.\n\nThe ``property()`` function is implemented as a data descriptor.\nAccordingly, instances cannot override the behavior of a property.\n\n\n__slots__\n---------\n\nBy default, instances of both old and new-style classes have a\ndictionary for attribute storage. This wastes space for objects\nhaving very few instance variables. The space consumption can become\nacute when creating large numbers of instances.\n\nThe default can be overridden by defining *__slots__* in a new-style\nclass definition. The *__slots__* declaration takes a sequence of\ninstance variables and reserves just enough space in each instance to\nhold a value for each variable. Space is saved because *__dict__* is\nnot created for each instance.\n\n__slots__\n\n This class variable can be assigned a string, iterable, or sequence\n of strings with variable names used by instances. If defined in a\n new-style class, *__slots__* reserves space for the declared\n variables and prevents the automatic creation of *__dict__* and\n *__weakref__* for each instance.\n\n Added in version 2.2.\n\nNotes on using *__slots__*\n\n* Without a *__dict__* variable, instances cannot be assigned new\n variables not listed in the *__slots__* definition. Attempts to\n assign to an unlisted variable name raises ``AttributeError``. If\n dynamic assignment of new variables is desired, then add\n ``\'__dict__\'`` to the sequence of strings in the *__slots__*\n declaration.\n\n Changed in version 2.3: Previously, adding ``\'__dict__\'`` to the\n *__slots__* declaration would not enable the assignment of new\n attributes not specifically listed in the sequence of instance\n variable names.\n\n* Without a *__weakref__* variable for each instance, classes defining\n *__slots__* do not support weak references to its instances. If weak\n reference support is needed, then add ``\'__weakref__\'`` to the\n sequence of strings in the *__slots__* declaration.\n\n Changed in version 2.3: Previously, adding ``\'__weakref__\'`` to the\n *__slots__* declaration would not enable support for weak\n references.\n\n* *__slots__* are implemented at the class level by creating\n descriptors (*Implementing Descriptors*) for each variable name. As\n a result, class attributes cannot be used to set default values for\n instance variables defined by *__slots__*; otherwise, the class\n attribute would overwrite the descriptor assignment.\n\n* If a class defines a slot also defined in a base class, the instance\n variable defined by the base class slot is inaccessible (except by\n retrieving its descriptor directly from the base class). This\n renders the meaning of the program undefined. In the future, a\n check may be added to prevent this.\n\n* The action of a *__slots__* declaration is limited to the class\n where it is defined. As a result, subclasses will have a *__dict__*\n unless they also define *__slots__*.\n\n* *__slots__* do not work for classes derived from "variable-length"\n built-in types such as ``long``, ``str`` and ``tuple``.\n\n* Any non-string iterable may be assigned to *__slots__*. Mappings may\n also be used; however, in the future, special meaning may be\n assigned to the values corresponding to each key.\n\n* *__class__* assignment works only if both classes have the same\n *__slots__*.\n\n Changed in version 2.6: Previously, *__class__* assignment raised an\n error if either new or old class had *__slots__*.\n\n\nCustomizing class creation\n==========================\n\nBy default, new-style classes are constructed using ``type()``. A\nclass definition is read into a separate namespace and the value of\nclass name is bound to the result of ``type(name, bases, dict)``.\n\nWhen the class definition is read, if *__metaclass__* is defined then\nthe callable assigned to it will be called instead of ``type()``. This\nallows classes or functions to be written which monitor or alter the\nclass creation process:\n\n* Modifying the class dictionary prior to the class being created.\n\n* Returning an instance of another class -- essentially performing the\n role of a factory function.\n\nThese steps will have to be performed in the metaclass\'s ``__new__()``\nmethod -- ``type.__new__()`` can then be called from this method to\ncreate a class with different properties. This example adds a new\nelement to the class dictionary before creating the class:\n\n class metacls(type):\n def __new__(mcs, name, bases, dict):\n dict[\'foo\'] = \'metacls was here\'\n return type.__new__(mcs, name, bases, dict)\n\nYou can of course also override other class methods (or add new\nmethods); for example defining a custom ``__call__()`` method in the\nmetaclass allows custom behavior when the class is called, e.g. not\nalways creating a new instance.\n\n__metaclass__\n\n This variable can be any callable accepting arguments for ``name``,\n ``bases``, and ``dict``. Upon class creation, the callable is used\n instead of the built-in ``type()``.\n\n Added in version 2.2.\n\nThe appropriate metaclass is determined by the following precedence\nrules:\n\n* If ``dict[\'__metaclass__\']`` exists, it is used.\n\n* Otherwise, if there is at least one base class, its metaclass is\n used (this looks for a *__class__* attribute first and if not found,\n uses its type).\n\n* Otherwise, if a global variable named __metaclass__ exists, it is\n used.\n\n* Otherwise, the old-style, classic metaclass (types.ClassType) is\n used.\n\nThe potential uses for metaclasses are boundless. Some ideas that have\nbeen explored including logging, interface checking, automatic\ndelegation, automatic property creation, proxies, frameworks, and\nautomatic resource locking/synchronization.\n\n\nEmulating callable objects\n==========================\n\nobject.__call__(self[, args...])\n\n Called when the instance is "called" as a function; if this method\n is defined, ``x(arg1, arg2, ...)`` is a shorthand for\n ``x.__call__(arg1, arg2, ...)``.\n\n\nEmulating container types\n=========================\n\nThe following methods can be defined to implement container objects.\nContainers usually are sequences (such as lists or tuples) or mappings\n(like dictionaries), but can represent other containers as well. The\nfirst set of methods is used either to emulate a sequence or to\nemulate a mapping; the difference is that for a sequence, the\nallowable keys should be the integers *k* for which ``0 <= k < N``\nwhere *N* is the length of the sequence, or slice objects, which\ndefine a range of items. (For backwards compatibility, the method\n``__getslice__()`` (see below) can also be defined to handle simple,\nbut not extended slices.) It is also recommended that mappings provide\nthe methods ``keys()``, ``values()``, ``items()``, ``has_key()``,\n``get()``, ``clear()``, ``setdefault()``, ``iterkeys()``,\n``itervalues()``, ``iteritems()``, ``pop()``, ``popitem()``,\n``copy()``, and ``update()`` behaving similar to those for Python\'s\nstandard dictionary objects. The ``UserDict`` module provides a\n``DictMixin`` class to help create those methods from a base set of\n``__getitem__()``, ``__setitem__()``, ``__delitem__()``, and\n``keys()``. Mutable sequences should provide methods ``append()``,\n``count()``, ``index()``, ``extend()``, ``insert()``, ``pop()``,\n``remove()``, ``reverse()`` and ``sort()``, like Python standard list\nobjects. Finally, sequence types should implement addition (meaning\nconcatenation) and multiplication (meaning repetition) by defining the\nmethods ``__add__()``, ``__radd__()``, ``__iadd__()``, ``__mul__()``,\n``__rmul__()`` and ``__imul__()`` described below; they should not\ndefine ``__coerce__()`` or other numerical operators. It is\nrecommended that both mappings and sequences implement the\n``__contains__()`` method to allow efficient use of the ``in``\noperator; for mappings, ``in`` should be equivalent of ``has_key()``;\nfor sequences, it should search through the values. It is further\nrecommended that both mappings and sequences implement the\n``__iter__()`` method to allow efficient iteration through the\ncontainer; for mappings, ``__iter__()`` should be the same as\n``iterkeys()``; for sequences, it should iterate through the values.\n\nobject.__len__(self)\n\n Called to implement the built-in function ``len()``. Should return\n the length of the object, an integer ``>=`` 0. Also, an object\n that doesn\'t define a ``__nonzero__()`` method and whose\n ``__len__()`` method returns zero is considered to be false in a\n Boolean context.\n\nobject.__getitem__(self, key)\n\n Called to implement evaluation of ``self[key]``. For sequence\n types, the accepted keys should be integers and slice objects.\n Note that the special interpretation of negative indexes (if the\n class wishes to emulate a sequence type) is up to the\n ``__getitem__()`` method. If *key* is of an inappropriate type,\n ``TypeError`` may be raised; if of a value outside the set of\n indexes for the sequence (after any special interpretation of\n negative values), ``IndexError`` should be raised. For mapping\n types, if *key* is missing (not in the container), ``KeyError``\n should be raised.\n\n Note: ``for`` loops expect that an ``IndexError`` will be raised for\n illegal indexes to allow proper detection of the end of the\n sequence.\n\nobject.__setitem__(self, key, value)\n\n Called to implement assignment to ``self[key]``. Same note as for\n ``__getitem__()``. This should only be implemented for mappings if\n the objects support changes to the values for keys, or if new keys\n can be added, or for sequences if elements can be replaced. The\n same exceptions should be raised for improper *key* values as for\n the ``__getitem__()`` method.\n\nobject.__delitem__(self, key)\n\n Called to implement deletion of ``self[key]``. Same note as for\n ``__getitem__()``. This should only be implemented for mappings if\n the objects support removal of keys, or for sequences if elements\n can be removed from the sequence. The same exceptions should be\n raised for improper *key* values as for the ``__getitem__()``\n method.\n\nobject.__iter__(self)\n\n This method is called when an iterator is required for a container.\n This method should return a new iterator object that can iterate\n over all the objects in the container. For mappings, it should\n iterate over the keys of the container, and should also be made\n available as the method ``iterkeys()``.\n\n Iterator objects also need to implement this method; they are\n required to return themselves. For more information on iterator\n objects, see *Iterator Types*.\n\nobject.__reversed__(self)\n\n Called (if present) by the ``reversed()`` builtin to implement\n reverse iteration. It should return a new iterator object that\n iterates over all the objects in the container in reverse order.\n\n If the ``__reversed__()`` method is not provided, the\n ``reversed()`` builtin will fall back to using the sequence\n protocol (``__len__()`` and ``__getitem__()``). Objects should\n normally only provide ``__reversed__()`` if they do not support the\n sequence protocol and an efficient implementation of reverse\n iteration is possible.\n\n Added in version 2.6.\n\nThe membership test operators (``in`` and ``not in``) are normally\nimplemented as an iteration through a sequence. However, container\nobjects can supply the following special method with a more efficient\nimplementation, which also does not require the object be a sequence.\n\nobject.__contains__(self, item)\n\n Called to implement membership test operators. Should return true\n if *item* is in *self*, false otherwise. For mapping objects, this\n should consider the keys of the mapping rather than the values or\n the key-item pairs.\n\n\nAdditional methods for emulation of sequence types\n==================================================\n\nThe following optional methods can be defined to further emulate\nsequence objects. Immutable sequences methods should at most only\ndefine ``__getslice__()``; mutable sequences might define all three\nmethods.\n\nobject.__getslice__(self, i, j)\n\n Deprecated in version 2.0: Support slice objects as parameters to\n the ``__getitem__()`` method. (However, built-in types in CPython\n currently still implement ``__getslice__()``. Therefore, you have\n to override it in derived classes when implementing slicing.)\n\n Called to implement evaluation of ``self[i:j]``. The returned\n object should be of the same type as *self*. Note that missing *i*\n or *j* in the slice expression are replaced by zero or\n ``sys.maxint``, respectively. If negative indexes are used in the\n slice, the length of the sequence is added to that index. If the\n instance does not implement the ``__len__()`` method, an\n ``AttributeError`` is raised. No guarantee is made that indexes\n adjusted this way are not still negative. Indexes which are\n greater than the length of the sequence are not modified. If no\n ``__getslice__()`` is found, a slice object is created instead, and\n passed to ``__getitem__()`` instead.\n\nobject.__setslice__(self, i, j, sequence)\n\n Called to implement assignment to ``self[i:j]``. Same notes for *i*\n and *j* as for ``__getslice__()``.\n\n This method is deprecated. If no ``__setslice__()`` is found, or\n for extended slicing of the form ``self[i:j:k]``, a slice object is\n created, and passed to ``__setitem__()``, instead of\n ``__setslice__()`` being called.\n\nobject.__delslice__(self, i, j)\n\n Called to implement deletion of ``self[i:j]``. Same notes for *i*\n and *j* as for ``__getslice__()``. This method is deprecated. If no\n ``__delslice__()`` is found, or for extended slicing of the form\n ``self[i:j:k]``, a slice object is created, and passed to\n ``__delitem__()``, instead of ``__delslice__()`` being called.\n\nNotice that these methods are only invoked when a single slice with a\nsingle colon is used, and the slice method is available. For slice\noperations involving extended slice notation, or in absence of the\nslice methods, ``__getitem__()``, ``__setitem__()`` or\n``__delitem__()`` is called with a slice object as argument.\n\nThe following example demonstrate how to make your program or module\ncompatible with earlier versions of Python (assuming that methods\n``__getitem__()``, ``__setitem__()`` and ``__delitem__()`` support\nslice objects as arguments):\n\n class MyClass:\n ...\n def __getitem__(self, index):\n ...\n def __setitem__(self, index, value):\n ...\n def __delitem__(self, index):\n ...\n\n if sys.version_info < (2, 0):\n # They won\'t be defined if version is at least 2.0 final\n\n def __getslice__(self, i, j):\n return self[max(0, i):max(0, j):]\n def __setslice__(self, i, j, seq):\n self[max(0, i):max(0, j):] = seq\n def __delslice__(self, i, j):\n del self[max(0, i):max(0, j):]\n ...\n\nNote the calls to ``max()``; these are necessary because of the\nhandling of negative indices before the ``__*slice__()`` methods are\ncalled. When negative indexes are used, the ``__*item__()`` methods\nreceive them as provided, but the ``__*slice__()`` methods get a\n"cooked" form of the index values. For each negative index value, the\nlength of the sequence is added to the index before calling the method\n(which may still result in a negative index); this is the customary\nhandling of negative indexes by the built-in sequence types, and the\n``__*item__()`` methods are expected to do this as well. However,\nsince they should already be doing that, negative indexes cannot be\npassed in; they must be constrained to the bounds of the sequence\nbefore being passed to the ``__*item__()`` methods. Calling ``max(0,\ni)`` conveniently returns the proper value.\n\n\nEmulating numeric types\n=======================\n\nThe following methods can be defined to emulate numeric objects.\nMethods corresponding to operations that are not supported by the\nparticular kind of number implemented (e.g., bitwise operations for\nnon-integral numbers) should be left undefined.\n\nobject.__add__(self, other)\nobject.__sub__(self, other)\nobject.__mul__(self, other)\nobject.__floordiv__(self, other)\nobject.__mod__(self, other)\nobject.__divmod__(self, other)\nobject.__pow__(self, other[, modulo])\nobject.__lshift__(self, other)\nobject.__rshift__(self, other)\nobject.__and__(self, other)\nobject.__xor__(self, other)\nobject.__or__(self, other)\n\n These methods are called to implement the binary arithmetic\n operations (``+``, ``-``, ``*``, ``//``, ``%``, ``divmod()``,\n ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``, ``|``). For\n instance, to evaluate the expression *x*``+``*y*, where *x* is an\n instance of a class that has an ``__add__()`` method,\n ``x.__add__(y)`` is called. The ``__divmod__()`` method should be\n the equivalent to using ``__floordiv__()`` and ``__mod__()``; it\n should not be related to ``__truediv__()`` (described below). Note\n that ``__pow__()`` should be defined to accept an optional third\n argument if the ternary version of the built-in ``pow()`` function\n is to be supported.\n\n If one of those methods does not support the operation with the\n supplied arguments, it should return ``NotImplemented``.\n\nobject.__div__(self, other)\nobject.__truediv__(self, other)\n\n The division operator (``/``) is implemented by these methods. The\n ``__truediv__()`` method is used when ``__future__.division`` is in\n effect, otherwise ``__div__()`` is used. If only one of these two\n methods is defined, the object will not support division in the\n alternate context; ``TypeError`` will be raised instead.\n\nobject.__radd__(self, other)\nobject.__rsub__(self, other)\nobject.__rmul__(self, other)\nobject.__rdiv__(self, other)\nobject.__rtruediv__(self, other)\nobject.__rfloordiv__(self, other)\nobject.__rmod__(self, other)\nobject.__rdivmod__(self, other)\nobject.__rpow__(self, other)\nobject.__rlshift__(self, other)\nobject.__rrshift__(self, other)\nobject.__rand__(self, other)\nobject.__rxor__(self, other)\nobject.__ror__(self, other)\n\n These methods are called to implement the binary arithmetic\n operations (``+``, ``-``, ``*``, ``/``, ``%``, ``divmod()``,\n ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``, ``|``) with\n reflected (swapped) operands. These functions are only called if\n the left operand does not support the corresponding operation and\n the operands are of different types. [4] For instance, to evaluate\n the expression *x*``-``*y*, where *y* is an instance of a class\n that has an ``__rsub__()`` method, ``y.__rsub__(x)`` is called if\n ``x.__sub__(y)`` returns *NotImplemented*.\n\n Note that ternary ``pow()`` will not try calling ``__rpow__()``\n (the coercion rules would become too complicated).\n\n Note: If the right operand\'s type is a subclass of the left operand\'s\n type and that subclass provides the reflected method for the\n operation, this method will be called before the left operand\'s\n non-reflected method. This behavior allows subclasses to\n override their ancestors\' operations.\n\nobject.__iadd__(self, other)\nobject.__isub__(self, other)\nobject.__imul__(self, other)\nobject.__idiv__(self, other)\nobject.__itruediv__(self, other)\nobject.__ifloordiv__(self, other)\nobject.__imod__(self, other)\nobject.__ipow__(self, other[, modulo])\nobject.__ilshift__(self, other)\nobject.__irshift__(self, other)\nobject.__iand__(self, other)\nobject.__ixor__(self, other)\nobject.__ior__(self, other)\n\n These methods are called to implement the augmented arithmetic\n operations (``+=``, ``-=``, ``*=``, ``/=``, ``//=``, ``%=``,\n ``**=``, ``<<=``, ``>>=``, ``&=``, ``^=``, ``|=``). These methods\n should attempt to do the operation in-place (modifying *self*) and\n return the result (which could be, but does not have to be,\n *self*). If a specific method is not defined, the augmented\n operation falls back to the normal methods. For instance, to\n evaluate the expression *x*``+=``*y*, where *x* is an instance of a\n class that has an ``__iadd__()`` method, ``x.__iadd__(y)`` is\n called. If *x* is an instance of a class that does not define a\n ``__iadd__()`` method, ``x.__add__(y)`` and ``y.__radd__(x)`` are\n considered, as with the evaluation of *x*``+``*y*.\n\nobject.__neg__(self)\nobject.__pos__(self)\nobject.__abs__(self)\nobject.__invert__(self)\n\n Called to implement the unary arithmetic operations (``-``, ``+``,\n ``abs()`` and ``~``).\n\nobject.__complex__(self)\nobject.__int__(self)\nobject.__long__(self)\nobject.__float__(self)\n\n Called to implement the built-in functions ``complex()``,\n ``int()``, ``long()``, and ``float()``. Should return a value of\n the appropriate type.\n\nobject.__oct__(self)\nobject.__hex__(self)\n\n Called to implement the built-in functions ``oct()`` and ``hex()``.\n Should return a string value.\n\nobject.__index__(self)\n\n Called to implement ``operator.index()``. Also called whenever\n Python needs an integer object (such as in slicing). Must return\n an integer (int or long).\n\n Added in version 2.5.\n\nobject.__coerce__(self, other)\n\n Called to implement "mixed-mode" numeric arithmetic. Should either\n return a 2-tuple containing *self* and *other* converted to a\n common numeric type, or ``None`` if conversion is impossible. When\n the common type would be the type of ``other``, it is sufficient to\n return ``None``, since the interpreter will also ask the other\n object to attempt a coercion (but sometimes, if the implementation\n of the other type cannot be changed, it is useful to do the\n conversion to the other type here). A return value of\n ``NotImplemented`` is equivalent to returning ``None``.\n\n\nCoercion rules\n==============\n\nThis section used to document the rules for coercion. As the language\nhas evolved, the coercion rules have become hard to document\nprecisely; documenting what one version of one particular\nimplementation does is undesirable. Instead, here are some informal\nguidelines regarding coercion. In Python 3.0, coercion will not be\nsupported.\n\n* If the left operand of a % operator is a string or Unicode object,\n no coercion takes place and the string formatting operation is\n invoked instead.\n\n* It is no longer recommended to define a coercion operation. Mixed-\n mode operations on types that don\'t define coercion pass the\n original arguments to the operation.\n\n* New-style classes (those derived from ``object``) never invoke the\n ``__coerce__()`` method in response to a binary operator; the only\n time ``__coerce__()`` is invoked is when the built-in function\n ``coerce()`` is called.\n\n* For most intents and purposes, an operator that returns\n ``NotImplemented`` is treated the same as one that is not\n implemented at all.\n\n* Below, ``__op__()`` and ``__rop__()`` are used to signify the\n generic method names corresponding to an operator; ``__iop__()`` is\n used for the corresponding in-place operator. For example, for the\n operator \'``+``\', ``__add__()`` and ``__radd__()`` are used for the\n left and right variant of the binary operator, and ``__iadd__()``\n for the in-place variant.\n\n* For objects *x* and *y*, first ``x.__op__(y)`` is tried. If this is\n not implemented or returns ``NotImplemented``, ``y.__rop__(x)`` is\n tried. If this is also not implemented or returns\n ``NotImplemented``, a ``TypeError`` exception is raised. But see\n the following exception:\n\n* Exception to the previous item: if the left operand is an instance\n of a built-in type or a new-style class, and the right operand is an\n instance of a proper subclass of that type or class and overrides\n the base\'s ``__rop__()`` method, the right operand\'s ``__rop__()``\n method is tried *before* the left operand\'s ``__op__()`` method.\n\n This is done so that a subclass can completely override binary\n operators. Otherwise, the left operand\'s ``__op__()`` method would\n always accept the right operand: when an instance of a given class\n is expected, an instance of a subclass of that class is always\n acceptable.\n\n* When either operand type defines a coercion, this coercion is called\n before that type\'s ``__op__()`` or ``__rop__()`` method is called,\n but no sooner. If the coercion returns an object of a different\n type for the operand whose coercion is invoked, part of the process\n is redone using the new object.\n\n* When an in-place operator (like \'``+=``\') is used, if the left\n operand implements ``__iop__()``, it is invoked without any\n coercion. When the operation falls back to ``__op__()`` and/or\n ``__rop__()``, the normal coercion rules apply.\n\n* In *x*``+``*y*, if *x* is a sequence that implements sequence\n concatenation, sequence concatenation is invoked.\n\n* In *x*``*``*y*, if one operator is a sequence that implements\n sequence repetition, and the other is an integer (``int`` or\n ``long``), sequence repetition is invoked.\n\n* Rich comparisons (implemented by methods ``__eq__()`` and so on)\n never use coercion. Three-way comparison (implemented by\n ``__cmp__()``) does use coercion under the same conditions as other\n binary operations use it.\n\n* In the current implementation, the built-in numeric types ``int``,\n ``long`` and ``float`` do not use coercion; the type ``complex``\n however does use it. The difference can become apparent when\n subclassing these types. Over time, the type ``complex`` may be\n fixed to avoid coercion. All these types implement a\n ``__coerce__()`` method, for use by the built-in ``coerce()``\n function.\n\n\nWith Statement Context Managers\n===============================\n\nAdded in version 2.5.\n\nA *context manager* is an object that defines the runtime context to\nbe established when executing a ``with`` statement. The context\nmanager handles the entry into, and the exit from, the desired runtime\ncontext for the execution of the block of code. Context managers are\nnormally invoked using the ``with`` statement (described in section\n*The with statement*), but can also be used by directly invoking their\nmethods.\n\nTypical uses of context managers include saving and restoring various\nkinds of global state, locking and unlocking resources, closing opened\nfiles, etc.\n\nFor more information on context managers, see *Context Manager Types*.\n\nobject.__enter__(self)\n\n Enter the runtime context related to this object. The ``with``\n statement will bind this method\'s return value to the target(s)\n specified in the ``as`` clause of the statement, if any.\n\nobject.__exit__(self, exc_type, exc_value, traceback)\n\n Exit the runtime context related to this object. The parameters\n describe the exception that caused the context to be exited. If the\n context was exited without an exception, all three arguments will\n be ``None``.\n\n If an exception is supplied, and the method wishes to suppress the\n exception (i.e., prevent it from being propagated), it should\n return a true value. Otherwise, the exception will be processed\n normally upon exit from this method.\n\n Note that ``__exit__()`` methods should not reraise the passed-in\n exception; this is the caller\'s responsibility.\n\nSee also:\n\n **PEP 0343** - The "with" statement\n The specification, background, and examples for the Python\n ``with`` statement.\n\n-[ Footnotes ]-\n\n[1] Since Python 2.2, a gradual merging of types and classes has been\n started that makes this and a few other assertions made in this\n manual not 100% accurate and complete: for example, it *is* now\n possible in some cases to change an object\'s type, under certain\n controlled conditions. Until this manual undergoes extensive\n revision, it must now be taken as authoritative only regarding\n "classic classes", that are still the default, for compatibility\n purposes, in Python 2.2 and 2.3. For more information, see\n http://www.python.org/doc/newstyle/.\n\n[2] This, and other statements, are only roughly true for instances of\n new-style classes.\n\n[3] A descriptor can define any combination of ``__get__()``,\n ``__set__()`` and ``__delete__()``. If it does not define\n ``__get__()``, then accessing the attribute even on an instance\n will return the descriptor object itself. If the descriptor\n defines ``__set__()`` and/or ``__delete__()``, it is a data\n descriptor; if it defines neither, it is a non-data descriptor.\n\n[4] For operands of the same type, it is assumed that if the non-\n reflected method (such as ``__add__()``) fails the operation is\n not supported, which is why the reflected method is not called.\n', - 'string-conversions': u'\nString conversions\n******************\n\nA string conversion is an expression list enclosed in reverse (a.k.a.\nbackward) quotes:\n\n string_conversion ::= "\'" expression_list "\'"\n\nA string conversion evaluates the contained expression list and\nconverts the resulting object into a string according to rules\nspecific to its type.\n\nIf the object is a string, a number, ``None``, or a tuple, list or\ndictionary containing only objects whose type is one of these, the\nresulting string is a valid Python expression which can be passed to\nthe built-in function ``eval()`` to yield an expression with the same\nvalue (or an approximation, if floating point numbers are involved).\n\n(In particular, converting a string adds quotes around it and converts\n"funny" characters to escape sequences that are safe to print.)\n\nRecursive objects (for example, lists or dictionaries that contain a\nreference to themselves, directly or indirectly) use ``...`` to\nindicate a recursive reference, and the result cannot be passed to\n``eval()`` to get an equal value (``SyntaxError`` will be raised\ninstead).\n\nThe built-in function ``repr()`` performs exactly the same conversion\nin its argument as enclosing it in parentheses and reverse quotes\ndoes. The built-in function ``str()`` performs a similar but more\nuser-friendly conversion.\n', - 'string-methods': u'\nString Methods\n**************\n\nBelow are listed the string methods which both 8-bit strings and\nUnicode objects support. Note that none of these methods take keyword\narguments.\n\nIn addition, Python\'s strings support the sequence type methods\ndescribed in the *Sequence Types --- str, unicode, list, tuple,\nbuffer, xrange* section. To output formatted strings use template\nstrings or the ``%`` operator described in the *String Formatting\nOperations* section. Also, see the ``re`` module for string functions\nbased on regular expressions.\n\nstr.capitalize()\n\n Return a copy of the string with only its first character\n capitalized.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.center(width[, fillchar])\n\n Return centered in a string of length *width*. Padding is done\n using the specified *fillchar* (default is a space).\n\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.count(sub[, start[, end]])\n\n Return the number of occurrences of substring *sub* in the range\n [*start*, *end*]. Optional arguments *start* and *end* are\n interpreted as in slice notation.\n\nstr.decode([encoding[, errors]])\n\n Decodes the string using the codec registered for *encoding*.\n *encoding* defaults to the default string encoding. *errors* may\n be given to set a different error handling scheme. The default is\n ``\'strict\'``, meaning that encoding errors raise ``UnicodeError``.\n Other possible values are ``\'ignore\'``, ``\'replace\'`` and any other\n name registered via ``codecs.register_error()``, see section *Codec\n Base Classes*.\n\n Added in version 2.2.\n\n Changed in version 2.3: Support for other error handling schemes\n added.\n\nstr.encode([encoding[, errors]])\n\n Return an encoded version of the string. Default encoding is the\n current default string encoding. *errors* may be given to set a\n different error handling scheme. The default for *errors* is\n ``\'strict\'``, meaning that encoding errors raise a\n ``UnicodeError``. Other possible values are ``\'ignore\'``,\n ``\'replace\'``, ``\'xmlcharrefreplace\'``, ``\'backslashreplace\'`` and\n any other name registered via ``codecs.register_error()``, see\n section *Codec Base Classes*. For a list of possible encodings, see\n section *Standard Encodings*.\n\n Added in version 2.0.\n\n Changed in version 2.3: Support for ``\'xmlcharrefreplace\'`` and\n ``\'backslashreplace\'`` and other error handling schemes added.\n\nstr.endswith(suffix[, start[, end]])\n\n Return ``True`` if the string ends with the specified *suffix*,\n otherwise return ``False``. *suffix* can also be a tuple of\n suffixes to look for. With optional *start*, test beginning at\n that position. With optional *end*, stop comparing at that\n position.\n\n Changed in version 2.5: Accept tuples as *suffix*.\n\nstr.expandtabs([tabsize])\n\n Return a copy of the string where all tab characters are replaced\n by one or more spaces, depending on the current column and the\n given tab size. The column number is reset to zero after each\n newline occurring in the string. If *tabsize* is not given, a tab\n size of ``8`` characters is assumed. This doesn\'t understand other\n non-printing characters or escape sequences.\n\nstr.find(sub[, start[, end]])\n\n Return the lowest index in the string where substring *sub* is\n found, such that *sub* is contained in the range [*start*, *end*].\n Optional arguments *start* and *end* are interpreted as in slice\n notation. Return ``-1`` if *sub* is not found.\n\nstr.format(format_string, *args, **kwargs)\n\n Perform a string formatting operation. The *format_string*\n argument can contain literal text or replacement fields delimited\n by braces ``{}``. Each replacement field contains either the\n numeric index of a positional argument, or the name of a keyword\n argument. Returns a copy of *format_string* where each replacement\n field is replaced with the string value of the corresponding\n argument.\n\n >>> "The sum of 1 + 2 is {0}".format(1+2)\n \'The sum of 1 + 2 is 3\'\n\n See *Format String Syntax* for a description of the various\n formatting options that can be specified in format strings.\n\n This method of string formatting is the new standard in Python 3.0,\n and should be preferred to the ``%`` formatting described in\n *String Formatting Operations* in new code.\n\n Added in version 2.6.\n\nstr.index(sub[, start[, end]])\n\n Like ``find()``, but raise ``ValueError`` when the substring is not\n found.\n\nstr.isalnum()\n\n Return true if all characters in the string are alphanumeric and\n there is at least one character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.isalpha()\n\n Return true if all characters in the string are alphabetic and\n there is at least one character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.isdigit()\n\n Return true if all characters in the string are digits and there is\n at least one character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.islower()\n\n Return true if all cased characters in the string are lowercase and\n there is at least one cased character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.isspace()\n\n Return true if there are only whitespace characters in the string\n and there is at least one character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.istitle()\n\n Return true if the string is a titlecased string and there is at\n least one character, for example uppercase characters may only\n follow uncased characters and lowercase characters only cased ones.\n Return false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.isupper()\n\n Return true if all cased characters in the string are uppercase and\n there is at least one cased character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.join(seq)\n\n Return a string which is the concatenation of the strings in the\n sequence *seq*. The separator between elements is the string\n providing this method.\n\nstr.ljust(width[, fillchar])\n\n Return the string left justified in a string of length *width*.\n Padding is done using the specified *fillchar* (default is a\n space). The original string is returned if *width* is less than\n ``len(s)``.\n\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.lower()\n\n Return a copy of the string converted to lowercase.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.lstrip([chars])\n\n Return a copy of the string with leading characters removed. The\n *chars* argument is a string specifying the set of characters to be\n removed. If omitted or ``None``, the *chars* argument defaults to\n removing whitespace. The *chars* argument is not a prefix; rather,\n all combinations of its values are stripped:\n\n >>> \' spacious \'.lstrip()\n \'spacious \'\n >>> \'www.example.com\'.lstrip(\'cmowz.\')\n \'example.com\'\n\n Changed in version 2.2.2: Support for the *chars* argument.\n\nstr.partition(sep)\n\n Split the string at the first occurrence of *sep*, and return a\n 3-tuple containing the part before the separator, the separator\n itself, and the part after the separator. If the separator is not\n found, return a 3-tuple containing the string itself, followed by\n two empty strings.\n\n Added in version 2.5.\n\nstr.replace(old, new[, count])\n\n Return a copy of the string with all occurrences of substring *old*\n replaced by *new*. If the optional argument *count* is given, only\n the first *count* occurrences are replaced.\n\nstr.rfind(sub[, start[, end]])\n\n Return the highest index in the string where substring *sub* is\n found, such that *sub* is contained within s[start,end]. Optional\n arguments *start* and *end* are interpreted as in slice notation.\n Return ``-1`` on failure.\n\nstr.rindex(sub[, start[, end]])\n\n Like ``rfind()`` but raises ``ValueError`` when the substring *sub*\n is not found.\n\nstr.rjust(width[, fillchar])\n\n Return the string right justified in a string of length *width*.\n Padding is done using the specified *fillchar* (default is a\n space). The original string is returned if *width* is less than\n ``len(s)``.\n\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.rpartition(sep)\n\n Split the string at the last occurrence of *sep*, and return a\n 3-tuple containing the part before the separator, the separator\n itself, and the part after the separator. If the separator is not\n found, return a 3-tuple containing two empty strings, followed by\n the string itself.\n\n Added in version 2.5.\n\nstr.rsplit([sep[, maxsplit]])\n\n Return a list of the words in the string, using *sep* as the\n delimiter string. If *maxsplit* is given, at most *maxsplit* splits\n are done, the *rightmost* ones. If *sep* is not specified or\n ``None``, any whitespace string is a separator. Except for\n splitting from the right, ``rsplit()`` behaves like ``split()``\n which is described in detail below.\n\n Added in version 2.4.\n\nstr.rstrip([chars])\n\n Return a copy of the string with trailing characters removed. The\n *chars* argument is a string specifying the set of characters to be\n removed. If omitted or ``None``, the *chars* argument defaults to\n removing whitespace. The *chars* argument is not a suffix; rather,\n all combinations of its values are stripped:\n\n >>> \' spacious \'.rstrip()\n \' spacious\'\n >>> \'mississippi\'.rstrip(\'ipz\')\n \'mississ\'\n\n Changed in version 2.2.2: Support for the *chars* argument.\n\nstr.split([sep[, maxsplit]])\n\n Return a list of the words in the string, using *sep* as the\n delimiter string. If *maxsplit* is given, at most *maxsplit*\n splits are done (thus, the list will have at most ``maxsplit+1``\n elements). If *maxsplit* is not specified, then there is no limit\n on the number of splits (all possible splits are made).\n\n If *sep* is given, consecutive delimiters are not grouped together\n and are deemed to delimit empty strings (for example,\n ``\'1,,2\'.split(\',\')`` returns ``[\'1\', \'\', \'2\']``). The *sep*\n argument may consist of multiple characters (for example,\n ``\'1<>2<>3\'.split(\'<>\')`` returns ``[\'1\', \'2\', \'3\']``). Splitting\n an empty string with a specified separator returns ``[\'\']``.\n\n If *sep* is not specified or is ``None``, a different splitting\n algorithm is applied: runs of consecutive whitespace are regarded\n as a single separator, and the result will contain no empty strings\n at the start or end if the string has leading or trailing\n whitespace. Consequently, splitting an empty string or a string\n consisting of just whitespace with a ``None`` separator returns\n ``[]``.\n\n For example, ``\' 1 2 3 \'.split()`` returns ``[\'1\', \'2\', \'3\']``,\n and ``\' 1 2 3 \'.split(None, 1)`` returns ``[\'1\', \'2 3 \']``.\n\nstr.splitlines([keepends])\n\n Return a list of the lines in the string, breaking at line\n boundaries. Line breaks are not included in the resulting list\n unless *keepends* is given and true.\n\nstr.startswith(prefix[, start[, end]])\n\n Return ``True`` if string starts with the *prefix*, otherwise\n return ``False``. *prefix* can also be a tuple of prefixes to look\n for. With optional *start*, test string beginning at that\n position. With optional *end*, stop comparing string at that\n position.\n\n Changed in version 2.5: Accept tuples as *prefix*.\n\nstr.strip([chars])\n\n Return a copy of the string with the leading and trailing\n characters removed. The *chars* argument is a string specifying the\n set of characters to be removed. If omitted or ``None``, the\n *chars* argument defaults to removing whitespace. The *chars*\n argument is not a prefix or suffix; rather, all combinations of its\n values are stripped:\n\n >>> \' spacious \'.strip()\n \'spacious\'\n >>> \'www.example.com\'.strip(\'cmowz.\')\n \'example\'\n\n Changed in version 2.2.2: Support for the *chars* argument.\n\nstr.swapcase()\n\n Return a copy of the string with uppercase characters converted to\n lowercase and vice versa.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.title()\n\n Return a titlecased version of the string: words start with\n uppercase characters, all remaining cased characters are lowercase.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.translate(table[, deletechars])\n\n Return a copy of the string where all characters occurring in the\n optional argument *deletechars* are removed, and the remaining\n characters have been mapped through the given translation table,\n which must be a string of length 256.\n\n You can use the ``maketrans()`` helper function in the ``string``\n module to create a translation table. For string objects, set the\n *table* argument to ``None`` for translations that only delete\n characters:\n\n >>> \'read this short text\'.translate(None, \'aeiou\')\n \'rd ths shrt txt\'\n\n Added in version 2.6: Support for a ``None`` *table* argument.\n\n For Unicode objects, the ``translate()`` method does not accept the\n optional *deletechars* argument. Instead, it returns a copy of the\n *s* where all characters have been mapped through the given\n translation table which must be a mapping of Unicode ordinals to\n Unicode ordinals, Unicode strings or ``None``. Unmapped characters\n are left untouched. Characters mapped to ``None`` are deleted.\n Note, a more flexible approach is to create a custom character\n mapping codec using the ``codecs`` module (see ``encodings.cp1251``\n for an example).\n\nstr.upper()\n\n Return a copy of the string converted to uppercase.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.zfill(width)\n\n Return the numeric string left filled with zeros in a string of\n length *width*. A sign prefix is handled correctly. The original\n string is returned if *width* is less than ``len(s)``.\n\n Added in version 2.2.2.\n\nThe following methods are present only on unicode objects:\n\nunicode.isnumeric()\n\n Return ``True`` if there are only numeric characters in S,\n ``False`` otherwise. Numeric characters include digit characters,\n and all characters that have the Unicode numeric value property,\n e.g. U+2155, VULGAR FRACTION ONE FIFTH.\n\nunicode.isdecimal()\n\n Return ``True`` if there are only decimal characters in S,\n ``False`` otherwise. Decimal characters include digit characters,\n and all characters that that can be used to form decimal-radix\n numbers, e.g. U+0660, ARABIC-INDIC DIGIT ZERO.\n', - 'strings': u'\nString literals\n***************\n\nString literals are described by the following lexical definitions:\n\n stringliteral ::= [stringprefix](shortstring | longstring)\n stringprefix ::= "r" | "u" | "ur" | "R" | "U" | "UR" | "Ur" | "uR"\n shortstring ::= "\'" shortstringitem* "\'" | \'"\' shortstringitem* \'"\'\n longstring ::= ""\'" longstringitem* ""\'"\n | \'"""\' longstringitem* \'"""\'\n shortstringitem ::= shortstringchar | escapeseq\n longstringitem ::= longstringchar | escapeseq\n shortstringchar ::= \n longstringchar ::= \n escapeseq ::= "\\" \n\nOne syntactic restriction not indicated by these productions is that\nwhitespace is not allowed between the **stringprefix** and the rest of\nthe string literal. The source character set is defined by the\nencoding declaration; it is ASCII if no encoding declaration is given\nin the source file; see section *Encoding declarations*.\n\nIn plain English: String literals can be enclosed in matching single\nquotes (``\'``) or double quotes (``"``). They can also be enclosed in\nmatching groups of three single or double quotes (these are generally\nreferred to as *triple-quoted strings*). The backslash (``\\``)\ncharacter is used to escape characters that otherwise have a special\nmeaning, such as newline, backslash itself, or the quote character.\nString literals may optionally be prefixed with a letter ``\'r\'`` or\n``\'R\'``; such strings are called *raw strings* and use different rules\nfor interpreting backslash escape sequences. A prefix of ``\'u\'`` or\n``\'U\'`` makes the string a Unicode string. Unicode strings use the\nUnicode character set as defined by the Unicode Consortium and ISO\n10646. Some additional escape sequences, described below, are\navailable in Unicode strings. The two prefix characters may be\ncombined; in this case, ``\'u\'`` must appear before ``\'r\'``.\n\nIn triple-quoted strings, unescaped newlines and quotes are allowed\n(and are retained), except that three unescaped quotes in a row\nterminate the string. (A "quote" is the character used to open the\nstring, i.e. either ``\'`` or ``"``.)\n\nUnless an ``\'r\'`` or ``\'R\'`` prefix is present, escape sequences in\nstrings are interpreted according to rules similar to those used by\nStandard C. The recognized escape sequences are:\n\n+-------------------+-----------------------------------+---------+\n| Escape Sequence | Meaning | Notes |\n+===================+===================================+=========+\n| ``\\newline`` | Ignored | |\n+-------------------+-----------------------------------+---------+\n| ``\\\\`` | Backslash (``\\``) | |\n+-------------------+-----------------------------------+---------+\n| ``\\\'`` | Single quote (``\'``) | |\n+-------------------+-----------------------------------+---------+\n| ``\\"`` | Double quote (``"``) | |\n+-------------------+-----------------------------------+---------+\n| ``\\a`` | ASCII Bell (BEL) | |\n+-------------------+-----------------------------------+---------+\n| ``\\b`` | ASCII Backspace (BS) | |\n+-------------------+-----------------------------------+---------+\n| ``\\f`` | ASCII Formfeed (FF) | |\n+-------------------+-----------------------------------+---------+\n| ``\\n`` | ASCII Linefeed (LF) | |\n+-------------------+-----------------------------------+---------+\n| ``\\N{name}`` | Character named *name* in the | |\n| | Unicode database (Unicode only) | |\n+-------------------+-----------------------------------+---------+\n| ``\\r`` | ASCII Carriage Return (CR) | |\n+-------------------+-----------------------------------+---------+\n| ``\\t`` | ASCII Horizontal Tab (TAB) | |\n+-------------------+-----------------------------------+---------+\n| ``\\uxxxx`` | Character with 16-bit hex value | (1) |\n| | *xxxx* (Unicode only) | |\n+-------------------+-----------------------------------+---------+\n| ``\\Uxxxxxxxx`` | Character with 32-bit hex value | (2) |\n| | *xxxxxxxx* (Unicode only) | |\n+-------------------+-----------------------------------+---------+\n| ``\\v`` | ASCII Vertical Tab (VT) | |\n+-------------------+-----------------------------------+---------+\n| ``\\ooo`` | Character with octal value *ooo* | (3,5) |\n+-------------------+-----------------------------------+---------+\n| ``\\xhh`` | Character with hex value *hh* | (4,5) |\n+-------------------+-----------------------------------+---------+\n\nNotes:\n\n1. Individual code units which form parts of a surrogate pair can be\n encoded using this escape sequence.\n\n2. Any Unicode character can be encoded this way, but characters\n outside the Basic Multilingual Plane (BMP) will be encoded using a\n surrogate pair if Python is compiled to use 16-bit code units (the\n default). Individual code units which form parts of a surrogate\n pair can be encoded using this escape sequence.\n\n3. As in Standard C, up to three octal digits are accepted.\n\n4. Unlike in Standard C, exactly two hex digits are required.\n\n5. In a string literal, hexadecimal and octal escapes denote the byte\n with the given value; it is not necessary that the byte encodes a\n character in the source character set. In a Unicode literal, these\n escapes denote a Unicode character with the given value.\n\nUnlike Standard C, all unrecognized escape sequences are left in the\nstring unchanged, i.e., *the backslash is left in the string*. (This\nbehavior is useful when debugging: if an escape sequence is mistyped,\nthe resulting output is more easily recognized as broken.) It is also\nimportant to note that the escape sequences marked as "(Unicode only)"\nin the table above fall into the category of unrecognized escapes for\nnon-Unicode string literals.\n\nWhen an ``\'r\'`` or ``\'R\'`` prefix is present, a character following a\nbackslash is included in the string without change, and *all\nbackslashes are left in the string*. For example, the string literal\n``r"\\n"`` consists of two characters: a backslash and a lowercase\n``\'n\'``. String quotes can be escaped with a backslash, but the\nbackslash remains in the string; for example, ``r"\\""`` is a valid\nstring literal consisting of two characters: a backslash and a double\nquote; ``r"\\"`` is not a valid string literal (even a raw string\ncannot end in an odd number of backslashes). Specifically, *a raw\nstring cannot end in a single backslash* (since the backslash would\nescape the following quote character). Note also that a single\nbackslash followed by a newline is interpreted as those two characters\nas part of the string, *not* as a line continuation.\n\nWhen an ``\'r\'`` or ``\'R\'`` prefix is used in conjunction with a\n``\'u\'`` or ``\'U\'`` prefix, then the ``\\uXXXX`` and ``\\UXXXXXXXX``\nescape sequences are processed while *all other backslashes are left\nin the string*. For example, the string literal ``ur"\\u0062\\n"``\nconsists of three Unicode characters: \'LATIN SMALL LETTER B\', \'REVERSE\nSOLIDUS\', and \'LATIN SMALL LETTER N\'. Backslashes can be escaped with\na preceding backslash; however, both remain in the string. As a\nresult, ``\\uXXXX`` escape sequences are only recognized when there are\nan odd number of backslashes.\n', - 'subscriptions': u'\nSubscriptions\n*************\n\nA subscription selects an item of a sequence (string, tuple or list)\nor mapping (dictionary) object:\n\n subscription ::= primary "[" expression_list "]"\n\nThe primary must evaluate to an object of a sequence or mapping type.\n\nIf the primary is a mapping, the expression list must evaluate to an\nobject whose value is one of the keys of the mapping, and the\nsubscription selects the value in the mapping that corresponds to that\nkey. (The expression list is a tuple except if it has exactly one\nitem.)\n\nIf the primary is a sequence, the expression (list) must evaluate to a\nplain integer. If this value is negative, the length of the sequence\nis added to it (so that, e.g., ``x[-1]`` selects the last item of\n``x``.) The resulting value must be a nonnegative integer less than\nthe number of items in the sequence, and the subscription selects the\nitem whose index is that value (counting from zero).\n\nA string\'s items are characters. A character is not a separate data\ntype but a string of exactly one character.\n', - 'truth': u"\nTruth Value Testing\n*******************\n\nAny object can be tested for truth value, for use in an ``if`` or\n``while`` condition or as operand of the Boolean operations below. The\nfollowing values are considered false:\n\n* ``None``\n\n* ``False``\n\n* zero of any numeric type, for example, ``0``, ``0L``, ``0.0``,\n ``0j``.\n\n* any empty sequence, for example, ``''``, ``()``, ``[]``.\n\n* any empty mapping, for example, ``{}``.\n\n* instances of user-defined classes, if the class defines a\n ``__nonzero__()`` or ``__len__()`` method, when that method returns\n the integer zero or ``bool`` value ``False``. [1]\n\nAll other values are considered true --- so objects of many types are\nalways true.\n\nOperations and built-in functions that have a Boolean result always\nreturn ``0`` or ``False`` for false and ``1`` or ``True`` for true,\nunless otherwise stated. (Important exception: the Boolean operations\n``or`` and ``and`` always return one of their operands.)\n", - 'try': u'\nThe ``try`` statement\n*********************\n\nThe ``try`` statement specifies exception handlers and/or cleanup code\nfor a group of statements:\n\n try_stmt ::= try1_stmt | try2_stmt\n try1_stmt ::= "try" ":" suite\n ("except" [expression ["," target]] ":" suite)+\n ["else" ":" suite]\n ["finally" ":" suite]\n try2_stmt ::= "try" ":" suite\n "finally" ":" suite\n\nChanged in version 2.5: In previous versions of Python,\n``try``...``except``...``finally`` did not work. ``try``...``except``\nhad to be nested in ``try``...``finally``.\n\nThe ``except`` clause(s) specify one or more exception handlers. When\nno exception occurs in the ``try`` clause, no exception handler is\nexecuted. When an exception occurs in the ``try`` suite, a search for\nan exception handler is started. This search inspects the except\nclauses in turn until one is found that matches the exception. An\nexpression-less except clause, if present, must be last; it matches\nany exception. For an except clause with an expression, that\nexpression is evaluated, and the clause matches the exception if the\nresulting object is "compatible" with the exception. An object is\ncompatible with an exception if it is the class or a base class of the\nexception object, a tuple containing an item compatible with the\nexception, or, in the (deprecated) case of string exceptions, is the\nraised string itself (note that the object identities must match, i.e.\nit must be the same string object, not just a string with the same\nvalue).\n\nIf no except clause matches the exception, the search for an exception\nhandler continues in the surrounding code and on the invocation stack.\n[1]\n\nIf the evaluation of an expression in the header of an except clause\nraises an exception, the original search for a handler is canceled and\na search starts for the new exception in the surrounding code and on\nthe call stack (it is treated as if the entire ``try`` statement\nraised the exception).\n\nWhen a matching except clause is found, the exception is assigned to\nthe target specified in that except clause, if present, and the except\nclause\'s suite is executed. All except clauses must have an\nexecutable block. When the end of this block is reached, execution\ncontinues normally after the entire try statement. (This means that\nif two nested handlers exist for the same exception, and the exception\noccurs in the try clause of the inner handler, the outer handler will\nnot handle the exception.)\n\nBefore an except clause\'s suite is executed, details about the\nexception are assigned to three variables in the ``sys`` module:\n``sys.exc_type`` receives the object identifying the exception;\n``sys.exc_value`` receives the exception\'s parameter;\n``sys.exc_traceback`` receives a traceback object (see section *The\nstandard type hierarchy*) identifying the point in the program where\nthe exception occurred. These details are also available through the\n``sys.exc_info()`` function, which returns a tuple ``(exc_type,\nexc_value, exc_traceback)``. Use of the corresponding variables is\ndeprecated in favor of this function, since their use is unsafe in a\nthreaded program. As of Python 1.5, the variables are restored to\ntheir previous values (before the call) when returning from a function\nthat handled an exception.\n\nThe optional ``else`` clause is executed if and when control flows off\nthe end of the ``try`` clause. [2] Exceptions in the ``else`` clause\nare not handled by the preceding ``except`` clauses.\n\nIf ``finally`` is present, it specifies a \'cleanup\' handler. The\n``try`` clause is executed, including any ``except`` and ``else``\nclauses. If an exception occurs in any of the clauses and is not\nhandled, the exception is temporarily saved. The ``finally`` clause is\nexecuted. If there is a saved exception, it is re-raised at the end\nof the ``finally`` clause. If the ``finally`` clause raises another\nexception or executes a ``return`` or ``break`` statement, the saved\nexception is lost. The exception information is not available to the\nprogram during execution of the ``finally`` clause.\n\nWhen a ``return``, ``break`` or ``continue`` statement is executed in\nthe ``try`` suite of a ``try``...``finally`` statement, the\n``finally`` clause is also executed \'on the way out.\' A ``continue``\nstatement is illegal in the ``finally`` clause. (The reason is a\nproblem with the current implementation --- this restriction may be\nlifted in the future).\n\nAdditional information on exceptions can be found in section\n*Exceptions*, and information on using the ``raise`` statement to\ngenerate exceptions may be found in section *The raise statement*.\n', - 'types': u'\nThe standard type hierarchy\n***************************\n\nBelow is a list of the types that are built into Python. Extension\nmodules (written in C, Java, or other languages, depending on the\nimplementation) can define additional types. Future versions of\nPython may add types to the type hierarchy (e.g., rational numbers,\nefficiently stored arrays of integers, etc.).\n\nSome of the type descriptions below contain a paragraph listing\n\'special attributes.\' These are attributes that provide access to the\nimplementation and are not intended for general use. Their definition\nmay change in the future.\n\nNone\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name ``None``.\n It is used to signify the absence of a value in many situations,\n e.g., it is returned from functions that don\'t explicitly return\n anything. Its truth value is false.\n\nNotImplemented\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name\n ``NotImplemented``. Numeric methods and rich comparison methods may\n return this value if they do not implement the operation for the\n operands provided. (The interpreter will then try the reflected\n operation, or some other fallback, depending on the operator.) Its\n truth value is true.\n\nEllipsis\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name\n ``Ellipsis``. It is used to indicate the presence of the ``...``\n syntax in a slice. Its truth value is true.\n\n``numbers.Number``\n These are created by numeric literals and returned as results by\n arithmetic operators and arithmetic built-in functions. Numeric\n objects are immutable; once created their value never changes.\n Python numbers are of course strongly related to mathematical\n numbers, but subject to the limitations of numerical representation\n in computers.\n\n Python distinguishes between integers, floating point numbers, and\n complex numbers:\n\n ``numbers.Integral``\n These represent elements from the mathematical set of integers\n (positive and negative).\n\n There are three types of integers:\n\n Plain integers\n These represent numbers in the range -2147483648 through\n 2147483647. (The range may be larger on machines with a\n larger natural word size, but not smaller.) When the result\n of an operation would fall outside this range, the result is\n normally returned as a long integer (in some cases, the\n exception ``OverflowError`` is raised instead). For the\n purpose of shift and mask operations, integers are assumed to\n have a binary, 2\'s complement notation using 32 or more bits,\n and hiding no bits from the user (i.e., all 4294967296\n different bit patterns correspond to different values).\n\n Long integers\n These represent numbers in an unlimited range, subject to\n available (virtual) memory only. For the purpose of shift\n and mask operations, a binary representation is assumed, and\n negative numbers are represented in a variant of 2\'s\n complement which gives the illusion of an infinite string of\n sign bits extending to the left.\n\n Booleans\n These represent the truth values False and True. The two\n objects representing the values False and True are the only\n Boolean objects. The Boolean type is a subtype of plain\n integers, and Boolean values behave like the values 0 and 1,\n respectively, in almost all contexts, the exception being\n that when converted to a string, the strings ``"False"`` or\n ``"True"`` are returned, respectively.\n\n The rules for integer representation are intended to give the\n most meaningful interpretation of shift and mask operations\n involving negative integers and the least surprises when\n switching between the plain and long integer domains. Any\n operation, if it yields a result in the plain integer domain,\n will yield the same result in the long integer domain or when\n using mixed operands. The switch between domains is transparent\n to the programmer.\n\n ``numbers.Real`` (``float``)\n These represent machine-level double precision floating point\n numbers. You are at the mercy of the underlying machine\n architecture (and C or Java implementation) for the accepted\n range and handling of overflow. Python does not support single-\n precision floating point numbers; the savings in processor and\n memory usage that are usually the reason for using these is\n dwarfed by the overhead of using objects in Python, so there is\n no reason to complicate the language with two kinds of floating\n point numbers.\n\n ``numbers.Complex``\n These represent complex numbers as a pair of machine-level\n double precision floating point numbers. The same caveats apply\n as for floating point numbers. The real and imaginary parts of a\n complex number ``z`` can be retrieved through the read-only\n attributes ``z.real`` and ``z.imag``.\n\nSequences\n These represent finite ordered sets indexed by non-negative\n numbers. The built-in function ``len()`` returns the number of\n items of a sequence. When the length of a sequence is *n*, the\n index set contains the numbers 0, 1, ..., *n*-1. Item *i* of\n sequence *a* is selected by ``a[i]``.\n\n Sequences also support slicing: ``a[i:j]`` selects all items with\n index *k* such that *i* ``<=`` *k* ``<`` *j*. When used as an\n expression, a slice is a sequence of the same type. This implies\n that the index set is renumbered so that it starts at 0.\n\n Some sequences also support "extended slicing" with a third "step"\n parameter: ``a[i:j:k]`` selects all items of *a* with index *x*\n where ``x = i + n*k``, *n* ``>=`` ``0`` and *i* ``<=`` *x* ``<``\n *j*.\n\n Sequences are distinguished according to their mutability:\n\n Immutable sequences\n An object of an immutable sequence type cannot change once it is\n created. (If the object contains references to other objects,\n these other objects may be mutable and may be changed; however,\n the collection of objects directly referenced by an immutable\n object cannot change.)\n\n The following types are immutable sequences:\n\n Strings\n The items of a string are characters. There is no separate\n character type; a character is represented by a string of one\n item. Characters represent (at least) 8-bit bytes. The\n built-in functions ``chr()`` and ``ord()`` convert between\n characters and nonnegative integers representing the byte\n values. Bytes with the values 0-127 usually represent the\n corresponding ASCII values, but the interpretation of values\n is up to the program. The string data type is also used to\n represent arrays of bytes, e.g., to hold data read from a\n file.\n\n (On systems whose native character set is not ASCII, strings\n may use EBCDIC in their internal representation, provided the\n functions ``chr()`` and ``ord()`` implement a mapping between\n ASCII and EBCDIC, and string comparison preserves the ASCII\n order. Or perhaps someone can propose a better rule?)\n\n Unicode\n The items of a Unicode object are Unicode code units. A\n Unicode code unit is represented by a Unicode object of one\n item and can hold either a 16-bit or 32-bit value\n representing a Unicode ordinal (the maximum value for the\n ordinal is given in ``sys.maxunicode``, and depends on how\n Python is configured at compile time). Surrogate pairs may\n be present in the Unicode object, and will be reported as two\n separate items. The built-in functions ``unichr()`` and\n ``ord()`` convert between code units and nonnegative integers\n representing the Unicode ordinals as defined in the Unicode\n Standard 3.0. Conversion from and to other encodings are\n possible through the Unicode method ``encode()`` and the\n built-in function ``unicode()``.\n\n Tuples\n The items of a tuple are arbitrary Python objects. Tuples of\n two or more items are formed by comma-separated lists of\n expressions. A tuple of one item (a \'singleton\') can be\n formed by affixing a comma to an expression (an expression by\n itself does not create a tuple, since parentheses must be\n usable for grouping of expressions). An empty tuple can be\n formed by an empty pair of parentheses.\n\n Mutable sequences\n Mutable sequences can be changed after they are created. The\n subscription and slicing notations can be used as the target of\n assignment and ``del`` (delete) statements.\n\n There is currently a single intrinsic mutable sequence type:\n\n Lists\n The items of a list are arbitrary Python objects. Lists are\n formed by placing a comma-separated list of expressions in\n square brackets. (Note that there are no special cases needed\n to form lists of length 0 or 1.)\n\n The extension module ``array`` provides an additional example of\n a mutable sequence type.\n\nSet types\n These represent unordered, finite sets of unique, immutable\n objects. As such, they cannot be indexed by any subscript. However,\n they can be iterated over, and the built-in function ``len()``\n returns the number of items in a set. Common uses for sets are fast\n membership testing, removing duplicates from a sequence, and\n computing mathematical operations such as intersection, union,\n difference, and symmetric difference.\n\n For set elements, the same immutability rules apply as for\n dictionary keys. Note that numeric types obey the normal rules for\n numeric comparison: if two numbers compare equal (e.g., ``1`` and\n ``1.0``), only one of them can be contained in a set.\n\n There are currently two intrinsic set types:\n\n Sets\n These represent a mutable set. They are created by the built-in\n ``set()`` constructor and can be modified afterwards by several\n methods, such as ``add()``.\n\n Frozen sets\n These represent an immutable set. They are created by the\n built-in ``frozenset()`` constructor. As a frozenset is\n immutable and *hashable*, it can be used again as an element of\n another set, or as a dictionary key.\n\nMappings\n These represent finite sets of objects indexed by arbitrary index\n sets. The subscript notation ``a[k]`` selects the item indexed by\n ``k`` from the mapping ``a``; this can be used in expressions and\n as the target of assignments or ``del`` statements. The built-in\n function ``len()`` returns the number of items in a mapping.\n\n There is currently a single intrinsic mapping type:\n\n Dictionaries\n These represent finite sets of objects indexed by nearly\n arbitrary values. The only types of values not acceptable as\n keys are values containing lists or dictionaries or other\n mutable types that are compared by value rather than by object\n identity, the reason being that the efficient implementation of\n dictionaries requires a key\'s hash value to remain constant.\n Numeric types used for keys obey the normal rules for numeric\n comparison: if two numbers compare equal (e.g., ``1`` and\n ``1.0``) then they can be used interchangeably to index the same\n dictionary entry.\n\n Dictionaries are mutable; they can be created by the ``{...}``\n notation (see section *Dictionary displays*).\n\n The extension modules ``dbm``, ``gdbm``, and ``bsddb`` provide\n additional examples of mapping types.\n\nCallable types\n These are the types to which the function call operation (see\n section *Calls*) can be applied:\n\n User-defined functions\n A user-defined function object is created by a function\n definition (see section *Function definitions*). It should be\n called with an argument list containing the same number of items\n as the function\'s formal parameter list.\n\n Special attributes:\n\n +-------------------------+---------------------------------+-------------+\n | Attribute | Meaning | |\n +=========================+=================================+=============+\n | ``func_doc`` | The function\'s documentation | Writable |\n | | string, or ``None`` if | |\n | | unavailable | |\n +-------------------------+---------------------------------+-------------+\n | ``__doc__`` | Another way of spelling | Writable |\n | | ``func_doc`` | |\n +-------------------------+---------------------------------+-------------+\n | ``func_name`` | The function\'s name | Writable |\n +-------------------------+---------------------------------+-------------+\n | ``__name__`` | Another way of spelling | Writable |\n | | ``func_name`` | |\n +-------------------------+---------------------------------+-------------+\n | ``__module__`` | The name of the module the | Writable |\n | | function was defined in, or | |\n | | ``None`` if unavailable. | |\n +-------------------------+---------------------------------+-------------+\n | ``func_defaults`` | A tuple containing default | Writable |\n | | argument values for those | |\n | | arguments that have defaults, | |\n | | or ``None`` if no arguments | |\n | | have a default value | |\n +-------------------------+---------------------------------+-------------+\n | ``func_code`` | The code object representing | Writable |\n | | the compiled function body. | |\n +-------------------------+---------------------------------+-------------+\n | ``func_globals`` | A reference to the dictionary | Read-only |\n | | that holds the function\'s | |\n | | global variables --- the global | |\n | | namespace of the module in | |\n | | which the function was defined. | |\n +-------------------------+---------------------------------+-------------+\n | ``func_dict`` | The namespace supporting | Writable |\n | | arbitrary function attributes. | |\n +-------------------------+---------------------------------+-------------+\n | ``func_closure`` | ``None`` or a tuple of cells | Read-only |\n | | that contain bindings for the | |\n | | function\'s free variables. | |\n +-------------------------+---------------------------------+-------------+\n\n Most of the attributes labelled "Writable" check the type of the\n assigned value.\n\n Changed in version 2.4: ``func_name`` is now writable.\n\n Function objects also support getting and setting arbitrary\n attributes, which can be used, for example, to attach metadata\n to functions. Regular attribute dot-notation is used to get and\n set such attributes. *Note that the current implementation only\n supports function attributes on user-defined functions. Function\n attributes on built-in functions may be supported in the\n future.*\n\n Additional information about a function\'s definition can be\n retrieved from its code object; see the description of internal\n types below.\n\n User-defined methods\n A user-defined method object combines a class, a class instance\n (or ``None``) and any callable object (normally a user-defined\n function).\n\n Special read-only attributes: ``im_self`` is the class instance\n object, ``im_func`` is the function object; ``im_class`` is the\n class of ``im_self`` for bound methods or the class that asked\n for the method for unbound methods; ``__doc__`` is the method\'s\n documentation (same as ``im_func.__doc__``); ``__name__`` is the\n method name (same as ``im_func.__name__``); ``__module__`` is\n the name of the module the method was defined in, or ``None`` if\n unavailable.\n\n Changed in version 2.2: ``im_self`` used to refer to the class\n that defined the method.\n\n Changed in version 2.6: For 3.0 forward-compatibility,\n ``im_func`` is also available as ``__func__``, and ``im_self``\n as ``__self__``.\n\n Methods also support accessing (but not setting) the arbitrary\n function attributes on the underlying function object.\n\n User-defined method objects may be created when getting an\n attribute of a class (perhaps via an instance of that class), if\n that attribute is a user-defined function object, an unbound\n user-defined method object, or a class method object. When the\n attribute is a user-defined method object, a new method object\n is only created if the class from which it is being retrieved is\n the same as, or a derived class of, the class stored in the\n original method object; otherwise, the original method object is\n used as it is.\n\n When a user-defined method object is created by retrieving a\n user-defined function object from a class, its ``im_self``\n attribute is ``None`` and the method object is said to be\n unbound. When one is created by retrieving a user-defined\n function object from a class via one of its instances, its\n ``im_self`` attribute is the instance, and the method object is\n said to be bound. In either case, the new method\'s ``im_class``\n attribute is the class from which the retrieval takes place, and\n its ``im_func`` attribute is the original function object.\n\n When a user-defined method object is created by retrieving\n another method object from a class or instance, the behaviour is\n the same as for a function object, except that the ``im_func``\n attribute of the new instance is not the original method object\n but its ``im_func`` attribute.\n\n When a user-defined method object is created by retrieving a\n class method object from a class or instance, its ``im_self``\n attribute is the class itself (the same as the ``im_class``\n attribute), and its ``im_func`` attribute is the function object\n underlying the class method.\n\n When an unbound user-defined method object is called, the\n underlying function (``im_func``) is called, with the\n restriction that the first argument must be an instance of the\n proper class (``im_class``) or of a derived class thereof.\n\n When a bound user-defined method object is called, the\n underlying function (``im_func``) is called, inserting the class\n instance (``im_self``) in front of the argument list. For\n instance, when ``C`` is a class which contains a definition for\n a function ``f()``, and ``x`` is an instance of ``C``, calling\n ``x.f(1)`` is equivalent to calling ``C.f(x, 1)``.\n\n When a user-defined method object is derived from a class method\n object, the "class instance" stored in ``im_self`` will actually\n be the class itself, so that calling either ``x.f(1)`` or\n ``C.f(1)`` is equivalent to calling ``f(C,1)`` where ``f`` is\n the underlying function.\n\n Note that the transformation from function object to (unbound or\n bound) method object happens each time the attribute is\n retrieved from the class or instance. In some cases, a fruitful\n optimization is to assign the attribute to a local variable and\n call that local variable. Also notice that this transformation\n only happens for user-defined functions; other callable objects\n (and all non-callable objects) are retrieved without\n transformation. It is also important to note that user-defined\n functions which are attributes of a class instance are not\n converted to bound methods; this *only* happens when the\n function is an attribute of the class.\n\n Generator functions\n A function or method which uses the ``yield`` statement (see\n section *The yield statement*) is called a *generator function*.\n Such a function, when called, always returns an iterator object\n which can be used to execute the body of the function: calling\n the iterator\'s ``next()`` method will cause the function to\n execute until it provides a value using the ``yield`` statement.\n When the function executes a ``return`` statement or falls off\n the end, a ``StopIteration`` exception is raised and the\n iterator will have reached the end of the set of values to be\n returned.\n\n Built-in functions\n A built-in function object is a wrapper around a C function.\n Examples of built-in functions are ``len()`` and ``math.sin()``\n (``math`` is a standard built-in module). The number and type of\n the arguments are determined by the C function. Special read-\n only attributes: ``__doc__`` is the function\'s documentation\n string, or ``None`` if unavailable; ``__name__`` is the\n function\'s name; ``__self__`` is set to ``None`` (but see the\n next item); ``__module__`` is the name of the module the\n function was defined in or ``None`` if unavailable.\n\n Built-in methods\n This is really a different disguise of a built-in function, this\n time containing an object passed to the C function as an\n implicit extra argument. An example of a built-in method is\n ``alist.append()``, assuming *alist* is a list object. In this\n case, the special read-only attribute ``__self__`` is set to the\n object denoted by *list*.\n\n Class Types\n Class types, or "new-style classes," are callable. These\n objects normally act as factories for new instances of\n themselves, but variations are possible for class types that\n override ``__new__()``. The arguments of the call are passed to\n ``__new__()`` and, in the typical case, to ``__init__()`` to\n initialize the new instance.\n\n Classic Classes\n Class objects are described below. When a class object is\n called, a new class instance (also described below) is created\n and returned. This implies a call to the class\'s ``__init__()``\n method if it has one. Any arguments are passed on to the\n ``__init__()`` method. If there is no ``__init__()`` method,\n the class must be called without arguments.\n\n Class instances\n Class instances are described below. Class instances are\n callable only when the class has a ``__call__()`` method;\n ``x(arguments)`` is a shorthand for ``x.__call__(arguments)``.\n\nModules\n Modules are imported by the ``import`` statement (see section *The\n import statement*). A module object has a namespace implemented by\n a dictionary object (this is the dictionary referenced by the\n func_globals attribute of functions defined in the module).\n Attribute references are translated to lookups in this dictionary,\n e.g., ``m.x`` is equivalent to ``m.__dict__["x"]``. A module object\n does not contain the code object used to initialize the module\n (since it isn\'t needed once the initialization is done).\n\n Attribute assignment updates the module\'s namespace dictionary,\n e.g., ``m.x = 1`` is equivalent to ``m.__dict__["x"] = 1``.\n\n Special read-only attribute: ``__dict__`` is the module\'s namespace\n as a dictionary object.\n\n Predefined (writable) attributes: ``__name__`` is the module\'s\n name; ``__doc__`` is the module\'s documentation string, or ``None``\n if unavailable; ``__file__`` is the pathname of the file from which\n the module was loaded, if it was loaded from a file. The\n ``__file__`` attribute is not present for C modules that are\n statically linked into the interpreter; for extension modules\n loaded dynamically from a shared library, it is the pathname of the\n shared library file.\n\nClasses\n Class objects are created by class definitions (see section *Class\n definitions*). A class has a namespace implemented by a dictionary\n object. Class attribute references are translated to lookups in\n this dictionary, e.g., ``C.x`` is translated to\n ``C.__dict__["x"]``. When the attribute name is not found there,\n the attribute search continues in the base classes. The search is\n depth-first, left-to-right in the order of occurrence in the base\n class list.\n\n When a class attribute reference (for class ``C``, say) would yield\n a user-defined function object or an unbound user-defined method\n object whose associated class is either ``C`` or one of its base\n classes, it is transformed into an unbound user-defined method\n object whose ``im_class`` attribute is ``C``. When it would yield a\n class method object, it is transformed into a bound user-defined\n method object whose ``im_class`` and ``im_self`` attributes are\n both ``C``. When it would yield a static method object, it is\n transformed into the object wrapped by the static method object.\n See section *Implementing Descriptors* for another way in which\n attributes retrieved from a class may differ from those actually\n contained in its ``__dict__``.\n\n Class attribute assignments update the class\'s dictionary, never\n the dictionary of a base class.\n\n A class object can be called (see above) to yield a class instance\n (see below).\n\n Special attributes: ``__name__`` is the class name; ``__module__``\n is the module name in which the class was defined; ``__dict__`` is\n the dictionary containing the class\'s namespace; ``__bases__`` is a\n tuple (possibly empty or a singleton) containing the base classes,\n in the order of their occurrence in the base class list;\n ``__doc__`` is the class\'s documentation string, or None if\n undefined.\n\nClass instances\n A class instance is created by calling a class object (see above).\n A class instance has a namespace implemented as a dictionary which\n is the first place in which attribute references are searched.\n When an attribute is not found there, and the instance\'s class has\n an attribute by that name, the search continues with the class\n attributes. If a class attribute is found that is a user-defined\n function object or an unbound user-defined method object whose\n associated class is the class (call it ``C``) of the instance for\n which the attribute reference was initiated or one of its bases, it\n is transformed into a bound user-defined method object whose\n ``im_class`` attribute is ``C`` and whose ``im_self`` attribute is\n the instance. Static method and class method objects are also\n transformed, as if they had been retrieved from class ``C``; see\n above under "Classes". See section *Implementing Descriptors* for\n another way in which attributes of a class retrieved via its\n instances may differ from the objects actually stored in the\n class\'s ``__dict__``. If no class attribute is found, and the\n object\'s class has a ``__getattr__()`` method, that is called to\n satisfy the lookup.\n\n Attribute assignments and deletions update the instance\'s\n dictionary, never a class\'s dictionary. If the class has a\n ``__setattr__()`` or ``__delattr__()`` method, this is called\n instead of updating the instance dictionary directly.\n\n Class instances can pretend to be numbers, sequences, or mappings\n if they have methods with certain special names. See section\n *Special method names*.\n\n Special attributes: ``__dict__`` is the attribute dictionary;\n ``__class__`` is the instance\'s class.\n\nFiles\n A file object represents an open file. File objects are created by\n the ``open()`` built-in function, and also by ``os.popen()``,\n ``os.fdopen()``, and the ``makefile()`` method of socket objects\n (and perhaps by other functions or methods provided by extension\n modules). The objects ``sys.stdin``, ``sys.stdout`` and\n ``sys.stderr`` are initialized to file objects corresponding to the\n interpreter\'s standard input, output and error streams. See *File\n Objects* for complete documentation of file objects.\n\nInternal types\n A few types used internally by the interpreter are exposed to the\n user. Their definitions may change with future versions of the\n interpreter, but they are mentioned here for completeness.\n\n Code objects\n Code objects represent *byte-compiled* executable Python code,\n or *bytecode*. The difference between a code object and a\n function object is that the function object contains an explicit\n reference to the function\'s globals (the module in which it was\n defined), while a code object contains no context; also the\n default argument values are stored in the function object, not\n in the code object (because they represent values calculated at\n run-time). Unlike function objects, code objects are immutable\n and contain no references (directly or indirectly) to mutable\n objects.\n\n Special read-only attributes: ``co_name`` gives the function\n name; ``co_argcount`` is the number of positional arguments\n (including arguments with default values); ``co_nlocals`` is the\n number of local variables used by the function (including\n arguments); ``co_varnames`` is a tuple containing the names of\n the local variables (starting with the argument names);\n ``co_cellvars`` is a tuple containing the names of local\n variables that are referenced by nested functions;\n ``co_freevars`` is a tuple containing the names of free\n variables; ``co_code`` is a string representing the sequence of\n bytecode instructions; ``co_consts`` is a tuple containing the\n literals used by the bytecode; ``co_names`` is a tuple\n containing the names used by the bytecode; ``co_filename`` is\n the filename from which the code was compiled;\n ``co_firstlineno`` is the first line number of the function;\n ``co_lnotab`` is a string encoding the mapping from bytecode\n offsets to line numbers (for details see the source code of the\n interpreter); ``co_stacksize`` is the required stack size\n (including local variables); ``co_flags`` is an integer encoding\n a number of flags for the interpreter.\n\n The following flag bits are defined for ``co_flags``: bit\n ``0x04`` is set if the function uses the ``*arguments`` syntax\n to accept an arbitrary number of positional arguments; bit\n ``0x08`` is set if the function uses the ``**keywords`` syntax\n to accept arbitrary keyword arguments; bit ``0x20`` is set if\n the function is a generator.\n\n Future feature declarations (``from __future__ import\n division``) also use bits in ``co_flags`` to indicate whether a\n code object was compiled with a particular feature enabled: bit\n ``0x2000`` is set if the function was compiled with future\n division enabled; bits ``0x10`` and ``0x1000`` were used in\n earlier versions of Python.\n\n Other bits in ``co_flags`` are reserved for internal use.\n\n If a code object represents a function, the first item in\n ``co_consts`` is the documentation string of the function, or\n ``None`` if undefined.\n\n Frame objects\n Frame objects represent execution frames. They may occur in\n traceback objects (see below).\n\n Special read-only attributes: ``f_back`` is to the previous\n stack frame (towards the caller), or ``None`` if this is the\n bottom stack frame; ``f_code`` is the code object being executed\n in this frame; ``f_locals`` is the dictionary used to look up\n local variables; ``f_globals`` is used for global variables;\n ``f_builtins`` is used for built-in (intrinsic) names;\n ``f_restricted`` is a flag indicating whether the function is\n executing in restricted execution mode; ``f_lasti`` gives the\n precise instruction (this is an index into the bytecode string\n of the code object).\n\n Special writable attributes: ``f_trace``, if not ``None``, is a\n function called at the start of each source code line (this is\n used by the debugger); ``f_exc_type``, ``f_exc_value``,\n ``f_exc_traceback`` represent the last exception raised in the\n parent frame provided another exception was ever raised in the\n current frame (in all other cases they are None); ``f_lineno``\n is the current line number of the frame --- writing to this from\n within a trace function jumps to the given line (only for the\n bottom-most frame). A debugger can implement a Jump command\n (aka Set Next Statement) by writing to f_lineno.\n\n Traceback objects\n Traceback objects represent a stack trace of an exception. A\n traceback object is created when an exception occurs. When the\n search for an exception handler unwinds the execution stack, at\n each unwound level a traceback object is inserted in front of\n the current traceback. When an exception handler is entered,\n the stack trace is made available to the program. (See section\n *The try statement*.) It is accessible as ``sys.exc_traceback``,\n and also as the third item of the tuple returned by\n ``sys.exc_info()``. The latter is the preferred interface,\n since it works correctly when the program is using multiple\n threads. When the program contains no suitable handler, the\n stack trace is written (nicely formatted) to the standard error\n stream; if the interpreter is interactive, it is also made\n available to the user as ``sys.last_traceback``.\n\n Special read-only attributes: ``tb_next`` is the next level in\n the stack trace (towards the frame where the exception\n occurred), or ``None`` if there is no next level; ``tb_frame``\n points to the execution frame of the current level;\n ``tb_lineno`` gives the line number where the exception\n occurred; ``tb_lasti`` indicates the precise instruction. The\n line number and last instruction in the traceback may differ\n from the line number of its frame object if the exception\n occurred in a ``try`` statement with no matching except clause\n or with a finally clause.\n\n Slice objects\n Slice objects are used to represent slices when *extended slice\n syntax* is used. This is a slice using two colons, or multiple\n slices or ellipses separated by commas, e.g., ``a[i:j:step]``,\n ``a[i:j, k:l]``, or ``a[..., i:j]``. They are also created by\n the built-in ``slice()`` function.\n\n Special read-only attributes: ``start`` is the lower bound;\n ``stop`` is the upper bound; ``step`` is the step value; each is\n ``None`` if omitted. These attributes can have any type.\n\n Slice objects support one method:\n\n slice.indices(self, length)\n\n This method takes a single integer argument *length* and\n computes information about the extended slice that the slice\n object would describe if applied to a sequence of *length*\n items. It returns a tuple of three integers; respectively\n these are the *start* and *stop* indices and the *step* or\n stride length of the slice. Missing or out-of-bounds indices\n are handled in a manner consistent with regular slices.\n\n Added in version 2.3.\n\n Static method objects\n Static method objects provide a way of defeating the\n transformation of function objects to method objects described\n above. A static method object is a wrapper around any other\n object, usually a user-defined method object. When a static\n method object is retrieved from a class or a class instance, the\n object actually returned is the wrapped object, which is not\n subject to any further transformation. Static method objects are\n not themselves callable, although the objects they wrap usually\n are. Static method objects are created by the built-in\n ``staticmethod()`` constructor.\n\n Class method objects\n A class method object, like a static method object, is a wrapper\n around another object that alters the way in which that object\n is retrieved from classes and class instances. The behaviour of\n class method objects upon such retrieval is described above,\n under "User-defined methods". Class method objects are created\n by the built-in ``classmethod()`` constructor.\n', - 'typesfunctions': u'\nFunctions\n*********\n\nFunction objects are created by function definitions. The only\noperation on a function object is to call it: ``func(argument-list)``.\n\nThere are really two flavors of function objects: built-in functions\nand user-defined functions. Both support the same operation (to call\nthe function), but the implementation is different, hence the\ndifferent object types.\n\nSee *Function definitions* for more information.\n', - 'typesmapping': u'\nMapping Types --- ``dict``\n**************************\n\nA *mapping* object maps *hashable* values to arbitrary objects.\nMappings are mutable objects. There is currently only one standard\nmapping type, the *dictionary*. (For other containers see the built\nin ``list``, ``set``, and ``tuple`` classes, and the ``collections``\nmodule.)\n\nA dictionary\'s keys are *almost* arbitrary values. Values that are\nnot *hashable*, that is, values containing lists, dictionaries or\nother mutable types (that are compared by value rather than by object\nidentity) may not be used as keys. Numeric types used for keys obey\nthe normal rules for numeric comparison: if two numbers compare equal\n(such as ``1`` and ``1.0``) then they can be used interchangeably to\nindex the same dictionary entry. (Note however, that since computers\nstore floating-point numbers as approximations it is usually unwise to\nuse them as dictionary keys.)\n\nDictionaries can be created by placing a comma-separated list of\n``key: value`` pairs within braces, for example: ``{\'jack\': 4098,\n\'sjoerd\': 4127}`` or ``{4098: \'jack\', 4127: \'sjoerd\'}``, or by the\n``dict`` constructor.\n\nclass dict([arg])\n\n Return a new dictionary initialized from an optional positional\n argument or from a set of keyword arguments. If no arguments are\n given, return a new empty dictionary. If the positional argument\n *arg* is a mapping object, return a dictionary mapping the same\n keys to the same values as does the mapping object. Otherwise the\n positional argument must be a sequence, a container that supports\n iteration, or an iterator object. The elements of the argument\n must each also be of one of those kinds, and each must in turn\n contain exactly two objects. The first is used as a key in the new\n dictionary, and the second as the key\'s value. If a given key is\n seen more than once, the last value associated with it is retained\n in the new dictionary.\n\n If keyword arguments are given, the keywords themselves with their\n associated values are added as items to the dictionary. If a key is\n specified both in the positional argument and as a keyword\n argument, the value associated with the keyword is retained in the\n dictionary. For example, these all return a dictionary equal to\n ``{"one": 2, "two": 3}``:\n\n * ``dict(one=2, two=3)``\n\n * ``dict({\'one\': 2, \'two\': 3})``\n\n * ``dict(zip((\'one\', \'two\'), (2, 3)))``\n\n * ``dict([[\'two\', 3], [\'one\', 2]])``\n\n The first example only works for keys that are valid Python\n identifiers; the others work with any valid keys.\n\n Added in version 2.2.\n\n Changed in version 2.3: Support for building a dictionary from\n keyword arguments added.\n\n These are the operations that dictionaries support (and therefore,\n custom mapping types should support too):\n\n len(d)\n\n Return the number of items in the dictionary *d*.\n\n d[key]\n\n Return the item of *d* with key *key*. Raises a ``KeyError`` if\n *key* is not in the map.\n\n Added in version 2.5: If a subclass of dict defines a method\n ``__missing__()``, if the key *key* is not present, the\n ``d[key]`` operation calls that method with the key *key* as\n argument. The ``d[key]`` operation then returns or raises\n whatever is returned or raised by the ``__missing__(key)`` call\n if the key is not present. No other operations or methods invoke\n ``__missing__()``. If ``__missing__()`` is not defined,\n ``KeyError`` is raised. ``__missing__()`` must be a method; it\n cannot be an instance variable. For an example, see\n ``collections.defaultdict``.\n\n d[key] = value\n\n Set ``d[key]`` to *value*.\n\n del d[key]\n\n Remove ``d[key]`` from *d*. Raises a ``KeyError`` if *key* is\n not in the map.\n\n key in d\n\n Return ``True`` if *d* has a key *key*, else ``False``.\n\n Added in version 2.2.\n\n key not in d\n\n Equivalent to ``not key in d``.\n\n Added in version 2.2.\n\n clear()\n\n Remove all items from the dictionary.\n\n copy()\n\n Return a shallow copy of the dictionary.\n\n fromkeys(seq[, value])\n\n Create a new dictionary with keys from *seq* and values set to\n *value*.\n\n ``fromkeys()`` is a class method that returns a new dictionary.\n *value* defaults to ``None``.\n\n Added in version 2.3.\n\n get(key[, default])\n\n Return the value for *key* if *key* is in the dictionary, else\n *default*. If *default* is not given, it defaults to ``None``,\n so that this method never raises a ``KeyError``.\n\n has_key(key)\n\n ``dict.has_key(key)`` is equivalent to ``key in d``, but\n deprecated.\n\n items()\n\n Return a copy of the dictionary\'s list of ``(key, value)``\n pairs.\n\n Note: Keys and values are listed in an arbitrary order which is non-\n random, varies across Python implementations, and depends on\n the dictionary\'s history of insertions and deletions. If\n ``items()``, ``keys()``, ``values()``, ``iteritems()``,\n ``iterkeys()``, and ``itervalues()`` are called with no\n intervening modifications to the dictionary, the lists will\n directly correspond. This allows the creation of ``(value,\n key)`` pairs using ``zip()``: ``pairs = zip(d.values(),\n d.keys())``. The same relationship holds for the\n ``iterkeys()`` and ``itervalues()`` methods: ``pairs =\n zip(d.itervalues(), d.iterkeys())`` provides the same value\n for ``pairs``. Another way to create the same list is ``pairs\n = [(v, k) for (k, v) in d.iteritems()]``.\n\n iteritems()\n\n Return an iterator over the dictionary\'s ``(key, value)`` pairs.\n See the note for ``dict.items()``.\n\n Added in version 2.2.\n\n iterkeys()\n\n Return an iterator over the dictionary\'s keys. See the note for\n ``dict.items()``.\n\n Added in version 2.2.\n\n itervalues()\n\n Return an iterator over the dictionary\'s values. See the note\n for ``dict.items()``.\n\n Added in version 2.2.\n\n keys()\n\n Return a copy of the dictionary\'s list of keys. See the note\n for ``dict.items()``.\n\n pop(key[, default])\n\n If *key* is in the dictionary, remove it and return its value,\n else return *default*. If *default* is not given and *key* is\n not in the dictionary, a ``KeyError`` is raised.\n\n Added in version 2.3.\n\n popitem()\n\n Remove and return an arbitrary ``(key, value)`` pair from the\n dictionary.\n\n ``popitem()`` is useful to destructively iterate over a\n dictionary, as often used in set algorithms. If the dictionary\n is empty, calling ``popitem()`` raises a ``KeyError``.\n\n setdefault(key[, default])\n\n If *key* is in the dictionary, return its value. If not, insert\n *key* with a value of *default* and return *default*. *default*\n defaults to ``None``.\n\n update([other])\n\n Update the dictionary with the key/value pairs from *other*,\n overwriting existing keys. Return ``None``.\n\n ``update()`` accepts either another dictionary object or an\n iterable of key/value pairs (as a tuple or other iterable of\n length two). If keyword arguments are specified, the dictionary\n is then is updated with those key/value pairs: ``d.update(red=1,\n blue=2)``.\n\n Changed in version 2.4: Allowed the argument to be an iterable\n of key/value pairs and allowed keyword arguments.\n\n values()\n\n Return a copy of the dictionary\'s list of values. See the note\n for ``dict.items()``.\n', - 'typesmethods': u"\nMethods\n*******\n\nMethods are functions that are called using the attribute notation.\nThere are two flavors: built-in methods (such as ``append()`` on\nlists) and class instance methods. Built-in methods are described\nwith the types that support them.\n\nThe implementation adds two special read-only attributes to class\ninstance methods: ``m.im_self`` is the object on which the method\noperates, and ``m.im_func`` is the function implementing the method.\nCalling ``m(arg-1, arg-2, ..., arg-n)`` is completely equivalent to\ncalling ``m.im_func(m.im_self, arg-1, arg-2, ..., arg-n)``.\n\nClass instance methods are either *bound* or *unbound*, referring to\nwhether the method was accessed through an instance or a class,\nrespectively. When a method is unbound, its ``im_self`` attribute\nwill be ``None`` and if called, an explicit ``self`` object must be\npassed as the first argument. In this case, ``self`` must be an\ninstance of the unbound method's class (or a subclass of that class),\notherwise a ``TypeError`` is raised.\n\nLike function objects, methods objects support getting arbitrary\nattributes. However, since method attributes are actually stored on\nthe underlying function object (``meth.im_func``), setting method\nattributes on either bound or unbound methods is disallowed.\nAttempting to set a method attribute results in a ``TypeError`` being\nraised. In order to set a method attribute, you need to explicitly\nset it on the underlying function object:\n\n class C:\n def method(self):\n pass\n\n c = C()\n c.method.im_func.whoami = 'my name is c'\n\nSee *The standard type hierarchy* for more information.\n", - 'typesmodules': u"\nModules\n*******\n\nThe only special operation on a module is attribute access:\n``m.name``, where *m* is a module and *name* accesses a name defined\nin *m*'s symbol table. Module attributes can be assigned to. (Note\nthat the ``import`` statement is not, strictly speaking, an operation\non a module object; ``import foo`` does not require a module object\nnamed *foo* to exist, rather it requires an (external) *definition*\nfor a module named *foo* somewhere.)\n\nA special member of every module is ``__dict__``. This is the\ndictionary containing the module's symbol table. Modifying this\ndictionary will actually change the module's symbol table, but direct\nassignment to the ``__dict__`` attribute is not possible (you can\nwrite ``m.__dict__['a'] = 1``, which defines ``m.a`` to be ``1``, but\nyou can't write ``m.__dict__ = {}``). Modifying ``__dict__`` directly\nis not recommended.\n\nModules built into the interpreter are written like this: ````. If loaded from a file, they are written as\n````.\n", - 'typesseq': u'\nSequence Types --- ``str``, ``unicode``, ``list``, ``tuple``, ``buffer``, ``xrange``\n************************************************************************************\n\nThere are six sequence types: strings, Unicode strings, lists, tuples,\nbuffers, and xrange objects. (For other containers see the built in\n``dict``, ``list``, ``set``, and ``tuple`` classes, and the\n``collections`` module.)\n\nString literals are written in single or double quotes: ``\'xyzzy\'``,\n``"frobozz"``. See *String literals* for more about string literals.\nUnicode strings are much like strings, but are specified in the syntax\nusing a preceding ``\'u\'`` character: ``u\'abc\'``, ``u"def"``. In\naddition to the functionality described here, there are also string-\nspecific methods described in the *String Methods* section. Lists are\nconstructed with square brackets, separating items with commas: ``[a,\nb, c]``. Tuples are constructed by the comma operator (not within\nsquare brackets), with or without enclosing parentheses, but an empty\ntuple must have the enclosing parentheses, such as ``a, b, c`` or\n``()``. A single item tuple must have a trailing comma, such as\n``(d,)``.\n\nBuffer objects are not directly supported by Python syntax, but can be\ncreated by calling the builtin function ``buffer()``. They don\'t\nsupport concatenation or repetition.\n\nObjects of type xrange are similar to buffers in that there is no\nspecific syntax to create them, but they are created using the\n``xrange()`` function. They don\'t support slicing, concatenation or\nrepetition, and using ``in``, ``not in``, ``min()`` or ``max()`` on\nthem is inefficient.\n\nMost sequence types support the following operations. The ``in`` and\n``not in`` operations have the same priorities as the comparison\noperations. The ``+`` and ``*`` operations have the same priority as\nthe corresponding numeric operations. [3] Additional methods are\nprovided for *Mutable Sequence Types*.\n\nThis table lists the sequence operations sorted in ascending priority\n(operations in the same box have the same priority). In the table,\n*s* and *t* are sequences of the same type; *n*, *i* and *j* are\nintegers:\n\n+--------------------+----------------------------------+------------+\n| Operation | Result | Notes |\n+====================+==================================+============+\n| ``x in s`` | ``True`` if an item of *s* is | (1) |\n| | equal to *x*, else ``False`` | |\n+--------------------+----------------------------------+------------+\n| ``x not in s`` | ``False`` if an item of *s* is | (1) |\n| | equal to *x*, else ``True`` | |\n+--------------------+----------------------------------+------------+\n| ``s + t`` | the concatenation of *s* and *t* | (6) |\n+--------------------+----------------------------------+------------+\n| ``s * n, n * s`` | *n* shallow copies of *s* | (2) |\n| | concatenated | |\n+--------------------+----------------------------------+------------+\n| ``s[i]`` | *i*\'th item of *s*, origin 0 | (3) |\n+--------------------+----------------------------------+------------+\n| ``s[i:j]`` | slice of *s* from *i* to *j* | (3)(4) |\n+--------------------+----------------------------------+------------+\n| ``s[i:j:k]`` | slice of *s* from *i* to *j* | (3)(5) |\n| | with step *k* | |\n+--------------------+----------------------------------+------------+\n| ``len(s)`` | length of *s* | |\n+--------------------+----------------------------------+------------+\n| ``min(s)`` | smallest item of *s* | |\n+--------------------+----------------------------------+------------+\n| ``max(s)`` | largest item of *s* | |\n+--------------------+----------------------------------+------------+\n\nSequence types also support comparisons. In particular, tuples and\nlists are compared lexicographically by comparing corresponding\nelements. This means that to compare equal, every element must compare\nequal and the two sequences must be of the same type and have the same\nlength. (For full details see *Comparisons* in the language\nreference.)\n\nNotes:\n\n1. When *s* is a string or Unicode string object the ``in`` and ``not\n in`` operations act like a substring test. In Python versions\n before 2.3, *x* had to be a string of length 1. In Python 2.3 and\n beyond, *x* may be a string of any length.\n\n2. Values of *n* less than ``0`` are treated as ``0`` (which yields an\n empty sequence of the same type as *s*). Note also that the copies\n are shallow; nested structures are not copied. This often haunts\n new Python programmers; consider:\n\n >>> lists = [[]] * 3\n >>> lists\n [[], [], []]\n >>> lists[0].append(3)\n >>> lists\n [[3], [3], [3]]\n\n What has happened is that ``[[]]`` is a one-element list containing\n an empty list, so all three elements of ``[[]] * 3`` are (pointers\n to) this single empty list. Modifying any of the elements of\n ``lists`` modifies this single list. You can create a list of\n different lists this way:\n\n >>> lists = [[] for i in range(3)]\n >>> lists[0].append(3)\n >>> lists[1].append(5)\n >>> lists[2].append(7)\n >>> lists\n [[3], [5], [7]]\n\n3. If *i* or *j* is negative, the index is relative to the end of the\n string: ``len(s) + i`` or ``len(s) + j`` is substituted. But note\n that ``-0`` is still ``0``.\n\n4. The slice of *s* from *i* to *j* is defined as the sequence of\n items with index *k* such that ``i <= k < j``. If *i* or *j* is\n greater than ``len(s)``, use ``len(s)``. If *i* is omitted or\n ``None``, use ``0``. If *j* is omitted or ``None``, use\n ``len(s)``. If *i* is greater than or equal to *j*, the slice is\n empty.\n\n5. The slice of *s* from *i* to *j* with step *k* is defined as the\n sequence of items with index ``x = i + n*k`` such that ``0 <= n <\n (j-i)/k``. In other words, the indices are ``i``, ``i+k``,\n ``i+2*k``, ``i+3*k`` and so on, stopping when *j* is reached (but\n never including *j*). If *i* or *j* is greater than ``len(s)``,\n use ``len(s)``. If *i* or *j* are omitted or ``None``, they become\n "end" values (which end depends on the sign of *k*). Note, *k*\n cannot be zero. If *k* is ``None``, it is treated like ``1``.\n\n6. If *s* and *t* are both strings, some Python implementations such\n as CPython can usually perform an in-place optimization for\n assignments of the form ``s=s+t`` or ``s+=t``. When applicable,\n this optimization makes quadratic run-time much less likely. This\n optimization is both version and implementation dependent. For\n performance sensitive code, it is preferable to use the\n ``str.join()`` method which assures consistent linear concatenation\n performance across versions and implementations.\n\n Changed in version 2.4: Formerly, string concatenation never\n occurred in-place.\n\n\nString Methods\n==============\n\nBelow are listed the string methods which both 8-bit strings and\nUnicode objects support. Note that none of these methods take keyword\narguments.\n\nIn addition, Python\'s strings support the sequence type methods\ndescribed in the *Sequence Types --- str, unicode, list, tuple,\nbuffer, xrange* section. To output formatted strings use template\nstrings or the ``%`` operator described in the *String Formatting\nOperations* section. Also, see the ``re`` module for string functions\nbased on regular expressions.\n\nstr.capitalize()\n\n Return a copy of the string with only its first character\n capitalized.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.center(width[, fillchar])\n\n Return centered in a string of length *width*. Padding is done\n using the specified *fillchar* (default is a space).\n\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.count(sub[, start[, end]])\n\n Return the number of occurrences of substring *sub* in the range\n [*start*, *end*]. Optional arguments *start* and *end* are\n interpreted as in slice notation.\n\nstr.decode([encoding[, errors]])\n\n Decodes the string using the codec registered for *encoding*.\n *encoding* defaults to the default string encoding. *errors* may\n be given to set a different error handling scheme. The default is\n ``\'strict\'``, meaning that encoding errors raise ``UnicodeError``.\n Other possible values are ``\'ignore\'``, ``\'replace\'`` and any other\n name registered via ``codecs.register_error()``, see section *Codec\n Base Classes*.\n\n Added in version 2.2.\n\n Changed in version 2.3: Support for other error handling schemes\n added.\n\nstr.encode([encoding[, errors]])\n\n Return an encoded version of the string. Default encoding is the\n current default string encoding. *errors* may be given to set a\n different error handling scheme. The default for *errors* is\n ``\'strict\'``, meaning that encoding errors raise a\n ``UnicodeError``. Other possible values are ``\'ignore\'``,\n ``\'replace\'``, ``\'xmlcharrefreplace\'``, ``\'backslashreplace\'`` and\n any other name registered via ``codecs.register_error()``, see\n section *Codec Base Classes*. For a list of possible encodings, see\n section *Standard Encodings*.\n\n Added in version 2.0.\n\n Changed in version 2.3: Support for ``\'xmlcharrefreplace\'`` and\n ``\'backslashreplace\'`` and other error handling schemes added.\n\nstr.endswith(suffix[, start[, end]])\n\n Return ``True`` if the string ends with the specified *suffix*,\n otherwise return ``False``. *suffix* can also be a tuple of\n suffixes to look for. With optional *start*, test beginning at\n that position. With optional *end*, stop comparing at that\n position.\n\n Changed in version 2.5: Accept tuples as *suffix*.\n\nstr.expandtabs([tabsize])\n\n Return a copy of the string where all tab characters are replaced\n by one or more spaces, depending on the current column and the\n given tab size. The column number is reset to zero after each\n newline occurring in the string. If *tabsize* is not given, a tab\n size of ``8`` characters is assumed. This doesn\'t understand other\n non-printing characters or escape sequences.\n\nstr.find(sub[, start[, end]])\n\n Return the lowest index in the string where substring *sub* is\n found, such that *sub* is contained in the range [*start*, *end*].\n Optional arguments *start* and *end* are interpreted as in slice\n notation. Return ``-1`` if *sub* is not found.\n\nstr.format(format_string, *args, **kwargs)\n\n Perform a string formatting operation. The *format_string*\n argument can contain literal text or replacement fields delimited\n by braces ``{}``. Each replacement field contains either the\n numeric index of a positional argument, or the name of a keyword\n argument. Returns a copy of *format_string* where each replacement\n field is replaced with the string value of the corresponding\n argument.\n\n >>> "The sum of 1 + 2 is {0}".format(1+2)\n \'The sum of 1 + 2 is 3\'\n\n See *Format String Syntax* for a description of the various\n formatting options that can be specified in format strings.\n\n This method of string formatting is the new standard in Python 3.0,\n and should be preferred to the ``%`` formatting described in\n *String Formatting Operations* in new code.\n\n Added in version 2.6.\n\nstr.index(sub[, start[, end]])\n\n Like ``find()``, but raise ``ValueError`` when the substring is not\n found.\n\nstr.isalnum()\n\n Return true if all characters in the string are alphanumeric and\n there is at least one character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.isalpha()\n\n Return true if all characters in the string are alphabetic and\n there is at least one character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.isdigit()\n\n Return true if all characters in the string are digits and there is\n at least one character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.islower()\n\n Return true if all cased characters in the string are lowercase and\n there is at least one cased character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.isspace()\n\n Return true if there are only whitespace characters in the string\n and there is at least one character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.istitle()\n\n Return true if the string is a titlecased string and there is at\n least one character, for example uppercase characters may only\n follow uncased characters and lowercase characters only cased ones.\n Return false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.isupper()\n\n Return true if all cased characters in the string are uppercase and\n there is at least one cased character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.join(seq)\n\n Return a string which is the concatenation of the strings in the\n sequence *seq*. The separator between elements is the string\n providing this method.\n\nstr.ljust(width[, fillchar])\n\n Return the string left justified in a string of length *width*.\n Padding is done using the specified *fillchar* (default is a\n space). The original string is returned if *width* is less than\n ``len(s)``.\n\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.lower()\n\n Return a copy of the string converted to lowercase.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.lstrip([chars])\n\n Return a copy of the string with leading characters removed. The\n *chars* argument is a string specifying the set of characters to be\n removed. If omitted or ``None``, the *chars* argument defaults to\n removing whitespace. The *chars* argument is not a prefix; rather,\n all combinations of its values are stripped:\n\n >>> \' spacious \'.lstrip()\n \'spacious \'\n >>> \'www.example.com\'.lstrip(\'cmowz.\')\n \'example.com\'\n\n Changed in version 2.2.2: Support for the *chars* argument.\n\nstr.partition(sep)\n\n Split the string at the first occurrence of *sep*, and return a\n 3-tuple containing the part before the separator, the separator\n itself, and the part after the separator. If the separator is not\n found, return a 3-tuple containing the string itself, followed by\n two empty strings.\n\n Added in version 2.5.\n\nstr.replace(old, new[, count])\n\n Return a copy of the string with all occurrences of substring *old*\n replaced by *new*. If the optional argument *count* is given, only\n the first *count* occurrences are replaced.\n\nstr.rfind(sub[, start[, end]])\n\n Return the highest index in the string where substring *sub* is\n found, such that *sub* is contained within s[start,end]. Optional\n arguments *start* and *end* are interpreted as in slice notation.\n Return ``-1`` on failure.\n\nstr.rindex(sub[, start[, end]])\n\n Like ``rfind()`` but raises ``ValueError`` when the substring *sub*\n is not found.\n\nstr.rjust(width[, fillchar])\n\n Return the string right justified in a string of length *width*.\n Padding is done using the specified *fillchar* (default is a\n space). The original string is returned if *width* is less than\n ``len(s)``.\n\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.rpartition(sep)\n\n Split the string at the last occurrence of *sep*, and return a\n 3-tuple containing the part before the separator, the separator\n itself, and the part after the separator. If the separator is not\n found, return a 3-tuple containing two empty strings, followed by\n the string itself.\n\n Added in version 2.5.\n\nstr.rsplit([sep[, maxsplit]])\n\n Return a list of the words in the string, using *sep* as the\n delimiter string. If *maxsplit* is given, at most *maxsplit* splits\n are done, the *rightmost* ones. If *sep* is not specified or\n ``None``, any whitespace string is a separator. Except for\n splitting from the right, ``rsplit()`` behaves like ``split()``\n which is described in detail below.\n\n Added in version 2.4.\n\nstr.rstrip([chars])\n\n Return a copy of the string with trailing characters removed. The\n *chars* argument is a string specifying the set of characters to be\n removed. If omitted or ``None``, the *chars* argument defaults to\n removing whitespace. The *chars* argument is not a suffix; rather,\n all combinations of its values are stripped:\n\n >>> \' spacious \'.rstrip()\n \' spacious\'\n >>> \'mississippi\'.rstrip(\'ipz\')\n \'mississ\'\n\n Changed in version 2.2.2: Support for the *chars* argument.\n\nstr.split([sep[, maxsplit]])\n\n Return a list of the words in the string, using *sep* as the\n delimiter string. If *maxsplit* is given, at most *maxsplit*\n splits are done (thus, the list will have at most ``maxsplit+1``\n elements). If *maxsplit* is not specified, then there is no limit\n on the number of splits (all possible splits are made).\n\n If *sep* is given, consecutive delimiters are not grouped together\n and are deemed to delimit empty strings (for example,\n ``\'1,,2\'.split(\',\')`` returns ``[\'1\', \'\', \'2\']``). The *sep*\n argument may consist of multiple characters (for example,\n ``\'1<>2<>3\'.split(\'<>\')`` returns ``[\'1\', \'2\', \'3\']``). Splitting\n an empty string with a specified separator returns ``[\'\']``.\n\n If *sep* is not specified or is ``None``, a different splitting\n algorithm is applied: runs of consecutive whitespace are regarded\n as a single separator, and the result will contain no empty strings\n at the start or end if the string has leading or trailing\n whitespace. Consequently, splitting an empty string or a string\n consisting of just whitespace with a ``None`` separator returns\n ``[]``.\n\n For example, ``\' 1 2 3 \'.split()`` returns ``[\'1\', \'2\', \'3\']``,\n and ``\' 1 2 3 \'.split(None, 1)`` returns ``[\'1\', \'2 3 \']``.\n\nstr.splitlines([keepends])\n\n Return a list of the lines in the string, breaking at line\n boundaries. Line breaks are not included in the resulting list\n unless *keepends* is given and true.\n\nstr.startswith(prefix[, start[, end]])\n\n Return ``True`` if string starts with the *prefix*, otherwise\n return ``False``. *prefix* can also be a tuple of prefixes to look\n for. With optional *start*, test string beginning at that\n position. With optional *end*, stop comparing string at that\n position.\n\n Changed in version 2.5: Accept tuples as *prefix*.\n\nstr.strip([chars])\n\n Return a copy of the string with the leading and trailing\n characters removed. The *chars* argument is a string specifying the\n set of characters to be removed. If omitted or ``None``, the\n *chars* argument defaults to removing whitespace. The *chars*\n argument is not a prefix or suffix; rather, all combinations of its\n values are stripped:\n\n >>> \' spacious \'.strip()\n \'spacious\'\n >>> \'www.example.com\'.strip(\'cmowz.\')\n \'example\'\n\n Changed in version 2.2.2: Support for the *chars* argument.\n\nstr.swapcase()\n\n Return a copy of the string with uppercase characters converted to\n lowercase and vice versa.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.title()\n\n Return a titlecased version of the string: words start with\n uppercase characters, all remaining cased characters are lowercase.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.translate(table[, deletechars])\n\n Return a copy of the string where all characters occurring in the\n optional argument *deletechars* are removed, and the remaining\n characters have been mapped through the given translation table,\n which must be a string of length 256.\n\n You can use the ``maketrans()`` helper function in the ``string``\n module to create a translation table. For string objects, set the\n *table* argument to ``None`` for translations that only delete\n characters:\n\n >>> \'read this short text\'.translate(None, \'aeiou\')\n \'rd ths shrt txt\'\n\n Added in version 2.6: Support for a ``None`` *table* argument.\n\n For Unicode objects, the ``translate()`` method does not accept the\n optional *deletechars* argument. Instead, it returns a copy of the\n *s* where all characters have been mapped through the given\n translation table which must be a mapping of Unicode ordinals to\n Unicode ordinals, Unicode strings or ``None``. Unmapped characters\n are left untouched. Characters mapped to ``None`` are deleted.\n Note, a more flexible approach is to create a custom character\n mapping codec using the ``codecs`` module (see ``encodings.cp1251``\n for an example).\n\nstr.upper()\n\n Return a copy of the string converted to uppercase.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.zfill(width)\n\n Return the numeric string left filled with zeros in a string of\n length *width*. A sign prefix is handled correctly. The original\n string is returned if *width* is less than ``len(s)``.\n\n Added in version 2.2.2.\n\nThe following methods are present only on unicode objects:\n\nunicode.isnumeric()\n\n Return ``True`` if there are only numeric characters in S,\n ``False`` otherwise. Numeric characters include digit characters,\n and all characters that have the Unicode numeric value property,\n e.g. U+2155, VULGAR FRACTION ONE FIFTH.\n\nunicode.isdecimal()\n\n Return ``True`` if there are only decimal characters in S,\n ``False`` otherwise. Decimal characters include digit characters,\n and all characters that that can be used to form decimal-radix\n numbers, e.g. U+0660, ARABIC-INDIC DIGIT ZERO.\n\n\nString Formatting Operations\n============================\n\nString and Unicode objects have one unique built-in operation: the\n``%`` operator (modulo). This is also known as the string\n*formatting* or *interpolation* operator. Given ``format % values``\n(where *format* is a string or Unicode object), ``%`` conversion\nspecifications in *format* are replaced with zero or more elements of\n*values*. The effect is similar to the using ``sprintf`` in the C\nlanguage. If *format* is a Unicode object, or if any of the objects\nbeing converted using the ``%s`` conversion are Unicode objects, the\nresult will also be a Unicode object.\n\nIf *format* requires a single argument, *values* may be a single non-\ntuple object. [4] Otherwise, *values* must be a tuple with exactly\nthe number of items specified by the format string, or a single\nmapping object (for example, a dictionary).\n\nA conversion specifier contains two or more characters and has the\nfollowing components, which must occur in this order:\n\n1. The ``\'%\'`` character, which marks the start of the specifier.\n\n2. Mapping key (optional), consisting of a parenthesised sequence of\n characters (for example, ``(somename)``).\n\n3. Conversion flags (optional), which affect the result of some\n conversion types.\n\n4. Minimum field width (optional). If specified as an ``\'*\'``\n (asterisk), the actual width is read from the next element of the\n tuple in *values*, and the object to convert comes after the\n minimum field width and optional precision.\n\n5. Precision (optional), given as a ``\'.\'`` (dot) followed by the\n precision. If specified as ``\'*\'`` (an asterisk), the actual width\n is read from the next element of the tuple in *values*, and the\n value to convert comes after the precision.\n\n6. Length modifier (optional).\n\n7. Conversion type.\n\nWhen the right argument is a dictionary (or other mapping type), then\nthe formats in the string *must* include a parenthesised mapping key\ninto that dictionary inserted immediately after the ``\'%\'`` character.\nThe mapping key selects the value to be formatted from the mapping.\nFor example:\n\n>>> print \'%(language)s has %(#)03d quote types.\' % \\\n... {\'language\': "Python", "#": 2}\nPython has 002 quote types.\n\nIn this case no ``*`` specifiers may occur in a format (since they\nrequire a sequential parameter list).\n\nThe conversion flag characters are:\n\n+-----------+-----------------------------------------------------------------------+\n| Flag | Meaning |\n+===========+=======================================================================+\n| ``\'#\'`` | The value conversion will use the "alternate form" (where defined |\n| | below). |\n+-----------+-----------------------------------------------------------------------+\n| ``\'0\'`` | The conversion will be zero padded for numeric values. |\n+-----------+-----------------------------------------------------------------------+\n| ``\'-\'`` | The converted value is left adjusted (overrides the ``\'0\'`` |\n| | conversion if both are given). |\n+-----------+-----------------------------------------------------------------------+\n| ``\' \'`` | (a space) A blank should be left before a positive number (or empty |\n| | string) produced by a signed conversion. |\n+-----------+-----------------------------------------------------------------------+\n| ``\'+\'`` | A sign character (``\'+\'`` or ``\'-\'``) will precede the conversion |\n| | (overrides a "space" flag). |\n+-----------+-----------------------------------------------------------------------+\n\nA length modifier (``h``, ``l``, or ``L``) may be present, but is\nignored as it is not necessary for Python -- so e.g. ``%ld`` is\nidentical to ``%d``.\n\nThe conversion types are:\n\n+--------------+-------------------------------------------------------+---------+\n| Conversion | Meaning | Notes |\n+==============+=======================================================+=========+\n| ``\'d\'`` | Signed integer decimal. | |\n+--------------+-------------------------------------------------------+---------+\n| ``\'i\'`` | Signed integer decimal. | |\n+--------------+-------------------------------------------------------+---------+\n| ``\'o\'`` | Signed octal value. | (1) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'u\'`` | Obselete type -- it is identical to ``\'d\'``. | (7) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'x\'`` | Signed hexadecimal (lowercase). | (2) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'X\'`` | Signed hexadecimal (uppercase). | (2) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'e\'`` | Floating point exponential format (lowercase). | (3) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'E\'`` | Floating point exponential format (uppercase). | (3) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'f\'`` | Floating point decimal format. | (3) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'F\'`` | Floating point decimal format. | (3) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'g\'`` | Floating point format. Uses lowercase exponential | (4) |\n| | format if exponent is less than -4 or not less than | |\n| | precision, decimal format otherwise. | |\n+--------------+-------------------------------------------------------+---------+\n| ``\'G\'`` | Floating point format. Uses uppercase exponential | (4) |\n| | format if exponent is less than -4 or not less than | |\n| | precision, decimal format otherwise. | |\n+--------------+-------------------------------------------------------+---------+\n| ``\'c\'`` | Single character (accepts integer or single character | |\n| | string). | |\n+--------------+-------------------------------------------------------+---------+\n| ``\'r\'`` | String (converts any python object using ``repr()``). | (5) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'s\'`` | String (converts any python object using ``str()``). | (6) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'%\'`` | No argument is converted, results in a ``\'%\'`` | |\n| | character in the result. | |\n+--------------+-------------------------------------------------------+---------+\n\nNotes:\n\n1. The alternate form causes a leading zero (``\'0\'``) to be inserted\n between left-hand padding and the formatting of the number if the\n leading character of the result is not already a zero.\n\n2. The alternate form causes a leading ``\'0x\'`` or ``\'0X\'`` (depending\n on whether the ``\'x\'`` or ``\'X\'`` format was used) to be inserted\n between left-hand padding and the formatting of the number if the\n leading character of the result is not already a zero.\n\n3. The alternate form causes the result to always contain a decimal\n point, even if no digits follow it.\n\n The precision determines the number of digits after the decimal\n point and defaults to 6.\n\n4. The alternate form causes the result to always contain a decimal\n point, and trailing zeroes are not removed as they would otherwise\n be.\n\n The precision determines the number of significant digits before\n and after the decimal point and defaults to 6.\n\n5. The ``%r`` conversion was added in Python 2.0.\n\n The precision determines the maximal number of characters used.\n\n6. If the object or format provided is a ``unicode`` string, the\n resulting string will also be ``unicode``.\n\n The precision determines the maximal number of characters used.\n\n7. See **PEP 237**.\n\nSince Python strings have an explicit length, ``%s`` conversions do\nnot assume that ``\'\\0\'`` is the end of the string.\n\nFor safety reasons, floating point precisions are clipped to 50;\n``%f`` conversions for numbers whose absolute value is over 1e25 are\nreplaced by ``%g`` conversions. [5] All other errors raise\nexceptions.\n\nAdditional string operations are defined in standard modules\n``string`` and ``re``.\n\n\nXRange Type\n===========\n\nThe ``xrange`` type is an immutable sequence which is commonly used\nfor looping. The advantage of the ``xrange`` type is that an\n``xrange`` object will always take the same amount of memory, no\nmatter the size of the range it represents. There are no consistent\nperformance advantages.\n\nXRange objects have very little behavior: they only support indexing,\niteration, and the ``len()`` function.\n\n\nMutable Sequence Types\n======================\n\nList objects support additional operations that allow in-place\nmodification of the object. Other mutable sequence types (when added\nto the language) should also support these operations. Strings and\ntuples are immutable sequence types: such objects cannot be modified\nonce created. The following operations are defined on mutable sequence\ntypes (where *x* is an arbitrary object):\n\n+--------------------------------+----------------------------------+-----------------------+\n| Operation | Result | Notes |\n+================================+==================================+=======================+\n| ``s[i] = x`` | item *i* of *s* is replaced by | |\n| | *x* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s[i:j] = t`` | slice of *s* from *i* to *j* is | |\n| | replaced by the contents of the | |\n| | iterable *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``del s[i:j]`` | same as ``s[i:j] = []`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s[i:j:k] = t`` | the elements of ``s[i:j:k]`` are | (1) |\n| | replaced by those of *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``del s[i:j:k]`` | removes the elements of | |\n| | ``s[i:j:k]`` from the list | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.append(x)`` | same as ``s[len(s):len(s)] = | (2) |\n| | [x]`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.extend(x)`` | same as ``s[len(s):len(s)] = x`` | (3) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.count(x)`` | return number of *i*\'s for which | |\n| | ``s[i] == x`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.index(x[, i[, j]])`` | return smallest *k* such that | (4) |\n| | ``s[k] == x`` and ``i <= k < j`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.insert(i, x)`` | same as ``s[i:i] = [x]`` | (5) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.pop([i])`` | same as ``x = s[i]; del s[i]; | (6) |\n| | return x`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.remove(x)`` | same as ``del s[s.index(x)]`` | (4) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.reverse()`` | reverses the items of *s* in | (7) |\n| | place | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.sort([cmp[, key[, | sort the items of *s* in place | (7)(8)(9)(10) |\n| reverse]]])`` | | |\n+--------------------------------+----------------------------------+-----------------------+\n\nNotes:\n\n1. *t* must have the same length as the slice it is replacing.\n\n2. The C implementation of Python has historically accepted multiple\n parameters and implicitly joined them into a tuple; this no longer\n works in Python 2.0. Use of this misfeature has been deprecated\n since Python 1.4.\n\n3. *x* can be any iterable object.\n\n4. Raises ``ValueError`` when *x* is not found in *s*. When a negative\n index is passed as the second or third parameter to the ``index()``\n method, the list length is added, as for slice indices. If it is\n still negative, it is truncated to zero, as for slice indices.\n\n Changed in version 2.3: Previously, ``index()`` didn\'t have\n arguments for specifying start and stop positions.\n\n5. When a negative index is passed as the first parameter to the\n ``insert()`` method, the list length is added, as for slice\n indices. If it is still negative, it is truncated to zero, as for\n slice indices.\n\n Changed in version 2.3: Previously, all negative indices were\n truncated to zero.\n\n6. The ``pop()`` method is only supported by the list and array types.\n The optional argument *i* defaults to ``-1``, so that by default\n the last item is removed and returned.\n\n7. The ``sort()`` and ``reverse()`` methods modify the list in place\n for economy of space when sorting or reversing a large list. To\n remind you that they operate by side effect, they don\'t return the\n sorted or reversed list.\n\n8. The ``sort()`` method takes optional arguments for controlling the\n comparisons.\n\n *cmp* specifies a custom comparison function of two arguments (list\n items) which should return a negative, zero or positive number\n depending on whether the first argument is considered smaller than,\n equal to, or larger than the second argument: ``cmp=lambda x,y:\n cmp(x.lower(), y.lower())``. The default value is ``None``.\n\n *key* specifies a function of one argument that is used to extract\n a comparison key from each list element: ``key=str.lower``. The\n default value is ``None``.\n\n *reverse* is a boolean value. If set to ``True``, then the list\n elements are sorted as if each comparison were reversed.\n\n In general, the *key* and *reverse* conversion processes are much\n faster than specifying an equivalent *cmp* function. This is\n because *cmp* is called multiple times for each list element while\n *key* and *reverse* touch each element only once.\n\n Changed in version 2.3: Support for ``None`` as an equivalent to\n omitting *cmp* was added.\n\n Changed in version 2.4: Support for *key* and *reverse* was added.\n\n9. Starting with Python 2.3, the ``sort()`` method is guaranteed to be\n stable. A sort is stable if it guarantees not to change the\n relative order of elements that compare equal --- this is helpful\n for sorting in multiple passes (for example, sort by department,\n then by salary grade).\n\n10. While a list is being sorted, the effect of attempting to mutate,\n or even inspect, the list is undefined. The C implementation of\n Python 2.3 and newer makes the list appear empty for the duration,\n and raises ``ValueError`` if it can detect that the list has been\n mutated during a sort.\n', - 'typesseq-mutable': u"\nMutable Sequence Types\n**********************\n\nList objects support additional operations that allow in-place\nmodification of the object. Other mutable sequence types (when added\nto the language) should also support these operations. Strings and\ntuples are immutable sequence types: such objects cannot be modified\nonce created. The following operations are defined on mutable sequence\ntypes (where *x* is an arbitrary object):\n\n+--------------------------------+----------------------------------+-----------------------+\n| Operation | Result | Notes |\n+================================+==================================+=======================+\n| ``s[i] = x`` | item *i* of *s* is replaced by | |\n| | *x* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s[i:j] = t`` | slice of *s* from *i* to *j* is | |\n| | replaced by the contents of the | |\n| | iterable *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``del s[i:j]`` | same as ``s[i:j] = []`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s[i:j:k] = t`` | the elements of ``s[i:j:k]`` are | (1) |\n| | replaced by those of *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``del s[i:j:k]`` | removes the elements of | |\n| | ``s[i:j:k]`` from the list | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.append(x)`` | same as ``s[len(s):len(s)] = | (2) |\n| | [x]`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.extend(x)`` | same as ``s[len(s):len(s)] = x`` | (3) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.count(x)`` | return number of *i*'s for which | |\n| | ``s[i] == x`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.index(x[, i[, j]])`` | return smallest *k* such that | (4) |\n| | ``s[k] == x`` and ``i <= k < j`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.insert(i, x)`` | same as ``s[i:i] = [x]`` | (5) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.pop([i])`` | same as ``x = s[i]; del s[i]; | (6) |\n| | return x`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.remove(x)`` | same as ``del s[s.index(x)]`` | (4) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.reverse()`` | reverses the items of *s* in | (7) |\n| | place | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.sort([cmp[, key[, | sort the items of *s* in place | (7)(8)(9)(10) |\n| reverse]]])`` | | |\n+--------------------------------+----------------------------------+-----------------------+\n\nNotes:\n\n1. *t* must have the same length as the slice it is replacing.\n\n2. The C implementation of Python has historically accepted multiple\n parameters and implicitly joined them into a tuple; this no longer\n works in Python 2.0. Use of this misfeature has been deprecated\n since Python 1.4.\n\n3. *x* can be any iterable object.\n\n4. Raises ``ValueError`` when *x* is not found in *s*. When a negative\n index is passed as the second or third parameter to the ``index()``\n method, the list length is added, as for slice indices. If it is\n still negative, it is truncated to zero, as for slice indices.\n\n Changed in version 2.3: Previously, ``index()`` didn't have\n arguments for specifying start and stop positions.\n\n5. When a negative index is passed as the first parameter to the\n ``insert()`` method, the list length is added, as for slice\n indices. If it is still negative, it is truncated to zero, as for\n slice indices.\n\n Changed in version 2.3: Previously, all negative indices were\n truncated to zero.\n\n6. The ``pop()`` method is only supported by the list and array types.\n The optional argument *i* defaults to ``-1``, so that by default\n the last item is removed and returned.\n\n7. The ``sort()`` and ``reverse()`` methods modify the list in place\n for economy of space when sorting or reversing a large list. To\n remind you that they operate by side effect, they don't return the\n sorted or reversed list.\n\n8. The ``sort()`` method takes optional arguments for controlling the\n comparisons.\n\n *cmp* specifies a custom comparison function of two arguments (list\n items) which should return a negative, zero or positive number\n depending on whether the first argument is considered smaller than,\n equal to, or larger than the second argument: ``cmp=lambda x,y:\n cmp(x.lower(), y.lower())``. The default value is ``None``.\n\n *key* specifies a function of one argument that is used to extract\n a comparison key from each list element: ``key=str.lower``. The\n default value is ``None``.\n\n *reverse* is a boolean value. If set to ``True``, then the list\n elements are sorted as if each comparison were reversed.\n\n In general, the *key* and *reverse* conversion processes are much\n faster than specifying an equivalent *cmp* function. This is\n because *cmp* is called multiple times for each list element while\n *key* and *reverse* touch each element only once.\n\n Changed in version 2.3: Support for ``None`` as an equivalent to\n omitting *cmp* was added.\n\n Changed in version 2.4: Support for *key* and *reverse* was added.\n\n9. Starting with Python 2.3, the ``sort()`` method is guaranteed to be\n stable. A sort is stable if it guarantees not to change the\n relative order of elements that compare equal --- this is helpful\n for sorting in multiple passes (for example, sort by department,\n then by salary grade).\n\n10. While a list is being sorted, the effect of attempting to mutate,\n or even inspect, the list is undefined. The C implementation of\n Python 2.3 and newer makes the list appear empty for the duration,\n and raises ``ValueError`` if it can detect that the list has been\n mutated during a sort.\n", - 'unary': u'\nUnary arithmetic operations\n***************************\n\nAll unary arithmetic (and bitwise) operations have the same priority:\n\n u_expr ::= power | "-" u_expr | "+" u_expr | "~" u_expr\n\nThe unary ``-`` (minus) operator yields the negation of its numeric\nargument.\n\nThe unary ``+`` (plus) operator yields its numeric argument unchanged.\n\nThe unary ``~`` (invert) operator yields the bitwise inversion of its\nplain or long integer argument. The bitwise inversion of ``x`` is\ndefined as ``-(x+1)``. It only applies to integral numbers.\n\nIn all three cases, if the argument does not have the proper type, a\n``TypeError`` exception is raised.\n', - 'while': u'\nThe ``while`` statement\n***********************\n\nThe ``while`` statement is used for repeated execution as long as an\nexpression is true:\n\n while_stmt ::= "while" expression ":" suite\n ["else" ":" suite]\n\nThis repeatedly tests the expression and, if it is true, executes the\nfirst suite; if the expression is false (which may be the first time\nit is tested) the suite of the ``else`` clause, if present, is\nexecuted and the loop terminates.\n\nA ``break`` statement executed in the first suite terminates the loop\nwithout executing the ``else`` clause\'s suite. A ``continue``\nstatement executed in the first suite skips the rest of the suite and\ngoes back to testing the expression.\n', - 'with': u'\nThe ``with`` statement\n**********************\n\nAdded in version 2.5.\n\nThe ``with`` statement is used to wrap the execution of a block with\nmethods defined by a context manager (see section *With Statement\nContext Managers*). This allows common\n``try``...``except``...``finally`` usage patterns to be encapsulated\nfor convenient reuse.\n\n with_stmt ::= "with" expression ["as" target] ":" suite\n\nThe execution of the ``with`` statement proceeds as follows:\n\n1. The context expression is evaluated to obtain a context manager.\n\n2. The context manager\'s ``__enter__()`` method is invoked.\n\n3. If a target was included in the ``with`` statement, the return\n value from ``__enter__()`` is assigned to it.\n\n Note: The ``with`` statement guarantees that if the ``__enter__()``\n method returns without an error, then ``__exit__()`` will always\n be called. Thus, if an error occurs during the assignment to the\n target list, it will be treated the same as an error occurring\n within the suite would be. See step 5 below.\n\n4. The suite is executed.\n\n5. The context manager\'s ``__exit__()`` method is invoked. If an\n exception caused the suite to be exited, its type, value, and\n traceback are passed as arguments to ``__exit__()``. Otherwise,\n three ``None`` arguments are supplied.\n\n If the suite was exited due to an exception, and the return value\n from the ``__exit__()`` method was false, the exception is\n reraised. If the return value was true, the exception is\n suppressed, and execution continues with the statement following\n the ``with`` statement.\n\n If the suite was exited for any reason other than an exception, the\n return value from ``__exit__()`` is ignored, and execution proceeds\n at the normal location for the kind of exit that was taken.\n\nNote: In Python 2.5, the ``with`` statement is only allowed when the\n ``with_statement`` feature has been enabled. It is always enabled\n in Python 2.6.\n\nSee also:\n\n **PEP 0343** - The "with" statement\n The specification, background, and examples for the Python\n ``with`` statement.\n', - 'yield': u'\nThe ``yield`` statement\n***********************\n\n yield_stmt ::= yield_expression\n\nThe ``yield`` statement is only used when defining a generator\nfunction, and is only used in the body of the generator function.\nUsing a ``yield`` statement in a function definition is sufficient to\ncause that definition to create a generator function instead of a\nnormal function.\n\nWhen a generator function is called, it returns an iterator known as a\ngenerator iterator, or more commonly, a generator. The body of the\ngenerator function is executed by calling the generator\'s ``next()``\nmethod repeatedly until it raises an exception.\n\nWhen a ``yield`` statement is executed, the state of the generator is\nfrozen and the value of **expression_list** is returned to\n``next()``\'s caller. By "frozen" we mean that all local state is\nretained, including the current bindings of local variables, the\ninstruction pointer, and the internal evaluation stack: enough\ninformation is saved so that the next time ``next()`` is invoked, the\nfunction can proceed exactly as if the ``yield`` statement were just\nanother external call.\n\nAs of Python version 2.5, the ``yield`` statement is now allowed in\nthe ``try`` clause of a ``try`` ... ``finally`` construct. If the\ngenerator is not resumed before it is finalized (by reaching a zero\nreference count or by being garbage collected), the generator-\niterator\'s ``close()`` method will be called, allowing any pending\n``finally`` clauses to execute.\n\nNote: In Python 2.2, the ``yield`` statement was only allowed when the\n ``generators`` feature has been enabled. This ``__future__`` import\n statement was used to enable the feature:\n\n from __future__ import generators\n\nSee also:\n\n **PEP 0255** - Simple Generators\n The proposal for adding generators and the ``yield`` statement\n to Python.\n\n **PEP 0342** - Coroutines via Enhanced Generators\n The proposal that, among other generator enhancements, proposed\n allowing ``yield`` to appear inside a ``try`` ... ``finally``\n block.\n'} +# Autogenerated by Sphinx on Sun Jun 1 23:04:03 2008 +topics = {'assert': '\nThe ``assert`` statement\n************************\n\nAssert statements are a convenient way to insert debugging assertions\ninto a program:\n\n assert_stmt ::= "assert" expression ["," expression]\n\nThe simple form, ``assert expression``, is equivalent to\n\n if __debug__:\n if not expression: raise AssertionError\n\nThe extended form, ``assert expression1, expression2``, is equivalent\nto\n\n if __debug__:\n if not expression1: raise AssertionError(expression2)\n\nThese equivalences assume that ``__debug__`` and ``AssertionError``\nrefer to the built-in variables with those names. In the current\nimplementation, the built-in variable ``__debug__`` is ``True`` under\nnormal circumstances, ``False`` when optimization is requested\n(command line option -O). The current code generator emits no code\nfor an assert statement when optimization is requested at compile\ntime. Note that it is unnecessary to include the source code for the\nexpression that failed in the error message; it will be displayed as\npart of the stack trace.\n\nAssignments to ``__debug__`` are illegal. The value for the built-in\nvariable is determined when the interpreter starts.\n', + 'assignment': '\nAssignment statements\n*********************\n\nAssignment statements are used to (re)bind names to values and to\nmodify attributes or items of mutable objects:\n\n assignment_stmt ::= (target_list "=")+ (expression_list | yield_expression)\n target_list ::= target ("," target)* [","]\n target ::= identifier\n | "(" target_list ")"\n | "[" target_list "]"\n | attributeref\n | subscription\n | slicing\n | "*" target\n\n(See section *Primaries* for the syntax definitions for the last three\nsymbols.)\n\nAn assignment statement evaluates the expression list (remember that\nthis can be a single expression or a comma-separated list, the latter\nyielding a tuple) and assigns the single resulting object to each of\nthe target lists, from left to right.\n\nAssignment is defined recursively depending on the form of the target\n(list). When a target is part of a mutable object (an attribute\nreference, subscription or slicing), the mutable object must\nultimately perform the assignment and decide about its validity, and\nmay raise an exception if the assignment is unacceptable. The rules\nobserved by various types and the exceptions raised are given with the\ndefinition of the object types (see section *The standard type\nhierarchy*).\n\nAssignment of an object to a target list, optionally enclosed in\nparentheses or square brackets, is recursively defined as follows.\n\n* If the target list is a single target: The object is assigned to\n that target.\n\n* If the target list is a comma-separated list of targets:\n\n * If the target list contains one target prefixed with an asterisk,\n called a "starred" target: The object must be a sequence with at\n least as many items as there are targets in the target list, minus\n one. The first items of the sequence are assigned, from left to\n right, to the targets before the starred target. The final items\n of the sequence are assigned to the targets after the starred\n target. A list of the remaining items in the sequence is then\n assigned to the starred target (the list can be empty).\n\n * Else: The object must be a sequence with the same number of items\n as there are targets in the target list, and the items are\n assigned, from left to right, to the corresponding targets.\n\nAssignment of an object to a single target is recursively defined as\nfollows.\n\n* If the target is an identifier (name):\n\n * If the name does not occur in a ``global`` or ``nonlocal``\n statement in the current code block: the name is bound to the\n object in the current local namespace.\n\n * Otherwise: the name is bound to the object in the global namespace\n or the outer namespace determined by ``nonlocal``, respectively.\n\n The name is rebound if it was already bound. This may cause the\n reference count for the object previously bound to the name to reach\n zero, causing the object to be deallocated and its destructor (if it\n has one) to be called.\n\n The name is rebound if it was already bound. This may cause the\n reference count for the object previously bound to the name to reach\n zero, causing the object to be deallocated and its destructor (if it\n has one) to be called.\n\n* If the target is a target list enclosed in parentheses or in square\n brackets: The object must be a sequence with the same number of\n items as there are targets in the target list, and its items are\n assigned, from left to right, to the corresponding targets.\n\n* If the target is an attribute reference: The primary expression in\n the reference is evaluated. It should yield an object with\n assignable attributes; if this is not the case, ``TypeError`` is\n raised. That object is then asked to assign the assigned object to\n the given attribute; if it cannot perform the assignment, it raises\n an exception (usually but not necessarily ``AttributeError``).\n\n* If the target is a subscription: The primary expression in the\n reference is evaluated. It should yield either a mutable sequence\n object (such as a list) or a mapping object (such as a dictionary).\n Next, the subscript expression is evaluated.\n\n If the primary is a mutable sequence object (such as a list), the\n subscript must yield an integer. If it is negative, the sequence\'s\n length is added to it. The resulting value must be a nonnegative\n integer less than the sequence\'s length, and the sequence is asked\n to assign the assigned object to its item with that index. If the\n index is out of range, ``IndexError`` is raised (assignment to a\n subscripted sequence cannot add new items to a list).\n\n If the primary is a mapping object (such as a dictionary), the\n subscript must have a type compatible with the mapping\'s key type,\n and the mapping is then asked to create a key/datum pair which maps\n the subscript to the assigned object. This can either replace an\n existing key/value pair with the same key value, or insert a new\n key/value pair (if no key with the same value existed).\n\n For user-defined objects, the ``__setitem__()`` method is called\n with appropriate arguments.\n\n* If the target is a slicing: The primary expression in the reference\n is evaluated. It should yield a mutable sequence object (such as a\n list). The assigned object should be a sequence object of the same\n type. Next, the lower and upper bound expressions are evaluated,\n insofar they are present; defaults are zero and the sequence\'s\n length. The bounds should evaluate to integers. If either bound is\n negative, the sequence\'s length is added to it. The resulting\n bounds are clipped to lie between zero and the sequence\'s length,\n inclusive. Finally, the sequence object is asked to replace the\n slice with the items of the assigned sequence. The length of the\n slice may be different from the length of the assigned sequence,\n thus changing the length of the target sequence, if the object\n allows it.\n\n(In the current implementation, the syntax for targets is taken to be\nthe same as for expressions, and invalid syntax is rejected during the\ncode generation phase, causing less detailed error messages.)\n\nWARNING: Although the definition of assignment implies that overlaps\nbetween the left-hand side and the right-hand side are \'safe\' (for\nexample ``a, b = b, a`` swaps two variables), overlaps *within* the\ncollection of assigned-to variables are not safe! For instance, the\nfollowing program prints ``[0, 2]``:\n\n x = [0, 1]\n i = 0\n i, x[i] = 1, 2\n print(x)\n\nSee also:\n\n **PEP 3132** - Extended Iterable Unpacking\n The specification for the ``*target`` feature.\n\n\nAugmented assignment statements\n===============================\n\nAugmented assignment is the combination, in a single statement, of a\nbinary operation and an assignment statement:\n\n augmented_assignment_stmt ::= target augop (expression_list | yield_expression)\n augop ::= "+=" | "-=" | "*=" | "/=" | "%=" | "**="\n | ">>=" | "<<=" | "&=" | "^=" | "|="\n\n(See section *Primaries* for the syntax definitions for the last three\nsymbols.)\n\nAn augmented assignment evaluates the target (which, unlike normal\nassignment statements, cannot be an unpacking) and the expression\nlist, performs the binary operation specific to the type of assignment\non the two operands, and assigns the result to the original target.\nThe target is only evaluated once.\n\nAn augmented assignment expression like ``x += 1`` can be rewritten as\n``x = x + 1`` to achieve a similar, but not exactly equal effect. In\nthe augmented version, ``x`` is only evaluated once. Also, when\npossible, the actual operation is performed *in-place*, meaning that\nrather than creating a new object and assigning that to the target,\nthe old object is modified instead.\n\nWith the exception of assigning to tuples and multiple targets in a\nsingle statement, the assignment done by augmented assignment\nstatements is handled the same way as normal assignments. Similarly,\nwith the exception of the possible *in-place* behavior, the binary\noperation performed by augmented assignment is the same as the normal\nbinary operations.\n\nFor targets which are attribute references, the initial value is\nretrieved with a ``getattr()`` and the result is assigned with a\n``setattr()``. Notice that the two methods do not necessarily refer\nto the same variable. When ``getattr()`` refers to a class variable,\n``setattr()`` still writes to an instance variable. For example:\n\n class A:\n x = 3 # class variable\n a = A()\n a.x += 1 # writes a.x as 4 leaving A.x as 3\n', + 'atom-identifiers': '\nIdentifiers (Names)\n*******************\n\nAn identifier occurring as an atom is a name. See section\n*Identifiers and keywords* for lexical definition and section *Naming\nand binding* for documentation of naming and binding.\n\nWhen the name is bound to an object, evaluation of the atom yields\nthat object. When a name is not bound, an attempt to evaluate it\nraises a ``NameError`` exception.\n\n**Private name mangling:** When an identifier that textually occurs in\na class definition begins with two or more underscore characters and\ndoes not end in two or more underscores, it is considered a *private\nname* of that class. Private names are transformed to a longer form\nbefore code is generated for them. The transformation inserts the\nclass name in front of the name, with leading underscores removed, and\na single underscore inserted in front of the class name. For example,\nthe identifier ``__spam`` occurring in a class named ``Ham`` will be\ntransformed to ``_Ham__spam``. This transformation is independent of\nthe syntactical context in which the identifier is used. If the\ntransformed name is extremely long (longer than 255 characters),\nimplementation defined truncation may happen. If the class name\nconsists only of underscores, no transformation is done.\n', + 'atom-literals': "\nLiterals\n********\n\nPython supports string and bytes literals and various numeric\nliterals:\n\n literal ::= stringliteral | bytesliteral\n | integer | floatnumber | imagnumber\n\nEvaluation of a literal yields an object of the given type (string,\nbytes, integer, floating point number, complex number) with the given\nvalue. The value may be approximated in the case of floating point\nand imaginary (complex) literals. See section *Literals* for details.\n\nWith the exception of bytes literals, these all correspond to\nimmutable data types, and hence the object's identity is less\nimportant than its value. Multiple evaluations of literals with the\nsame value (either the same occurrence in the program text or a\ndifferent occurrence) may obtain the same object or a different object\nwith the same value.\n", + 'attribute-access': '\nCustomizing attribute access\n****************************\n\nThe following methods can be defined to customize the meaning of\nattribute access (use of, assignment to, or deletion of ``x.name``)\nfor class instances.\n\nobject.__getattr__(self, name)\n\n Called when an attribute lookup has not found the attribute in the\n usual places (i.e. it is not an instance attribute nor is it found\n in the class tree for ``self``). ``name`` is the attribute name.\n This method should return the (computed) attribute value or raise\n an ``AttributeError`` exception.\n\n Note that if the attribute is found through the normal mechanism,\n ``__getattr__()`` is not called. (This is an intentional asymmetry\n between ``__getattr__()`` and ``__setattr__()``.) This is done both\n for efficiency reasons and because otherwise ``__setattr__()``\n would have no way to access other attributes of the instance. Note\n that at least for instance variables, you can fake total control by\n not inserting any values in the instance attribute dictionary (but\n instead inserting them in another object). See the\n ``__getattribute__()`` method below for a way to actually get total\n control over attribute access.\n\nobject.__getattribute__(self, name)\n\n Called unconditionally to implement attribute accesses for\n instances of the class. If the class also defines\n ``__getattr__()``, the latter will not be called unless\n ``__getattribute__()`` either calls it explicitly or raises an\n ``AttributeError``. This method should return the (computed)\n attribute value or raise an ``AttributeError`` exception. In order\n to avoid infinite recursion in this method, its implementation\n should always call the base class method with the same name to\n access any attributes it needs, for example,\n ``object.__getattribute__(self, name)``.\n\nobject.__setattr__(self, name, value)\n\n Called when an attribute assignment is attempted. This is called\n instead of the normal mechanism (i.e. store the value in the\n instance dictionary). *name* is the attribute name, *value* is the\n value to be assigned to it.\n\n If ``__setattr__()`` wants to assign to an instance attribute, it\n should call the base class method with the same name, for example,\n ``object.__setattr__(self, name, value)``.\n\nobject.__delattr__(self, name)\n\n Like ``__setattr__()`` but for attribute deletion instead of\n assignment. This should only be implemented if ``del obj.name`` is\n meaningful for the object.\n\n\nImplementing Descriptors\n========================\n\nThe following methods only apply when an instance of the class\ncontaining the method (a so-called *descriptor* class) appears in the\nclass dictionary of another class, known as the *owner* class. In the\nexamples below, "the attribute" refers to the attribute whose name is\nthe key of the property in the owner class\' ``__dict__``.\n\nobject.__get__(self, instance, owner)\n\n Called to get the attribute of the owner class (class attribute\n access) or of an instance of that class (instance attribute\n access). *owner* is always the owner class, while *instance* is the\n instance that the attribute was accessed through, or ``None`` when\n the attribute is accessed through the *owner*. This method should\n return the (computed) attribute value or raise an\n ``AttributeError`` exception.\n\nobject.__set__(self, instance, value)\n\n Called to set the attribute on an instance *instance* of the owner\n class to a new value, *value*.\n\nobject.__delete__(self, instance)\n\n Called to delete the attribute on an instance *instance* of the\n owner class.\n\n\nInvoking Descriptors\n====================\n\nIn general, a descriptor is an object attribute with "binding\nbehavior", one whose attribute access has been overridden by methods\nin the descriptor protocol: ``__get__()``, ``__set__()``, and\n``__delete__()``. If any of those methods are defined for an object,\nit is said to be a descriptor.\n\nThe default behavior for attribute access is to get, set, or delete\nthe attribute from an object\'s dictionary. For instance, ``a.x`` has a\nlookup chain starting with ``a.__dict__[\'x\']``, then\n``type(a).__dict__[\'x\']``, and continuing through the base classes of\n``type(a)`` excluding metaclasses.\n\nHowever, if the looked-up value is an object defining one of the\ndescriptor methods, then Python may override the default behavior and\ninvoke the descriptor method instead. Where this occurs in the\nprecedence chain depends on which descriptor methods were defined and\nhow they were called.\n\nThe starting point for descriptor invocation is a binding, ``a.x``.\nHow the arguments are assembled depends on ``a``:\n\nDirect Call\n The simplest and least common call is when user code directly\n invokes a descriptor method: ``x.__get__(a)``.\n\nInstance Binding\n If binding to an object instance, ``a.x`` is transformed into the\n call: ``type(a).__dict__[\'x\'].__get__(a, type(a))``.\n\nClass Binding\n If binding to a class, ``A.x`` is transformed into the call:\n ``A.__dict__[\'x\'].__get__(None, A)``.\n\nSuper Binding\n If ``a`` is an instance of ``super``, then the binding ``super(B,\n obj).m()`` searches ``obj.__class__.__mro__`` for the base class\n ``A`` immediately preceding ``B`` and then invokes the descriptor\n with the call: ``A.__dict__[\'m\'].__get__(obj, A)``.\n\nFor instance bindings, the precedence of descriptor invocation depends\non the which descriptor methods are defined. Normally, data\ndescriptors define both ``__get__()`` and ``__set__()``, while non-\ndata descriptors have just the ``__get__()`` method. Data descriptors\nalways override a redefinition in an instance dictionary. In\ncontrast, non-data descriptors can be overridden by instances. [1]\n\nPython methods (including ``staticmethod()`` and ``classmethod()``)\nare implemented as non-data descriptors. Accordingly, instances can\nredefine and override methods. This allows individual instances to\nacquire behaviors that differ from other instances of the same class.\n\nThe ``property()`` function is implemented as a data descriptor.\nAccordingly, instances cannot override the behavior of a property.\n\n\n__slots__\n=========\n\nBy default, instances of classes have a dictionary for attribute\nstorage. This wastes space for objects having very few instance\nvariables. The space consumption can become acute when creating large\nnumbers of instances.\n\nThe default can be overridden by defining *__slots__* in a class\ndefinition. The *__slots__* declaration takes a sequence of instance\nvariables and reserves just enough space in each instance to hold a\nvalue for each variable. Space is saved because *__dict__* is not\ncreated for each instance.\n\nobject.__slots__\n\n This class variable can be assigned a string, iterable, or sequence\n of strings with variable names used by instances. If defined in a\n class, *__slots__* reserves space for the declared variables and\n prevents the automatic creation of *__dict__* and *__weakref__* for\n each instance.\n\n\nNotes on using *__slots__*\n--------------------------\n\n* Without a *__dict__* variable, instances cannot be assigned new\n variables not listed in the *__slots__* definition. Attempts to\n assign to an unlisted variable name raises ``AttributeError``. If\n dynamic assignment of new variables is desired, then add\n ``\'__dict__\'`` to the sequence of strings in the *__slots__*\n declaration.\n\n* Without a *__weakref__* variable for each instance, classes defining\n *__slots__* do not support weak references to its instances. If weak\n reference support is needed, then add ``\'__weakref__\'`` to the\n sequence of strings in the *__slots__* declaration.\n\n* *__slots__* are implemented at the class level by creating\n descriptors (*Implementing Descriptors*) for each variable name. As\n a result, class attributes cannot be used to set default values for\n instance variables defined by *__slots__*; otherwise, the class\n attribute would overwrite the descriptor assignment.\n\n* If a class defines a slot also defined in a base class, the instance\n variable defined by the base class slot is inaccessible (except by\n retrieving its descriptor directly from the base class). This\n renders the meaning of the program undefined. In the future, a\n check may be added to prevent this.\n\n* The action of a *__slots__* declaration is limited to the class\n where it is defined. As a result, subclasses will have a *__dict__*\n unless they also define *__slots__*.\n\n* *__slots__* do not work for classes derived from "variable-length"\n built-in types such as ``int``, ``str`` and ``tuple``.\n\n* Any non-string iterable may be assigned to *__slots__*. Mappings may\n also be used; however, in the future, special meaning may be\n assigned to the values corresponding to each key.\n\n* *__class__* assignment works only if both classes have the same\n *__slots__*.\n', + 'attribute-references': '\nAttribute references\n********************\n\nAn attribute reference is a primary followed by a period and a name:\n\n attributeref ::= primary "." identifier\n\nThe primary must evaluate to an object of a type that supports\nattribute references, which most objects do. This object is then\nasked to produce the attribute whose name is the identifier (which can\nbe customized by overriding the ``__getattr__()`` method). If this\nattribute is not available, the exception ``AttributeError`` is\nraised. Otherwise, the type and value of the object produced is\ndetermined by the object. Multiple evaluations of the same attribute\nreference may yield different objects.\n', + 'augassign': '\nAugmented assignment statements\n*******************************\n\nAugmented assignment is the combination, in a single statement, of a\nbinary operation and an assignment statement:\n\n augmented_assignment_stmt ::= target augop (expression_list | yield_expression)\n augop ::= "+=" | "-=" | "*=" | "/=" | "%=" | "**="\n | ">>=" | "<<=" | "&=" | "^=" | "|="\n\n(See section *Primaries* for the syntax definitions for the last three\nsymbols.)\n\nAn augmented assignment evaluates the target (which, unlike normal\nassignment statements, cannot be an unpacking) and the expression\nlist, performs the binary operation specific to the type of assignment\non the two operands, and assigns the result to the original target.\nThe target is only evaluated once.\n\nAn augmented assignment expression like ``x += 1`` can be rewritten as\n``x = x + 1`` to achieve a similar, but not exactly equal effect. In\nthe augmented version, ``x`` is only evaluated once. Also, when\npossible, the actual operation is performed *in-place*, meaning that\nrather than creating a new object and assigning that to the target,\nthe old object is modified instead.\n\nWith the exception of assigning to tuples and multiple targets in a\nsingle statement, the assignment done by augmented assignment\nstatements is handled the same way as normal assignments. Similarly,\nwith the exception of the possible *in-place* behavior, the binary\noperation performed by augmented assignment is the same as the normal\nbinary operations.\n\nFor targets which are attribute references, the initial value is\nretrieved with a ``getattr()`` and the result is assigned with a\n``setattr()``. Notice that the two methods do not necessarily refer\nto the same variable. When ``getattr()`` refers to a class variable,\n``setattr()`` still writes to an instance variable. For example:\n\n class A:\n x = 3 # class variable\n a = A()\n a.x += 1 # writes a.x as 4 leaving A.x as 3\n', + 'binary': '\nBinary arithmetic operations\n****************************\n\nThe binary arithmetic operations have the conventional priority\nlevels. Note that some of these operations also apply to certain non-\nnumeric types. Apart from the power operator, there are only two\nlevels, one for multiplicative operators and one for additive\noperators:\n\n m_expr ::= u_expr | m_expr "*" u_expr | m_expr "//" u_expr | m_expr "/" u_expr\n | m_expr "%" u_expr\n a_expr ::= m_expr | a_expr "+" m_expr | a_expr "-" m_expr\n\nThe ``*`` (multiplication) operator yields the product of its\narguments. The arguments must either both be numbers, or one argument\nmust be an integer and the other must be a sequence. In the former\ncase, the numbers are converted to a common type and then multiplied\ntogether. In the latter case, sequence repetition is performed; a\nnegative repetition factor yields an empty sequence.\n\nThe ``/`` (division) and ``//`` (floor division) operators yield the\nquotient of their arguments. The numeric arguments are first\nconverted to a common type. Integer division yields a float, while\nfloor division of integers results in an integer; the result is that\nof mathematical division with the \'floor\' function applied to the\nresult. Division by zero raises the ``ZeroDivisionError`` exception.\n\nThe ``%`` (modulo) operator yields the remainder from the division of\nthe first argument by the second. The numeric arguments are first\nconverted to a common type. A zero right argument raises the\n``ZeroDivisionError`` exception. The arguments may be floating point\nnumbers, e.g., ``3.14%0.7`` equals ``0.34`` (since ``3.14`` equals\n``4*0.7 + 0.34``.) The modulo operator always yields a result with\nthe same sign as its second operand (or zero); the absolute value of\nthe result is strictly smaller than the absolute value of the second\noperand [1].\n\nThe floor division and modulo operators are connected by the following\nidentity: ``x == (x//y)*y + (x%y)``. Floor division and modulo are\nalso connected with the built-in function ``divmod()``: ``divmod(x, y)\n== (x//y, x%y)``. [2].\n\nIn addition to performing the modulo operation on numbers, the ``%``\noperator is also overloaded by string objects to perform old-style\nstring formatting (also known as interpolation). The syntax for\nstring formatting is described in the Python Library Reference,\nsection *Old String Formatting Operations*.\n\nThe floor division operator, the modulo operator, and the ``divmod()``\nfunction are not defined for complex numbers. Instead, convert to a\nfloating point number using the ``abs()`` function if appropriate.\n\nThe ``+`` (addition) operator yields the sum of its arguments. The\narguments must either both be numbers or both sequences of the same\ntype. In the former case, the numbers are converted to a common type\nand then added together. In the latter case, the sequences are\nconcatenated.\n\nThe ``-`` (subtraction) operator yields the difference of its\narguments. The numeric arguments are first converted to a common\ntype.\n', + 'bitwise': '\nBinary bitwise operations\n*************************\n\nEach of the three bitwise operations has a different priority level:\n\n and_expr ::= shift_expr | and_expr "&" shift_expr\n xor_expr ::= and_expr | xor_expr "^" and_expr\n or_expr ::= xor_expr | or_expr "|" xor_expr\n\nThe ``&`` operator yields the bitwise AND of its arguments, which must\nbe integers.\n\nThe ``^`` operator yields the bitwise XOR (exclusive OR) of its\narguments, which must be integers.\n\nThe ``|`` operator yields the bitwise (inclusive) OR of its arguments,\nwhich must be integers.\n', + 'bltin-code-objects': '\nCode Objects\n************\n\nCode objects are used by the implementation to represent "pseudo-\ncompiled" executable Python code such as a function body. They differ\nfrom function objects because they don\'t contain a reference to their\nglobal execution environment. Code objects are returned by the built-\nin ``compile()`` function and can be extracted from function objects\nthrough their ``__code__`` attribute. See also the ``code`` module.\n\nA code object can be executed or evaluated by passing it (instead of a\nsource string) to the ``exec()`` or ``eval()`` built-in functions.\n\nSee *The standard type hierarchy* for more information.\n', + 'bltin-ellipsis-object': '\nThe Ellipsis Object\n*******************\n\nThis object is commonly used by slicing (see *Slicings*). It supports\nno special operations. There is exactly one ellipsis object, named\n``Ellipsis`` (a built-in name).\n\nIt is written as ``Ellipsis`` or ``...``.\n', + 'bltin-file-objects': '\nFile Objects\n************\n\nFile objects are implemented using C\'s ``stdio`` package and can be\ncreated with the built-in ``open()`` function. File objects are also\nreturned by some other built-in functions and methods, such as\n``os.popen()`` and ``os.fdopen()`` and the ``makefile()`` method of\nsocket objects. Temporary files can be created using the ``tempfile``\nmodule, and high-level file operations such as copying, moving, and\ndeleting files and directories can be achieved with the ``shutil``\nmodule.\n\nWhen a file operation fails for an I/O-related reason, the exception\n``IOError`` is raised. This includes situations where the operation\nis not defined for some reason, like ``seek()`` on a tty device or\nwriting a file opened for reading.\n\nFiles have the following methods:\n\nfile.close()\n\n Close the file. A closed file cannot be read or written any more.\n Any operation which requires that the file be open will raise a\n ``ValueError`` after the file has been closed. Calling ``close()``\n more than once is allowed.\n\n You can avoid having to call this method explicitly if you use the\n ``with`` statement. For example, the following code will\n automatically close *f* when the ``with`` block is exited:\n\n from __future__ import with_statement\n\n with open("hello.txt") as f:\n for line in f:\n print(line)\n\n In older versions of Python, you would have needed to do this to\n get the same effect:\n\n f = open("hello.txt")\n try:\n for line in f:\n print(line)\n finally:\n f.close()\n\n Note: Not all "file-like" types in Python support use as a context\n manager for the ``with`` statement. If your code is intended to\n work with any file-like object, you can use the function\n ``contextlib.closing()`` instead of using the object directly.\n\nfile.flush()\n\n Flush the internal buffer, like ``stdio``\'s ``fflush``. This may\n be a no-op on some file-like objects.\n\nfile.fileno()\n\n Return the integer "file descriptor" that is used by the underlying\n implementation to request I/O operations from the operating system.\n This can be useful for other, lower level interfaces that use file\n descriptors, such as the ``fcntl`` module or ``os.read()`` and\n friends.\n\n Note: File-like objects which do not have a real file descriptor should\n *not* provide this method!\n\nfile.isatty()\n\n Return ``True`` if the file is connected to a tty(-like) device,\n else ``False``.\n\n Note: If a file-like object is not associated with a real file, this\n method should *not* be implemented.\n\nfile.__next__()\n\n A file object is its own iterator, for example ``iter(f)`` returns\n *f* (unless *f* is closed). When a file is used as an iterator,\n typically in a ``for`` loop (for example, ``for line in f:\n print(line)``), the ``__next__()`` method is called repeatedly.\n This method returns the next input line, or raises\n ``StopIteration`` when EOF is hit when the file is open for reading\n (behavior is undefined when the file is open for writing). In\n order to make a ``for`` loop the most efficient way of looping over\n the lines of a file (a very common operation), the ``__next__()``\n method uses a hidden read-ahead buffer. As a consequence of using\n a read-ahead buffer, combining ``__next__()`` with other file\n methods (like ``readline()``) does not work right. However, using\n ``seek()`` to reposition the file to an absolute position will\n flush the read-ahead buffer.\n\nfile.read([size])\n\n Read at most *size* bytes from the file (less if the read hits EOF\n before obtaining *size* bytes). If the *size* argument is negative\n or omitted, read all data until EOF is reached. The bytes are\n returned as a string object. An empty string is returned when EOF\n is encountered immediately. (For certain files, like ttys, it\n makes sense to continue reading after an EOF is hit.) Note that\n this method may call the underlying C function ``fread`` more than\n once in an effort to acquire as close to *size* bytes as possible.\n Also note that when in non-blocking mode, less data than what was\n requested may be returned, even if no *size* parameter was given.\n\nfile.readline([size])\n\n Read one entire line from the file. A trailing newline character\n is kept in the string (but may be absent when a file ends with an\n incomplete line). [6] If the *size* argument is present and non-\n negative, it is a maximum byte count (including the trailing\n newline) and an incomplete line may be returned. An empty string is\n returned *only* when EOF is encountered immediately.\n\n Note: Unlike ``stdio``\'s ``fgets``, the returned string contains null\n characters (``\'\\0\'``) if they occurred in the input.\n\nfile.readlines([sizehint])\n\n Read until EOF using ``readline()`` and return a list containing\n the lines thus read. If the optional *sizehint* argument is\n present, instead of reading up to EOF, whole lines totalling\n approximately *sizehint* bytes (possibly after rounding up to an\n internal buffer size) are read. Objects implementing a file-like\n interface may choose to ignore *sizehint* if it cannot be\n implemented, or cannot be implemented efficiently.\n\nfile.seek(offset[, whence])\n\n Set the file\'s current position, like ``stdio``\'s ``fseek``. The\n *whence* argument is optional and defaults to ``os.SEEK_SET`` or\n ``0`` (absolute file positioning); other values are ``os.SEEK_CUR``\n or ``1`` (seek relative to the current position) and\n ``os.SEEK_END`` or ``2`` (seek relative to the file\'s end). There\n is no return value.\n\n For example, ``f.seek(2, os.SEEK_CUR)`` advances the position by\n two and ``f.seek(-3, os.SEEK_END)`` sets the position to the third\n to last.\n\n Note that if the file is opened for appending (mode ``\'a\'`` or\n ``\'a+\'``), any ``seek()`` operations will be undone at the next\n write. If the file is only opened for writing in append mode (mode\n ``\'a\'``), this method is essentially a no-op, but it remains useful\n for files opened in append mode with reading enabled (mode\n ``\'a+\'``). If the file is opened in text mode (without ``\'b\'``),\n only offsets returned by ``tell()`` are legal. Use of other\n offsets causes undefined behavior.\n\n Note that not all file objects are seekable.\n\nfile.tell()\n\n Return the file\'s current position, like ``stdio``\'s ``ftell``.\n\n Note: On Windows, ``tell()`` can return illegal values (after an\n ``fgets``) when reading files with Unix-style line-endings. Use\n binary mode (``\'rb\'``) to circumvent this problem.\n\nfile.truncate([size])\n\n Truncate the file\'s size. If the optional *size* argument is\n present, the file is truncated to (at most) that size. The size\n defaults to the current position. The current file position is not\n changed. Note that if a specified size exceeds the file\'s current\n size, the result is platform-dependent: possibilities include that\n the file may remain unchanged, increase to the specified size as if\n zero-filled, or increase to the specified size with undefined new\n content. Availability: Windows, many Unix variants.\n\nfile.write(str)\n\n Write a string to the file. Due to buffering, the string may not\n actually show up in the file until the ``flush()`` or ``close()``\n method is called.\n\n The meaning of the return value is not defined for every file-like\n object. Some (mostly low-level) file-like objects may return the\n number of bytes actually written, others return ``None``.\n\nfile.writelines(sequence)\n\n Write a sequence of strings to the file. The sequence can be any\n iterable object producing strings, typically a list of strings.\n There is no return value. (The name is intended to match\n ``readlines()``; ``writelines()`` does not add line separators.)\n\nFiles support the iterator protocol. Each iteration returns the same\nresult as ``file.readline()``, and iteration ends when the\n``readline()`` method returns an empty string.\n\nFile objects also offer a number of other interesting attributes.\nThese are not required for file-like objects, but should be\nimplemented if they make sense for the particular object.\n\nfile.closed\n\n bool indicating the current state of the file object. This is a\n read-only attribute; the ``close()`` method changes the value. It\n may not be available on all file-like objects.\n\nfile.encoding\n\n The encoding that this file uses. When strings are written to a\n file, they will be converted to byte strings using this encoding.\n In addition, when the file is connected to a terminal, the\n attribute gives the encoding that the terminal is likely to use\n (that information might be incorrect if the user has misconfigured\n the terminal). The attribute is read-only and may not be present\n on all file-like objects. It may also be ``None``, in which case\n the file uses the system default encoding for converting strings.\n\nfile.mode\n\n The I/O mode for the file. If the file was created using the\n ``open()`` built-in function, this will be the value of the *mode*\n parameter. This is a read-only attribute and may not be present on\n all file-like objects.\n\nfile.name\n\n If the file object was created using ``open()``, the name of the\n file. Otherwise, some string that indicates the source of the file\n object, of the form ``<...>``. This is a read-only attribute and\n may not be present on all file-like objects.\n\nfile.newlines\n\n If Python was built with the *--with-universal-newlines* option to\n **configure** (the default) this read-only attribute exists, and\n for files opened in universal newline read mode it keeps track of\n the types of newlines encountered while reading the file. The\n values it can take are ``\'\\r\'``, ``\'\\n\'``, ``\'\\r\\n\'``, ``None``\n (unknown, no newlines read yet) or a tuple containing all the\n newline types seen, to indicate that multiple newline conventions\n were encountered. For files not opened in universal newline read\n mode the value of this attribute will be ``None``.\n', + 'bltin-null-object': "\nThe Null Object\n***************\n\nThis object is returned by functions that don't explicitly return a\nvalue. It supports no special operations. There is exactly one null\nobject, named ``None`` (a built-in name).\n\nIt is written as ``None``.\n", + 'bltin-type-objects': "\nType Objects\n************\n\nType objects represent the various object types. An object's type is\naccessed by the built-in function ``type()``. There are no special\noperations on types. The standard module ``types`` defines names for\nall standard built-in types.\n\nTypes are written like this: ````.\n", + 'booleans': '\nBoolean operations\n******************\n\nBoolean operations have the lowest priority of all Python operations:\n\n expression ::= conditional_expression | lambda_form\n expression_nocond ::= or_test | lambda_form_nocond\n conditional_expression ::= or_test ["if" or_test "else" expression]\n or_test ::= and_test | or_test "or" and_test\n and_test ::= not_test | and_test "and" not_test\n not_test ::= comparison | "not" not_test\n\nIn the context of Boolean operations, and also when expressions are\nused by control flow statements, the following values are interpreted\nas false: ``False``, ``None``, numeric zero of all types, and empty\nstrings and containers (including strings, tuples, lists,\ndictionaries, sets and frozensets). All other values are interpreted\nas true. User-defined objects can customize their truth value by\nproviding a ``__bool__()`` method.\n\nThe operator ``not`` yields ``True`` if its argument is false,\n``False`` otherwise.\n\nThe expression ``x if C else y`` first evaluates *C* (*not* *x*); if\n*C* is true, *x* is evaluated and its value is returned; otherwise,\n*y* is evaluated and its value is returned.\n\nThe expression ``x and y`` first evaluates *x*; if *x* is false, its\nvalue is returned; otherwise, *y* is evaluated and the resulting value\nis returned.\n\nThe expression ``x or y`` first evaluates *x*; if *x* is true, its\nvalue is returned; otherwise, *y* is evaluated and the resulting value\nis returned.\n\n(Note that neither ``and`` nor ``or`` restrict the value and type they\nreturn to ``False`` and ``True``, but rather return the last evaluated\nargument. This is sometimes useful, e.g., if ``s`` is a string that\nshould be replaced by a default value if it is empty, the expression\n``s or \'foo\'`` yields the desired value. Because ``not`` has to\ninvent a value anyway, it does not bother to return a value of the\nsame type as its argument, so e.g., ``not \'foo\'`` yields ``False``,\nnot ``\'\'``.)\n', + 'break': '\nThe ``break`` statement\n***********************\n\n break_stmt ::= "break"\n\n``break`` may only occur syntactically nested in a ``for`` or\n``while`` loop, but not nested in a function or class definition\nwithin that loop.\n\nIt terminates the nearest enclosing loop, skipping the optional\n``else`` clause if the loop has one.\n\nIf a ``for`` loop is terminated by ``break``, the loop control target\nkeeps its current value.\n\nWhen ``break`` passes control out of a ``try`` statement with a\n``finally`` clause, that ``finally`` clause is executed before really\nleaving the loop.\n', + 'callable-types': '\nEmulating callable objects\n**************************\n\nobject.__call__(self[, args...])\n\n Called when the instance is "called" as a function; if this method\n is defined, ``x(arg1, arg2, ...)`` is a shorthand for\n ``x.__call__(arg1, arg2, ...)``.\n', + 'calls': '\nCalls\n*****\n\nA call calls a callable object (e.g., a function) with a possibly\nempty series of arguments:\n\n call ::= primary "(" [argument_list [","]\n | expression genexpr_for] ")"\n argument_list ::= positional_arguments ["," keyword_arguments]\n ["," "*" expression]\n ["," "**" expression]\n | keyword_arguments ["," "*" expression]\n ["," "**" expression]\n | "*" expression ["," "**" expression]\n | "**" expression\n positional_arguments ::= expression ("," expression)*\n keyword_arguments ::= keyword_item ("," keyword_item)*\n keyword_item ::= identifier "=" expression\n\nA trailing comma may be present after the positional and keyword\narguments but does not affect the semantics.\n\nThe primary must evaluate to a callable object (user-defined\nfunctions, built-in functions, methods of built-in objects, class\nobjects, methods of class instances, and all objects having a\n``__call__()`` method are callable). All argument expressions are\nevaluated before the call is attempted. Please refer to section\n*Function definitions* for the syntax of formal parameter lists.\n\nIf keyword arguments are present, they are first converted to\npositional arguments, as follows. First, a list of unfilled slots is\ncreated for the formal parameters. If there are N positional\narguments, they are placed in the first N slots. Next, for each\nkeyword argument, the identifier is used to determine the\ncorresponding slot (if the identifier is the same as the first formal\nparameter name, the first slot is used, and so on). If the slot is\nalready filled, a ``TypeError`` exception is raised. Otherwise, the\nvalue of the argument is placed in the slot, filling it (even if the\nexpression is ``None``, it fills the slot). When all arguments have\nbeen processed, the slots that are still unfilled are filled with the\ncorresponding default value from the function definition. (Default\nvalues are calculated, once, when the function is defined; thus, a\nmutable object such as a list or dictionary used as default value will\nbe shared by all calls that don\'t specify an argument value for the\ncorresponding slot; this should usually be avoided.) If there are any\nunfilled slots for which no default value is specified, a\n``TypeError`` exception is raised. Otherwise, the list of filled\nslots is used as the argument list for the call.\n\nNote: An implementation may provide builtin functions whose positional\n parameters do not have names, even if they are \'named\' for the\n purpose of documentation, and which therefore cannot be supplied by\n keyword. In CPython, this is the case for functions implemented in\n C that use ``PyArg_ParseTuple`` to parse their arguments.\n\nIf there are more positional arguments than there are formal parameter\nslots, a ``TypeError`` exception is raised, unless a formal parameter\nusing the syntax ``*identifier`` is present; in this case, that formal\nparameter receives a tuple containing the excess positional arguments\n(or an empty tuple if there were no excess positional arguments).\n\nIf any keyword argument does not correspond to a formal parameter\nname, a ``TypeError`` exception is raised, unless a formal parameter\nusing the syntax ``**identifier`` is present; in this case, that\nformal parameter receives a dictionary containing the excess keyword\narguments (using the keywords as keys and the argument values as\ncorresponding values), or a (new) empty dictionary if there were no\nexcess keyword arguments.\n\nIf the syntax ``*expression`` appears in the function call,\n``expression`` must evaluate to a sequence. Elements from this\nsequence are treated as if they were additional positional arguments;\nif there are positional arguments *x1*,...,*xN* , and ``expression``\nevaluates to a sequence *y1*,...,*yM*, this is equivalent to a call\nwith M+N positional arguments *x1*,...,*xN*,*y1*,...,*yM*.\n\nA consequence of this is that although the ``*expression`` syntax\nappears *after* any keyword arguments, it is processed *before* the\nkeyword arguments (and the ``**expression`` argument, if any -- see\nbelow). So:\n\n >>> def f(a, b):\n ... print(a, b)\n ...\n >>> f(b=1, *(2,))\n 2 1\n >>> f(a=1, *(2,))\n Traceback (most recent call last):\n File "", line 1, in ?\n TypeError: f() got multiple values for keyword argument \'a\'\n >>> f(1, *(2,))\n 1 2\n\nIt is unusual for both keyword arguments and the ``*expression``\nsyntax to be used in the same call, so in practice this confusion does\nnot arise.\n\nIf the syntax ``**expression`` appears in the function call,\n``expression`` must evaluate to a mapping, the contents of which are\ntreated as additional keyword arguments. In the case of a keyword\nappearing in both ``expression`` and as an explicit keyword argument,\na ``TypeError`` exception is raised.\n\nFormal parameters using the syntax ``*identifier`` or ``**identifier``\ncannot be used as positional argument slots or as keyword argument\nnames.\n\nA call always returns some value, possibly ``None``, unless it raises\nan exception. How this value is computed depends on the type of the\ncallable object.\n\nIf it is---\n\na user-defined function:\n The code block for the function is executed, passing it the\n argument list. The first thing the code block will do is bind the\n formal parameters to the arguments; this is described in section\n *Function definitions*. When the code block executes a ``return``\n statement, this specifies the return value of the function call.\n\na built-in function or method:\n The result is up to the interpreter; see *Built-in Functions* for\n the descriptions of built-in functions and methods.\n\na class object:\n A new instance of that class is returned.\n\na class instance method:\n The corresponding user-defined function is called, with an argument\n list that is one longer than the argument list of the call: the\n instance becomes the first argument.\n\na class instance:\n The class must define a ``__call__()`` method; the effect is then\n the same as if that method was called.\n', + 'class': '\nClass definitions\n*****************\n\nA class definition defines a class object (see section *The standard\ntype hierarchy*):\n\n classdef ::= [decorators] "class" classname [inheritance] ":" suite\n inheritance ::= "(" [expression_list] ")"\n classname ::= identifier\n\nA class definition is an executable statement. It first evaluates the\ninheritance list, if present. Each item in the inheritance list\nshould evaluate to a class object or class type which allows\nsubclassing. The class\'s suite is then executed in a new execution\nframe (see section *Naming and binding*), using a newly created local\nnamespace and the original global namespace. (Usually, the suite\ncontains only function definitions.) When the class\'s suite finishes\nexecution, its execution frame is discarded but its local namespace is\nsaved. A class object is then created using the inheritance list for\nthe base classes and the saved local namespace for the attribute\ndictionary. The class name is bound to this class object in the\noriginal local namespace.\n\nClasses can also be decorated; as with functions,\n\n @f1(arg)\n @f2\n class Foo: pass\n\nis equivalent to\n\n class Foo: pass\n Foo = f1(arg)(f2(Foo))\n\n**Programmer\'s note:** Variables defined in the class definition are\nclass can be set in a method with ``self.name = value``. Both class\nand instance variables are accessible through the notation\n"``self.name``", and an instance variable hides a class variable with\nthe same name when accessed in this way. Class variables can be used\nas defaults for instance variables, but using mutable values there can\nlead to unexpected results. Descriptors can be used to create\ninstance variables with different implementation details.\n\nSee also:\n\n **PEP 3129** - Class Decorators\n\nClass definitions, like function definitions, may be wrapped by one or\nmore *decorator* expressions. The evaluation rules for the decorator\nexpressions are the same as for functions. The result must be a class\nobject, which is then bound to the class name.\n\n-[ Footnotes ]-\n\n[1] The exception is propagated to the invocation stack only if there\n is no ``finally`` clause that negates the exception.\n\n[2] Currently, control "flows off the end" except in the case of an\n exception or the execution of a ``return``, ``continue``, or\n ``break`` statement.\n', + 'comparisons': '\nComparisons\n***********\n\nUnlike C, all comparison operations in Python have the same priority,\nwhich is lower than that of any arithmetic, shifting or bitwise\noperation. Also unlike C, expressions like ``a < b < c`` have the\ninterpretation that is conventional in mathematics:\n\n comparison ::= or_expr ( comp_operator or_expr )*\n comp_operator ::= "<" | ">" | "==" | ">=" | "<=" | "!="\n | "is" ["not"] | ["not"] "in"\n\nComparisons yield boolean values: ``True`` or ``False``.\n\nComparisons can be chained arbitrarily, e.g., ``x < y <= z`` is\nequivalent to ``x < y and y <= z``, except that ``y`` is evaluated\nonly once (but in both cases ``z`` is not evaluated at all when ``x <\ny`` is found to be false).\n\nFormally, if *a*, *b*, *c*, ..., *y*, *z* are expressions and *op1*,\n*op2*, ..., *opN* are comparison operators, then ``a op1 b op2 c ... y\nopN z`` is equivalent to ``a op1 b and b op2 c and ... y opN z``,\nexcept that each expression is evaluated at most once.\n\nNote that ``a op1 b op2 c`` doesn\'t imply any kind of comparison\nbetween *a* and *c*, so that, e.g., ``x < y > z`` is perfectly legal\n(though perhaps not pretty).\n\nThe operators ``<``, ``>``, ``==``, ``>=``, ``<=``, and ``!=`` compare\nthe values of two objects. The objects need not have the same type.\nIf both are numbers, they are converted to a common type. Otherwise,\nobjects of different types *always* compare unequal, and are ordered\nconsistently but arbitrarily. You can control comparison behavior of\nobjects of non-builtin types by defining a ``__cmp__()`` method or\nrich comparison methods like ``__gt__()``, described in section\n*Special method names*.\n\n(This unusual definition of comparison was used to simplify the\ndefinition of operations like sorting and the ``in`` and ``not in``\noperators. In the future, the comparison rules for objects of\ndifferent types are likely to change.)\n\nComparison of objects of the same type depends on the type:\n\n* Numbers are compared arithmetically.\n\n* Bytes objects are compared lexicographically using the numeric\n values of their elements.\n\n* Strings are compared lexicographically using the numeric equivalents\n (the result of the built-in function ``ord()``) of their characters.\n [3] String and bytes object can\'t be compared!\n\n* Tuples and lists are compared lexicographically using comparison of\n corresponding elements. This means that to compare equal, each\n element must compare equal and the two sequences must be of the same\n type and have the same length.\n\n If not equal, the sequences are ordered the same as their first\n differing elements. For example, ``cmp([1,2,x], [1,2,y])`` returns\n the same as ``cmp(x,y)``. If the corresponding element does not\n exist, the shorter sequence is ordered first (for example, ``[1,2] <\n [1,2,3]``).\n\n* Mappings (dictionaries) compare equal if and only if their sorted\n ``(key, value)`` lists compare equal. [4] Outcomes other than\n equality are resolved consistently, but are not otherwise defined.\n [5]\n\n* Most other objects of builtin types compare unequal unless they are\n the same object; the choice whether one object is considered smaller\n or larger than another one is made arbitrarily but consistently\n within one execution of a program.\n\nThe operators ``in`` and ``not in`` test for membership. ``x in s``\nevaluates to true if *x* is a member of *s*, and false otherwise. ``x\nnot in s`` returns the negation of ``x in s``. All built-in sequences\nand set types support this as well as dictionary, for which ``in``\ntests whether a the dictionary has a given key.\n\nFor the list and tuple types, ``x in y`` is true if and only if there\nexists an index *i* such that ``x == y[i]`` is true.\n\nFor the string and bytes types, ``x in y`` is true if and only if *x*\nis a substring of *y*. An equivalent test is ``y.find(x) != -1``.\nEmpty strings are always considered to be a substring of any other\nstring, so ``"" in "abc"`` will return ``True``.\n\nFor user-defined classes which define the ``__contains__()`` method,\n``x in y`` is true if and only if ``y.__contains__(x)`` is true.\n\nFor user-defined classes which do not define ``__contains__()`` and do\ndefine ``__getitem__()``, ``x in y`` is true if and only if there is a\nnon-negative integer index *i* such that ``x == y[i]``, and all lower\ninteger indices do not raise ``IndexError`` exception. (If any other\nexception is raised, it is as if ``in`` raised that exception).\n\nThe operator ``not in`` is defined to have the inverse true value of\n``in``.\n\nThe operators ``is`` and ``is not`` test for object identity: ``x is\ny`` is true if and only if *x* and *y* are the same object. ``x is\nnot y`` yields the inverse truth value.\n', + 'compound': '\nCompound statements\n*******************\n\nCompound statements contain (groups of) other statements; they affect\nor control the execution of those other statements in some way. In\ngeneral, compound statements span multiple lines, although in simple\nincarnations a whole compound statement may be contained in one line.\n\nThe ``if``, ``while`` and ``for`` statements implement traditional\ncontrol flow constructs. ``try`` specifies exception handlers and/or\ncleanup code for a group of statements, while the ``with`` statement\nallows the execution of initialization and finalization code around a\nblock of code. Function and class definitions are also syntactically\ncompound statements.\n\nCompound statements consist of one or more \'clauses.\' A clause\nconsists of a header and a \'suite.\' The clause headers of a\nparticular compound statement are all at the same indentation level.\nEach clause header begins with a uniquely identifying keyword and ends\nwith a colon. A suite is a group of statements controlled by a\nclause. A suite can be one or more semicolon-separated simple\nstatements on the same line as the header, following the header\'s\ncolon, or it can be one or more indented statements on subsequent\nlines. Only the latter form of suite can contain nested compound\nstatements; the following is illegal, mostly because it wouldn\'t be\nclear to which ``if`` clause a following ``else`` clause would belong:\n\n if test1: if test2: print(x)\n\nAlso note that the semicolon binds tighter than the colon in this\ncontext, so that in the following example, either all or none of the\n``print()`` calls are executed:\n\n if x < y < z: print(x); print(y); print(z)\n\nSummarizing:\n\n compound_stmt ::= if_stmt\n | while_stmt\n | for_stmt\n | try_stmt\n | with_stmt\n | funcdef\n | classdef\n | decorated\n suite ::= stmt_list NEWLINE | NEWLINE INDENT statement+ DEDENT\n statement ::= stmt_list NEWLINE | compound_stmt\n stmt_list ::= simple_stmt (";" simple_stmt)* [";"]\n\nNote that statements always end in a ``NEWLINE`` possibly followed by\na ``DEDENT``. Also note that optional continuation clauses always\nbegin with a keyword that cannot start a statement, thus there are no\nambiguities (the \'dangling ``else``\' problem is solved in Python by\nrequiring nested ``if`` statements to be indented).\n\nThe formatting of the grammar rules in the following sections places\neach clause on a separate line for clarity.\n\n\nThe ``if`` statement\n====================\n\nThe ``if`` statement is used for conditional execution:\n\n if_stmt ::= "if" expression ":" suite\n ( "elif" expression ":" suite )*\n ["else" ":" suite]\n\nIt selects exactly one of the suites by evaluating the expressions one\nby one until one is found to be true (see section *Boolean operations*\nfor the definition of true and false); then that suite is executed\n(and no other part of the ``if`` statement is executed or evaluated).\nIf all expressions are false, the suite of the ``else`` clause, if\npresent, is executed.\n\n\nThe ``while`` statement\n=======================\n\nThe ``while`` statement is used for repeated execution as long as an\nexpression is true:\n\n while_stmt ::= "while" expression ":" suite\n ["else" ":" suite]\n\nThis repeatedly tests the expression and, if it is true, executes the\nfirst suite; if the expression is false (which may be the first time\nit is tested) the suite of the ``else`` clause, if present, is\nexecuted and the loop terminates.\n\nA ``break`` statement executed in the first suite terminates the loop\nwithout executing the ``else`` clause\'s suite. A ``continue``\nstatement executed in the first suite skips the rest of the suite and\ngoes back to testing the expression.\n\n\nThe ``for`` statement\n=====================\n\nThe ``for`` statement is used to iterate over the elements of a\nsequence (such as a string, tuple or list) or other iterable object:\n\n for_stmt ::= "for" target_list "in" expression_list ":" suite\n ["else" ":" suite]\n\nThe expression list is evaluated once; it should yield an iterable\nobject. An iterator is created for the result of the\n``expression_list``. The suite is then executed once for each item\nprovided by the iterator, in the order of ascending indices. Each\nitem in turn is assigned to the target list using the standard rules\nfor assignments (see *Assignment statements*), and then the suite is\nexecuted. When the items are exhausted (which is immediately when the\nsequence is empty or an iterator raises a ``StopIteration``\nexception), the suite in the ``else`` clause, if present, is executed,\nand the loop terminates.\n\nA ``break`` statement executed in the first suite terminates the loop\nwithout executing the ``else`` clause\'s suite. A ``continue``\nstatement executed in the first suite skips the rest of the suite and\ncontinues with the next item, or with the ``else`` clause if there was\nno next item.\n\nThe suite may assign to the variable(s) in the target list; this does\nnot affect the next item assigned to it.\n\nNames in the target list are not deleted when the loop is finished,\nbut if the sequence is empty, it will not have been assigned to at all\nby the loop. Hint: the built-in function ``range()`` returns an\niterator of integers suitable to emulate the effect of Pascal\'s ``for\ni := a to b do``; e.g., ``range(3)`` returns the list ``[0, 1, 2]``.\n\nWarning: There is a subtlety when the sequence is being modified by the loop\n (this can only occur for mutable sequences, i.e. lists). An\n internal counter is used to keep track of which item is used next,\n and this is incremented on each iteration. When this counter has\n reached the length of the sequence the loop terminates. This means\n that if the suite deletes the current (or a previous) item from the\n sequence, the next item will be skipped (since it gets the index of\n the current item which has already been treated). Likewise, if the\n suite inserts an item in the sequence before the current item, the\n current item will be treated again the next time through the loop.\n This can lead to nasty bugs that can be avoided by making a\n temporary copy using a slice of the whole sequence, e.g.,\n\n for x in a[:]:\n if x < 0: a.remove(x)\n\n\nThe ``try`` statement\n=====================\n\nThe ``try`` statement specifies exception handlers and/or cleanup code\nfor a group of statements:\n\n try_stmt ::= try1_stmt | try2_stmt\n try1_stmt ::= "try" ":" suite\n ("except" [expression ["as" target]] ":" suite)+\n ["else" ":" suite]\n ["finally" ":" suite]\n try2_stmt ::= "try" ":" suite\n "finally" ":" suite\n\nThe ``except`` clause(s) specify one or more exception handlers. When\nno exception occurs in the ``try`` clause, no exception handler is\nexecuted. When an exception occurs in the ``try`` suite, a search for\nan exception handler is started. This search inspects the except\nclauses in turn until one is found that matches the exception. An\nexpression-less except clause, if present, must be last; it matches\nany exception. For an except clause with an expression, that\nexpression is evaluated, and the clause matches the exception if the\nresulting object is "compatible" with the exception. An object is\ncompatible with an exception if it is the class or a base class of the\nexception object or a tuple containing an item compatible with the\nexception.\n\nIf no except clause matches the exception, the search for an exception\nhandler continues in the surrounding code and on the invocation stack.\n[1]\n\nIf the evaluation of an expression in the header of an except clause\nraises an exception, the original search for a handler is canceled and\na search starts for the new exception in the surrounding code and on\nthe call stack (it is treated as if the entire ``try`` statement\nraised the exception).\n\nWhen a matching except clause is found, the exception is assigned to\nthe target specified after the ``as`` keyword in that except clause,\nif present, and the except clause\'s suite is executed. All except\nclauses must have an executable block. When the end of this block is\nreached, execution continues normally after the entire try statement.\n(This means that if two nested handlers exist for the same exception,\nand the exception occurs in the try clause of the inner handler, the\nouter handler will not handle the exception.)\n\nWhen an exception has been assigned using ``as target``, it is cleared\nat the end of the except clause. This is as if\n\n except E as N:\n foo\n\nwas translated to\n\n except E as N:\n try:\n foo\n finally:\n N = None\n del N\n\nThat means that you have to assign the exception to a different name\nif you want to be able to refer to it after the except clause. The\nreason for this is that with the traceback attached to them,\nexceptions will form a reference cycle with the stack frame, keeping\nall locals in that frame alive until the next garbage collection\noccurs.\n\nBefore an except clause\'s suite is executed, details about the\nexception are stored in the ``sys`` module and can be access via\n``sys.exc_info()``. ``sys.exc_info()`` returns a 3-tuple consisting\nof: ``exc_type``, the exception class; ``exc_value``, the exception\ninstance; ``exc_traceback``, a traceback object (see section *The\nstandard type hierarchy*) identifying the point in the program where\nthe exception occurred. ``sys.exc_info()`` values are restored to\ntheir previous values (before the call) when returning from a function\nthat handled an exception.\n\nThe optional ``else`` clause is executed if and when control flows off\nthe end of the ``try`` clause. [2] Exceptions in the ``else`` clause\nare not handled by the preceding ``except`` clauses.\n\nIf ``finally`` is present, it specifies a \'cleanup\' handler. The\n``try`` clause is executed, including any ``except`` and ``else``\nclauses. If an exception occurs in any of the clauses and is not\nhandled, the exception is temporarily saved. The ``finally`` clause is\nexecuted. If there is a saved exception, it is re-raised at the end\nof the ``finally`` clause. If the ``finally`` clause raises another\nexception or executes a ``return`` or ``break`` statement, the saved\nexception is lost. The exception information is not available to the\nprogram during execution of the ``finally`` clause.\n\nWhen a ``return``, ``break`` or ``continue`` statement is executed in\nthe ``try`` suite of a ``try``...``finally`` statement, the\n``finally`` clause is also executed \'on the way out.\' A ``continue``\nstatement is illegal in the ``finally`` clause. (The reason is a\nproblem with the current implementation --- this restriction may be\nlifted in the future).\n\nAdditional information on exceptions can be found in section\n*Exceptions*, and information on using the ``raise`` statement to\ngenerate exceptions may be found in section *The raise statement*.\n\n\nThe ``with`` statement\n======================\n\nThe ``with`` statement is used to wrap the execution of a block with\nmethods defined by a context manager (see section *With Statement\nContext Managers*). This allows common\n``try``...``except``...``finally`` usage patterns to be encapsulated\nfor convenient reuse.\n\n with_stmt ::= "with" expression ["as" target] ":" suite\n\nThe execution of the ``with`` statement proceeds as follows:\n\n1. The context expression is evaluated to obtain a context manager.\n\n2. The context manager\'s ``__enter__()`` method is invoked.\n\n3. If a target was included in the ``with`` statement, the return\n value from ``__enter__()`` is assigned to it.\n\n Note: The ``with`` statement guarantees that if the ``__enter__()``\n method returns without an error, then ``__exit__()`` will always\n be called. Thus, if an error occurs during the assignment to the\n target list, it will be treated the same as an error occurring\n within the suite would be. See step 5 below.\n\n4. The suite is executed.\n\n5. The context manager\'s ``__exit__()`` method is invoked. If an\n exception caused the suite to be exited, its type, value, and\n traceback are passed as arguments to ``__exit__()``. Otherwise,\n three ``None`` arguments are supplied.\n\n If the suite was exited due to an exception, and the return value\n from the ``__exit__()`` method was false, the exception is\n reraised. If the return value was true, the exception is\n suppressed, and execution continues with the statement following\n the ``with`` statement.\n\n If the suite was exited for any reason other than an exception, the\n return value from ``__exit__()`` is ignored, and execution proceeds\n at the normal location for the kind of exit that was taken.\n\nSee also:\n\n **PEP 0343** - The "with" statement\n The specification, background, and examples for the Python\n ``with`` statement.\n\n\nFunction definitions\n====================\n\nA function definition defines a user-defined function object (see\nsection *The standard type hierarchy*):\n\n funcdef ::= [decorators] "def" funcname "(" [parameter_list] ")" ["->" expression]? ":" suite\n decorators ::= decorator+\n decorator ::= "@" dotted_name ["(" [argument_list [","]] ")"] NEWLINE\n funcdef ::= "def" funcname "(" [parameter_list] ")" ":" suite\n dotted_name ::= identifier ("." identifier)*\n parameter_list ::= (defparameter ",")*\n ( "*" [parameter] ("," defparameter)*\n [, "**" parameter]\n | "**" parameter\n | defparameter [","] )\n parameter ::= identifier [":" expression]\n defparameter ::= parameter ["=" expression]\n funcname ::= identifier\n\nA function definition is an executable statement. Its execution binds\nthe function name in the current local namespace to a function object\n(a wrapper around the executable code for the function). This\nfunction object contains a reference to the current global namespace\nas the global namespace to be used when the function is called.\n\nThe function definition does not execute the function body; this gets\nexecuted only when the function is called.\n\nA function definition may be wrapped by one or more *decorator*\nexpressions. Decorator expressions are evaluated when the function is\ndefined, in the scope that contains the function definition. The\nresult must be a callable, which is invoked with the function object\nas the only argument. The returned value is bound to the function name\ninstead of the function object. Multiple decorators are applied in\nnested fashion. For example, the following code\n\n @f1(arg)\n @f2\n def func(): pass\n\nis equivalent to\n\n def func(): pass\n func = f1(arg)(f2(func))\n\nWhen one or more parameters have the form *parameter* ``=``\n*expression*, the function is said to have "default parameter values."\nFor a parameter with a default value, the corresponding argument may\nbe omitted from a call, in which case the parameter\'s default value is\nsubstituted. If a parameter has a default value, all following\nparameters up until the "``*``" must also have a default value ---\nthis is a syntactic restriction that is not expressed by the grammar.\n\n**Default parameter values are evaluated when the function definition\nis executed.** This means that the expression is evaluated once, when\nthe function is defined, and that that same "pre-computed" value is\nused for each call. This is especially important to understand when a\ndefault parameter is a mutable object, such as a list or a dictionary:\nif the function modifies the object (e.g. by appending an item to a\nlist), the default value is in effect modified. This is generally not\nwhat was intended. A way around this is to use ``None`` as the\ndefault, and explicitly test for it in the body of the function, e.g.:\n\n def whats_on_the_telly(penguin=None):\n if penguin is None:\n penguin = []\n penguin.append("property of the zoo")\n return penguin\n\nFunction call semantics are described in more detail in section\n*Calls*. A function call always assigns values to all parameters\nmentioned in the parameter list, either from position arguments, from\nkeyword arguments, or from default values. If the form\n"``*identifier``" is present, it is initialized to a tuple receiving\nany excess positional parameters, defaulting to the empty tuple. If\nthe form "``**identifier``" is present, it is initialized to a new\ndictionary receiving any excess keyword arguments, defaulting to a new\nempty dictionary. Parameters after "``*``" or "``*identifier``" are\nkeyword-only parameters and may only be passed used keyword arguments.\n\nParameters may have annotations of the form "``: expression``"\nfollowing the parameter name. Any parameter may have an annotation\neven those of the form ``*identifier`` or ``**identifier``. Functions\nmay have "return" annotation of the form "``-> expression``" after the\nparameter list. These annotations can be any valid Python expression\nand are evaluated when the function definition is executed.\nAnnotations may be evaluated in a different order than they appear in\nthe source code. The presence of annotations does not change the\nsemantics of a function. The annotation values are available as\nvalues of a dictionary keyed by the parameters\' names in the\n``__annotations__`` attribute of the function object.\n\nIt is also possible to create anonymous functions (functions not bound\nto a name), for immediate use in expressions. This uses lambda forms,\ndescribed in section *Expression lists*. Note that the lambda form is\nmerely a shorthand for a simplified function definition; a function\ndefined in a "``def``" statement can be passed around or assigned to\nanother name just like a function defined by a lambda form. The\n"``def``" form is actually more powerful since it allows the execution\nof multiple statements and annotations.\n\n**Programmer\'s note:** Functions are first-class objects. A "``def``"\nform executed inside a function definition defines a local function\nthat can be returned or passed around. Free variables used in the\nnested function can access the local variables of the function\ncontaining the def. See section *Naming and binding* for details.\n\n\nClass definitions\n=================\n\nA class definition defines a class object (see section *The standard\ntype hierarchy*):\n\n classdef ::= [decorators] "class" classname [inheritance] ":" suite\n inheritance ::= "(" [expression_list] ")"\n classname ::= identifier\n\nA class definition is an executable statement. It first evaluates the\ninheritance list, if present. Each item in the inheritance list\nshould evaluate to a class object or class type which allows\nsubclassing. The class\'s suite is then executed in a new execution\nframe (see section *Naming and binding*), using a newly created local\nnamespace and the original global namespace. (Usually, the suite\ncontains only function definitions.) When the class\'s suite finishes\nexecution, its execution frame is discarded but its local namespace is\nsaved. A class object is then created using the inheritance list for\nthe base classes and the saved local namespace for the attribute\ndictionary. The class name is bound to this class object in the\noriginal local namespace.\n\nClasses can also be decorated; as with functions,\n\n @f1(arg)\n @f2\n class Foo: pass\n\nis equivalent to\n\n class Foo: pass\n Foo = f1(arg)(f2(Foo))\n\n**Programmer\'s note:** Variables defined in the class definition are\nclass can be set in a method with ``self.name = value``. Both class\nand instance variables are accessible through the notation\n"``self.name``", and an instance variable hides a class variable with\nthe same name when accessed in this way. Class variables can be used\nas defaults for instance variables, but using mutable values there can\nlead to unexpected results. Descriptors can be used to create\ninstance variables with different implementation details.\n\nSee also:\n\n **PEP 3129** - Class Decorators\n\nClass definitions, like function definitions, may be wrapped by one or\nmore *decorator* expressions. The evaluation rules for the decorator\nexpressions are the same as for functions. The result must be a class\nobject, which is then bound to the class name.\n\n-[ Footnotes ]-\n\n[1] The exception is propagated to the invocation stack only if there\n is no ``finally`` clause that negates the exception.\n\n[2] Currently, control "flows off the end" except in the case of an\n exception or the execution of a ``return``, ``continue``, or\n ``break`` statement.\n', + 'context-managers': '\nWith Statement Context Managers\n*******************************\n\nA *context manager* is an object that defines the runtime context to\nbe established when executing a ``with`` statement. The context\nmanager handles the entry into, and the exit from, the desired runtime\ncontext for the execution of the block of code. Context managers are\nnormally invoked using the ``with`` statement (described in section\n*The with statement*), but can also be used by directly invoking their\nmethods.\n\nTypical uses of context managers include saving and restoring various\nkinds of global state, locking and unlocking resources, closing opened\nfiles, etc.\n\nFor more information on context managers, see *Context Manager Types*.\n\nobject.__enter__(self)\n\n Enter the runtime context related to this object. The ``with``\n statement will bind this method\'s return value to the target(s)\n specified in the ``as`` clause of the statement, if any.\n\nobject.__exit__(self, exc_type, exc_value, traceback)\n\n Exit the runtime context related to this object. The parameters\n describe the exception that caused the context to be exited. If the\n context was exited without an exception, all three arguments will\n be ``None``.\n\n If an exception is supplied, and the method wishes to suppress the\n exception (i.e., prevent it from being propagated), it should\n return a true value. Otherwise, the exception will be processed\n normally upon exit from this method.\n\n Note that ``__exit__()`` methods should not reraise the passed-in\n exception; this is the caller\'s responsibility.\n\nSee also:\n\n **PEP 0343** - The "with" statement\n The specification, background, and examples for the Python\n ``with`` statement.\n\n-[ Footnotes ]-\n\n[1] A descriptor can define any combination of ``__get__()``,\n ``__set__()`` and ``__delete__()``. If it does not define\n ``__get__()``, then accessing the attribute even on an instance\n will return the descriptor object itself. If the descriptor\n defines ``__set__()`` and/or ``__delete__()``, it is a data\n descriptor; if it defines neither, it is a non-data descriptor.\n\n[2] For operands of the same type, it is assumed that if the non-\n reflected method (such as ``__add__()``) fails the operation is\n not supported, which is why the reflected method is not called.\n', + 'continue': '\nThe ``continue`` statement\n**************************\n\n continue_stmt ::= "continue"\n\n``continue`` may only occur syntactically nested in a ``for`` or\n``while`` loop, but not nested in a function or class definition or\n``finally`` clause within that loop. It continues with the next cycle\nof the nearest enclosing loop.\n\nWhen ``continue`` passes control out of a ``try`` statement with a\n``finally`` clause, that ``finally`` clause is executed before really\nstarting the next loop cycle.\n', + 'conversions': '\nArithmetic conversions\n**********************\n\nWhen a description of an arithmetic operator below uses the phrase\n"the numeric arguments are converted to a common type," this means\nthat the operator implementation for built-in types works that way:\n\n* If either argument is a complex number, the other is converted to\n complex;\n\n* otherwise, if either argument is a floating point number, the other\n is converted to floating point;\n\n* otherwise, both must be integers and no conversion is necessary.\n\nSome additional rules apply for certain operators (e.g., a string left\nargument to the \'%\' operator). Extensions must define their own\nconversion behavior.\n', + 'customization': '\nBasic customization\n*******************\n\nobject.__new__(cls[, ...])\n\n Called to create a new instance of class *cls*. ``__new__()`` is a\n static method (special-cased so you need not declare it as such)\n that takes the class of which an instance was requested as its\n first argument. The remaining arguments are those passed to the\n object constructor expression (the call to the class). The return\n value of ``__new__()`` should be the new object instance (usually\n an instance of *cls*).\n\n Typical implementations create a new instance of the class by\n invoking the superclass\'s ``__new__()`` method using\n ``super(currentclass, cls).__new__(cls[, ...])`` with appropriate\n arguments and then modifying the newly-created instance as\n necessary before returning it.\n\n If ``__new__()`` returns an instance of *cls*, then the new\n instance\'s ``__init__()`` method will be invoked like\n ``__init__(self[, ...])``, where *self* is the new instance and the\n remaining arguments are the same as were passed to ``__new__()``.\n\n If ``__new__()`` does not return an instance of *cls*, then the new\n instance\'s ``__init__()`` method will not be invoked.\n\n ``__new__()`` is intended mainly to allow subclasses of immutable\n types (like int, str, or tuple) to customize instance creation. It\n is also commonly overridden in custom metaclasses in order to\n customize class creation.\n\nobject.__init__(self[, ...])\n\n Called when the instance is created. The arguments are those\n passed to the class constructor expression. If a base class has an\n ``__init__()`` method, the derived class\'s ``__init__()`` method,\n if any, must explicitly call it to ensure proper initialization of\n the base class part of the instance; for example:\n ``BaseClass.__init__(self, [args...])``. As a special constraint\n on constructors, no value may be returned; doing so will cause a\n ``TypeError`` to be raised at runtime.\n\nobject.__del__(self)\n\n Called when the instance is about to be destroyed. This is also\n called a destructor. If a base class has a ``__del__()`` method,\n the derived class\'s ``__del__()`` method, if any, must explicitly\n call it to ensure proper deletion of the base class part of the\n instance. Note that it is possible (though not recommended!) for\n the ``__del__()`` method to postpone destruction of the instance by\n creating a new reference to it. It may then be called at a later\n time when this new reference is deleted. It is not guaranteed that\n ``__del__()`` methods are called for objects that still exist when\n the interpreter exits.\n\n Note: ``del x`` doesn\'t directly call ``x.__del__()`` --- the former\n decrements the reference count for ``x`` by one, and the latter\n is only called when ``x``\'s reference count reaches zero. Some\n common situations that may prevent the reference count of an\n object from going to zero include: circular references between\n objects (e.g., a doubly-linked list or a tree data structure with\n parent and child pointers); a reference to the object on the\n stack frame of a function that caught an exception (the traceback\n stored in ``sys.exc_info()[2]`` keeps the stack frame alive); or\n a reference to the object on the stack frame that raised an\n unhandled exception in interactive mode (the traceback stored in\n ``sys.last_traceback`` keeps the stack frame alive). The first\n situation can only be remedied by explicitly breaking the cycles;\n the latter two situations can be resolved by storing ``None`` in\n ``sys.last_traceback``. Circular references which are garbage are\n detected when the option cycle detector is enabled (it\'s on by\n default), but can only be cleaned up if there are no Python-\n level ``__del__()`` methods involved. Refer to the documentation\n for the ``gc`` module for more information about how\n ``__del__()`` methods are handled by the cycle detector,\n particularly the description of the ``garbage`` value.\n\n Warning: Due to the precarious circumstances under which ``__del__()``\n methods are invoked, exceptions that occur during their execution\n are ignored, and a warning is printed to ``sys.stderr`` instead.\n Also, when ``__del__()`` is invoked in response to a module being\n deleted (e.g., when execution of the program is done), other\n globals referenced by the ``__del__()`` method may already have\n been deleted. For this reason, ``__del__()`` methods should do\n the absolute minimum needed to maintain external invariants.\n Starting with version 1.5, Python guarantees that globals whose\n name begins with a single underscore are deleted from their\n module before other globals are deleted; if no other references\n to such globals exist, this may help in assuring that imported\n modules are still available at the time when the ``__del__()``\n method is called.\n\nobject.__repr__(self)\n\n Called by the ``repr()`` built-in function and by string\n conversions (reverse quotes) to compute the "official" string\n representation of an object. If at all possible, this should look\n like a valid Python expression that could be used to recreate an\n object with the same value (given an appropriate environment). If\n this is not possible, a string of the form ``<...some useful\n description...>`` should be returned. The return value must be a\n string object. If a class defines ``__repr__()`` but not\n ``__str__()``, then ``__repr__()`` is also used when an "informal"\n string representation of instances of that class is required.\n\n This is typically used for debugging, so it is important that the\n representation is information-rich and unambiguous.\n\nobject.__str__(self)\n\n Called by the ``str()`` built-in function and by the ``print()``\n function to compute the "informal" string representation of an\n object. This differs from ``__repr__()`` in that it does not have\n to be a valid Python expression: a more convenient or concise\n representation may be used instead. The return value must be a\n string object.\n\nobject.__format__(self, format_spec)\n\n Called by the ``format()`` built-in function (and by extension, the\n ``format()`` method of class ``str``) to produce a "formatted"\n string representation of an object. The ``format_spec`` argument is\n a string that contains a description of the formatting options\n desired. The interpretation of the ``format_spec`` argument is up\n to the type implementing ``__format__()``, however most classes\n will either delegate formatting to one of the built-in types, or\n use a similar formatting option syntax.\n\n See *Format Specification Mini-Language* for a description of the\n standard formatting syntax.\n\n The return value must be a string object.\n\nobject.__lt__(self, other)\nobject.__le__(self, other)\nobject.__eq__(self, other)\nobject.__ne__(self, other)\nobject.__gt__(self, other)\nobject.__ge__(self, other)\n\n These are the so-called "rich comparison" methods, and are called\n for comparison operators in preference to ``__cmp__()`` below. The\n correspondence between operator symbols and method names is as\n follows: ``xy`` calls ``x.__gt__(y)``, and ``x>=y`` calls\n ``x.__ge__(y)``.\n\n A rich comparison method may return the singleton\n ``NotImplemented`` if it does not implement the operation for a\n given pair of arguments. By convention, ``False`` and ``True`` are\n returned for a successful comparison. However, these methods can\n return any value, so if the comparison operator is used in a\n Boolean context (e.g., in the condition of an ``if`` statement),\n Python will call ``bool()`` on the value to determine if the result\n is true or false.\n\n There are no implied relationships among the comparison operators.\n The truth of ``x==y`` does not imply that ``x!=y`` is false.\n Accordingly, when defining ``__eq__()``, one should also define\n ``__ne__()`` so that the operators will behave as expected. See\n the paragraph on ``__hash__()`` for some important notes on\n creating *hashable* objects which support custom comparison\n operations and are usable as dictionary keys.\n\n There are no swapped-argument versions of these methods (to be used\n when the left argument does not support the operation but the right\n argument does); rather, ``__lt__()`` and ``__gt__()`` are each\n other\'s reflection, ``__le__()`` and ``__ge__()`` are each other\'s\n reflection, and ``__eq__()`` and ``__ne__()`` are their own\n reflection.\n\n Arguments to rich comparison methods are never coerced.\n\nobject.__cmp__(self, other)\n\n Called by comparison operations if rich comparison (see above) is\n not defined. Should return a negative integer if ``self < other``,\n zero if ``self == other``, a positive integer if ``self > other``.\n If no ``__cmp__()``, ``__eq__()`` or ``__ne__()`` operation is\n defined, class instances are compared by object identity\n ("address"). See also the description of ``__hash__()`` for some\n important notes on creating *hashable* objects which support custom\n comparison operations and are usable as dictionary keys.\n\nobject.__hash__(self)\n\n Called for the key object for dictionary operations, and by the\n built-in function ``hash()``. Should return an integer usable as a\n hash value for dictionary operations. The only required property\n is that objects which compare equal have the same hash value; it is\n advised to somehow mix together (e.g., using exclusive or) the hash\n values for the components of the object that also play a part in\n comparison of objects.\n\n If a class does not define a ``__cmp__()`` or ``__eq__()`` method\n it should not define a ``__hash__()`` operation either; if it\n defines ``__cmp__()`` or ``__eq__()`` but not ``__hash__()``, its\n instances will not be usable as dictionary keys. If a class\n defines mutable objects and implements a ``__cmp__()`` or\n ``__eq__()`` method, it should not implement ``__hash__()``, since\n the dictionary implementation requires that a key\'s hash value is\n immutable (if the object\'s hash value changes, it will be in the\n wrong hash bucket).\n\n User-defined classes have ``__cmp__()`` and ``__hash__()`` methods\n by default; with them, all objects compare unequal and\n ``x.__hash__()`` returns ``id(x)``.\n\nobject.__bool__(self)\n\n Called to implement truth value testing, and the built-in operation\n ``bool()``; should return ``False`` or ``True``. When this method\n is not defined, ``__len__()`` is called, if it is defined (see\n below) and ``True`` is returned when the length is not zero. If a\n class defines neither ``__len__()`` nor ``__bool__()``, all its\n instances are considered true.\n', + 'debugger': '\n``pdb`` --- The Python Debugger\n*******************************\n\nThe module ``pdb`` defines an interactive source code debugger for\nPython programs. It supports setting (conditional) breakpoints and\nsingle stepping at the source line level, inspection of stack frames,\nsource code listing, and evaluation of arbitrary Python code in the\ncontext of any stack frame. It also supports post-mortem debugging\nand can be called under program control.\n\nThe debugger is extensible --- it is actually defined as the class\n``Pdb``. This is currently undocumented but easily understood by\nreading the source. The extension interface uses the modules ``bdb``\n(undocumented) and ``cmd``.\n\nThe debugger\'s prompt is ``(Pdb)``. Typical usage to run a program\nunder control of the debugger is:\n\n >>> import pdb\n >>> import mymodule\n >>> pdb.run(\'mymodule.test()\')\n > (0)?()\n (Pdb) continue\n > (1)?()\n (Pdb) continue\n NameError: \'spam\'\n > (1)?()\n (Pdb)\n\n``pdb.py`` can also be invoked as a script to debug other scripts.\nFor example:\n\n python -m pdb myscript.py\n\nWhen invoked as a script, pdb will automatically enter post-mortem\ndebugging if the program being debugged exits abnormally. After post-\nmortem debugging (or after normal exit of the program), pdb will\nrestart the program. Automatic restarting preserves pdb\'s state (such\nas breakpoints) and in most cases is more useful than quitting the\ndebugger upon program\'s exit.\n\nTypical usage to inspect a crashed program is:\n\n >>> import pdb\n >>> import mymodule\n >>> mymodule.test()\n Traceback (most recent call last):\n File "", line 1, in ?\n File "./mymodule.py", line 4, in test\n test2()\n File "./mymodule.py", line 3, in test2\n print(spam)\n NameError: spam\n >>> pdb.pm()\n > ./mymodule.py(3)test2()\n -> print(spam)\n (Pdb)\n\nThe module defines the following functions; each enters the debugger\nin a slightly different way:\n\npdb.run(statement[, globals[, locals]])\n\n Execute the *statement* (given as a string) under debugger control.\n The debugger prompt appears before any code is executed; you can\n set breakpoints and type ``continue``, or you can step through the\n statement using ``step`` or ``next`` (all these commands are\n explained below). The optional *globals* and *locals* arguments\n specify the environment in which the code is executed; by default\n the dictionary of the module ``__main__`` is used. (See the\n explanation of the built-in ``exec()`` or ``eval()`` functions.)\n\npdb.runeval(expression[, globals[, locals]])\n\n Evaluate the *expression* (given as a string) under debugger\n control. When ``runeval()`` returns, it returns the value of the\n expression. Otherwise this function is similar to ``run()``.\n\npdb.runcall(function[, argument, ...])\n\n Call the *function* (a function or method object, not a string)\n with the given arguments. When ``runcall()`` returns, it returns\n whatever the function call returned. The debugger prompt appears\n as soon as the function is entered.\n\npdb.set_trace()\n\n Enter the debugger at the calling stack frame. This is useful to\n hard-code a breakpoint at a given point in a program, even if the\n code is not otherwise being debugged (e.g. when an assertion\n fails).\n\npdb.post_mortem([traceback])\n\n Enter post-mortem debugging of the given *traceback* object. If no\n *traceback* is given, it uses the one of the exception that is\n currently being handled (an exception must be being handled if the\n default is to be used).\n\npdb.pm()\n\n Enter post-mortem debugging of the traceback found in\n ``sys.last_traceback``.\n', + 'del': '\nThe ``del`` statement\n*********************\n\n del_stmt ::= "del" target_list\n\nDeletion is recursively defined very similar to the way assignment is\ndefined. Rather that spelling it out in full details, here are some\nhints.\n\nDeletion of a target list recursively deletes each target, from left\nto right.\n\nDeletion of a name removes the binding of that name from the local or\nglobal namespace, depending on whether the name occurs in a ``global``\nstatement in the same code block. If the name is unbound, a\n``NameError`` exception will be raised.\n\nIt is illegal to delete a name from the local namespace if it occurs\nas a free variable in a nested block.\n\nDeletion of attribute references, subscriptions and slicings is passed\nto the primary object involved; deletion of a slicing is in general\nequivalent to assignment of an empty slice of the right type (but even\nthis is determined by the sliced object).\n', + 'dict': '\nDictionary displays\n*******************\n\nA dictionary display is a possibly empty series of key/datum pairs\nenclosed in curly braces:\n\n dict_display ::= "{" [key_datum_list | dict_comprehension] "}"\n key_datum_list ::= key_datum ("," key_datum)* [","]\n key_datum ::= expression ":" expression\n dict_comprehension ::= expression ":" expression comp_for\n\nA dictionary display yields a new dictionary object.\n\nIf a comma-separated sequence of key/datum pairs is given, they are\nevaluated from left to right to define the entries of the dictionary:\neach key object is used as a key into the dictionary to store the\ncorresponding datum. This means that you can specify the same key\nmultiple times in the key/datum list, and the final dictionary\'s value\nfor that key will be the last one given.\n\nA dict comprehension, in contrast to list and set comprehensions,\nneeds two expressions separated with a colon followed by the usual\n"for" and "if" clauses. When the comprehension is run, the resulting\nkey and value elements are inserted in the new dictionary in the order\nthey are produced.\n\nRestrictions on the types of the key values are listed earlier in\nsection *The standard type hierarchy*. (To summarize, the key type\nshould be *hashable*, which excludes all mutable objects.) Clashes\nbetween duplicate keys are not detected; the last datum (textually\nrightmost in the display) stored for a given key value prevails.\n', + 'dynamic-features': '\nInteraction with dynamic features\n*********************************\n\nThere are several cases where Python statements are illegal when used\nin conjunction with nested scopes that contain free variables.\n\nIf a variable is referenced in an enclosing scope, it is illegal to\ndelete the name. An error will be reported at compile time.\n\nIf the wild card form of import --- ``import *`` --- is used in a\nfunction and the function contains or is a nested block with free\nvariables, the compiler will raise a ``SyntaxError``.\n\nThe ``eval()`` and ``exec()`` functions do not have access to the full\nenvironment for resolving names. Names may be resolved in the local\nand global namespaces of the caller. Free variables are not resolved\nin the nearest enclosing namespace, but in the global namespace. [1]\nThe ``exec()`` and ``eval()`` functions have optional arguments to\noverride the global and local namespace. If only one namespace is\nspecified, it is used for both.\n', + 'else': '\nThe ``if`` statement\n********************\n\nThe ``if`` statement is used for conditional execution:\n\n if_stmt ::= "if" expression ":" suite\n ( "elif" expression ":" suite )*\n ["else" ":" suite]\n\nIt selects exactly one of the suites by evaluating the expressions one\nby one until one is found to be true (see section *Boolean operations*\nfor the definition of true and false); then that suite is executed\n(and no other part of the ``if`` statement is executed or evaluated).\nIf all expressions are false, the suite of the ``else`` clause, if\npresent, is executed.\n', + 'exceptions': '\nExceptions\n**********\n\nExceptions are a means of breaking out of the normal flow of control\nof a code block in order to handle errors or other exceptional\nconditions. An exception is *raised* at the point where the error is\ndetected; it may be *handled* by the surrounding code block or by any\ncode block that directly or indirectly invoked the code block where\nthe error occurred.\n\nThe Python interpreter raises an exception when it detects a run-time\nerror (such as division by zero). A Python program can also\nexplicitly raise an exception with the ``raise`` statement. Exception\nhandlers are specified with the ``try`` ... ``except`` statement. The\n``finally`` clause of such a statement can be used to specify cleanup\ncode which does not handle the exception, but is executed whether an\nexception occurred or not in the preceding code.\n\nPython uses the "termination" model of error handling: an exception\nhandler can find out what happened and continue execution at an outer\nlevel, but it cannot repair the cause of the error and retry the\nfailing operation (except by re-entering the offending piece of code\nfrom the top).\n\nWhen an exception is not handled at all, the interpreter terminates\nexecution of the program, or returns to its interactive main loop. In\neither case, it prints a stack backtrace, except when the exception is\n``SystemExit``.\n\nExceptions are identified by class instances. The ``except`` clause\nis selected depending on the class of the instance: it must reference\nthe class of the instance or a base class thereof. The instance can\nbe received by the handler and can carry additional information about\nthe exceptional condition.\n\nWarning: Exception messages are not part of the Python API. Their contents\n may change from one version of Python to the next without warning\n and should not be relied on by code which will run under multiple\n versions of the interpreter.\n\nSee also the description of the ``try`` statement in section *The try\nstatement* and ``raise`` statement in section *The raise statement*.\n\n-[ Footnotes ]-\n\n[1] This limitation occurs because the code that is executed by these\n operations is not available at the time the module is compiled.\n', + 'execmodel': '\nExecution model\n***************\n\n\nNaming and binding\n==================\n\n*Names* refer to objects. Names are introduced by name binding\noperations. Each occurrence of a name in the program text refers to\nthe *binding* of that name established in the innermost function block\ncontaining the use.\n\nA *block* is a piece of Python program text that is executed as a\nunit. The following are blocks: a module, a function body, and a class\ndefinition. Each command typed interactively is a block. A script\nfile (a file given as standard input to the interpreter or specified\non the interpreter command line the first argument) is a code block.\nA script command (a command specified on the interpreter command line\nwith the \'**-c**\' option) is a code block. The string argument passed\nto the built-in functions ``eval()`` and ``exec()`` is a code block.\n\nA code block is executed in an *execution frame*. A frame contains\nsome administrative information (used for debugging) and determines\nwhere and how execution continues after the code block\'s execution has\ncompleted.\n\nA *scope* defines the visibility of a name within a block. If a local\nvariable is defined in a block, its scope includes that block. If the\ndefinition occurs in a function block, the scope extends to any blocks\ncontained within the defining one, unless a contained block introduces\na different binding for the name. The scope of names defined in a\nclass block is limited to the class block; it does not extend to the\ncode blocks of methods -- this includes generator expressions since\nthey are implemented using a function scope. This means that the\nfollowing will fail:\n\n class A:\n a = 42\n b = list(a + i for i in range(10))\n\nWhen a name is used in a code block, it is resolved using the nearest\nenclosing scope. The set of all such scopes visible to a code block\nis called the block\'s *environment*.\n\nIf a name is bound in a block, it is a local variable of that block,\nunless declared as ``nonlocal``. If a name is bound at the module\nlevel, it is a global variable. (The variables of the module code\nblock are local and global.) If a variable is used in a code block\nbut not defined there, it is a *free variable*.\n\nWhen a name is not found at all, a ``NameError`` exception is raised.\nIf the name refers to a local variable that has not been bound, a\n``UnboundLocalError`` exception is raised. ``UnboundLocalError`` is a\nsubclass of ``NameError``.\n\nThe following constructs bind names: formal parameters to functions,\n``import`` statements, class and function definitions (these bind the\nclass or function name in the defining block), and targets that are\nidentifiers if occurring in an assignment, ``for`` loop header, or in\nthe second position of an ``except`` clause header. The ``import``\nstatement of the form "``from ...import *``" binds all names defined\nin the imported module, except those beginning with an underscore.\nThis form may only be used at the module level.\n\nA target occurring in a ``del`` statement is also considered bound for\nthis purpose (though the actual semantics are to unbind the name). It\nis illegal to unbind a name that is referenced by an enclosing scope;\nthe compiler will report a ``SyntaxError``.\n\nEach assignment or import statement occurs within a block defined by a\nclass or function definition or at the module level (the top-level\ncode block).\n\nIf a name binding operation occurs anywhere within a code block, all\nuses of the name within the block are treated as references to the\ncurrent block. This can lead to errors when a name is used within a\nblock before it is bound. This rule is subtle. Python lacks\ndeclarations and allows name binding operations to occur anywhere\nwithin a code block. The local variables of a code block can be\ndetermined by scanning the entire text of the block for name binding\noperations.\n\nIf the ``global`` statement occurs within a block, all uses of the\nname specified in the statement refer to the binding of that name in\nthe top-level namespace. Names are resolved in the top-level\nnamespace by searching the global namespace, i.e. the namespace of the\nmodule containing the code block, and the builtin namespace, the\nnamespace of the module ``builtins``. The global namespace is\nsearched first. If the name is not found there, the builtin namespace\nis searched. The global statement must precede all uses of the name.\n\nThe built-in namespace associated with the execution of a code block\nis actually found by looking up the name ``__builtins__`` in its\nglobal namespace; this should be a dictionary or a module (in the\nlatter case the module\'s dictionary is used). By default, when in the\n``__main__`` module, ``__builtins__`` is the built-in module\n``builtins``; when in any other module, ``__builtins__`` is an alias\nfor the dictionary of the ``builtins`` module itself.\n``__builtins__`` can be set to a user-created dictionary to create a\nweak form of restricted execution.\n\nNote: Users should not touch ``__builtins__``; it is strictly an\n implementation detail. Users wanting to override values in the\n built-in namespace should ``import`` the ``builtins`` module and\n modify its attributes appropriately.\n\nThe namespace for a module is automatically created the first time a\nmodule is imported. The main module for a script is always called\n``__main__``.\n\nThe global statement has the same scope as a name binding operation in\nthe same block. If the nearest enclosing scope for a free variable\ncontains a global statement, the free variable is treated as a global.\n\nA class definition is an executable statement that may use and define\nnames. These references follow the normal rules for name resolution.\nThe namespace of the class definition becomes the attribute dictionary\nof the class. Names defined at the class scope are not visible in\nmethods.\n\n\nInteraction with dynamic features\n---------------------------------\n\nThere are several cases where Python statements are illegal when used\nin conjunction with nested scopes that contain free variables.\n\nIf a variable is referenced in an enclosing scope, it is illegal to\ndelete the name. An error will be reported at compile time.\n\nIf the wild card form of import --- ``import *`` --- is used in a\nfunction and the function contains or is a nested block with free\nvariables, the compiler will raise a ``SyntaxError``.\n\nThe ``eval()`` and ``exec()`` functions do not have access to the full\nenvironment for resolving names. Names may be resolved in the local\nand global namespaces of the caller. Free variables are not resolved\nin the nearest enclosing namespace, but in the global namespace. [1]\nThe ``exec()`` and ``eval()`` functions have optional arguments to\noverride the global and local namespace. If only one namespace is\nspecified, it is used for both.\n\n\nExceptions\n==========\n\nExceptions are a means of breaking out of the normal flow of control\nof a code block in order to handle errors or other exceptional\nconditions. An exception is *raised* at the point where the error is\ndetected; it may be *handled* by the surrounding code block or by any\ncode block that directly or indirectly invoked the code block where\nthe error occurred.\n\nThe Python interpreter raises an exception when it detects a run-time\nerror (such as division by zero). A Python program can also\nexplicitly raise an exception with the ``raise`` statement. Exception\nhandlers are specified with the ``try`` ... ``except`` statement. The\n``finally`` clause of such a statement can be used to specify cleanup\ncode which does not handle the exception, but is executed whether an\nexception occurred or not in the preceding code.\n\nPython uses the "termination" model of error handling: an exception\nhandler can find out what happened and continue execution at an outer\nlevel, but it cannot repair the cause of the error and retry the\nfailing operation (except by re-entering the offending piece of code\nfrom the top).\n\nWhen an exception is not handled at all, the interpreter terminates\nexecution of the program, or returns to its interactive main loop. In\neither case, it prints a stack backtrace, except when the exception is\n``SystemExit``.\n\nExceptions are identified by class instances. The ``except`` clause\nis selected depending on the class of the instance: it must reference\nthe class of the instance or a base class thereof. The instance can\nbe received by the handler and can carry additional information about\nthe exceptional condition.\n\nWarning: Exception messages are not part of the Python API. Their contents\n may change from one version of Python to the next without warning\n and should not be relied on by code which will run under multiple\n versions of the interpreter.\n\nSee also the description of the ``try`` statement in section *The try\nstatement* and ``raise`` statement in section *The raise statement*.\n\n-[ Footnotes ]-\n\n[1] This limitation occurs because the code that is executed by these\n operations is not available at the time the module is compiled.\n', + 'exprlists': '\nExpression lists\n****************\n\n expression_list ::= expression ( "," expression )* [","]\n\nAn expression list containing at least one comma yields a tuple. The\nlength of the tuple is the number of expressions in the list. The\nexpressions are evaluated from left to right.\n\nThe trailing comma is required only to create a single tuple (a.k.a. a\n*singleton*); it is optional in all other cases. A single expression\nwithout a trailing comma doesn\'t create a tuple, but rather yields the\nvalue of that expression. (To create an empty tuple, use an empty pair\nof parentheses: ``()``.)\n', + 'floating': '\nFloating point literals\n***********************\n\nFloating point literals are described by the following lexical\ndefinitions:\n\n floatnumber ::= pointfloat | exponentfloat\n pointfloat ::= [intpart] fraction | intpart "."\n exponentfloat ::= (intpart | pointfloat) exponent\n intpart ::= digit+\n fraction ::= "." digit+\n exponent ::= ("e" | "E") ["+" | "-"] digit+\n\nNote that the integer and exponent parts are always interpreted using\nradix 10. For example, ``077e010`` is legal, and denotes the same\nnumber as ``77e10``. The allowed range of floating point literals is\nimplementation-dependent. Some examples of floating point literals:\n\n 3.14 10. .001 1e100 3.14e-10 0e0\n\nNote that numeric literals do not include a sign; a phrase like ``-1``\nis actually an expression composed of the unary operator ``-`` and the\nliteral ``1``.\n', + 'for': '\nThe ``for`` statement\n*********************\n\nThe ``for`` statement is used to iterate over the elements of a\nsequence (such as a string, tuple or list) or other iterable object:\n\n for_stmt ::= "for" target_list "in" expression_list ":" suite\n ["else" ":" suite]\n\nThe expression list is evaluated once; it should yield an iterable\nobject. An iterator is created for the result of the\n``expression_list``. The suite is then executed once for each item\nprovided by the iterator, in the order of ascending indices. Each\nitem in turn is assigned to the target list using the standard rules\nfor assignments (see *Assignment statements*), and then the suite is\nexecuted. When the items are exhausted (which is immediately when the\nsequence is empty or an iterator raises a ``StopIteration``\nexception), the suite in the ``else`` clause, if present, is executed,\nand the loop terminates.\n\nA ``break`` statement executed in the first suite terminates the loop\nwithout executing the ``else`` clause\'s suite. A ``continue``\nstatement executed in the first suite skips the rest of the suite and\ncontinues with the next item, or with the ``else`` clause if there was\nno next item.\n\nThe suite may assign to the variable(s) in the target list; this does\nnot affect the next item assigned to it.\n\nNames in the target list are not deleted when the loop is finished,\nbut if the sequence is empty, it will not have been assigned to at all\nby the loop. Hint: the built-in function ``range()`` returns an\niterator of integers suitable to emulate the effect of Pascal\'s ``for\ni := a to b do``; e.g., ``range(3)`` returns the list ``[0, 1, 2]``.\n\nWarning: There is a subtlety when the sequence is being modified by the loop\n (this can only occur for mutable sequences, i.e. lists). An\n internal counter is used to keep track of which item is used next,\n and this is incremented on each iteration. When this counter has\n reached the length of the sequence the loop terminates. This means\n that if the suite deletes the current (or a previous) item from the\n sequence, the next item will be skipped (since it gets the index of\n the current item which has already been treated). Likewise, if the\n suite inserts an item in the sequence before the current item, the\n current item will be treated again the next time through the loop.\n This can lead to nasty bugs that can be avoided by making a\n temporary copy using a slice of the whole sequence, e.g.,\n\n for x in a[:]:\n if x < 0: a.remove(x)\n', + 'formatstrings': '\nFormat String Syntax\n********************\n\nThe ``str.format()`` method and the ``Formatter`` class share the same\nsyntax for format strings (although in the case of ``Formatter``,\nsubclasses can define their own format string syntax.)\n\nFormat strings contain "replacement fields" surrounded by curly braces\n``{}``. Anything that is not contained in braces is considered literal\ntext, which is copied unchanged to the output. If you need to include\na brace character in the literal text, it can be escaped by doubling:\n``{{`` and ``}}``.\n\nThe grammar for a replacement field is as follows:\n\n replacement_field ::= "{" field_name ["!" conversion] [":" format_spec] "}"\n field_name ::= (identifier | integer) ("." attribute_name | "[" element_index "]")*\n attribute_name ::= identifier\n element_index ::= integer\n conversion ::= "r" | "s"\n format_spec ::= \n\nIn less formal terms, the replacement field starts with a\n*field_name*, which can either be a number (for a positional\nargument), or an identifier (for keyword arguments). Following this\nis an optional *conversion* field, which is preceded by an exclamation\npoint ``\'!\'``, and a *format_spec*, which is preceded by a colon\n``\':\'``.\n\nThe *field_name* itself begins with either a number or a keyword. If\nit\'s a number, it refers to a positional argument, and if it\'s a\nkeyword it refers to a named keyword argument. This can be followed\nby any number of index or attribute expressions. An expression of the\nform ``\'.name\'`` selects the named attribute using ``getattr()``,\nwhile an expression of the form ``\'[index]\'`` does an index lookup\nusing ``__getitem__()``.\n\nSome simple format string examples:\n\n "First, thou shalt count to {0}" # References first positional argument\n "My quest is {name}" # References keyword argument \'name\'\n "Weight in tons {0.weight}" # \'weight\' attribute of first positional arg\n "Units destroyed: {players[0]}" # First element of keyword argument \'players\'.\n\nThe *conversion* field causes a type coercion before formatting.\nNormally, the job of formatting a value is done by the\n``__format__()`` method of the value itself. However, in some cases\nit is desirable to force a type to be formatted as a string,\noverriding its own definition of formatting. By converting the value\nto a string before calling ``__format__()``, the normal formatting\nlogic is bypassed.\n\nTwo conversion flags are currently supported: ``\'!s\'`` which calls\n``str()`` on the value, and ``\'!r\'`` which calls ``repr()``.\n\nSome examples:\n\n "Harold\'s a clever {0!s}" # Calls str() on the argument first\n "Bring out the holy {name!r}" # Calls repr() on the argument first\n\nThe *format_spec* field contains a specification of how the value\nshould be presented, including such details as field width, alignment,\npadding, decimal precision and so on. Each value type can define it\'s\nown "formatting mini-language" or interpretation of the *format_spec*.\n\nMost built-in types support a common formatting mini-language, which\nis described in the next section.\n\nA *format_spec* field can also include nested replacement fields\nwithin it. These nested replacement fields can contain only a field\nname; conversion flags and format specifications are not allowed. The\nreplacement fields within the format_spec are substituted before the\n*format_spec* string is interpreted. This allows the formatting of a\nvalue to be dynamically specified.\n\nFor example, suppose you wanted to have a replacement field whose\nfield width is determined by another variable:\n\n "A man with two {0:{1}}".format("noses", 10)\n\nThis would first evaluate the inner replacement field, making the\nformat string effectively:\n\n "A man with two {0:10}"\n\nThen the outer replacement field would be evaluated, producing:\n\n "noses "\n\nWhich is subsitituted into the string, yielding:\n\n "A man with two noses "\n\n(The extra space is because we specified a field width of 10, and\nbecause left alignment is the default for strings.)\n\n\nFormat Specification Mini-Language\n==================================\n\n"Format specifications" are used within replacement fields contained\nwithin a format string to define how individual values are presented\n(see *Format String Syntax*.) They can also be passed directly to the\nbuiltin ``format()`` function. Each formattable type may define how\nthe format specification is to be interpreted.\n\nMost built-in types implement the following options for format\nspecifications, although some of the formatting options are only\nsupported by the numeric types.\n\nA general convention is that an empty format string (``""``) produces\nthe same result as if you had called ``str()`` on the value.\n\nThe general form of a *standard format specifier* is:\n\n format_spec ::= [[fill]align][sign][0][width][.precision][type]\n fill ::= \n align ::= "<" | ">" | "=" | "^"\n sign ::= "+" | "-" | " "\n width ::= integer\n precision ::= integer\n type ::= "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g" | "G" | "n" | "o" | "x" | "X" | "%"\n\nThe *fill* character can be any character other than \'}\' (which\nsignifies the end of the field). The presence of a fill character is\nsignaled by the *next* character, which must be one of the alignment\noptions. If the second character of *format_spec* is not a valid\nalignment option, then it is assumed that both the fill character and\nthe alignment option are absent.\n\nThe meaning of the various alignment options is as follows:\n\n +-----------+------------------------------------------------------------+\n | Option | Meaning |\n +===========+============================================================+\n | ``\'<\'`` | Forces the field to be left-aligned within the available |\n | | space (This is the default.) |\n +-----------+------------------------------------------------------------+\n | ``\'>\'`` | Forces the field to be right-aligned within the available |\n | | space. |\n +-----------+------------------------------------------------------------+\n | ``\'=\'`` | Forces the padding to be placed after the sign (if any) |\n | | but before the digits. This is used for printing fields |\n | | in the form \'+000000120\'. This alignment option is only |\n | | valid for numeric types. |\n +-----------+------------------------------------------------------------+\n | ``\'^\'`` | Forces the field to be centered within the available |\n | | space. |\n +-----------+------------------------------------------------------------+\n\nNote that unless a minimum field width is defined, the field width\nwill always be the same size as the data to fill it, so that the\nalignment option has no meaning in this case.\n\nThe *sign* option is only valid for number types, and can be one of\nthe following:\n\n +-----------+------------------------------------------------------------+\n | Option | Meaning |\n +===========+============================================================+\n | ``\'+\'`` | indicates that a sign should be used for both positive as |\n | | well as negative numbers. |\n +-----------+------------------------------------------------------------+\n | ``\'-\'`` | indicates that a sign should be used only for negative |\n | | numbers (this is the default behavior). |\n +-----------+------------------------------------------------------------+\n | space | indicates that a leading space should be used on positive |\n | | numbers, and a minus sign on negative numbers. |\n +-----------+------------------------------------------------------------+\n\n*width* is a decimal integer defining the minimum field width. If not\nspecified, then the field width will be determined by the content.\n\nIf the *width* field is preceded by a zero (``\'0\'``) character, this\nenables zero-padding. This is equivalent to an *alignment* type of\n``\'=\'`` and a *fill* character of ``\'0\'``.\n\nThe *precision* is a decimal number indicating how many digits should\nbe displayed after the decimal point for a floating point value. For\nnon-number types the field indicates the maximum field size - in other\nwords, how many characters will be used from the field content. The\n*precision* is ignored for integer values.\n\nFinally, the *type* determines how the data should be presented.\n\nThe available integer presentation types are:\n\n +-----------+------------------------------------------------------------+\n | Type | Meaning |\n +===========+============================================================+\n | ``\'b\'`` | Binary. Outputs the number in base 2. |\n +-----------+------------------------------------------------------------+\n | ``\'c\'`` | Character. Converts the integer to the corresponding |\n | | unicode character before printing. |\n +-----------+------------------------------------------------------------+\n | ``\'d\'`` | Decimal Integer. Outputs the number in base 10. |\n +-----------+------------------------------------------------------------+\n | ``\'o\'`` | Octal format. Outputs the number in base 8. |\n +-----------+------------------------------------------------------------+\n | ``\'x\'`` | Hex format. Outputs the number in base 16, using lower- |\n | | case letters for the digits above 9. |\n +-----------+------------------------------------------------------------+\n | ``\'X\'`` | Hex format. Outputs the number in base 16, using upper- |\n | | case letters for the digits above 9. |\n +-----------+------------------------------------------------------------+\n | ``\'n\'`` | Number. This is the same as ``\'d\'``, except that it uses |\n | | the current locale setting to insert the appropriate |\n | | number separator characters. |\n +-----------+------------------------------------------------------------+\n | None | the same as ``\'d\'`` |\n +-----------+------------------------------------------------------------+\n\nThe available presentation types for floating point and decimal values\nare:\n\n +-----------+------------------------------------------------------------+\n | Type | Meaning |\n +===========+============================================================+\n | ``\'e\'`` | Exponent notation. Prints the number in scientific |\n | | notation using the letter \'e\' to indicate the exponent. |\n +-----------+------------------------------------------------------------+\n | ``\'E\'`` | Exponent notation. Same as ``\'e\'`` except it uses an upper |\n | | case \'E\' as the separator character. |\n +-----------+------------------------------------------------------------+\n | ``\'f\'`` | Fixed point. Displays the number as a fixed-point number. |\n +-----------+------------------------------------------------------------+\n | ``\'F\'`` | Fixed point. Same as ``\'f\'``. |\n +-----------+------------------------------------------------------------+\n | ``\'g\'`` | General format. This prints the number as a fixed-point |\n | | number, unless the number is too large, in which case it |\n | | switches to ``\'e\'`` exponent notation. |\n +-----------+------------------------------------------------------------+\n | ``\'G\'`` | General format. Same as ``\'g\'`` except switches to ``\'E\'`` |\n | | if the number gets to large. |\n +-----------+------------------------------------------------------------+\n | ``\'n\'`` | Number. This is the same as ``\'g\'``, except that it uses |\n | | the current locale setting to insert the appropriate |\n | | number separator characters. |\n +-----------+------------------------------------------------------------+\n | ``\'%\'`` | Percentage. Multiplies the number by 100 and displays in |\n | | fixed (``\'f\'``) format, followed by a percent sign. |\n +-----------+------------------------------------------------------------+\n | None | the same as ``\'g\'`` |\n +-----------+------------------------------------------------------------+\n', + 'function': '\nFunction definitions\n********************\n\nA function definition defines a user-defined function object (see\nsection *The standard type hierarchy*):\n\n funcdef ::= [decorators] "def" funcname "(" [parameter_list] ")" ["->" expression]? ":" suite\n decorators ::= decorator+\n decorator ::= "@" dotted_name ["(" [argument_list [","]] ")"] NEWLINE\n funcdef ::= "def" funcname "(" [parameter_list] ")" ":" suite\n dotted_name ::= identifier ("." identifier)*\n parameter_list ::= (defparameter ",")*\n ( "*" [parameter] ("," defparameter)*\n [, "**" parameter]\n | "**" parameter\n | defparameter [","] )\n parameter ::= identifier [":" expression]\n defparameter ::= parameter ["=" expression]\n funcname ::= identifier\n\nA function definition is an executable statement. Its execution binds\nthe function name in the current local namespace to a function object\n(a wrapper around the executable code for the function). This\nfunction object contains a reference to the current global namespace\nas the global namespace to be used when the function is called.\n\nThe function definition does not execute the function body; this gets\nexecuted only when the function is called.\n\nA function definition may be wrapped by one or more *decorator*\nexpressions. Decorator expressions are evaluated when the function is\ndefined, in the scope that contains the function definition. The\nresult must be a callable, which is invoked with the function object\nas the only argument. The returned value is bound to the function name\ninstead of the function object. Multiple decorators are applied in\nnested fashion. For example, the following code\n\n @f1(arg)\n @f2\n def func(): pass\n\nis equivalent to\n\n def func(): pass\n func = f1(arg)(f2(func))\n\nWhen one or more parameters have the form *parameter* ``=``\n*expression*, the function is said to have "default parameter values."\nFor a parameter with a default value, the corresponding argument may\nbe omitted from a call, in which case the parameter\'s default value is\nsubstituted. If a parameter has a default value, all following\nparameters up until the "``*``" must also have a default value ---\nthis is a syntactic restriction that is not expressed by the grammar.\n\n**Default parameter values are evaluated when the function definition\nis executed.** This means that the expression is evaluated once, when\nthe function is defined, and that that same "pre-computed" value is\nused for each call. This is especially important to understand when a\ndefault parameter is a mutable object, such as a list or a dictionary:\nif the function modifies the object (e.g. by appending an item to a\nlist), the default value is in effect modified. This is generally not\nwhat was intended. A way around this is to use ``None`` as the\ndefault, and explicitly test for it in the body of the function, e.g.:\n\n def whats_on_the_telly(penguin=None):\n if penguin is None:\n penguin = []\n penguin.append("property of the zoo")\n return penguin\n\nFunction call semantics are described in more detail in section\n*Calls*. A function call always assigns values to all parameters\nmentioned in the parameter list, either from position arguments, from\nkeyword arguments, or from default values. If the form\n"``*identifier``" is present, it is initialized to a tuple receiving\nany excess positional parameters, defaulting to the empty tuple. If\nthe form "``**identifier``" is present, it is initialized to a new\ndictionary receiving any excess keyword arguments, defaulting to a new\nempty dictionary. Parameters after "``*``" or "``*identifier``" are\nkeyword-only parameters and may only be passed used keyword arguments.\n\nParameters may have annotations of the form "``: expression``"\nfollowing the parameter name. Any parameter may have an annotation\neven those of the form ``*identifier`` or ``**identifier``. Functions\nmay have "return" annotation of the form "``-> expression``" after the\nparameter list. These annotations can be any valid Python expression\nand are evaluated when the function definition is executed.\nAnnotations may be evaluated in a different order than they appear in\nthe source code. The presence of annotations does not change the\nsemantics of a function. The annotation values are available as\nvalues of a dictionary keyed by the parameters\' names in the\n``__annotations__`` attribute of the function object.\n\nIt is also possible to create anonymous functions (functions not bound\nto a name), for immediate use in expressions. This uses lambda forms,\ndescribed in section *Expression lists*. Note that the lambda form is\nmerely a shorthand for a simplified function definition; a function\ndefined in a "``def``" statement can be passed around or assigned to\nanother name just like a function defined by a lambda form. The\n"``def``" form is actually more powerful since it allows the execution\nof multiple statements and annotations.\n\n**Programmer\'s note:** Functions are first-class objects. A "``def``"\nform executed inside a function definition defines a local function\nthat can be returned or passed around. Free variables used in the\nnested function can access the local variables of the function\ncontaining the def. See section *Naming and binding* for details.\n', + 'global': '\nThe ``global`` statement\n************************\n\n global_stmt ::= "global" identifier ("," identifier)*\n\nThe ``global`` statement is a declaration which holds for the entire\ncurrent code block. It means that the listed identifiers are to be\ninterpreted as globals. It would be impossible to assign to a global\nvariable without ``global``, although free variables may refer to\nglobals without being declared global.\n\nNames listed in a ``global`` statement must not be used in the same\ncode block textually preceding that ``global`` statement.\n\nNames listed in a ``global`` statement must not be defined as formal\nparameters or in a ``for`` loop control target, ``class`` definition,\nfunction definition, or ``import`` statement.\n\n(The current implementation does not enforce the latter two\nrestrictions, but programs should not abuse this freedom, as future\nimplementations may enforce them or silently change the meaning of the\nprogram.)\n\n**Programmer\'s note:** the ``global`` is a directive to the parser.\nIt applies only to code parsed at the same time as the ``global``\nstatement. In particular, a ``global`` statement contained in a string\nor code object supplied to the builtin ``exec()`` function does not\naffect the code block *containing* the function call, and code\ncontained in such a string is unaffected by ``global`` statements in\nthe code containing the function call. The same applies to the\n``eval()`` and ``compile()`` functions.\n', + 'id-classes': '\nReserved classes of identifiers\n*******************************\n\nCertain classes of identifiers (besides keywords) have special\nmeanings. These classes are identified by the patterns of leading and\ntrailing underscore characters:\n\n``_*``\n Not imported by ``from module import *``. The special identifier\n ``_`` is used in the interactive interpreter to store the result of\n the last evaluation; it is stored in the ``builtins`` module. When\n not in interactive mode, ``_`` has no special meaning and is not\n defined. See section *The import statement*.\n\n Note: The name ``_`` is often used in conjunction with\n internationalization; refer to the documentation for the\n ``gettext`` module for more information on this convention.\n\n``__*__``\n System-defined names. These names are defined by the interpreter\n and its implementation (including the standard library);\n applications should not expect to define additional names using\n this convention. The set of names of this class defined by Python\n may be extended in future versions. See section *Special method\n names*.\n\n``__*``\n Class-private names. Names in this category, when used within the\n context of a class definition, are re-written to use a mangled form\n to help avoid name clashes between "private" attributes of base and\n derived classes. See section *Identifiers (Names)*.\n', + 'identifiers': '\nIdentifiers and keywords\n************************\n\nIdentifiers (also referred to as *names*) are described by the\nfollowing lexical definitions.\n\nThe syntax of identifiers in Python is based on the Unicode standard\nannex UAX-31, with elaboration and changes as defined below; see also\n**PEP 3131** for further details.\n\nWithin the ASCII range (U+0001..U+007F), the valid characters for\nidentifiers are the same as in Python 2.x: the uppercase and lowercase\nletters ``A`` through ``Z``, the underscore ``_`` and, except for the\nfirst character, the digits ``0`` through ``9``.\n\nPython 3.0 introduces additional characters from outside the ASCII\nrange (see **PEP 3131**). For these characters, the classification\nuses the version of the Unicode Character Database as included in the\n``unicodedata`` module.\n\nIdentifiers are unlimited in length. Case is significant.\n\n identifier ::= id_start id_continue*\n id_start ::= \n id_continue ::= \n\nThe Unicode category codes mentioned above stand for:\n\n* *Lu* - uppercase letters\n\n* *Ll* - lowercase letters\n\n* *Lt* - titlecase letters\n\n* *Lm* - modifier letters\n\n* *Lo* - other letters\n\n* *Nl* - letter numbers\n\n* *Mn* - nonspacing marks\n\n* *Mc* - spacing combining marks\n\n* *Nd* - decimal numbers\n\n* *Pc* - connector punctuations\n\nAll identifiers are converted into the normal form NFC while parsing;\ncomparison of identifiers is based on NFC.\n\nA non-normative HTML file listing all valid identifier characters for\nUnicode 4.1 can be found at http://www.dcl.hpi.uni-\npotsdam.de/home/loewis/table-3131.html.\n\n\nKeywords\n========\n\nThe following identifiers are used as reserved words, or *keywords* of\nthe language, and cannot be used as ordinary identifiers. They must\nbe spelled exactly as written here:\n\n False class finally is return\n None continue for lambda try\n True def from nonlocal while\n and del global not with\n as elif if or yield\n assert else import pass\n break except in raise\n\n\nReserved classes of identifiers\n===============================\n\nCertain classes of identifiers (besides keywords) have special\nmeanings. These classes are identified by the patterns of leading and\ntrailing underscore characters:\n\n``_*``\n Not imported by ``from module import *``. The special identifier\n ``_`` is used in the interactive interpreter to store the result of\n the last evaluation; it is stored in the ``builtins`` module. When\n not in interactive mode, ``_`` has no special meaning and is not\n defined. See section *The import statement*.\n\n Note: The name ``_`` is often used in conjunction with\n internationalization; refer to the documentation for the\n ``gettext`` module for more information on this convention.\n\n``__*__``\n System-defined names. These names are defined by the interpreter\n and its implementation (including the standard library);\n applications should not expect to define additional names using\n this convention. The set of names of this class defined by Python\n may be extended in future versions. See section *Special method\n names*.\n\n``__*``\n Class-private names. Names in this category, when used within the\n context of a class definition, are re-written to use a mangled form\n to help avoid name clashes between "private" attributes of base and\n derived classes. See section *Identifiers (Names)*.\n', + 'if': '\nThe ``if`` statement\n********************\n\nThe ``if`` statement is used for conditional execution:\n\n if_stmt ::= "if" expression ":" suite\n ( "elif" expression ":" suite )*\n ["else" ":" suite]\n\nIt selects exactly one of the suites by evaluating the expressions one\nby one until one is found to be true (see section *Boolean operations*\nfor the definition of true and false); then that suite is executed\n(and no other part of the ``if`` statement is executed or evaluated).\nIf all expressions are false, the suite of the ``else`` clause, if\npresent, is executed.\n', + 'imaginary': '\nImaginary literals\n******************\n\nImaginary literals are described by the following lexical definitions:\n\n imagnumber ::= (floatnumber | intpart) ("j" | "J")\n\nAn imaginary literal yields a complex number with a real part of 0.0.\nComplex numbers are represented as a pair of floating point numbers\nand have the same restrictions on their range. To create a complex\nnumber with a nonzero real part, add a floating point number to it,\ne.g., ``(3+4j)``. Some examples of imaginary literals:\n\n 3.14j 10.j 10j .001j 1e100j 3.14e-10j\n', + 'import': '\nThe ``import`` statement\n************************\n\n import_stmt ::= "import" module ["as" name] ( "," module ["as" name] )*\n | "from" relative_module "import" identifier ["as" name]\n ( "," identifier ["as" name] )*\n | "from" relative_module "import" "(" identifier ["as" name]\n ( "," identifier ["as" name] )* [","] ")"\n | "from" module "import" "*"\n module ::= (identifier ".")* identifier\n relative_module ::= "."* module | "."+\n name ::= identifier\n\nImport statements are executed in two steps: (1) find a module, and\ninitialize it if necessary; (2) define a name or names in the local\nnamespace (of the scope where the ``import`` statement occurs). The\nfirst form (without ``from``) repeats these steps for each identifier\nin the list. The form with ``from`` performs step (1) once, and then\nperforms step (2) repeatedly.\n\nIn this context, to "initialize" a built-in or extension module means\nto call an initialization function that the module must provide for\nthe purpose (in the reference implementation, the function\'s name is\nobtained by prepending string "init" to the module\'s name); to\n"initialize" a Python-coded module means to execute the module\'s body.\n\nThe system maintains a table of modules that have been or are being\ninitialized, indexed by module name. This table is accessible as\n``sys.modules``. When a module name is found in this table, step (1)\nis finished. If not, a search for a module definition is started.\nWhen a module is found, it is loaded. Details of the module searching\nand loading process are implementation and platform specific. It\ngenerally involves searching for a "built-in" module with the given\nname and then searching a list of locations given as ``sys.path``.\n\nIf a built-in module is found, its built-in initialization code is\nexecuted and step (1) is finished. If no matching file is found,\n``ImportError`` is raised. If a file is found, it is parsed, yielding\nan executable code block. If a syntax error occurs, ``SyntaxError``\nis raised. Otherwise, an empty module of the given name is created\nand inserted in the module table, and then the code block is executed\nin the context of this module. Exceptions during this execution\nterminate step (1).\n\nWhen step (1) finishes without raising an exception, step (2) can\nbegin.\n\nThe first form of ``import`` statement binds the module name in the\nlocal namespace to the module object, and then goes on to import the\nnext identifier, if any. If the module name is followed by ``as``,\nthe name following ``as`` is used as the local name for the module.\n\nThe ``from`` form does not bind the module name: it goes through the\nlist of identifiers, looks each one of them up in the module found in\nstep (1), and binds the name in the local namespace to the object thus\nfound. As with the first form of ``import``, an alternate local name\ncan be supplied by specifying "``as`` localname". If a name is not\nfound, ``ImportError`` is raised. If the list of identifiers is\nreplaced by a star (``\'*\'``), all public names defined in the module\nare bound in the local namespace of the ``import`` statement..\n\nThe *public names* defined by a module are determined by checking the\nmodule\'s namespace for a variable named ``__all__``; if defined, it\nmust be a sequence of strings which are names defined or imported by\nthat module. The names given in ``__all__`` are all considered public\nand are required to exist. If ``__all__`` is not defined, the set of\npublic names includes all names found in the module\'s namespace which\ndo not begin with an underscore character (``\'_\'``). ``__all__``\nshould contain the entire public API. It is intended to avoid\naccidentally exporting items that are not part of the API (such as\nlibrary modules which were imported and used within the module).\n\nThe ``from`` form with ``*`` may only occur in a module scope. If the\nwild card form of import --- ``import *`` --- is used in a function\nand the function contains or is a nested block with free variables,\nthe compiler will raise a ``SyntaxError``.\n\n**Hierarchical module names:** when the module names contains one or\nmore dots, the module search path is carried out differently. The\nsequence of identifiers up to the last dot is used to find a\n"package"; the final identifier is then searched inside the package.\nA package is generally a subdirectory of a directory on ``sys.path``\nthat has a file ``__init__.py``. [XXX Can\'t be bothered to spell this\nout right now; see the URL\nhttp://www.python.org/doc/essays/packages.html for more details, also\nabout how the module search works from inside a package.]\n\nThe built-in function ``__import__()`` is provided to support\napplications that determine which modules need to be loaded\ndynamically; refer to *Built-in Functions* for additional information.\n\n\nFuture statements\n=================\n\nA *future statement* is a directive to the compiler that a particular\nmodule should be compiled using syntax or semantics that will be\navailable in a specified future release of Python. The future\nstatement is intended to ease migration to future versions of Python\nthat introduce incompatible changes to the language. It allows use of\nthe new features on a per-module basis before the release in which the\nfeature becomes standard.\n\n future_statement ::= "from" "__future__" "import" feature ["as" name]\n ("," feature ["as" name])*\n | "from" "__future__" "import" "(" feature ["as" name]\n ("," feature ["as" name])* [","] ")"\n feature ::= identifier\n name ::= identifier\n\nA future statement must appear near the top of the module. The only\nlines that can appear before a future statement are:\n\n* the module docstring (if any),\n\n* comments,\n\n* blank lines, and\n\n* other future statements.\n\nThe features recognized by Python 3.0 are ``absolute_import``,\n``division``, ``generators``, ``nested_scopes`` and\n``with_statement``. They are all redundant because they are always\nenabled, and only kept for backwards compatibility.\n\nA future statement is recognized and treated specially at compile\ntime: Changes to the semantics of core constructs are often\nimplemented by generating different code. It may even be the case\nthat a new feature introduces new incompatible syntax (such as a new\nreserved word), in which case the compiler may need to parse the\nmodule differently. Such decisions cannot be pushed off until\nruntime.\n\nFor any given release, the compiler knows which feature names have\nbeen defined, and raises a compile-time error if a future statement\ncontains a feature not known to it.\n\nThe direct runtime semantics are the same as for any import statement:\nthere is a standard module ``__future__``, described later, and it\nwill be imported in the usual way at the time the future statement is\nexecuted.\n\nThe interesting runtime semantics depend on the specific feature\nenabled by the future statement.\n\nNote that there is nothing special about the statement:\n\n import __future__ [as name]\n\nThat is not a future statement; it\'s an ordinary import statement with\nno special semantics or syntax restrictions.\n\nCode compiled by calls to the builtin functions ``exec()`` and\n``compile()`` that occur in a module ``M`` containing a future\nstatement will, by default, use the new syntax or semantics associated\nwith the future statement. This can be controlled by optional\narguments to ``compile()`` --- see the documentation of that function\nfor details.\n\nA future statement typed at an interactive interpreter prompt will\ntake effect for the rest of the interpreter session. If an\ninterpreter is started with the *-i* option, is passed a script name\nto execute, and the script includes a future statement, it will be in\neffect in the interactive session started after the script is\nexecuted.\n', + 'in': '\nComparisons\n***********\n\nUnlike C, all comparison operations in Python have the same priority,\nwhich is lower than that of any arithmetic, shifting or bitwise\noperation. Also unlike C, expressions like ``a < b < c`` have the\ninterpretation that is conventional in mathematics:\n\n comparison ::= or_expr ( comp_operator or_expr )*\n comp_operator ::= "<" | ">" | "==" | ">=" | "<=" | "!="\n | "is" ["not"] | ["not"] "in"\n\nComparisons yield boolean values: ``True`` or ``False``.\n\nComparisons can be chained arbitrarily, e.g., ``x < y <= z`` is\nequivalent to ``x < y and y <= z``, except that ``y`` is evaluated\nonly once (but in both cases ``z`` is not evaluated at all when ``x <\ny`` is found to be false).\n\nFormally, if *a*, *b*, *c*, ..., *y*, *z* are expressions and *op1*,\n*op2*, ..., *opN* are comparison operators, then ``a op1 b op2 c ... y\nopN z`` is equivalent to ``a op1 b and b op2 c and ... y opN z``,\nexcept that each expression is evaluated at most once.\n\nNote that ``a op1 b op2 c`` doesn\'t imply any kind of comparison\nbetween *a* and *c*, so that, e.g., ``x < y > z`` is perfectly legal\n(though perhaps not pretty).\n\nThe operators ``<``, ``>``, ``==``, ``>=``, ``<=``, and ``!=`` compare\nthe values of two objects. The objects need not have the same type.\nIf both are numbers, they are converted to a common type. Otherwise,\nobjects of different types *always* compare unequal, and are ordered\nconsistently but arbitrarily. You can control comparison behavior of\nobjects of non-builtin types by defining a ``__cmp__()`` method or\nrich comparison methods like ``__gt__()``, described in section\n*Special method names*.\n\n(This unusual definition of comparison was used to simplify the\ndefinition of operations like sorting and the ``in`` and ``not in``\noperators. In the future, the comparison rules for objects of\ndifferent types are likely to change.)\n\nComparison of objects of the same type depends on the type:\n\n* Numbers are compared arithmetically.\n\n* Bytes objects are compared lexicographically using the numeric\n values of their elements.\n\n* Strings are compared lexicographically using the numeric equivalents\n (the result of the built-in function ``ord()``) of their characters.\n [3] String and bytes object can\'t be compared!\n\n* Tuples and lists are compared lexicographically using comparison of\n corresponding elements. This means that to compare equal, each\n element must compare equal and the two sequences must be of the same\n type and have the same length.\n\n If not equal, the sequences are ordered the same as their first\n differing elements. For example, ``cmp([1,2,x], [1,2,y])`` returns\n the same as ``cmp(x,y)``. If the corresponding element does not\n exist, the shorter sequence is ordered first (for example, ``[1,2] <\n [1,2,3]``).\n\n* Mappings (dictionaries) compare equal if and only if their sorted\n ``(key, value)`` lists compare equal. [4] Outcomes other than\n equality are resolved consistently, but are not otherwise defined.\n [5]\n\n* Most other objects of builtin types compare unequal unless they are\n the same object; the choice whether one object is considered smaller\n or larger than another one is made arbitrarily but consistently\n within one execution of a program.\n\nThe operators ``in`` and ``not in`` test for membership. ``x in s``\nevaluates to true if *x* is a member of *s*, and false otherwise. ``x\nnot in s`` returns the negation of ``x in s``. All built-in sequences\nand set types support this as well as dictionary, for which ``in``\ntests whether a the dictionary has a given key.\n\nFor the list and tuple types, ``x in y`` is true if and only if there\nexists an index *i* such that ``x == y[i]`` is true.\n\nFor the string and bytes types, ``x in y`` is true if and only if *x*\nis a substring of *y*. An equivalent test is ``y.find(x) != -1``.\nEmpty strings are always considered to be a substring of any other\nstring, so ``"" in "abc"`` will return ``True``.\n\nFor user-defined classes which define the ``__contains__()`` method,\n``x in y`` is true if and only if ``y.__contains__(x)`` is true.\n\nFor user-defined classes which do not define ``__contains__()`` and do\ndefine ``__getitem__()``, ``x in y`` is true if and only if there is a\nnon-negative integer index *i* such that ``x == y[i]``, and all lower\ninteger indices do not raise ``IndexError`` exception. (If any other\nexception is raised, it is as if ``in`` raised that exception).\n\nThe operator ``not in`` is defined to have the inverse true value of\n``in``.\n\nThe operators ``is`` and ``is not`` test for object identity: ``x is\ny`` is true if and only if *x* and *y* are the same object. ``x is\nnot y`` yields the inverse truth value.\n', + 'integers': '\nInteger literals\n****************\n\nInteger literals are described by the following lexical definitions:\n\n integer ::= decimalinteger | octinteger | hexinteger | bininteger\n decimalinteger ::= nonzerodigit digit* | "0"+\n nonzerodigit ::= "1"..."9"\n digit ::= "0"..."9"\n octinteger ::= "0" ("o" | "O") octdigit+\n hexinteger ::= "0" ("x" | "X") hexdigit+\n bininteger ::= "0" ("b" | "B") bindigit+\n octdigit ::= "0"..."7"\n hexdigit ::= digit | "a"..."f" | "A"..."F"\n bindigit ::= "0" | "1"\n\nThere is no limit for the length of integer literals apart from what\ncan be stored in available memory.\n\nNote that leading zeros in a non-zero decimal number are not allowed.\nThis is for disambiguation with C-style octal literals, which Python\nused before version 3.0.\n\nSome examples of integer literals:\n\n 7 2147483647 0o177 0b100110111\n 3 79228162514264337593543950336 0o377 0x100000000\n 79228162514264337593543950336 0xdeadbeef\n', + 'lambda': '\nExpression lists\n****************\n\n expression_list ::= expression ( "," expression )* [","]\n\nAn expression list containing at least one comma yields a tuple. The\nlength of the tuple is the number of expressions in the list. The\nexpressions are evaluated from left to right.\n\nThe trailing comma is required only to create a single tuple (a.k.a. a\n*singleton*); it is optional in all other cases. A single expression\nwithout a trailing comma doesn\'t create a tuple, but rather yields the\nvalue of that expression. (To create an empty tuple, use an empty pair\nof parentheses: ``()``.)\n', + 'lists': '\nList displays\n*************\n\nA list display is a possibly empty series of expressions enclosed in\nsquare brackets:\n\n list_display ::= "[" [expression_list | comprehension] "]"\n\nA list display yields a new list object, the contents being specified\nby either a list of expressions or a comprehension. When a comma-\nseparated list of expressions is supplied, its elements are evaluated\nfrom left to right and placed into the list object in that order.\nWhen a comprehension is supplied, the list is constructed from the\nelements resulting from the comprehension.\n', + 'naming': '\nNaming and binding\n******************\n\n*Names* refer to objects. Names are introduced by name binding\noperations. Each occurrence of a name in the program text refers to\nthe *binding* of that name established in the innermost function block\ncontaining the use.\n\nA *block* is a piece of Python program text that is executed as a\nunit. The following are blocks: a module, a function body, and a class\ndefinition. Each command typed interactively is a block. A script\nfile (a file given as standard input to the interpreter or specified\non the interpreter command line the first argument) is a code block.\nA script command (a command specified on the interpreter command line\nwith the \'**-c**\' option) is a code block. The string argument passed\nto the built-in functions ``eval()`` and ``exec()`` is a code block.\n\nA code block is executed in an *execution frame*. A frame contains\nsome administrative information (used for debugging) and determines\nwhere and how execution continues after the code block\'s execution has\ncompleted.\n\nA *scope* defines the visibility of a name within a block. If a local\nvariable is defined in a block, its scope includes that block. If the\ndefinition occurs in a function block, the scope extends to any blocks\ncontained within the defining one, unless a contained block introduces\na different binding for the name. The scope of names defined in a\nclass block is limited to the class block; it does not extend to the\ncode blocks of methods -- this includes generator expressions since\nthey are implemented using a function scope. This means that the\nfollowing will fail:\n\n class A:\n a = 42\n b = list(a + i for i in range(10))\n\nWhen a name is used in a code block, it is resolved using the nearest\nenclosing scope. The set of all such scopes visible to a code block\nis called the block\'s *environment*.\n\nIf a name is bound in a block, it is a local variable of that block,\nunless declared as ``nonlocal``. If a name is bound at the module\nlevel, it is a global variable. (The variables of the module code\nblock are local and global.) If a variable is used in a code block\nbut not defined there, it is a *free variable*.\n\nWhen a name is not found at all, a ``NameError`` exception is raised.\nIf the name refers to a local variable that has not been bound, a\n``UnboundLocalError`` exception is raised. ``UnboundLocalError`` is a\nsubclass of ``NameError``.\n\nThe following constructs bind names: formal parameters to functions,\n``import`` statements, class and function definitions (these bind the\nclass or function name in the defining block), and targets that are\nidentifiers if occurring in an assignment, ``for`` loop header, or in\nthe second position of an ``except`` clause header. The ``import``\nstatement of the form "``from ...import *``" binds all names defined\nin the imported module, except those beginning with an underscore.\nThis form may only be used at the module level.\n\nA target occurring in a ``del`` statement is also considered bound for\nthis purpose (though the actual semantics are to unbind the name). It\nis illegal to unbind a name that is referenced by an enclosing scope;\nthe compiler will report a ``SyntaxError``.\n\nEach assignment or import statement occurs within a block defined by a\nclass or function definition or at the module level (the top-level\ncode block).\n\nIf a name binding operation occurs anywhere within a code block, all\nuses of the name within the block are treated as references to the\ncurrent block. This can lead to errors when a name is used within a\nblock before it is bound. This rule is subtle. Python lacks\ndeclarations and allows name binding operations to occur anywhere\nwithin a code block. The local variables of a code block can be\ndetermined by scanning the entire text of the block for name binding\noperations.\n\nIf the ``global`` statement occurs within a block, all uses of the\nname specified in the statement refer to the binding of that name in\nthe top-level namespace. Names are resolved in the top-level\nnamespace by searching the global namespace, i.e. the namespace of the\nmodule containing the code block, and the builtin namespace, the\nnamespace of the module ``builtins``. The global namespace is\nsearched first. If the name is not found there, the builtin namespace\nis searched. The global statement must precede all uses of the name.\n\nThe built-in namespace associated with the execution of a code block\nis actually found by looking up the name ``__builtins__`` in its\nglobal namespace; this should be a dictionary or a module (in the\nlatter case the module\'s dictionary is used). By default, when in the\n``__main__`` module, ``__builtins__`` is the built-in module\n``builtins``; when in any other module, ``__builtins__`` is an alias\nfor the dictionary of the ``builtins`` module itself.\n``__builtins__`` can be set to a user-created dictionary to create a\nweak form of restricted execution.\n\nNote: Users should not touch ``__builtins__``; it is strictly an\n implementation detail. Users wanting to override values in the\n built-in namespace should ``import`` the ``builtins`` module and\n modify its attributes appropriately.\n\nThe namespace for a module is automatically created the first time a\nmodule is imported. The main module for a script is always called\n``__main__``.\n\nThe global statement has the same scope as a name binding operation in\nthe same block. If the nearest enclosing scope for a free variable\ncontains a global statement, the free variable is treated as a global.\n\nA class definition is an executable statement that may use and define\nnames. These references follow the normal rules for name resolution.\nThe namespace of the class definition becomes the attribute dictionary\nof the class. Names defined at the class scope are not visible in\nmethods.\n\n\nInteraction with dynamic features\n=================================\n\nThere are several cases where Python statements are illegal when used\nin conjunction with nested scopes that contain free variables.\n\nIf a variable is referenced in an enclosing scope, it is illegal to\ndelete the name. An error will be reported at compile time.\n\nIf the wild card form of import --- ``import *`` --- is used in a\nfunction and the function contains or is a nested block with free\nvariables, the compiler will raise a ``SyntaxError``.\n\nThe ``eval()`` and ``exec()`` functions do not have access to the full\nenvironment for resolving names. Names may be resolved in the local\nand global namespaces of the caller. Free variables are not resolved\nin the nearest enclosing namespace, but in the global namespace. [1]\nThe ``exec()`` and ``eval()`` functions have optional arguments to\noverride the global and local namespace. If only one namespace is\nspecified, it is used for both.\n', + 'numbers': "\nNumeric literals\n****************\n\nThere are three types of numeric literals: integers, floating point\nnumbers, and imaginary numbers. There are no complex literals\n(complex numbers can be formed by adding a real number and an\nimaginary number).\n\nNote that numeric literals do not include a sign; a phrase like ``-1``\nis actually an expression composed of the unary operator '``-``' and\nthe literal ``1``.\n", + 'numeric-types': "\nEmulating numeric types\n***********************\n\nThe following methods can be defined to emulate numeric objects.\nMethods corresponding to operations that are not supported by the\nparticular kind of number implemented (e.g., bitwise operations for\nnon-integral numbers) should be left undefined.\n\nobject.__add__(self, other)\nobject.__sub__(self, other)\nobject.__mul__(self, other)\nobject.__floordiv__(self, other)\nobject.__mod__(self, other)\nobject.__divmod__(self, other)\nobject.__pow__(self, other[, modulo])\nobject.__lshift__(self, other)\nobject.__rshift__(self, other)\nobject.__and__(self, other)\nobject.__xor__(self, other)\nobject.__or__(self, other)\n\n These methods are called to implement the binary arithmetic\n operations (``+``, ``-``, ``*``, ``//``, ``%``, ``divmod()``,\n ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``, ``|``). For\n instance, to evaluate the expression *x*``+``*y*, where *x* is an\n instance of a class that has an ``__add__()`` method,\n ``x.__add__(y)`` is called. The ``__divmod__()`` method should be\n the equivalent to using ``__floordiv__()`` and ``__mod__()``; it\n should not be related to ``__truediv__()`` (described below). Note\n that ``__pow__()`` should be defined to accept an optional third\n argument if the ternary version of the built-in ``pow()`` function\n is to be supported.\n\n If one of those methods does not support the operation with the\n supplied arguments, it should return ``NotImplemented``.\n\nobject.__div__(self, other)\nobject.__truediv__(self, other)\n\n The division operator (``/``) is implemented by these methods. The\n ``__truediv__()`` method is used when ``__future__.division`` is in\n effect, otherwise ``__div__()`` is used. If only one of these two\n methods is defined, the object will not support division in the\n alternate context; ``TypeError`` will be raised instead.\n\nobject.__radd__(self, other)\nobject.__rsub__(self, other)\nobject.__rmul__(self, other)\nobject.__rdiv__(self, other)\nobject.__rtruediv__(self, other)\nobject.__rfloordiv__(self, other)\nobject.__rmod__(self, other)\nobject.__rdivmod__(self, other)\nobject.__rpow__(self, other)\nobject.__rlshift__(self, other)\nobject.__rrshift__(self, other)\nobject.__rand__(self, other)\nobject.__rxor__(self, other)\nobject.__ror__(self, other)\n\n These methods are called to implement the binary arithmetic\n operations (``+``, ``-``, ``*``, ``/``, ``%``, ``divmod()``,\n ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``, ``|``) with\n reflected (swapped) operands. These functions are only called if\n the left operand does not support the corresponding operation and\n the operands are of different types. [2] For instance, to evaluate\n the expression *x*``-``*y*, where *y* is an instance of a class\n that has an ``__rsub__()`` method, ``y.__rsub__(x)`` is called if\n ``x.__sub__(y)`` returns *NotImplemented*.\n\n Note that ternary ``pow()`` will not try calling ``__rpow__()``\n (the coercion rules would become too complicated).\n\n Note: If the right operand's type is a subclass of the left operand's\n type and that subclass provides the reflected method for the\n operation, this method will be called before the left operand's\n non-reflected method. This behavior allows subclasses to\n override their ancestors' operations.\n\nobject.__iadd__(self, other)\nobject.__isub__(self, other)\nobject.__imul__(self, other)\nobject.__idiv__(self, other)\nobject.__itruediv__(self, other)\nobject.__ifloordiv__(self, other)\nobject.__imod__(self, other)\nobject.__ipow__(self, other[, modulo])\nobject.__ilshift__(self, other)\nobject.__irshift__(self, other)\nobject.__iand__(self, other)\nobject.__ixor__(self, other)\nobject.__ior__(self, other)\n\n These methods are called to implement the augmented arithmetic\n operations (``+=``, ``-=``, ``*=``, ``/=``, ``//=``, ``%=``,\n ``**=``, ``<<=``, ``>>=``, ``&=``, ``^=``, ``|=``). These methods\n should attempt to do the operation in-place (modifying *self*) and\n return the result (which could be, but does not have to be,\n *self*). If a specific method is not defined, the augmented\n operation falls back to the normal methods. For instance, to\n evaluate the expression *x*``+=``*y*, where *x* is an instance of a\n class that has an ``__iadd__()`` method, ``x.__iadd__(y)`` is\n called. If *x* is an instance of a class that does not define a\n ``__iadd__()`` method, ``x.__add__(y)`` and ``y.__radd__(x)`` are\n considered, as with the evaluation of *x*``+``*y*.\n\nobject.__neg__(self)\nobject.__pos__(self)\nobject.__abs__(self)\nobject.__invert__(self)\n\n Called to implement the unary arithmetic operations (``-``, ``+``,\n ``abs()`` and ``~``).\n\nobject.__complex__(self)\nobject.__int__(self)\nobject.__float__(self)\n\n Called to implement the built-in functions ``complex()``, ``int()``\n and ``float()``. Should return a value of the appropriate type.\n\nobject.__index__(self)\n\n Called to implement ``operator.index()``. Also called whenever\n Python needs an integer object (such as in slicing, or in the\n built-in ``bin()``, ``hex()`` and ``oct()`` functions). Must return\n an integer.\n", + 'objects': '\nObjects, values and types\n*************************\n\n*Objects* are Python\'s abstraction for data. All data in a Python\nprogram is represented by objects or by relations between objects. (In\na sense, and in conformance to Von Neumann\'s model of a "stored\nprogram computer," code is also represented by objects.)\n\nEvery object has an identity, a type and a value. An object\'s\n*identity* never changes once it has been created; you may think of it\nas the object\'s address in memory. The \'``is``\' operator compares the\nidentity of two objects; the ``id()`` function returns an integer\nrepresenting its identity (currently implemented as its address). An\nobject\'s *type* is also unchangeable. An object\'s type determines the\noperations that the object supports (e.g., "does it have a length?")\nand also defines the possible values for objects of that type. The\n``type()`` function returns an object\'s type (which is an object\nitself). The *value* of some objects can change. Objects whose value\ncan change are said to be *mutable*; objects whose value is\nunchangeable once they are created are called *immutable*. (The value\nof an immutable container object that contains a reference to a\nmutable object can change when the latter\'s value is changed; however\nthe container is still considered immutable, because the collection of\nobjects it contains cannot be changed. So, immutability is not\nstrictly the same as having an unchangeable value, it is more subtle.)\nAn object\'s mutability is determined by its type; for instance,\nnumbers, strings and tuples are immutable, while dictionaries and\nlists are mutable.\n\nObjects are never explicitly destroyed; however, when they become\nunreachable they may be garbage-collected. An implementation is\nallowed to postpone garbage collection or omit it altogether --- it is\na matter of implementation quality how garbage collection is\nimplemented, as long as no objects are collected that are still\nreachable. (Implementation note: the current implementation uses a\nreference-counting scheme with (optional) delayed detection of\ncyclically linked garbage, which collects most objects as soon as they\nbecome unreachable, but is not guaranteed to collect garbage\ncontaining circular references. See the documentation of the ``gc``\nmodule for information on controlling the collection of cyclic\ngarbage.)\n\nNote that the use of the implementation\'s tracing or debugging\nfacilities may keep objects alive that would normally be collectable.\nAlso note that catching an exception with a \'``try``...``except``\'\nstatement may keep objects alive.\n\nSome objects contain references to "external" resources such as open\nfiles or windows. It is understood that these resources are freed\nwhen the object is garbage-collected, but since garbage collection is\nnot guaranteed to happen, such objects also provide an explicit way to\nrelease the external resource, usually a ``close()`` method. Programs\nare strongly recommended to explicitly close such objects. The\n\'``try``...``finally``\' statement provides a convenient way to do\nthis.\n\nSome objects contain references to other objects; these are called\n*containers*. Examples of containers are tuples, lists and\ndictionaries. The references are part of a container\'s value. In\nmost cases, when we talk about the value of a container, we imply the\nvalues, not the identities of the contained objects; however, when we\ntalk about the mutability of a container, only the identities of the\nimmediately contained objects are implied. So, if an immutable\ncontainer (like a tuple) contains a reference to a mutable object, its\nvalue changes if that mutable object is changed.\n\nTypes affect almost all aspects of object behavior. Even the\nimportance of object identity is affected in some sense: for immutable\ntypes, operations that compute new values may actually return a\nreference to any existing object with the same type and value, while\nfor mutable objects this is not allowed. E.g., after ``a = 1; b =\n1``, ``a`` and ``b`` may or may not refer to the same object with the\nvalue one, depending on the implementation, but after ``c = []; d =\n[]``, ``c`` and ``d`` are guaranteed to refer to two different,\nunique, newly created empty lists. (Note that ``c = d = []`` assigns\nthe same object to both ``c`` and ``d``.)\n', + 'operator-summary': '\nSummary\n*******\n\nThe following table summarizes the operator precedences in Python,\nfrom lowest precedence (least binding) to highest precedence (most\nbinding). Operators in the same box have the same precedence. Unless\nthe syntax is explicitly given, operators are binary. Operators in\nthe same box group left to right (except for comparisons, including\ntests, which all have the same precedence and chain from left to right\n--- see section *Comparisons* --- and exponentiation, which groups\nfrom right to left).\n\n+------------------------------------------------+---------------------------------------+\n| Operator | Description |\n+================================================+=======================================+\n| ``lambda`` | Lambda expression |\n+------------------------------------------------+---------------------------------------+\n| ``or`` | Boolean OR |\n+------------------------------------------------+---------------------------------------+\n| ``and`` | Boolean AND |\n+------------------------------------------------+---------------------------------------+\n| ``not`` *x* | Boolean NOT |\n+------------------------------------------------+---------------------------------------+\n| ``in``, ``not`` ``in`` | Membership tests |\n+------------------------------------------------+---------------------------------------+\n| ``is``, ``is not`` | Identity tests |\n+------------------------------------------------+---------------------------------------+\n| ``<``, ``<=``, ``>``, ``>=``, ``!=``, ``==`` | Comparisons |\n+------------------------------------------------+---------------------------------------+\n| ``|`` | Bitwise OR |\n+------------------------------------------------+---------------------------------------+\n| ``^`` | Bitwise XOR |\n+------------------------------------------------+---------------------------------------+\n| ``&`` | Bitwise AND |\n+------------------------------------------------+---------------------------------------+\n| ``<<``, ``>>`` | Shifts |\n+------------------------------------------------+---------------------------------------+\n| ``+``, ``-`` | Addition and subtraction |\n+------------------------------------------------+---------------------------------------+\n| ``*``, ``/``, ``//``, ``%`` | Multiplication, division, remainder |\n+------------------------------------------------+---------------------------------------+\n| ``+x``, ``-x`` | Positive, negative |\n+------------------------------------------------+---------------------------------------+\n| ``~x`` | Bitwise not |\n+------------------------------------------------+---------------------------------------+\n| ``**`` | Exponentiation |\n+------------------------------------------------+---------------------------------------+\n| ``x.attribute`` | Attribute reference |\n+------------------------------------------------+---------------------------------------+\n| ``x[index]`` | Subscription |\n+------------------------------------------------+---------------------------------------+\n| ``x[index:index]`` | Slicing |\n+------------------------------------------------+---------------------------------------+\n| ``f(arguments...)`` | Function call |\n+------------------------------------------------+---------------------------------------+\n| ``(expressions...)`` | Binding, tuple display, generator |\n| | expressions |\n+------------------------------------------------+---------------------------------------+\n| ``[expressions...]`` | List display |\n+------------------------------------------------+---------------------------------------+\n| ``{expressions...}`` | Dictionary or set display |\n+------------------------------------------------+---------------------------------------+\n\n-[ Footnotes ]-\n\n[1] While ``abs(x%y) < abs(y)`` is true mathematically, for floats it\n may not be true numerically due to roundoff. For example, and\n assuming a platform on which a Python float is an IEEE 754 double-\n precision number, in order that ``-1e-100 % 1e100`` have the same\n sign as ``1e100``, the computed result is ``-1e-100 + 1e100``,\n which is numerically exactly equal to ``1e100``. Function\n ``fmod()`` in the ``math`` module returns a result whose sign\n matches the sign of the first argument instead, and so returns\n ``-1e-100`` in this case. Which approach is more appropriate\n depends on the application.\n\n[2] If x is very close to an exact integer multiple of y, it\'s\n possible for ``x//y`` to be one larger than ``(x-x%y)//y`` due to\n rounding. In such cases, Python returns the latter result, in\n order to preserve that ``divmod(x,y)[0] * y + x % y`` be very\n close to ``x``.\n\n[3] While comparisons between strings make sense at the byte level,\n they may be counter-intuitive to users. For example, the strings\n ``"\\u00C7"`` and ``"\\u0327\\u0043"`` compare differently, even\n though they both represent the same unicode character (LATIN\n CAPTITAL LETTER C WITH CEDILLA). To compare strings in a human\n recognizable way, compare using ``unicodedata.normalize()``.\n\n[4] The implementation computes this efficiently, without constructing\n lists or sorting.\n\n[5] Earlier versions of Python used lexicographic comparison of the\n sorted (key, value) lists, but this was very expensive for the\n common case of comparing for equality. An even earlier version of\n Python compared dictionaries by identity only, but this caused\n surprises because people expected to be able to test a dictionary\n for emptiness by comparing it to ``{}``.\n', + 'pass': '\nThe ``pass`` statement\n**********************\n\n pass_stmt ::= "pass"\n\n``pass`` is a null operation --- when it is executed, nothing happens.\nIt is useful as a placeholder when a statement is required\nsyntactically, but no code needs to be executed, for example:\n\n def f(arg): pass # a function that does nothing (yet)\n\n class C: pass # a class with no methods (yet)\n', + 'power': '\nThe power operator\n******************\n\nThe power operator binds more tightly than unary operators on its\nleft; it binds less tightly than unary operators on its right. The\nsyntax is:\n\n power ::= primary ["**" u_expr]\n\nThus, in an unparenthesized sequence of power and unary operators, the\noperators are evaluated from right to left (this does not constrain\nthe evaluation order for the operands): ``-1**2`` results in ``-1``.\n\nThe power operator has the same semantics as the built-in ``pow()``\nfunction, when called with two arguments: it yields its left argument\nraised to the power of its right argument. The numeric arguments are\nfirst converted to a common type, and the result is of that type.\n\nFor int operands, the result has the same type as the operands unless\nthe second argument is negative; in that case, all arguments are\nconverted to float and a float result is delivered. For example,\n``10**2`` returns ``100``, but ``10**-2`` returns ``0.01``.\n\nRaising ``0.0`` to a negative power results in a\n``ZeroDivisionError``. Raising a negative number to a fractional power\nresults in a ``complex`` number. (In earlier versions it raised a\n``ValueError``.)\n', + 'raise': '\nThe ``raise`` statement\n***********************\n\n raise_stmt ::= "raise" [expression ["from" expression]]\n\nIf no expressions are present, ``raise`` re-raises the last exception\nthat was active in the current scope. If no exception is active in\nthe current scope, a ``TypeError`` exception is raised indicating that\nthis is an error (if running under IDLE, a ``queue.Empty`` exception\nis raised instead).\n\nOtherwise, ``raise`` evaluates the first expression as the exception\nobject. It must be either a subclass or an instance of\n``BaseException``. If it is a class, the exception instance will be\nobtained when needed by instantiating the class with no arguments.\n\nThe *type* of the exception is the exception instance\'s class, the\n*value* is the instance itself.\n\nA traceback object is normally created automatically when an exception\nis raised and attached to it as the ``__traceback__`` attribute, which\nis writable. You can create an exception and set your own traceback in\none step using the ``with_traceback()`` exception method (which\nreturns the same exception instance, with its traceback set to its\nargument), like so:\n\n raise RuntimeError("foo occurred").with_traceback(tracebackobj)\n\nThe "from" clause is used for exception chaining, which is not\ndocumented yet.\n\nAdditional information on exceptions can be found in section\n*Exceptions*, and information about handling exceptions is in section\n*The try statement*.\n', + 'return': '\nThe ``return`` statement\n************************\n\n return_stmt ::= "return" [expression_list]\n\n``return`` may only occur syntactically nested in a function\ndefinition, not within a nested class definition.\n\nIf an expression list is present, it is evaluated, else ``None`` is\nsubstituted.\n\n``return`` leaves the current function call with the expression list\n(or ``None``) as return value.\n\nWhen ``return`` passes control out of a ``try`` statement with a\n``finally`` clause, that ``finally`` clause is executed before really\nleaving the function.\n\nIn a generator function, the ``return`` statement is not allowed to\ninclude an **expression_list**. In that context, a bare ``return``\nindicates that the generator is done and will cause ``StopIteration``\nto be raised.\n', + 'sequence-types': "\nEmulating container types\n*************************\n\nThe following methods can be defined to implement container objects.\nContainers usually are sequences (such as lists or tuples) or mappings\n(like dictionaries), but can represent other containers as well. The\nfirst set of methods is used either to emulate a sequence or to\nemulate a mapping; the difference is that for a sequence, the\nallowable keys should be the integers *k* for which ``0 <= k < N``\nwhere *N* is the length of the sequence, or slice objects, which\ndefine a range of items. It is also recommended that mappings provide\nthe methods ``keys()``, ``values()``, ``items()``, ``get()``,\n``clear()``, ``setdefault()``, ``pop()``, ``popitem()``, ``copy()``,\nand ``update()`` behaving similar to those for Python's standard\ndictionary objects. The ``collections`` module provides a\n``MutableMapping`` abstract base class to help create those methods\nfrom a base set of ``__getitem__()``, ``__setitem__()``,\n``__delitem__()``, and ``keys()``. Mutable sequences should provide\nmethods ``append()``, ``count()``, ``index()``, ``extend()``,\n``insert()``, ``pop()``, ``remove()``, ``reverse()`` and ``sort()``,\nlike Python standard list objects. Finally, sequence types should\nimplement addition (meaning concatenation) and multiplication (meaning\nrepetition) by defining the methods ``__add__()``, ``__radd__()``,\n``__iadd__()``, ``__mul__()``, ``__rmul__()`` and ``__imul__()``\ndescribed below; they should not define other numerical operators. It\nis recommended that both mappings and sequences implement the\n``__contains__()`` method to allow efficient use of the ``in``\noperator; for mappings, ``in`` should search the mapping's keys; for\nsequences, it should search through the values. It is further\nrecommended that both mappings and sequences implement the\n``__iter__()`` method to allow efficient iteration through the\ncontainer; for mappings, ``__iter__()`` should be the same as\n``keys()``; for sequences, it should iterate through the values.\n\nobject.__len__(self)\n\n Called to implement the built-in function ``len()``. Should return\n the length of the object, an integer ``>=`` 0. Also, an object\n that doesn't define a ``__bool__()`` method and whose ``__len__()``\n method returns zero is considered to be false in a Boolean context.\n\nNote: Slicing is done exclusively with the following three methods. A\n call like\n\n a[1:2] = b\n\n is translated to\n\n a[slice(1, 2, None)] = b\n\n and so forth. Missing slice items are always filled in with\n ``None``.\n\nobject.__getitem__(self, key)\n\n Called to implement evaluation of ``self[key]``. For sequence\n types, the accepted keys should be integers and slice objects.\n Note that the special interpretation of negative indexes (if the\n class wishes to emulate a sequence type) is up to the\n ``__getitem__()`` method. If *key* is of an inappropriate type,\n ``TypeError`` may be raised; if of a value outside the set of\n indexes for the sequence (after any special interpretation of\n negative values), ``IndexError`` should be raised. For mapping\n types, if *key* is missing (not in the container), ``KeyError``\n should be raised.\n\n Note: ``for`` loops expect that an ``IndexError`` will be raised for\n illegal indexes to allow proper detection of the end of the\n sequence.\n\nobject.__setitem__(self, key, value)\n\n Called to implement assignment to ``self[key]``. Same note as for\n ``__getitem__()``. This should only be implemented for mappings if\n the objects support changes to the values for keys, or if new keys\n can be added, or for sequences if elements can be replaced. The\n same exceptions should be raised for improper *key* values as for\n the ``__getitem__()`` method.\n\nobject.__delitem__(self, key)\n\n Called to implement deletion of ``self[key]``. Same note as for\n ``__getitem__()``. This should only be implemented for mappings if\n the objects support removal of keys, or for sequences if elements\n can be removed from the sequence. The same exceptions should be\n raised for improper *key* values as for the ``__getitem__()``\n method.\n\nobject.__iter__(self)\n\n This method is called when an iterator is required for a container.\n This method should return a new iterator object that can iterate\n over all the objects in the container. For mappings, it should\n iterate over the keys of the container, and should also be made\n available as the method ``keys()``.\n\n Iterator objects also need to implement this method; they are\n required to return themselves. For more information on iterator\n objects, see *Iterator Types*.\n\nobject.__reversed__(self)\n\n Called (if present) by the ``reversed()`` builtin to implement\n reverse iteration. It should return a new iterator object that\n iterates over all the objects in the container in reverse order.\n\n If the ``__reversed__()`` method is not provided, the\n ``reversed()`` builtin will fall back to using the sequence\n protocol (``__len__()`` and ``__getitem__()``). Objects should\n normally only provide ``__reversed__()`` if they do not support the\n sequence protocol and an efficient implementation of reverse\n iteration is possible.\n\nThe membership test operators (``in`` and ``not in``) are normally\nimplemented as an iteration through a sequence. However, container\nobjects can supply the following special method with a more efficient\nimplementation, which also does not require the object be a sequence.\n\nobject.__contains__(self, item)\n\n Called to implement membership test operators. Should return true\n if *item* is in *self*, false otherwise. For mapping objects, this\n should consider the keys of the mapping rather than the values or\n the key-item pairs.\n", + 'shifting': '\nShifting operations\n*******************\n\nThe shifting operations have lower priority than the arithmetic\noperations:\n\n shift_expr ::= a_expr | shift_expr ( "<<" | ">>" ) a_expr\n\nThese operators accept integers as arguments. They shift the first\nargument to the left or right by the number of bits given by the\nsecond argument.\n\nA right shift by *n* bits is defined as division by ``pow(2,n)``. A\nleft shift by *n* bits is defined as multiplication with ``pow(2,n)``.\n', + 'slicings': '\nSlicings\n********\n\nA slicing selects a range of items in a sequence object (e.g., a\nstring, tuple or list). Slicings may be used as expressions or as\ntargets in assignment or ``del`` statements. The syntax for a\nslicing:\n\n slicing ::= primary "[" slice_list "]"\n slice_list ::= slice_item ("," slice_item)* [","]\n slice_item ::= expression | proper_slice\n proper_slice ::= [lower_bound] ":" [upper_bound] [ ":" [stride] ]\n lower_bound ::= expression\n upper_bound ::= expression\n stride ::= expression\n\nThere is ambiguity in the formal syntax here: anything that looks like\nan expression list also looks like a slice list, so any subscription\ncan be interpreted as a slicing. Rather than further complicating the\nsyntax, this is disambiguated by defining that in this case the\ninterpretation as a subscription takes priority over the\ninterpretation as a slicing (this is the case if the slice list\ncontains no proper slice).\n\nThe semantics for a slicing are as follows. The primary must evaluate\nto a mapping object, and it is indexed (using the same\n``__getitem__()`` method as normal subscription) with a key that is\nconstructed from the slice list, as follows. If the slice list\ncontains at least one comma, the key is a tuple containing the\nconversion of the slice items; otherwise, the conversion of the lone\nslice item is the key. The conversion of a slice item that is an\nexpression is that expression. The conversion of a proper slice is a\nslice object (see section *The standard type hierarchy*) whose\n``start``, ``stop`` and ``step`` attributes are the values of the\nexpressions given as lower bound, upper bound and stride,\nrespectively, substituting ``None`` for missing expressions.\n', + 'specialattrs': "\nSpecial Attributes\n******************\n\nThe implementation adds a few special read-only attributes to several\nobject types, where they are relevant. Some of these are not reported\nby the ``dir()`` built-in function.\n\nobject.__dict__\n\n A dictionary or other mapping object used to store an object's\n (writable) attributes.\n\ninstance.__class__\n\n The class to which a class instance belongs.\n\nclass.__bases__\n\n The tuple of base classes of a class object. If there are no base\n classes, this will be an empty tuple.\n\nclass.__name__\n\n The name of the class or type.\n\n-[ Footnotes ]-\n\n[1] Additional information on these special methods may be found in\n the Python Reference Manual (*Basic customization*).\n\n[2] As a consequence, the list ``[1, 2]`` is considered equal to\n ``[1.0, 2.0]``, and similarly for tuples.\n\n[3] They must have since the parser can't tell the type of the\n operands.\n\n[4] To format only a tuple you should therefore provide a singleton\n tuple whose only element is the tuple to be formatted.\n\n[5] These numbers are fairly arbitrary. They are intended to avoid\n printing endless strings of meaningless digits without hampering\n correct use and without having to know the exact precision of\n floating point values on a particular machine.\n\n[6] The advantage of leaving the newline on is that returning an empty\n string is then an unambiguous EOF indication. It is also possible\n (in cases where it might matter, for example, if you want to make\n an exact copy of a file while scanning its lines) to tell whether\n the last line of a file ended in a newline or not (yes this\n happens!).\n", + 'specialnames': '\nSpecial method names\n********************\n\nA class can implement certain operations that are invoked by special\nsyntax (such as arithmetic operations or subscripting and slicing) by\ndefining methods with special names. This is Python\'s approach to\n*operator overloading*, allowing classes to define their own behavior\nwith respect to language operators. For instance, if a class defines\na method named ``__getitem__()``, and ``x`` is an instance of this\nclass, then ``x[i]`` is equivalent to ``x.__getitem__(i)``. Except\nwhere mentioned, attempts to execute an operation raise an exception\nwhen no appropriate method is defined.\n\nSpecial methods are only guaranteed to work if defined in an object\'s\nclass, not in the object\'s instance dictionary. That explains why\nthis won\'t work:\n\n >>> class C:\n ... pass\n ...\n >>> c = C()\n >>> c.__len__ = lambda: 5\n >>> len(c)\n Traceback (most recent call last):\n File "", line 1, in \n TypeError: object of type \'C\' has no len()\n\nWhen implementing a class that emulates any built-in type, it is\nimportant that the emulation only be implemented to the degree that it\nmakes sense for the object being modelled. For example, some\nsequences may work well with retrieval of individual elements, but\nextracting a slice may not make sense. (One example of this is the\n``NodeList`` interface in the W3C\'s Document Object Model.)\n\n\nBasic customization\n===================\n\nobject.__new__(cls[, ...])\n\n Called to create a new instance of class *cls*. ``__new__()`` is a\n static method (special-cased so you need not declare it as such)\n that takes the class of which an instance was requested as its\n first argument. The remaining arguments are those passed to the\n object constructor expression (the call to the class). The return\n value of ``__new__()`` should be the new object instance (usually\n an instance of *cls*).\n\n Typical implementations create a new instance of the class by\n invoking the superclass\'s ``__new__()`` method using\n ``super(currentclass, cls).__new__(cls[, ...])`` with appropriate\n arguments and then modifying the newly-created instance as\n necessary before returning it.\n\n If ``__new__()`` returns an instance of *cls*, then the new\n instance\'s ``__init__()`` method will be invoked like\n ``__init__(self[, ...])``, where *self* is the new instance and the\n remaining arguments are the same as were passed to ``__new__()``.\n\n If ``__new__()`` does not return an instance of *cls*, then the new\n instance\'s ``__init__()`` method will not be invoked.\n\n ``__new__()`` is intended mainly to allow subclasses of immutable\n types (like int, str, or tuple) to customize instance creation. It\n is also commonly overridden in custom metaclasses in order to\n customize class creation.\n\nobject.__init__(self[, ...])\n\n Called when the instance is created. The arguments are those\n passed to the class constructor expression. If a base class has an\n ``__init__()`` method, the derived class\'s ``__init__()`` method,\n if any, must explicitly call it to ensure proper initialization of\n the base class part of the instance; for example:\n ``BaseClass.__init__(self, [args...])``. As a special constraint\n on constructors, no value may be returned; doing so will cause a\n ``TypeError`` to be raised at runtime.\n\nobject.__del__(self)\n\n Called when the instance is about to be destroyed. This is also\n called a destructor. If a base class has a ``__del__()`` method,\n the derived class\'s ``__del__()`` method, if any, must explicitly\n call it to ensure proper deletion of the base class part of the\n instance. Note that it is possible (though not recommended!) for\n the ``__del__()`` method to postpone destruction of the instance by\n creating a new reference to it. It may then be called at a later\n time when this new reference is deleted. It is not guaranteed that\n ``__del__()`` methods are called for objects that still exist when\n the interpreter exits.\n\n Note: ``del x`` doesn\'t directly call ``x.__del__()`` --- the former\n decrements the reference count for ``x`` by one, and the latter\n is only called when ``x``\'s reference count reaches zero. Some\n common situations that may prevent the reference count of an\n object from going to zero include: circular references between\n objects (e.g., a doubly-linked list or a tree data structure with\n parent and child pointers); a reference to the object on the\n stack frame of a function that caught an exception (the traceback\n stored in ``sys.exc_info()[2]`` keeps the stack frame alive); or\n a reference to the object on the stack frame that raised an\n unhandled exception in interactive mode (the traceback stored in\n ``sys.last_traceback`` keeps the stack frame alive). The first\n situation can only be remedied by explicitly breaking the cycles;\n the latter two situations can be resolved by storing ``None`` in\n ``sys.last_traceback``. Circular references which are garbage are\n detected when the option cycle detector is enabled (it\'s on by\n default), but can only be cleaned up if there are no Python-\n level ``__del__()`` methods involved. Refer to the documentation\n for the ``gc`` module for more information about how\n ``__del__()`` methods are handled by the cycle detector,\n particularly the description of the ``garbage`` value.\n\n Warning: Due to the precarious circumstances under which ``__del__()``\n methods are invoked, exceptions that occur during their execution\n are ignored, and a warning is printed to ``sys.stderr`` instead.\n Also, when ``__del__()`` is invoked in response to a module being\n deleted (e.g., when execution of the program is done), other\n globals referenced by the ``__del__()`` method may already have\n been deleted. For this reason, ``__del__()`` methods should do\n the absolute minimum needed to maintain external invariants.\n Starting with version 1.5, Python guarantees that globals whose\n name begins with a single underscore are deleted from their\n module before other globals are deleted; if no other references\n to such globals exist, this may help in assuring that imported\n modules are still available at the time when the ``__del__()``\n method is called.\n\nobject.__repr__(self)\n\n Called by the ``repr()`` built-in function and by string\n conversions (reverse quotes) to compute the "official" string\n representation of an object. If at all possible, this should look\n like a valid Python expression that could be used to recreate an\n object with the same value (given an appropriate environment). If\n this is not possible, a string of the form ``<...some useful\n description...>`` should be returned. The return value must be a\n string object. If a class defines ``__repr__()`` but not\n ``__str__()``, then ``__repr__()`` is also used when an "informal"\n string representation of instances of that class is required.\n\n This is typically used for debugging, so it is important that the\n representation is information-rich and unambiguous.\n\nobject.__str__(self)\n\n Called by the ``str()`` built-in function and by the ``print()``\n function to compute the "informal" string representation of an\n object. This differs from ``__repr__()`` in that it does not have\n to be a valid Python expression: a more convenient or concise\n representation may be used instead. The return value must be a\n string object.\n\nobject.__format__(self, format_spec)\n\n Called by the ``format()`` built-in function (and by extension, the\n ``format()`` method of class ``str``) to produce a "formatted"\n string representation of an object. The ``format_spec`` argument is\n a string that contains a description of the formatting options\n desired. The interpretation of the ``format_spec`` argument is up\n to the type implementing ``__format__()``, however most classes\n will either delegate formatting to one of the built-in types, or\n use a similar formatting option syntax.\n\n See *Format Specification Mini-Language* for a description of the\n standard formatting syntax.\n\n The return value must be a string object.\n\nobject.__lt__(self, other)\nobject.__le__(self, other)\nobject.__eq__(self, other)\nobject.__ne__(self, other)\nobject.__gt__(self, other)\nobject.__ge__(self, other)\n\n These are the so-called "rich comparison" methods, and are called\n for comparison operators in preference to ``__cmp__()`` below. The\n correspondence between operator symbols and method names is as\n follows: ``xy`` calls ``x.__gt__(y)``, and ``x>=y`` calls\n ``x.__ge__(y)``.\n\n A rich comparison method may return the singleton\n ``NotImplemented`` if it does not implement the operation for a\n given pair of arguments. By convention, ``False`` and ``True`` are\n returned for a successful comparison. However, these methods can\n return any value, so if the comparison operator is used in a\n Boolean context (e.g., in the condition of an ``if`` statement),\n Python will call ``bool()`` on the value to determine if the result\n is true or false.\n\n There are no implied relationships among the comparison operators.\n The truth of ``x==y`` does not imply that ``x!=y`` is false.\n Accordingly, when defining ``__eq__()``, one should also define\n ``__ne__()`` so that the operators will behave as expected. See\n the paragraph on ``__hash__()`` for some important notes on\n creating *hashable* objects which support custom comparison\n operations and are usable as dictionary keys.\n\n There are no swapped-argument versions of these methods (to be used\n when the left argument does not support the operation but the right\n argument does); rather, ``__lt__()`` and ``__gt__()`` are each\n other\'s reflection, ``__le__()`` and ``__ge__()`` are each other\'s\n reflection, and ``__eq__()`` and ``__ne__()`` are their own\n reflection.\n\n Arguments to rich comparison methods are never coerced.\n\nobject.__cmp__(self, other)\n\n Called by comparison operations if rich comparison (see above) is\n not defined. Should return a negative integer if ``self < other``,\n zero if ``self == other``, a positive integer if ``self > other``.\n If no ``__cmp__()``, ``__eq__()`` or ``__ne__()`` operation is\n defined, class instances are compared by object identity\n ("address"). See also the description of ``__hash__()`` for some\n important notes on creating *hashable* objects which support custom\n comparison operations and are usable as dictionary keys.\n\nobject.__hash__(self)\n\n Called for the key object for dictionary operations, and by the\n built-in function ``hash()``. Should return an integer usable as a\n hash value for dictionary operations. The only required property\n is that objects which compare equal have the same hash value; it is\n advised to somehow mix together (e.g., using exclusive or) the hash\n values for the components of the object that also play a part in\n comparison of objects.\n\n If a class does not define a ``__cmp__()`` or ``__eq__()`` method\n it should not define a ``__hash__()`` operation either; if it\n defines ``__cmp__()`` or ``__eq__()`` but not ``__hash__()``, its\n instances will not be usable as dictionary keys. If a class\n defines mutable objects and implements a ``__cmp__()`` or\n ``__eq__()`` method, it should not implement ``__hash__()``, since\n the dictionary implementation requires that a key\'s hash value is\n immutable (if the object\'s hash value changes, it will be in the\n wrong hash bucket).\n\n User-defined classes have ``__cmp__()`` and ``__hash__()`` methods\n by default; with them, all objects compare unequal and\n ``x.__hash__()`` returns ``id(x)``.\n\nobject.__bool__(self)\n\n Called to implement truth value testing, and the built-in operation\n ``bool()``; should return ``False`` or ``True``. When this method\n is not defined, ``__len__()`` is called, if it is defined (see\n below) and ``True`` is returned when the length is not zero. If a\n class defines neither ``__len__()`` nor ``__bool__()``, all its\n instances are considered true.\n\n\nCustomizing attribute access\n============================\n\nThe following methods can be defined to customize the meaning of\nattribute access (use of, assignment to, or deletion of ``x.name``)\nfor class instances.\n\nobject.__getattr__(self, name)\n\n Called when an attribute lookup has not found the attribute in the\n usual places (i.e. it is not an instance attribute nor is it found\n in the class tree for ``self``). ``name`` is the attribute name.\n This method should return the (computed) attribute value or raise\n an ``AttributeError`` exception.\n\n Note that if the attribute is found through the normal mechanism,\n ``__getattr__()`` is not called. (This is an intentional asymmetry\n between ``__getattr__()`` and ``__setattr__()``.) This is done both\n for efficiency reasons and because otherwise ``__setattr__()``\n would have no way to access other attributes of the instance. Note\n that at least for instance variables, you can fake total control by\n not inserting any values in the instance attribute dictionary (but\n instead inserting them in another object). See the\n ``__getattribute__()`` method below for a way to actually get total\n control over attribute access.\n\nobject.__getattribute__(self, name)\n\n Called unconditionally to implement attribute accesses for\n instances of the class. If the class also defines\n ``__getattr__()``, the latter will not be called unless\n ``__getattribute__()`` either calls it explicitly or raises an\n ``AttributeError``. This method should return the (computed)\n attribute value or raise an ``AttributeError`` exception. In order\n to avoid infinite recursion in this method, its implementation\n should always call the base class method with the same name to\n access any attributes it needs, for example,\n ``object.__getattribute__(self, name)``.\n\nobject.__setattr__(self, name, value)\n\n Called when an attribute assignment is attempted. This is called\n instead of the normal mechanism (i.e. store the value in the\n instance dictionary). *name* is the attribute name, *value* is the\n value to be assigned to it.\n\n If ``__setattr__()`` wants to assign to an instance attribute, it\n should call the base class method with the same name, for example,\n ``object.__setattr__(self, name, value)``.\n\nobject.__delattr__(self, name)\n\n Like ``__setattr__()`` but for attribute deletion instead of\n assignment. This should only be implemented if ``del obj.name`` is\n meaningful for the object.\n\n\nImplementing Descriptors\n------------------------\n\nThe following methods only apply when an instance of the class\ncontaining the method (a so-called *descriptor* class) appears in the\nclass dictionary of another class, known as the *owner* class. In the\nexamples below, "the attribute" refers to the attribute whose name is\nthe key of the property in the owner class\' ``__dict__``.\n\nobject.__get__(self, instance, owner)\n\n Called to get the attribute of the owner class (class attribute\n access) or of an instance of that class (instance attribute\n access). *owner* is always the owner class, while *instance* is the\n instance that the attribute was accessed through, or ``None`` when\n the attribute is accessed through the *owner*. This method should\n return the (computed) attribute value or raise an\n ``AttributeError`` exception.\n\nobject.__set__(self, instance, value)\n\n Called to set the attribute on an instance *instance* of the owner\n class to a new value, *value*.\n\nobject.__delete__(self, instance)\n\n Called to delete the attribute on an instance *instance* of the\n owner class.\n\n\nInvoking Descriptors\n--------------------\n\nIn general, a descriptor is an object attribute with "binding\nbehavior", one whose attribute access has been overridden by methods\nin the descriptor protocol: ``__get__()``, ``__set__()``, and\n``__delete__()``. If any of those methods are defined for an object,\nit is said to be a descriptor.\n\nThe default behavior for attribute access is to get, set, or delete\nthe attribute from an object\'s dictionary. For instance, ``a.x`` has a\nlookup chain starting with ``a.__dict__[\'x\']``, then\n``type(a).__dict__[\'x\']``, and continuing through the base classes of\n``type(a)`` excluding metaclasses.\n\nHowever, if the looked-up value is an object defining one of the\ndescriptor methods, then Python may override the default behavior and\ninvoke the descriptor method instead. Where this occurs in the\nprecedence chain depends on which descriptor methods were defined and\nhow they were called.\n\nThe starting point for descriptor invocation is a binding, ``a.x``.\nHow the arguments are assembled depends on ``a``:\n\nDirect Call\n The simplest and least common call is when user code directly\n invokes a descriptor method: ``x.__get__(a)``.\n\nInstance Binding\n If binding to an object instance, ``a.x`` is transformed into the\n call: ``type(a).__dict__[\'x\'].__get__(a, type(a))``.\n\nClass Binding\n If binding to a class, ``A.x`` is transformed into the call:\n ``A.__dict__[\'x\'].__get__(None, A)``.\n\nSuper Binding\n If ``a`` is an instance of ``super``, then the binding ``super(B,\n obj).m()`` searches ``obj.__class__.__mro__`` for the base class\n ``A`` immediately preceding ``B`` and then invokes the descriptor\n with the call: ``A.__dict__[\'m\'].__get__(obj, A)``.\n\nFor instance bindings, the precedence of descriptor invocation depends\non the which descriptor methods are defined. Normally, data\ndescriptors define both ``__get__()`` and ``__set__()``, while non-\ndata descriptors have just the ``__get__()`` method. Data descriptors\nalways override a redefinition in an instance dictionary. In\ncontrast, non-data descriptors can be overridden by instances. [1]\n\nPython methods (including ``staticmethod()`` and ``classmethod()``)\nare implemented as non-data descriptors. Accordingly, instances can\nredefine and override methods. This allows individual instances to\nacquire behaviors that differ from other instances of the same class.\n\nThe ``property()`` function is implemented as a data descriptor.\nAccordingly, instances cannot override the behavior of a property.\n\n\n__slots__\n---------\n\nBy default, instances of classes have a dictionary for attribute\nstorage. This wastes space for objects having very few instance\nvariables. The space consumption can become acute when creating large\nnumbers of instances.\n\nThe default can be overridden by defining *__slots__* in a class\ndefinition. The *__slots__* declaration takes a sequence of instance\nvariables and reserves just enough space in each instance to hold a\nvalue for each variable. Space is saved because *__dict__* is not\ncreated for each instance.\n\nobject.__slots__\n\n This class variable can be assigned a string, iterable, or sequence\n of strings with variable names used by instances. If defined in a\n class, *__slots__* reserves space for the declared variables and\n prevents the automatic creation of *__dict__* and *__weakref__* for\n each instance.\n\n\nNotes on using *__slots__*\n~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n* Without a *__dict__* variable, instances cannot be assigned new\n variables not listed in the *__slots__* definition. Attempts to\n assign to an unlisted variable name raises ``AttributeError``. If\n dynamic assignment of new variables is desired, then add\n ``\'__dict__\'`` to the sequence of strings in the *__slots__*\n declaration.\n\n* Without a *__weakref__* variable for each instance, classes defining\n *__slots__* do not support weak references to its instances. If weak\n reference support is needed, then add ``\'__weakref__\'`` to the\n sequence of strings in the *__slots__* declaration.\n\n* *__slots__* are implemented at the class level by creating\n descriptors (*Implementing Descriptors*) for each variable name. As\n a result, class attributes cannot be used to set default values for\n instance variables defined by *__slots__*; otherwise, the class\n attribute would overwrite the descriptor assignment.\n\n* If a class defines a slot also defined in a base class, the instance\n variable defined by the base class slot is inaccessible (except by\n retrieving its descriptor directly from the base class). This\n renders the meaning of the program undefined. In the future, a\n check may be added to prevent this.\n\n* The action of a *__slots__* declaration is limited to the class\n where it is defined. As a result, subclasses will have a *__dict__*\n unless they also define *__slots__*.\n\n* *__slots__* do not work for classes derived from "variable-length"\n built-in types such as ``int``, ``str`` and ``tuple``.\n\n* Any non-string iterable may be assigned to *__slots__*. Mappings may\n also be used; however, in the future, special meaning may be\n assigned to the values corresponding to each key.\n\n* *__class__* assignment works only if both classes have the same\n *__slots__*.\n\n\nCustomizing class creation\n==========================\n\nBy default, classes are constructed using ``type()``. A class\ndefinition is read into a separate namespace and the value of class\nname is bound to the result of ``type(name, bases, dict)``.\n\nWhen the class definition is read, if *__metaclass__* is defined then\nthe callable assigned to it will be called instead of ``type()``. This\nallows classes or functions to be written which monitor or alter the\nclass creation process:\n\n* Modifying the class dictionary prior to the class being created.\n\n* Returning an instance of another class -- essentially performing the\n role of a factory function.\n\nThese steps will have to be performed in the metaclass\'s ``__new__()``\nmethod -- ``type.__new__()`` can then be called from this method to\ncreate a class with different properties. This example adds a new\nelement to the class dictionary before creating the class:\n\n class metacls(type):\n def __new__(mcs, name, bases, dict):\n dict[\'foo\'] = \'metacls was here\'\n return type.__new__(mcs, name, bases, dict)\n\nYou can of course also override other class methods (or add new\nmethods); for example defining a custom ``__call__()`` method in the\nmetaclass allows custom behavior when the class is called, e.g. not\nalways creating a new instance.\n\n__metaclass__\n\n This variable can be any callable accepting arguments for ``name``,\n ``bases``, and ``dict``. Upon class creation, the callable is used\n instead of the built-in ``type()``.\n\nThe appropriate metaclass is determined by the following precedence\nrules:\n\n* If ``dict[\'__metaclass__\']`` exists, it is used.\n\n* Otherwise, if there is at least one base class, its metaclass is\n used (this looks for a *__class__* attribute first and if not found,\n uses its type).\n\n* Otherwise, if a global variable named __metaclass__ exists, it is\n used.\n\n* Otherwise, the default metaclass (``type``) is used.\n\nThe potential uses for metaclasses are boundless. Some ideas that have\nbeen explored including logging, interface checking, automatic\ndelegation, automatic property creation, proxies, frameworks, and\nautomatic resource locking/synchronization.\n\n\nEmulating callable objects\n==========================\n\nobject.__call__(self[, args...])\n\n Called when the instance is "called" as a function; if this method\n is defined, ``x(arg1, arg2, ...)`` is a shorthand for\n ``x.__call__(arg1, arg2, ...)``.\n\n\nEmulating container types\n=========================\n\nThe following methods can be defined to implement container objects.\nContainers usually are sequences (such as lists or tuples) or mappings\n(like dictionaries), but can represent other containers as well. The\nfirst set of methods is used either to emulate a sequence or to\nemulate a mapping; the difference is that for a sequence, the\nallowable keys should be the integers *k* for which ``0 <= k < N``\nwhere *N* is the length of the sequence, or slice objects, which\ndefine a range of items. It is also recommended that mappings provide\nthe methods ``keys()``, ``values()``, ``items()``, ``get()``,\n``clear()``, ``setdefault()``, ``pop()``, ``popitem()``, ``copy()``,\nand ``update()`` behaving similar to those for Python\'s standard\ndictionary objects. The ``collections`` module provides a\n``MutableMapping`` abstract base class to help create those methods\nfrom a base set of ``__getitem__()``, ``__setitem__()``,\n``__delitem__()``, and ``keys()``. Mutable sequences should provide\nmethods ``append()``, ``count()``, ``index()``, ``extend()``,\n``insert()``, ``pop()``, ``remove()``, ``reverse()`` and ``sort()``,\nlike Python standard list objects. Finally, sequence types should\nimplement addition (meaning concatenation) and multiplication (meaning\nrepetition) by defining the methods ``__add__()``, ``__radd__()``,\n``__iadd__()``, ``__mul__()``, ``__rmul__()`` and ``__imul__()``\ndescribed below; they should not define other numerical operators. It\nis recommended that both mappings and sequences implement the\n``__contains__()`` method to allow efficient use of the ``in``\noperator; for mappings, ``in`` should search the mapping\'s keys; for\nsequences, it should search through the values. It is further\nrecommended that both mappings and sequences implement the\n``__iter__()`` method to allow efficient iteration through the\ncontainer; for mappings, ``__iter__()`` should be the same as\n``keys()``; for sequences, it should iterate through the values.\n\nobject.__len__(self)\n\n Called to implement the built-in function ``len()``. Should return\n the length of the object, an integer ``>=`` 0. Also, an object\n that doesn\'t define a ``__bool__()`` method and whose ``__len__()``\n method returns zero is considered to be false in a Boolean context.\n\nNote: Slicing is done exclusively with the following three methods. A\n call like\n\n a[1:2] = b\n\n is translated to\n\n a[slice(1, 2, None)] = b\n\n and so forth. Missing slice items are always filled in with\n ``None``.\n\nobject.__getitem__(self, key)\n\n Called to implement evaluation of ``self[key]``. For sequence\n types, the accepted keys should be integers and slice objects.\n Note that the special interpretation of negative indexes (if the\n class wishes to emulate a sequence type) is up to the\n ``__getitem__()`` method. If *key* is of an inappropriate type,\n ``TypeError`` may be raised; if of a value outside the set of\n indexes for the sequence (after any special interpretation of\n negative values), ``IndexError`` should be raised. For mapping\n types, if *key* is missing (not in the container), ``KeyError``\n should be raised.\n\n Note: ``for`` loops expect that an ``IndexError`` will be raised for\n illegal indexes to allow proper detection of the end of the\n sequence.\n\nobject.__setitem__(self, key, value)\n\n Called to implement assignment to ``self[key]``. Same note as for\n ``__getitem__()``. This should only be implemented for mappings if\n the objects support changes to the values for keys, or if new keys\n can be added, or for sequences if elements can be replaced. The\n same exceptions should be raised for improper *key* values as for\n the ``__getitem__()`` method.\n\nobject.__delitem__(self, key)\n\n Called to implement deletion of ``self[key]``. Same note as for\n ``__getitem__()``. This should only be implemented for mappings if\n the objects support removal of keys, or for sequences if elements\n can be removed from the sequence. The same exceptions should be\n raised for improper *key* values as for the ``__getitem__()``\n method.\n\nobject.__iter__(self)\n\n This method is called when an iterator is required for a container.\n This method should return a new iterator object that can iterate\n over all the objects in the container. For mappings, it should\n iterate over the keys of the container, and should also be made\n available as the method ``keys()``.\n\n Iterator objects also need to implement this method; they are\n required to return themselves. For more information on iterator\n objects, see *Iterator Types*.\n\nobject.__reversed__(self)\n\n Called (if present) by the ``reversed()`` builtin to implement\n reverse iteration. It should return a new iterator object that\n iterates over all the objects in the container in reverse order.\n\n If the ``__reversed__()`` method is not provided, the\n ``reversed()`` builtin will fall back to using the sequence\n protocol (``__len__()`` and ``__getitem__()``). Objects should\n normally only provide ``__reversed__()`` if they do not support the\n sequence protocol and an efficient implementation of reverse\n iteration is possible.\n\nThe membership test operators (``in`` and ``not in``) are normally\nimplemented as an iteration through a sequence. However, container\nobjects can supply the following special method with a more efficient\nimplementation, which also does not require the object be a sequence.\n\nobject.__contains__(self, item)\n\n Called to implement membership test operators. Should return true\n if *item* is in *self*, false otherwise. For mapping objects, this\n should consider the keys of the mapping rather than the values or\n the key-item pairs.\n\n\nEmulating numeric types\n=======================\n\nThe following methods can be defined to emulate numeric objects.\nMethods corresponding to operations that are not supported by the\nparticular kind of number implemented (e.g., bitwise operations for\nnon-integral numbers) should be left undefined.\n\nobject.__add__(self, other)\nobject.__sub__(self, other)\nobject.__mul__(self, other)\nobject.__floordiv__(self, other)\nobject.__mod__(self, other)\nobject.__divmod__(self, other)\nobject.__pow__(self, other[, modulo])\nobject.__lshift__(self, other)\nobject.__rshift__(self, other)\nobject.__and__(self, other)\nobject.__xor__(self, other)\nobject.__or__(self, other)\n\n These methods are called to implement the binary arithmetic\n operations (``+``, ``-``, ``*``, ``//``, ``%``, ``divmod()``,\n ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``, ``|``). For\n instance, to evaluate the expression *x*``+``*y*, where *x* is an\n instance of a class that has an ``__add__()`` method,\n ``x.__add__(y)`` is called. The ``__divmod__()`` method should be\n the equivalent to using ``__floordiv__()`` and ``__mod__()``; it\n should not be related to ``__truediv__()`` (described below). Note\n that ``__pow__()`` should be defined to accept an optional third\n argument if the ternary version of the built-in ``pow()`` function\n is to be supported.\n\n If one of those methods does not support the operation with the\n supplied arguments, it should return ``NotImplemented``.\n\nobject.__div__(self, other)\nobject.__truediv__(self, other)\n\n The division operator (``/``) is implemented by these methods. The\n ``__truediv__()`` method is used when ``__future__.division`` is in\n effect, otherwise ``__div__()`` is used. If only one of these two\n methods is defined, the object will not support division in the\n alternate context; ``TypeError`` will be raised instead.\n\nobject.__radd__(self, other)\nobject.__rsub__(self, other)\nobject.__rmul__(self, other)\nobject.__rdiv__(self, other)\nobject.__rtruediv__(self, other)\nobject.__rfloordiv__(self, other)\nobject.__rmod__(self, other)\nobject.__rdivmod__(self, other)\nobject.__rpow__(self, other)\nobject.__rlshift__(self, other)\nobject.__rrshift__(self, other)\nobject.__rand__(self, other)\nobject.__rxor__(self, other)\nobject.__ror__(self, other)\n\n These methods are called to implement the binary arithmetic\n operations (``+``, ``-``, ``*``, ``/``, ``%``, ``divmod()``,\n ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``, ``|``) with\n reflected (swapped) operands. These functions are only called if\n the left operand does not support the corresponding operation and\n the operands are of different types. [2] For instance, to evaluate\n the expression *x*``-``*y*, where *y* is an instance of a class\n that has an ``__rsub__()`` method, ``y.__rsub__(x)`` is called if\n ``x.__sub__(y)`` returns *NotImplemented*.\n\n Note that ternary ``pow()`` will not try calling ``__rpow__()``\n (the coercion rules would become too complicated).\n\n Note: If the right operand\'s type is a subclass of the left operand\'s\n type and that subclass provides the reflected method for the\n operation, this method will be called before the left operand\'s\n non-reflected method. This behavior allows subclasses to\n override their ancestors\' operations.\n\nobject.__iadd__(self, other)\nobject.__isub__(self, other)\nobject.__imul__(self, other)\nobject.__idiv__(self, other)\nobject.__itruediv__(self, other)\nobject.__ifloordiv__(self, other)\nobject.__imod__(self, other)\nobject.__ipow__(self, other[, modulo])\nobject.__ilshift__(self, other)\nobject.__irshift__(self, other)\nobject.__iand__(self, other)\nobject.__ixor__(self, other)\nobject.__ior__(self, other)\n\n These methods are called to implement the augmented arithmetic\n operations (``+=``, ``-=``, ``*=``, ``/=``, ``//=``, ``%=``,\n ``**=``, ``<<=``, ``>>=``, ``&=``, ``^=``, ``|=``). These methods\n should attempt to do the operation in-place (modifying *self*) and\n return the result (which could be, but does not have to be,\n *self*). If a specific method is not defined, the augmented\n operation falls back to the normal methods. For instance, to\n evaluate the expression *x*``+=``*y*, where *x* is an instance of a\n class that has an ``__iadd__()`` method, ``x.__iadd__(y)`` is\n called. If *x* is an instance of a class that does not define a\n ``__iadd__()`` method, ``x.__add__(y)`` and ``y.__radd__(x)`` are\n considered, as with the evaluation of *x*``+``*y*.\n\nobject.__neg__(self)\nobject.__pos__(self)\nobject.__abs__(self)\nobject.__invert__(self)\n\n Called to implement the unary arithmetic operations (``-``, ``+``,\n ``abs()`` and ``~``).\n\nobject.__complex__(self)\nobject.__int__(self)\nobject.__float__(self)\n\n Called to implement the built-in functions ``complex()``, ``int()``\n and ``float()``. Should return a value of the appropriate type.\n\nobject.__index__(self)\n\n Called to implement ``operator.index()``. Also called whenever\n Python needs an integer object (such as in slicing, or in the\n built-in ``bin()``, ``hex()`` and ``oct()`` functions). Must return\n an integer.\n\n\nWith Statement Context Managers\n===============================\n\nA *context manager* is an object that defines the runtime context to\nbe established when executing a ``with`` statement. The context\nmanager handles the entry into, and the exit from, the desired runtime\ncontext for the execution of the block of code. Context managers are\nnormally invoked using the ``with`` statement (described in section\n*The with statement*), but can also be used by directly invoking their\nmethods.\n\nTypical uses of context managers include saving and restoring various\nkinds of global state, locking and unlocking resources, closing opened\nfiles, etc.\n\nFor more information on context managers, see *Context Manager Types*.\n\nobject.__enter__(self)\n\n Enter the runtime context related to this object. The ``with``\n statement will bind this method\'s return value to the target(s)\n specified in the ``as`` clause of the statement, if any.\n\nobject.__exit__(self, exc_type, exc_value, traceback)\n\n Exit the runtime context related to this object. The parameters\n describe the exception that caused the context to be exited. If the\n context was exited without an exception, all three arguments will\n be ``None``.\n\n If an exception is supplied, and the method wishes to suppress the\n exception (i.e., prevent it from being propagated), it should\n return a true value. Otherwise, the exception will be processed\n normally upon exit from this method.\n\n Note that ``__exit__()`` methods should not reraise the passed-in\n exception; this is the caller\'s responsibility.\n\nSee also:\n\n **PEP 0343** - The "with" statement\n The specification, background, and examples for the Python\n ``with`` statement.\n\n-[ Footnotes ]-\n\n[1] A descriptor can define any combination of ``__get__()``,\n ``__set__()`` and ``__delete__()``. If it does not define\n ``__get__()``, then accessing the attribute even on an instance\n will return the descriptor object itself. If the descriptor\n defines ``__set__()`` and/or ``__delete__()``, it is a data\n descriptor; if it defines neither, it is a non-data descriptor.\n\n[2] For operands of the same type, it is assumed that if the non-\n reflected method (such as ``__add__()``) fails the operation is\n not supported, which is why the reflected method is not called.\n', + 'string-methods': '\nString Methods\n**************\n\nString objects support the methods listed below. Note that none of\nthese methods take keyword arguments.\n\nIn addition, Python\'s strings support the sequence type methods\ndescribed in the *Sequence Types --- str, bytes, bytearray, list,\ntuple, range* section. To output formatted strings, see the *String\nFormatting* section. Also, see the ``re`` module for string functions\nbased on regular expressions.\n\nstr.capitalize()\n\n Return a copy of the string with only its first character\n capitalized.\n\nstr.center(width[, fillchar])\n\n Return centered in a string of length *width*. Padding is done\n using the specified *fillchar* (default is a space).\n\nstr.count(sub[, start[, end]])\n\n Return the number of occurrences of substring *sub* in the range\n [*start*, *end*]. Optional arguments *start* and *end* are\n interpreted as in slice notation.\n\nstr.encode([encoding[, errors]])\n\n Return an encoded version of the string. Default encoding is the\n current default string encoding. *errors* may be given to set a\n different error handling scheme. The default for *errors* is\n ``\'strict\'``, meaning that encoding errors raise a\n ``UnicodeError``. Other possible values are ``\'ignore\'``,\n ``\'replace\'``, ``\'xmlcharrefreplace\'``, ``\'backslashreplace\'`` and\n any other name registered via ``codecs.register_error()``, see\n section *Codec Base Classes*. For a list of possible encodings, see\n section *Standard Encodings*.\n\nstr.endswith(suffix[, start[, end]])\n\n Return ``True`` if the string ends with the specified *suffix*,\n otherwise return ``False``. *suffix* can also be a tuple of\n suffixes to look for. With optional *start*, test beginning at\n that position. With optional *end*, stop comparing at that\n position.\n\nstr.expandtabs([tabsize])\n\n Return a copy of the string where all tab characters are replaced\n by one or more spaces, depending on the current column and the\n given tab size. The column number is reset to zero after each\n newline occurring in the string. If *tabsize* is not given, a tab\n size of ``8`` characters is assumed. This doesn\'t understand other\n non-printing characters or escape sequences.\n\nstr.find(sub[, start[, end]])\n\n Return the lowest index in the string where substring *sub* is\n found, such that *sub* is contained in the range [*start*, *end*].\n Optional arguments *start* and *end* are interpreted as in slice\n notation. Return ``-1`` if *sub* is not found.\n\nstr.format(format_string, *args, **kwargs)\n\n Perform a string formatting operation. The *format_string*\n argument can contain literal text or replacement fields delimited\n by braces ``{}``. Each replacement field contains either the\n numeric index of a positional argument, or the name of a keyword\n argument. Returns a copy of *format_string* where each replacement\n field is replaced with the string value of the corresponding\n argument.\n\n >>> "The sum of 1 + 2 is {0}".format(1+2)\n \'The sum of 1 + 2 is 3\'\n\n See *Format String Syntax* for a description of the various\n formatting options that can be specified in format strings.\n\nstr.index(sub[, start[, end]])\n\n Like ``find()``, but raise ``ValueError`` when the substring is not\n found.\n\nstr.isalnum()\n\n Return true if all characters in the string are alphanumeric and\n there is at least one character, false otherwise.\n\nstr.isalpha()\n\n Return true if all characters in the string are alphabetic and\n there is at least one character, false otherwise.\n\nstr.isdigit()\n\n Return true if all characters in the string are digits and there is\n at least one character, false otherwise.\n\nstr.isidentifier()\n\n Return true if the string is a valid identifier according to the\n language definition, section *Identifiers and keywords*.\n\nstr.islower()\n\n Return true if all cased characters in the string are lowercase and\n there is at least one cased character, false otherwise.\n\nstr.isspace()\n\n Return true if there are only whitespace characters in the string\n and there is at least one character, false otherwise.\n\nstr.istitle()\n\n Return true if the string is a titlecased string and there is at\n least one character, for example uppercase characters may only\n follow uncased characters and lowercase characters only cased ones.\n Return false otherwise.\n\nstr.isupper()\n\n Return true if all cased characters in the string are uppercase and\n there is at least one cased character, false otherwise.\n\nstr.join(seq)\n\n Return a string which is the concatenation of the values in the\n sequence *seq*. Non-string values in *seq* will be converted to a\n string using their respective ``str()`` value. If there are any\n ``bytes`` objects in *seq*, a ``TypeError`` will be raised. The\n separator between elements is the string providing this method.\n\nstr.ljust(width[, fillchar])\n\n Return the string left justified in a string of length *width*.\n Padding is done using the specified *fillchar* (default is a\n space). The original string is returned if *width* is less than\n ``len(s)``.\n\nstr.lower()\n\n Return a copy of the string converted to lowercase.\n\nstr.lstrip([chars])\n\n Return a copy of the string with leading characters removed. The\n *chars* argument is a string specifying the set of characters to be\n removed. If omitted or ``None``, the *chars* argument defaults to\n removing whitespace. The *chars* argument is not a prefix; rather,\n all combinations of its values are stripped:\n\n >>> \' spacious \'.lstrip()\n \'spacious \'\n >>> \'www.example.com\'.lstrip(\'cmowz.\')\n \'example.com\'\n\nstr.maketrans(x[, y[, z]])\n\n This static method returns a translation table usable for\n ``str.translate()``.\n\n If there is only one argument, it must be a dictionary mapping\n Unicode ordinals (integers) or characters (strings of length 1) to\n Unicode ordinals, strings (of arbitrary lengths) or None.\n Character keys will then be converted to ordinals.\n\n If there are two arguments, they must be strings of equal length,\n and in the resulting dictionary, each character in x will be mapped\n to the character at the same position in y. If there is a third\n argument, it must be a string, whose characters will be mapped to\n None in the result.\n\nstr.partition(sep)\n\n Split the string at the first occurrence of *sep*, and return a\n 3-tuple containing the part before the separator, the separator\n itself, and the part after the separator. If the separator is not\n found, return a 3-tuple containing the string itself, followed by\n two empty strings.\n\nstr.replace(old, new[, count])\n\n Return a copy of the string with all occurrences of substring *old*\n replaced by *new*. If the optional argument *count* is given, only\n the first *count* occurrences are replaced.\n\nstr.rfind(sub[, start[, end]])\n\n Return the highest index in the string where substring *sub* is\n found, such that *sub* is contained within s[start,end]. Optional\n arguments *start* and *end* are interpreted as in slice notation.\n Return ``-1`` on failure.\n\nstr.rindex(sub[, start[, end]])\n\n Like ``rfind()`` but raises ``ValueError`` when the substring *sub*\n is not found.\n\nstr.rjust(width[, fillchar])\n\n Return the string right justified in a string of length *width*.\n Padding is done using the specified *fillchar* (default is a\n space). The original string is returned if *width* is less than\n ``len(s)``.\n\nstr.rpartition(sep)\n\n Split the string at the last occurrence of *sep*, and return a\n 3-tuple containing the part before the separator, the separator\n itself, and the part after the separator. If the separator is not\n found, return a 3-tuple containing two empty strings, followed by\n the string itself.\n\nstr.rsplit([sep[, maxsplit]])\n\n Return a list of the words in the string, using *sep* as the\n delimiter string. If *maxsplit* is given, at most *maxsplit* splits\n are done, the *rightmost* ones. If *sep* is not specified or\n ``None``, any whitespace string is a separator. Except for\n splitting from the right, ``rsplit()`` behaves like ``split()``\n which is described in detail below.\n\nstr.rstrip([chars])\n\n Return a copy of the string with trailing characters removed. The\n *chars* argument is a string specifying the set of characters to be\n removed. If omitted or ``None``, the *chars* argument defaults to\n removing whitespace. The *chars* argument is not a suffix; rather,\n all combinations of its values are stripped:\n\n >>> \' spacious \'.rstrip()\n \' spacious\'\n >>> \'mississippi\'.rstrip(\'ipz\')\n \'mississ\'\n\nstr.split([sep[, maxsplit]])\n\n Return a list of the words in the string, using *sep* as the\n delimiter string. If *maxsplit* is given, at most *maxsplit*\n splits are done (thus, the list will have at most ``maxsplit+1``\n elements). If *maxsplit* is not specified, then there is no limit\n on the number of splits (all possible splits are made).\n\n If *sep* is given, consecutive delimiters are not grouped together\n and are deemed to delimit empty strings (for example,\n ``\'1,,2\'.split(\',\')`` returns ``[\'1\', \'\', \'2\']``). The *sep*\n argument may consist of multiple characters (for example,\n ``\'1<>2<>3\'.split(\'<>\')`` returns ``[\'1\', \'2\', \'3\']``). Splitting\n an empty string with a specified separator returns ``[\'\']``.\n\n If *sep* is not specified or is ``None``, a different splitting\n algorithm is applied: runs of consecutive whitespace are regarded\n as a single separator, and the result will contain no empty strings\n at the start or end if the string has leading or trailing\n whitespace. Consequently, splitting an empty string or a string\n consisting of just whitespace with a ``None`` separator returns\n ``[]``.\n\n For example, ``\' 1 2 3 \'.split()`` returns ``[\'1\', \'2\', \'3\']``,\n and ``\' 1 2 3 \'.split(None, 1)`` returns ``[\'1\', \'2 3 \']``.\n\nstr.splitlines([keepends])\n\n Return a list of the lines in the string, breaking at line\n boundaries. Line breaks are not included in the resulting list\n unless *keepends* is given and true.\n\nstr.startswith(prefix[, start[, end]])\n\n Return ``True`` if string starts with the *prefix*, otherwise\n return ``False``. *prefix* can also be a tuple of prefixes to look\n for. With optional *start*, test string beginning at that\n position. With optional *end*, stop comparing string at that\n position.\n\nstr.strip([chars])\n\n Return a copy of the string with the leading and trailing\n characters removed. The *chars* argument is a string specifying the\n set of characters to be removed. If omitted or ``None``, the\n *chars* argument defaults to removing whitespace. The *chars*\n argument is not a prefix or suffix; rather, all combinations of its\n values are stripped:\n\n >>> \' spacious \'.strip()\n \'spacious\'\n >>> \'www.example.com\'.strip(\'cmowz.\')\n \'example\'\n\nstr.swapcase()\n\n Return a copy of the string with uppercase characters converted to\n lowercase and vice versa.\n\nstr.title()\n\n Return a titlecased version of the string: words start with\n uppercase characters, all remaining cased characters are lowercase.\n\nstr.translate(map)\n\n Return a copy of the *s* where all characters have been mapped\n through the *map* which must be a dictionary of Unicode\n ordinals(integers) to Unicode ordinals, strings or ``None``.\n Unmapped characters are left untouched. Characters mapped to\n ``None`` are deleted.\n\n A *map* for ``translate()`` is usually best created by\n ``str.maketrans()``.\n\n You can use the ``maketrans()`` helper function in the ``string``\n module to create a translation table. For string objects, set the\n *table* argument to ``None`` for translations that only delete\n characters:\n\n Note: An even more flexible approach is to create a custom character\n mapping codec using the ``codecs`` module (see\n ``encodings.cp1251`` for an example).\n\nstr.upper()\n\n Return a copy of the string converted to uppercase.\n\nstr.zfill(width)\n\n Return the numeric string left filled with zeros in a string of\n length *width*. A sign prefix is handled correctly. The original\n string is returned if *width* is less than ``len(s)``.\n\nstr.isnumeric()\n\n Return ``True`` if there are only numeric characters in S,\n ``False`` otherwise. Numeric characters include digit characters,\n and all characters that have the Unicode numeric value property,\n e.g. U+2155, VULGAR FRACTION ONE FIFTH.\n\nstr.isdecimal()\n\n Return ``True`` if there are only decimal characters in S,\n ``False`` otherwise. Decimal characters include digit characters,\n and all characters that that can be used to form decimal-radix\n numbers, e.g. U+0660, ARABIC-INDIC DIGIT ZERO.\n', + 'strings': '\nString and Bytes literals\n*************************\n\nString literals are described by the following lexical definitions:\n\n stringliteral ::= [stringprefix](shortstring | longstring)\n stringprefix ::= "r" | "R"\n shortstring ::= "\'" shortstringitem* "\'" | \'"\' shortstringitem* \'"\'\n longstring ::= "\'\'\'" longstringitem* "\'\'\'" | \'"""\' longstringitem* \'"""\'\n shortstringitem ::= shortstringchar | stringescapeseq\n longstringitem ::= longstringchar | stringescapeseq\n shortstringchar ::= \n longstringchar ::= \n stringescapeseq ::= "\\" \n\n bytesliteral ::= bytesprefix(shortbytes | longbytes)\n bytesprefix ::= "b" | "B"\n shortbytes ::= "\'" shortbytesitem* "\'" | \'"\' shortbytesitem* \'"\'\n longbytes ::= "\'\'\'" longbytesitem* "\'\'\'" | \'"""\' longbytesitem* \'"""\'\n shortbytesitem ::= shortbyteschar | bytesescapeseq\n longbytesitem ::= longbyteschar | bytesescapeseq\n shortbyteschar ::= \n longbyteschar ::= \n bytesescapeseq ::= "\\" \n\nOne syntactic restriction not indicated by these productions is that\nwhitespace is not allowed between the **stringprefix** or\n**bytesprefix** and the rest of the literal. The source character set\nis defined by the encoding declaration; it is UTF-8 if no encoding\ndeclaration is given in the source file; see section *Encoding\ndeclarations*.\n\nIn plain English: Both types of literals can be enclosed in matching\nsingle quotes (``\'``) or double quotes (``"``). They can also be\nenclosed in matching groups of three single or double quotes (these\nare generally referred to as *triple-quoted strings*). The backslash\n(``\\``) character is used to escape characters that otherwise have a\nspecial meaning, such as newline, backslash itself, or the quote\ncharacter.\n\nString literals may optionally be prefixed with a letter ``\'r\'`` or\n``\'R\'``; such strings are called *raw strings* and treat backslashes\nas literal characters. As a result, ``\'\\U\'`` and ``\'\\u\'`` escapes in\nraw strings are not treated specially.\n\nBytes literals are always prefixed with ``\'b\'`` or ``\'B\'``; they\nproduce an instance of the ``bytes`` type instead of the ``str`` type.\nThey may only contain ASCII characters; bytes with a numeric value of\n128 or greater must be expressed with escapes.\n\nIn triple-quoted strings, unescaped newlines and quotes are allowed\n(and are retained), except that three unescaped quotes in a row\nterminate the string. (A "quote" is the character used to open the\nstring, i.e. either ``\'`` or ``"``.)\n\nUnless an ``\'r\'`` or ``\'R\'`` prefix is present, escape sequences in\nstrings are interpreted according to rules similar to those used by\nStandard C. The recognized escape sequences are:\n\n+-------------------+-----------------------------------+---------+\n| Escape Sequence | Meaning | Notes |\n+===================+===================================+=========+\n| ``\\newline`` | Backslash and newline ignored | |\n+-------------------+-----------------------------------+---------+\n| ``\\\\`` | Backslash (``\\``) | |\n+-------------------+-----------------------------------+---------+\n| ``\\\'`` | Single quote (``\'``) | |\n+-------------------+-----------------------------------+---------+\n| ``\\"`` | Double quote (``"``) | |\n+-------------------+-----------------------------------+---------+\n| ``\\a`` | ASCII Bell (BEL) | |\n+-------------------+-----------------------------------+---------+\n| ``\\b`` | ASCII Backspace (BS) | |\n+-------------------+-----------------------------------+---------+\n| ``\\f`` | ASCII Formfeed (FF) | |\n+-------------------+-----------------------------------+---------+\n| ``\\n`` | ASCII Linefeed (LF) | |\n+-------------------+-----------------------------------+---------+\n| ``\\r`` | ASCII Carriage Return (CR) | |\n+-------------------+-----------------------------------+---------+\n| ``\\t`` | ASCII Horizontal Tab (TAB) | |\n+-------------------+-----------------------------------+---------+\n| ``\\v`` | ASCII Vertical Tab (VT) | |\n+-------------------+-----------------------------------+---------+\n| ``\\ooo`` | Character with octal value *ooo* | (1,3) |\n+-------------------+-----------------------------------+---------+\n| ``\\xhh`` | Character with hex value *hh* | (2,3) |\n+-------------------+-----------------------------------+---------+\n\nEscape sequences only recognized in string literals are:\n\n+-------------------+-----------------------------------+---------+\n| Escape Sequence | Meaning | Notes |\n+===================+===================================+=========+\n| ``\\N{name}`` | Character named *name* in the | |\n| | Unicode database | |\n+-------------------+-----------------------------------+---------+\n| ``\\uxxxx`` | Character with 16-bit hex value | (4) |\n| | *xxxx* | |\n+-------------------+-----------------------------------+---------+\n| ``\\Uxxxxxxxx`` | Character with 32-bit hex value | (5) |\n| | *xxxxxxxx* | |\n+-------------------+-----------------------------------+---------+\n\nNotes:\n\n1. As in Standard C, up to three octal digits are accepted.\n\n2. Unlike in Standard C, at most two hex digits are accepted.\n\n3. In a bytes literal, hexadecimal and octal escapes denote the byte\n with the given value. In a string literal, these escapes denote a\n Unicode character with the given value.\n\n4. Individual code units which form parts of a surrogate pair can be\n encoded using this escape sequence. Unlike in Standard C, exactly\n two hex digits are required.\n\n5. Any Unicode character can be encoded this way, but characters\n outside the Basic Multilingual Plane (BMP) will be encoded using a\n surrogate pair if Python is compiled to use 16-bit code units (the\n default). Individual code units which form parts of a surrogate\n pair can be encoded using this escape sequence.\n\nUnlike Standard C, all unrecognized escape sequences are left in the\nstring unchanged, i.e., *the backslash is left in the string*. (This\nbehavior is useful when debugging: if an escape sequence is mistyped,\nthe resulting output is more easily recognized as broken.) It is also\nimportant to note that the escape sequences only recognized in string\nliterals fall into the category of unrecognized escapes for bytes\nliterals.\n\nEven in a raw string, string quotes can be escaped with a backslash,\nbut the backslash remains in the string; for example, ``r"\\""`` is a\nvalid string literal consisting of two characters: a backslash and a\ndouble quote; ``r"\\"`` is not a valid string literal (even a raw\nstring cannot end in an odd number of backslashes). Specifically, *a\nraw string cannot end in a single backslash* (since the backslash\nwould escape the following quote character). Note also that a single\nbackslash followed by a newline is interpreted as those two characters\nas part of the string, *not* as a line continuation.\n', + 'subscriptions': '\nSubscriptions\n*************\n\nA subscription selects an item of a sequence (string, tuple or list)\nor mapping (dictionary) object:\n\n subscription ::= primary "[" expression_list "]"\n\nThe primary must evaluate to an object that supports subscription,\ne.g. a list or dictionary. User-defined objects can support\nsubscription by defining a ``__getitem__()`` method.\n\nFor built-in objects, there are two types of objects that support\nsubscription:\n\nIf the primary is a mapping, the expression list must evaluate to an\nobject whose value is one of the keys of the mapping, and the\nsubscription selects the value in the mapping that corresponds to that\nkey. (The expression list is a tuple except if it has exactly one\nitem.)\n\nIf the primary is a sequence, the expression (list) must evaluate to\nan integer. If this value is negative, the length of the sequence is\nadded to it (so that, e.g., ``x[-1]`` selects the last item of ``x``.)\nThe resulting value must be a nonnegative integer less than the number\nof items in the sequence, and the subscription selects the item whose\nindex is that value (counting from zero).\n\nA string\'s items are characters. A character is not a separate data\ntype but a string of exactly one character.\n', + 'truth': "\nTruth Value Testing\n*******************\n\nAny object can be tested for truth value, for use in an ``if`` or\n``while`` condition or as operand of the Boolean operations below. The\nfollowing values are considered false:\n\n* ``None``\n\n* ``False``\n\n* zero of any numeric type, for example, ``0``, ``0L``, ``0.0``,\n ``0j``.\n\n* any empty sequence, for example, ``''``, ``()``, ``[]``.\n\n* any empty mapping, for example, ``{}``.\n\n* instances of user-defined classes, if the class defines a\n ``__bool__()`` or ``__len__()`` method, when that method returns the\n integer zero or ``bool`` value ``False``. [1]\n\nAll other values are considered true --- so objects of many types are\nalways true.\n\nOperations and built-in functions that have a Boolean result always\nreturn ``0`` or ``False`` for false and ``1`` or ``True`` for true,\nunless otherwise stated. (Important exception: the Boolean operations\n``or`` and ``and`` always return one of their operands.)\n", + 'try': '\nThe ``try`` statement\n*********************\n\nThe ``try`` statement specifies exception handlers and/or cleanup code\nfor a group of statements:\n\n try_stmt ::= try1_stmt | try2_stmt\n try1_stmt ::= "try" ":" suite\n ("except" [expression ["as" target]] ":" suite)+\n ["else" ":" suite]\n ["finally" ":" suite]\n try2_stmt ::= "try" ":" suite\n "finally" ":" suite\n\nThe ``except`` clause(s) specify one or more exception handlers. When\nno exception occurs in the ``try`` clause, no exception handler is\nexecuted. When an exception occurs in the ``try`` suite, a search for\nan exception handler is started. This search inspects the except\nclauses in turn until one is found that matches the exception. An\nexpression-less except clause, if present, must be last; it matches\nany exception. For an except clause with an expression, that\nexpression is evaluated, and the clause matches the exception if the\nresulting object is "compatible" with the exception. An object is\ncompatible with an exception if it is the class or a base class of the\nexception object or a tuple containing an item compatible with the\nexception.\n\nIf no except clause matches the exception, the search for an exception\nhandler continues in the surrounding code and on the invocation stack.\n[1]\n\nIf the evaluation of an expression in the header of an except clause\nraises an exception, the original search for a handler is canceled and\na search starts for the new exception in the surrounding code and on\nthe call stack (it is treated as if the entire ``try`` statement\nraised the exception).\n\nWhen a matching except clause is found, the exception is assigned to\nthe target specified after the ``as`` keyword in that except clause,\nif present, and the except clause\'s suite is executed. All except\nclauses must have an executable block. When the end of this block is\nreached, execution continues normally after the entire try statement.\n(This means that if two nested handlers exist for the same exception,\nand the exception occurs in the try clause of the inner handler, the\nouter handler will not handle the exception.)\n\nWhen an exception has been assigned using ``as target``, it is cleared\nat the end of the except clause. This is as if\n\n except E as N:\n foo\n\nwas translated to\n\n except E as N:\n try:\n foo\n finally:\n N = None\n del N\n\nThat means that you have to assign the exception to a different name\nif you want to be able to refer to it after the except clause. The\nreason for this is that with the traceback attached to them,\nexceptions will form a reference cycle with the stack frame, keeping\nall locals in that frame alive until the next garbage collection\noccurs.\n\nBefore an except clause\'s suite is executed, details about the\nexception are stored in the ``sys`` module and can be access via\n``sys.exc_info()``. ``sys.exc_info()`` returns a 3-tuple consisting\nof: ``exc_type``, the exception class; ``exc_value``, the exception\ninstance; ``exc_traceback``, a traceback object (see section *The\nstandard type hierarchy*) identifying the point in the program where\nthe exception occurred. ``sys.exc_info()`` values are restored to\ntheir previous values (before the call) when returning from a function\nthat handled an exception.\n\nThe optional ``else`` clause is executed if and when control flows off\nthe end of the ``try`` clause. [2] Exceptions in the ``else`` clause\nare not handled by the preceding ``except`` clauses.\n\nIf ``finally`` is present, it specifies a \'cleanup\' handler. The\n``try`` clause is executed, including any ``except`` and ``else``\nclauses. If an exception occurs in any of the clauses and is not\nhandled, the exception is temporarily saved. The ``finally`` clause is\nexecuted. If there is a saved exception, it is re-raised at the end\nof the ``finally`` clause. If the ``finally`` clause raises another\nexception or executes a ``return`` or ``break`` statement, the saved\nexception is lost. The exception information is not available to the\nprogram during execution of the ``finally`` clause.\n\nWhen a ``return``, ``break`` or ``continue`` statement is executed in\nthe ``try`` suite of a ``try``...``finally`` statement, the\n``finally`` clause is also executed \'on the way out.\' A ``continue``\nstatement is illegal in the ``finally`` clause. (The reason is a\nproblem with the current implementation --- this restriction may be\nlifted in the future).\n\nAdditional information on exceptions can be found in section\n*Exceptions*, and information on using the ``raise`` statement to\ngenerate exceptions may be found in section *The raise statement*.\n', + 'types': '\nThe standard type hierarchy\n***************************\n\nBelow is a list of the types that are built into Python. Extension\nmodules (written in C, Java, or other languages, depending on the\nimplementation) can define additional types. Future versions of\nPython may add types to the type hierarchy (e.g., rational numbers,\nefficiently stored arrays of integers, etc.).\n\nSome of the type descriptions below contain a paragraph listing\n\'special attributes.\' These are attributes that provide access to the\nimplementation and are not intended for general use. Their definition\nmay change in the future.\n\nNone\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name ``None``.\n It is used to signify the absence of a value in many situations,\n e.g., it is returned from functions that don\'t explicitly return\n anything. Its truth value is false.\n\nNotImplemented\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name\n ``NotImplemented``. Numeric methods and rich comparison methods may\n return this value if they do not implement the operation for the\n operands provided. (The interpreter will then try the reflected\n operation, or some other fallback, depending on the operator.) Its\n truth value is true.\n\nEllipsis\n This type has a single value. There is a single object with this\n value. This object is accessed through the literal ``...`` or the\n built-in name ``Ellipsis``. Its truth value is true.\n\n``numbers.Number``\n These are created by numeric literals and returned as results by\n arithmetic operators and arithmetic built-in functions. Numeric\n objects are immutable; once created their value never changes.\n Python numbers are of course strongly related to mathematical\n numbers, but subject to the limitations of numerical representation\n in computers.\n\n Python distinguishes between integers, floating point numbers, and\n complex numbers:\n\n ``numbers.Integral``\n These represent elements from the mathematical set of integers\n (positive and negative).\n\n There are two types of integers:\n\n Integers\n\n These represent numbers in an unlimited range, subject to\n available (virtual) memory only. For the purpose of shift\n and mask operations, a binary representation is assumed, and\n negative numbers are represented in a variant of 2\'s\n complement which gives the illusion of an infinite string of\n sign bits extending to the left.\n\n Booleans\n These represent the truth values False and True. The two\n objects representing the values False and True are the only\n Boolean objects. The Boolean type is a subtype of the integer\n type, and Boolean values behave like the values 0 and 1,\n respectively, in almost all contexts, the exception being\n that when converted to a string, the strings ``"False"`` or\n ``"True"`` are returned, respectively.\n\n The rules for integer representation are intended to give the\n most meaningful interpretation of shift and mask operations\n involving negative integers.\n\n ``numbers.Real`` (``float``)\n These represent machine-level double precision floating point\n numbers. You are at the mercy of the underlying machine\n architecture (and C or Java implementation) for the accepted\n range and handling of overflow. Python does not support single-\n precision floating point numbers; the savings in processor and\n memory usage that are usually the reason for using these is\n dwarfed by the overhead of using objects in Python, so there is\n no reason to complicate the language with two kinds of floating\n point numbers.\n\n ``numbers.Complex``\n These represent complex numbers as a pair of machine-level\n double precision floating point numbers. The same caveats apply\n as for floating point numbers. The real and imaginary parts of a\n complex number ``z`` can be retrieved through the read-only\n attributes ``z.real`` and ``z.imag``.\n\nSequences\n These represent finite ordered sets indexed by non-negative\n numbers. The built-in function ``len()`` returns the number of\n items of a sequence. When the length of a sequence is *n*, the\n index set contains the numbers 0, 1, ..., *n*-1. Item *i* of\n sequence *a* is selected by ``a[i]``.\n\n Sequences also support slicing: ``a[i:j]`` selects all items with\n index *k* such that *i* ``<=`` *k* ``<`` *j*. When used as an\n expression, a slice is a sequence of the same type. This implies\n that the index set is renumbered so that it starts at 0.\n\n Some sequences also support "extended slicing" with a third "step"\n parameter: ``a[i:j:k]`` selects all items of *a* with index *x*\n where ``x = i + n*k``, *n* ``>=`` ``0`` and *i* ``<=`` *x* ``<``\n *j*.\n\n Sequences are distinguished according to their mutability:\n\n Immutable sequences\n An object of an immutable sequence type cannot change once it is\n created. (If the object contains references to other objects,\n these other objects may be mutable and may be changed; however,\n the collection of objects directly referenced by an immutable\n object cannot change.)\n\n The following types are immutable sequences:\n\n Strings\n The items of a string object are Unicode code units. A\n Unicode code unit is represented by a string object of one\n item and can hold either a 16-bit or 32-bit value\n representing a Unicode ordinal (the maximum value for the\n ordinal is given in ``sys.maxunicode``, and depends on how\n Python is configured at compile time). Surrogate pairs may\n be present in the Unicode object, and will be reported as two\n separate items. The built-in functions ``chr()`` and\n ``ord()`` convert between code units and nonnegative integers\n representing the Unicode ordinals as defined in the Unicode\n Standard 3.0. Conversion from and to other encodings are\n possible through the string method ``encode()``.\n\n Tuples\n The items of a tuple are arbitrary Python objects. Tuples of\n two or more items are formed by comma-separated lists of\n expressions. A tuple of one item (a \'singleton\') can be\n formed by affixing a comma to an expression (an expression by\n itself does not create a tuple, since parentheses must be\n usable for grouping of expressions). An empty tuple can be\n formed by an empty pair of parentheses.\n\n Mutable sequences\n Mutable sequences can be changed after they are created. The\n subscription and slicing notations can be used as the target of\n assignment and ``del`` (delete) statements.\n\n There is currently a single intrinsic mutable sequence type:\n\n Lists\n The items of a list are arbitrary Python objects. Lists are\n formed by placing a comma-separated list of expressions in\n square brackets. (Note that there are no special cases needed\n to form lists of length 0 or 1.)\n\n Bytes\n A bytes object is a mutable array. The items are 8-bit\n bytes, represented by integers in the range 0 <= x < 256.\n Bytes literals (like ``b\'abc\'`` and the built-in function\n ``bytes()`` can be used to construct bytes objects. Also,\n bytes objects can be decoded to strings via the ``decode()``\n method.\n\n The extension module ``array`` provides an additional example of\n a mutable sequence type.\n\nSet types\n These represent unordered, finite sets of unique, immutable\n objects. As such, they cannot be indexed by any subscript. However,\n they can be iterated over, and the built-in function ``len()``\n returns the number of items in a set. Common uses for sets are fast\n membership testing, removing duplicates from a sequence, and\n computing mathematical operations such as intersection, union,\n difference, and symmetric difference.\n\n For set elements, the same immutability rules apply as for\n dictionary keys. Note that numeric types obey the normal rules for\n numeric comparison: if two numbers compare equal (e.g., ``1`` and\n ``1.0``), only one of them can be contained in a set.\n\n There are currently two intrinsic set types:\n\n Sets\n These represent a mutable set. They are created by the built-in\n ``set()`` constructor and can be modified afterwards by several\n methods, such as ``add()``.\n\n Frozen sets\n These represent an immutable set. They are created by the\n built-in ``frozenset()`` constructor. As a frozenset is\n immutable and *hashable*, it can be used again as an element of\n another set, or as a dictionary key.\n\nMappings\n These represent finite sets of objects indexed by arbitrary index\n sets. The subscript notation ``a[k]`` selects the item indexed by\n ``k`` from the mapping ``a``; this can be used in expressions and\n as the target of assignments or ``del`` statements. The built-in\n function ``len()`` returns the number of items in a mapping.\n\n There is currently a single intrinsic mapping type:\n\n Dictionaries\n These represent finite sets of objects indexed by nearly\n arbitrary values. The only types of values not acceptable as\n keys are values containing lists or dictionaries or other\n mutable types that are compared by value rather than by object\n identity, the reason being that the efficient implementation of\n dictionaries requires a key\'s hash value to remain constant.\n Numeric types used for keys obey the normal rules for numeric\n comparison: if two numbers compare equal (e.g., ``1`` and\n ``1.0``) then they can be used interchangeably to index the same\n dictionary entry.\n\n Dictionaries are mutable; they can be created by the ``{...}``\n notation (see section *Dictionary displays*).\n\n The extension modules ``dbm.ndbm``, ``dbm.gnu``, and ``bsddb``\n provide additional examples of mapping types.\n\nCallable types\n These are the types to which the function call operation (see\n section *Calls*) can be applied:\n\n User-defined functions\n A user-defined function object is created by a function\n definition (see section *Function definitions*). It should be\n called with an argument list containing the same number of items\n as the function\'s formal parameter list.\n\n Special attributes:\n\n +---------------------------+---------------------------------+-------------+\n | Attribute | Meaning | |\n +===========================+=================================+=============+\n | ``__doc__`` | The function\'s documentation | Writable |\n | | string, or ``None`` if | |\n | | unavailable | |\n +---------------------------+---------------------------------+-------------+\n | ``__name__`` | The function\'s name | Writable |\n +---------------------------+---------------------------------+-------------+\n | ``__module__`` | The name of the module the | Writable |\n | | function was defined in, or | |\n | | ``None`` if unavailable. | |\n +---------------------------+---------------------------------+-------------+\n | ``__defaults__`` | A tuple containing default | Writable |\n | | argument values for those | |\n | | arguments that have defaults, | |\n | | or ``None`` if no arguments | |\n | | have a default value | |\n +---------------------------+---------------------------------+-------------+\n | ``__code__`` | The code object representing | Writable |\n | | the compiled function body. | |\n +---------------------------+---------------------------------+-------------+\n | ``__globals__`` | A reference to the dictionary | Read-only |\n | | that holds the function\'s | |\n | | global variables --- the global | |\n | | namespace of the module in | |\n | | which the function was defined. | |\n +---------------------------+---------------------------------+-------------+\n | ``__dict__`` | The namespace supporting | Writable |\n | | arbitrary function attributes. | |\n +---------------------------+---------------------------------+-------------+\n | ``__closure__`` | ``None`` or a tuple of cells | Read-only |\n | | that contain bindings for the | |\n | | function\'s free variables. | |\n +---------------------------+---------------------------------+-------------+\n | ``__annotations__`` | A dict containing annotations | Writable |\n | | of parameters. The keys of the | |\n | | dict are the parameter names, | |\n | | or ``\'return\'`` for the return | |\n | | annotation, if provided. | |\n +---------------------------+---------------------------------+-------------+\n | ``__kwdefaults__`` | A dict containing defaults for | Writable |\n | | keyword-only parameters. | |\n +---------------------------+---------------------------------+-------------+\n\n Most of the attributes labelled "Writable" check the type of the\n assigned value.\n\n Function objects also support getting and setting arbitrary\n attributes, which can be used, for example, to attach metadata\n to functions. Regular attribute dot-notation is used to get and\n set such attributes. *Note that the current implementation only\n supports function attributes on user-defined functions. Function\n attributes on built-in functions may be supported in the\n future.*\n\n Additional information about a function\'s definition can be\n retrieved from its code object; see the description of internal\n types below.\n\n Instance methods\n An instance method object combines a class, a class instance and\n any callable object (normally a user-defined function).\n\n Special read-only attributes: ``__self__`` is the class instance\n object, ``__func__`` is the function object; ``__doc__`` is the\n method\'s documentation (same as ``__func__.__doc__``);\n ``__name__`` is the method name (same as ``__func__.__name__``);\n ``__module__`` is the name of the module the method was defined\n in, or ``None`` if unavailable.\n\n Methods also support accessing (but not setting) the arbitrary\n function attributes on the underlying function object.\n\n User-defined method objects may be created when getting an\n attribute of a class (perhaps via an instance of that class), if\n that attribute is a user-defined function object or a class\n method object.\n\n When an instance method object is created by retrieving a user-\n defined function object from a class via one of its instances,\n its ``__self__`` attribute is the instance, and the method\n object is said to be bound. The new method\'s ``__func__``\n attribute is the original function object.\n\n When a user-defined method object is created by retrieving\n another method object from a class or instance, the behaviour is\n the same as for a function object, except that the ``__func__``\n attribute of the new instance is not the original method object\n but its ``__func__`` attribute.\n\n When an instance method object is created by retrieving a class\n method object from a class or instance, its ``__self__``\n attribute is the class itself, and its ``__func__`` attribute is\n the function object underlying the class method.\n\n When an instance method object is called, the underlying\n function (``__func__``) is called, inserting the class instance\n (``__self__``) in front of the argument list. For instance,\n when ``C`` is a class which contains a definition for a function\n ``f()``, and ``x`` is an instance of ``C``, calling ``x.f(1)``\n is equivalent to calling ``C.f(x, 1)``.\n\n When an instance method object is derived from a class method\n object, the "class instance" stored in ``__self__`` will\n actually be the class itself, so that calling either ``x.f(1)``\n or ``C.f(1)`` is equivalent to calling ``f(C,1)`` where ``f`` is\n the underlying function.\n\n Note that the transformation from function object to instance\n method object happens each time the attribute is retrieved from\n the instance. In some cases, a fruitful optimization is to\n assign the attribute to a local variable and call that local\n variable. Also notice that this transformation only happens for\n user-defined functions; other callable objects (and all non-\n callable objects) are retrieved without transformation. It is\n also important to note that user-defined functions which are\n attributes of a class instance are not converted to bound\n methods; this *only* happens when the function is an attribute\n of the class.\n\n Generator functions\n A function or method which uses the ``yield`` statement (see\n section *The yield statement*) is called a *generator function*.\n Such a function, when called, always returns an iterator object\n which can be used to execute the body of the function: calling\n the iterator\'s ``__next__()`` method will cause the function to\n execute until it provides a value using the ``yield`` statement.\n When the function executes a ``return`` statement or falls off\n the end, a ``StopIteration`` exception is raised and the\n iterator will have reached the end of the set of values to be\n returned.\n\n Built-in functions\n A built-in function object is a wrapper around a C function.\n Examples of built-in functions are ``len()`` and ``math.sin()``\n (``math`` is a standard built-in module). The number and type of\n the arguments are determined by the C function. Special read-\n only attributes: ``__doc__`` is the function\'s documentation\n string, or ``None`` if unavailable; ``__name__`` is the\n function\'s name; ``__self__`` is set to ``None`` (but see the\n next item); ``__module__`` is the name of the module the\n function was defined in or ``None`` if unavailable.\n\n Built-in methods\n This is really a different disguise of a built-in function, this\n time containing an object passed to the C function as an\n implicit extra argument. An example of a built-in method is\n ``alist.append()``, assuming *alist* is a list object. In this\n case, the special read-only attribute ``__self__`` is set to the\n object denoted by *list*.\n\n Classes\n Classes are callable. These objects normally act as factories\n for new instances of themselves, but variations are possible for\n class types that override ``__new__()``. The arguments of the\n call are passed to ``__new__()`` and, in the typical case, to\n ``__init__()`` to initialize the new instance.\n\n Class Instances\n Instances of arbitrary classes can be made callable by defining\n a ``__call__()`` method in their class.\n\nModules\n Modules are imported by the ``import`` statement (see section *The\n import statement*). A module object has a namespace implemented by\n a dictionary object (this is the dictionary referenced by the\n __globals__ attribute of functions defined in the module).\n Attribute references are translated to lookups in this dictionary,\n e.g., ``m.x`` is equivalent to ``m.__dict__["x"]``. A module object\n does not contain the code object used to initialize the module\n (since it isn\'t needed once the initialization is done).\n\n Attribute assignment updates the module\'s namespace dictionary,\n e.g., ``m.x = 1`` is equivalent to ``m.__dict__["x"] = 1``.\n\n Special read-only attribute: ``__dict__`` is the module\'s namespace\n as a dictionary object.\n\n Predefined (writable) attributes: ``__name__`` is the module\'s\n name; ``__doc__`` is the module\'s documentation string, or ``None``\n if unavailable; ``__file__`` is the pathname of the file from which\n the module was loaded, if it was loaded from a file. The\n ``__file__`` attribute is not present for C modules that are\n statically linked into the interpreter; for extension modules\n loaded dynamically from a shared library, it is the pathname of the\n shared library file.\n\nCustom classes\n Class objects are created by class definitions (see section *Class\n definitions*). A class has a namespace implemented by a dictionary\n object. Class attribute references are translated to lookups in\n this dictionary, e.g., ``C.x`` is translated to\n ``C.__dict__["x"]``. When the attribute name is not found there,\n the attribute search continues in the base classes. The search is\n depth-first, left-to-right in the order of occurrence in the base\n class list.\n\n When a class attribute reference (for class ``C``, say) would yield\n a class method object, it is transformed into an instance method\n object whose ``__self__`` attributes is ``C``. When it would yield\n a static method object, it is transformed into the object wrapped\n by the static method object. See section *Implementing Descriptors*\n for another way in which attributes retrieved from a class may\n differ from those actually contained in its ``__dict__``.\n\n Class attribute assignments update the class\'s dictionary, never\n the dictionary of a base class.\n\n A class object can be called (see above) to yield a class instance\n (see below).\n\n Special attributes: ``__name__`` is the class name; ``__module__``\n is the module name in which the class was defined; ``__dict__`` is\n the dictionary containing the class\'s namespace; ``__bases__`` is a\n tuple (possibly empty or a singleton) containing the base classes,\n in the order of their occurrence in the base class list;\n ``__doc__`` is the class\'s documentation string, or None if\n undefined.\n\nClass instances\n A class instance is created by calling a class object (see above).\n A class instance has a namespace implemented as a dictionary which\n is the first place in which attribute references are searched.\n When an attribute is not found there, and the instance\'s class has\n an attribute by that name, the search continues with the class\n attributes. If a class attribute is found that is a user-defined\n function object, it is transformed into an instance method object\n whose ``__self__`` attribute is the instance. Static method and\n class method objects are also transformed; see above under\n "Classes". See section *Implementing Descriptors* for another way\n in which attributes of a class retrieved via its instances may\n differ from the objects actually stored in the class\'s\n ``__dict__``. If no class attribute is found, and the object\'s\n class has a ``__getattr__()`` method, that is called to satisfy the\n lookup.\n\n Attribute assignments and deletions update the instance\'s\n dictionary, never a class\'s dictionary. If the class has a\n ``__setattr__()`` or ``__delattr__()`` method, this is called\n instead of updating the instance dictionary directly.\n\n Class instances can pretend to be numbers, sequences, or mappings\n if they have methods with certain special names. See section\n *Special method names*.\n\n Special attributes: ``__dict__`` is the attribute dictionary;\n ``__class__`` is the instance\'s class.\n\nFiles\n A file object represents an open file. File objects are created by\n the ``open()`` built-in function, and also by ``os.popen()``,\n ``os.fdopen()``, and the ``makefile()`` method of socket objects\n (and perhaps by other functions or methods provided by extension\n modules). The objects ``sys.stdin``, ``sys.stdout`` and\n ``sys.stderr`` are initialized to file objects corresponding to the\n interpreter\'s standard input, output and error streams. See *File\n Objects* for complete documentation of file objects.\n\nInternal types\n A few types used internally by the interpreter are exposed to the\n user. Their definitions may change with future versions of the\n interpreter, but they are mentioned here for completeness.\n\n Code objects\n Code objects represent *byte-compiled* executable Python code,\n or *bytecode*. The difference between a code object and a\n function object is that the function object contains an explicit\n reference to the function\'s globals (the module in which it was\n defined), while a code object contains no context; also the\n default argument values are stored in the function object, not\n in the code object (because they represent values calculated at\n run-time). Unlike function objects, code objects are immutable\n and contain no references (directly or indirectly) to mutable\n objects.\n\n Special read-only attributes: ``co_name`` gives the function\n name; ``co_argcount`` is the number of positional arguments\n (including arguments with default values); ``co_nlocals`` is the\n number of local variables used by the function (including\n arguments); ``co_varnames`` is a tuple containing the names of\n the local variables (starting with the argument names);\n ``co_cellvars`` is a tuple containing the names of local\n variables that are referenced by nested functions;\n ``co_freevars`` is a tuple containing the names of free\n variables; ``co_code`` is a string representing the sequence of\n bytecode instructions; ``co_consts`` is a tuple containing the\n literals used by the bytecode; ``co_names`` is a tuple\n containing the names used by the bytecode; ``co_filename`` is\n the filename from which the code was compiled;\n ``co_firstlineno`` is the first line number of the function;\n ``co_lnotab`` is a string encoding the mapping from bytecode\n offsets to line numbers (for details see the source code of the\n interpreter); ``co_stacksize`` is the required stack size\n (including local variables); ``co_flags`` is an integer encoding\n a number of flags for the interpreter.\n\n The following flag bits are defined for ``co_flags``: bit\n ``0x04`` is set if the function uses the ``*arguments`` syntax\n to accept an arbitrary number of positional arguments; bit\n ``0x08`` is set if the function uses the ``**keywords`` syntax\n to accept arbitrary keyword arguments; bit ``0x20`` is set if\n the function is a generator.\n\n Future feature declarations (``from __future__ import\n division``) also use bits in ``co_flags`` to indicate whether a\n code object was compiled with a particular feature enabled: bit\n ``0x2000`` is set if the function was compiled with future\n division enabled; bits ``0x10`` and ``0x1000`` were used in\n earlier versions of Python.\n\n Other bits in ``co_flags`` are reserved for internal use.\n\n If a code object represents a function, the first item in\n ``co_consts`` is the documentation string of the function, or\n ``None`` if undefined.\n\n Frame objects\n Frame objects represent execution frames. They may occur in\n traceback objects (see below).\n\n Special read-only attributes: ``f_back`` is to the previous\n stack frame (towards the caller), or ``None`` if this is the\n bottom stack frame; ``f_code`` is the code object being executed\n in this frame; ``f_locals`` is the dictionary used to look up\n local variables; ``f_globals`` is used for global variables;\n ``f_builtins`` is used for built-in (intrinsic) names;\n ``f_lasti`` gives the precise instruction (this is an index into\n the bytecode string of the code object).\n\n Special writable attributes: ``f_trace``, if not ``None``, is a\n function called at the start of each source code line (this is\n used by the debugger); ``f_exc_type``, ``f_exc_value``,\n ``f_exc_traceback`` represent the last exception raised in the\n parent frame provided another exception was ever raised in the\n current frame (in all other cases they are None); ``f_lineno``\n is the current line number of the frame --- writing to this from\n within a trace function jumps to the given line (only for the\n bottom-most frame). A debugger can implement a Jump command\n (aka Set Next Statement) by writing to f_lineno.\n\n Traceback objects\n Traceback objects represent a stack trace of an exception. A\n traceback object is created when an exception occurs. When the\n search for an exception handler unwinds the execution stack, at\n each unwound level a traceback object is inserted in front of\n the current traceback. When an exception handler is entered,\n the stack trace is made available to the program. (See section\n *The try statement*.) It is accessible as the third item of the\n tuple returned by ``sys.exc_info()``. When the program contains\n no suitable handler, the stack trace is written (nicely\n formatted) to the standard error stream; if the interpreter is\n interactive, it is also made available to the user as\n ``sys.last_traceback``.\n\n Special read-only attributes: ``tb_next`` is the next level in\n the stack trace (towards the frame where the exception\n occurred), or ``None`` if there is no next level; ``tb_frame``\n points to the execution frame of the current level;\n ``tb_lineno`` gives the line number where the exception\n occurred; ``tb_lasti`` indicates the precise instruction. The\n line number and last instruction in the traceback may differ\n from the line number of its frame object if the exception\n occurred in a ``try`` statement with no matching except clause\n or with a finally clause.\n\n Slice objects\n Slice objects are used to represent slices for ``__getitem__()``\n methods. They are also created by the built-in ``slice()``\n function.\n\n Special read-only attributes: ``start`` is the lower bound;\n ``stop`` is the upper bound; ``step`` is the step value; each is\n ``None`` if omitted. These attributes can have any type.\n\n Slice objects support one method:\n\n slice.indices(self, length)\n\n This method takes a single integer argument *length* and\n computes information about the slice that the slice object\n would describe if applied to a sequence of *length* items.\n It returns a tuple of three integers; respectively these are\n the *start* and *stop* indices and the *step* or stride\n length of the slice. Missing or out-of-bounds indices are\n handled in a manner consistent with regular slices.\n\n Static method objects\n Static method objects provide a way of defeating the\n transformation of function objects to method objects described\n above. A static method object is a wrapper around any other\n object, usually a user-defined method object. When a static\n method object is retrieved from a class or a class instance, the\n object actually returned is the wrapped object, which is not\n subject to any further transformation. Static method objects are\n not themselves callable, although the objects they wrap usually\n are. Static method objects are created by the built-in\n ``staticmethod()`` constructor.\n\n Class method objects\n A class method object, like a static method object, is a wrapper\n around another object that alters the way in which that object\n is retrieved from classes and class instances. The behaviour of\n class method objects upon such retrieval is described above,\n under "User-defined methods". Class method objects are created\n by the built-in ``classmethod()`` constructor.\n', + 'typesfunctions': '\nFunctions\n*********\n\nFunction objects are created by function definitions. The only\noperation on a function object is to call it: ``func(argument-list)``.\n\nThere are really two flavors of function objects: built-in functions\nand user-defined functions. Both support the same operation (to call\nthe function), but the implementation is different, hence the\ndifferent object types.\n\nSee *Function definitions* for more information.\n', + 'typesmapping': '\nMapping Types --- ``dict``\n**************************\n\nA *mapping* object maps *hashable* values to arbitrary objects.\nMappings are mutable objects. There is currently only one standard\nmapping type, the *dictionary*. (For other containers see the built\nin ``list``, ``set``, and ``tuple`` classes, and the ``collections``\nmodule.)\n\nA dictionary\'s keys are *almost* arbitrary values. Values that are\nnot *hashable*, that is, values containing lists, dictionaries or\nother mutable types (that are compared by value rather than by object\nidentity) may not be used as keys. Numeric types used for keys obey\nthe normal rules for numeric comparison: if two numbers compare equal\n(such as ``1`` and ``1.0``) then they can be used interchangeably to\nindex the same dictionary entry. (Note however, that since computers\nstore floating-point numbers as approximations it is usually unwise to\nuse them as dictionary keys.)\n\nDictionaries can be created by placing a comma-separated list of\n``key: value`` pairs within braces, for example: ``{\'jack\': 4098,\n\'sjoerd\': 4127}`` or ``{4098: \'jack\', 4127: \'sjoerd\'}``, or by the\n``dict`` constructor.\n\nclass dict([arg])\n\n Return a new dictionary initialized from an optional positional\n argument or from a set of keyword arguments. If no arguments are\n given, return a new empty dictionary. If the positional argument\n *arg* is a mapping object, return a dictionary mapping the same\n keys to the same values as does the mapping object. Otherwise the\n positional argument must be a sequence, a container that supports\n iteration, or an iterator object. The elements of the argument\n must each also be of one of those kinds, and each must in turn\n contain exactly two objects. The first is used as a key in the new\n dictionary, and the second as the key\'s value. If a given key is\n seen more than once, the last value associated with it is retained\n in the new dictionary.\n\n If keyword arguments are given, the keywords themselves with their\n associated values are added as items to the dictionary. If a key\n is specified both in the positional argument and as a keyword\n argument, the value associated with the keyword is retained in the\n dictionary. For example, these all return a dictionary equal to\n ``{"one": 2, "two": 3}``:\n\n * ``dict(one=2, two=3)``\n\n * ``dict({\'one\': 2, \'two\': 3})``\n\n * ``dict(zip((\'one\', \'two\'), (2, 3)))``\n\n * ``dict([[\'two\', 3], [\'one\', 2]])``\n\n The first example only works for keys that are valid Python\n identifiers; the others work with any valid keys.\n\n These are the operations that dictionaries support (and therefore,\n custom mapping types should support too):\n\n len(d)\n\n Return the number of items in the dictionary *d*.\n\n d[key]\n\n Return the item of *d* with key *key*. Raises a ``KeyError`` if\n *key* is not in the map.\n\n If a subclass of dict defines a method ``__missing__()``, if the\n key *key* is not present, the ``d[key]`` operation calls that\n method with the key *key* as argument. The ``d[key]`` operation\n then returns or raises whatever is returned or raised by the\n ``__missing__(key)`` call if the key is not present. No other\n operations or methods invoke ``__missing__()``. If\n ``__missing__()`` is not defined, ``KeyError`` is raised.\n ``__missing__()`` must be a method; it cannot be an instance\n variable. For an example, see ``collections.defaultdict``.\n\n d[key] = value\n\n Set ``d[key]`` to *value*.\n\n del d[key]\n\n Remove ``d[key]`` from *d*. Raises a ``KeyError`` if *key* is\n not in the map.\n\n key in d\n\n Return ``True`` if *d* has a key *key*, else ``False``.\n\n key not in d\n\n Equivalent to ``not key in d``.\n\n clear()\n\n Remove all items from the dictionary.\n\n copy()\n\n Return a shallow copy of the dictionary.\n\n fromkeys(seq[, value])\n\n Create a new dictionary with keys from *seq* and values set to\n *value*.\n\n ``fromkeys()`` is a class method that returns a new dictionary.\n *value* defaults to ``None``.\n\n get(key[, default])\n\n Return the value for *key* if *key* is in the dictionary, else\n *default*. If *default* is not given, it defaults to ``None``,\n so that this method never raises a ``KeyError``.\n\n items()\n\n Return a new view of the dictionary\'s items (``(key, value)``\n pairs). See below for documentation of view objects.\n\n keys()\n\n Return a new view of the dictionary\'s keys. See below for\n documentation of view objects.\n\n pop(key[, default])\n\n If *key* is in the dictionary, remove it and return its value,\n else return *default*. If *default* is not given and *key* is\n not in the dictionary, a ``KeyError`` is raised.\n\n popitem()\n\n Remove and return an arbitrary ``(key, value)`` pair from the\n dictionary.\n\n ``popitem()`` is useful to destructively iterate over a\n dictionary, as often used in set algorithms. If the dictionary\n is empty, calling ``popitem()`` raises a ``KeyError``.\n\n setdefault(key[, default])\n\n If *key* is in the dictionary, return its value. If not, insert\n *key* with a value of *default* and return *default*. *default*\n defaults to ``None``.\n\n update([other])\n\n Update the dictionary with the key/value pairs from *other*,\n overwriting existing keys. Return ``None``.\n\n ``update()`` accepts either another dictionary object or an\n iterable of key/value pairs (as a tuple or other iterable of\n length two). If keyword arguments are specified, the\n dictionary is then is updated with those key/value pairs:\n ``d.update(red=1, blue=2)``.\n\n values()\n\n Return a new view of the dictionary\'s values. See below for\n documentation of view objects.\n\n\nDictionary view objects\n=======================\n\nThe objects returned by ``dict.keys()``, ``dict.values()`` and\n``dict.items()`` are *view objects*. They provide a dynamic view on\nthe dictionary\'s entries, which means that when the dictionary\nchanges, the view reflects these changes. The keys and items views\nhave a set-like character since their entries\n\nDictionary views can be iterated over to yield their respective data,\nand support membership tests:\n\nlen(dictview)\n\n Return the number of entries in the dictionary.\n\niter(dictview)\n\n Return an iterator over the keys, values or items (represented as\n tuples of ``(key, value)``) in the dictionary.\n\n Keys and values are iterated over in an arbitrary order which is\n non-random, varies across Python implementations, and depends on\n the dictionary\'s history of insertions and deletions. If keys,\n values and items views are iterated over with no intervening\n modifications to the dictionary, the order of items will directly\n correspond. This allows the creation of ``(value, key)`` pairs\n using ``zip()``: ``pairs = zip(d.values(), d.keys())``. Another\n way to create the same list is ``pairs = [(v, k) for (k, v) in\n d.items()]``.\n\nx in dictview\n\n Return ``True`` if *x* is in the underlying dictionary\'s keys,\n values or items (in the latter case, *x* should be a ``(key,\n value)`` tuple).\n\nThe keys and items views also provide set-like operations ("other"\nhere refers to another dictionary view or a set):\n\ndictview & other\n\n Return the intersection of the dictview and the other object as a\n new set.\n\ndictview | other\n\n Return the union of the dictview and the other object as a new set.\n\ndictview - other\n\n Return the difference between the dictview and the other object\n (all elements in *dictview* that aren\'t in *other*) as a new set.\n\ndictview ^ other\n\n Return the symmetric difference (all elements either in *dictview*\n or *other*, but not in both) of the dictview and the other object\n as a new set.\n\nWarning: Since a dictionary\'s values are not required to be hashable, any of\n these four operations will fail if an involved dictionary contains\n such a value.\n\nAn example of dictionary view usage:\n\n >>> dishes = {\'eggs\': 2, \'sausage\': 1, \'bacon\': 1, \'spam\': 500}\n >>> keys = dishes.keys()\n >>> values = dishes.values()\n\n >>> # iteration\n >>> n = 0\n >>> for val in values:\n ... n += val\n >>> print(n)\n 504\n\n >>> # keys and values are iterated over in the same order\n >>> list(keys)\n [\'eggs\', \'bacon\', \'sausage\', \'spam\']\n >>> list(values)\n [2, 1, 1, 500]\n\n >>> # view objects are dynamic and reflect dict changes\n >>> del dishes[\'eggs\']\n >>> del dishes[\'sausage\']\n >>> list(keys)\n [\'spam\', \'bacon\']\n\n >>> # set operations\n >>> keys & {\'eggs\', \'bacon\', \'salad\'}\n {\'eggs\', \'bacon\'}\n', + 'typesmethods': "\nMethods\n*******\n\nMethods are functions that are called using the attribute notation.\nThere are two flavors: built-in methods (such as ``append()`` on\nlists) and class instance methods. Built-in methods are described\nwith the types that support them.\n\nIf you access a method (a function defined in a class namespace)\nthrough an instance, you get a special object: a *bound method* (also\ncalled *instance method*) object. When called, it will add the\n``self`` argument to the argument list. Bound methods have two\nspecial read-only attributes: ``m.__self__`` is the object on which\nthe method operates, and ``m.__func__`` is the function implementing\nthe method. Calling ``m(arg-1, arg-2, ..., arg-n)`` is completely\nequivalent to calling ``m.__func__(m.__self__, arg-1, arg-2, ...,\narg-n)``.\n\nLike function objects, bound method objects support getting arbitrary\nattributes. However, since method attributes are actually stored on\nthe underlying function object (``meth.__func__``), setting method\nattributes on bound methods is disallowed. Attempting to set a method\nattribute results in a ``TypeError`` being raised. In order to set a\nmethod attribute, you need to explicitly set it on the underlying\nfunction object:\n\n class C:\n def method(self):\n pass\n\n c = C()\n c.method.__func__.whoami = 'my name is c'\n\nSee *The standard type hierarchy* for more information.\n", + 'typesmodules': "\nModules\n*******\n\nThe only special operation on a module is attribute access:\n``m.name``, where *m* is a module and *name* accesses a name defined\nin *m*'s symbol table. Module attributes can be assigned to. (Note\nthat the ``import`` statement is not, strictly speaking, an operation\non a module object; ``import foo`` does not require a module object\nnamed *foo* to exist, rather it requires an (external) *definition*\nfor a module named *foo* somewhere.)\n\nA special member of every module is ``__dict__``. This is the\ndictionary containing the module's symbol table. Modifying this\ndictionary will actually change the module's symbol table, but direct\nassignment to the ``__dict__`` attribute is not possible (you can\nwrite ``m.__dict__['a'] = 1``, which defines ``m.a`` to be ``1``, but\nyou can't write ``m.__dict__ = {}``). Modifying ``__dict__`` directly\nis not recommended.\n\nModules built into the interpreter are written like this: ````. If loaded from a file, they are written as\n````.\n", + 'typesseq': '\nSequence Types --- ``str``, ``bytes``, ``bytearray``, ``list``, ``tuple``, ``range``\n************************************************************************************\n\nThere are five sequence types: strings, byte sequences, byte arrays,\nlists, tuples, and range objects. (For other containers see the\nbuilt-in ``dict``, ``list``, ``set``, and ``tuple`` classes, and the\n``collections`` module.)\n\nStrings contain Unicode characters. Their literals are written in\nsingle or double quotes: ``\'xyzzy\'``, ``"frobozz"``. See *String and\nBytes literals* for more about string literals. In addition to the\nfunctionality described here, there are also string-specific methods\ndescribed in the *String Methods* section.\n\nBytes and bytearray objects contain single bytes -- the former is\nimmutable while the latter is a mutable sequence. Bytes objects can\nbe constructed from literals too; use a ``b`` prefix with normal\nstring syntax: ``b\'xyzzy\'``. To construct byte arrays, use the\n``bytearray()`` function.\n\nWarning: While string objects are sequences of characters (represented by\n strings of length 1), bytes and bytearray objects are sequences of\n *integers* (between 0 and 255), representing the ASCII value of\n single bytes. That means that for a bytes or bytearray object *b*,\n ``b[0]`` will be an integer, while ``b[0:1]`` will be a bytes or\n bytearray object of length 1.Also, while in previous Python\n versions, byte strings and Unicode strings could be exchanged for\n each other rather freely (barring encoding issues), strings and\n bytes are now completely separate concepts. There\'s no implicit\n en-/decoding if you pass and object of the wrong type. A string\n always compares unequal to a bytes or bytearray object.\n\nLists are constructed with square brackets, separating items with\ncommas: ``[a, b, c]``. Tuples are constructed by the comma operator\n(not within square brackets), with or without enclosing parentheses,\nbut an empty tuple must have the enclosing parentheses, such as ``a,\nb, c`` or ``()``. A single item tuple must have a trailing comma,\nsuch as ``(d,)``.\n\nObjects of type range are created using the ``range()`` function.\nThey don\'t support slicing, concatenation or repetition, and using\n``in``, ``not in``, ``min()`` or ``max()`` on them is inefficient.\n\nMost sequence types support the following operations. The ``in`` and\n``not in`` operations have the same priorities as the comparison\noperations. The ``+`` and ``*`` operations have the same priority as\nthe corresponding numeric operations. [3] Additional methods are\nprovided for *Mutable Sequence Types*.\n\nThis table lists the sequence operations sorted in ascending priority\n(operations in the same box have the same priority). In the table,\n*s* and *t* are sequences of the same type; *n*, *i* and *j* are\nintegers:\n\n+--------------------+----------------------------------+------------+\n| Operation | Result | Notes |\n+====================+==================================+============+\n| ``x in s`` | ``True`` if an item of *s* is | (1) |\n| | equal to *x*, else ``False`` | |\n+--------------------+----------------------------------+------------+\n| ``x not in s`` | ``False`` if an item of *s* is | (1) |\n| | equal to *x*, else ``True`` | |\n+--------------------+----------------------------------+------------+\n| ``s + t`` | the concatenation of *s* and *t* | (6) |\n+--------------------+----------------------------------+------------+\n| ``s * n, n * s`` | *n* shallow copies of *s* | (2) |\n| | concatenated | |\n+--------------------+----------------------------------+------------+\n| ``s[i]`` | *i*\'th item of *s*, origin 0 | (3) |\n+--------------------+----------------------------------+------------+\n| ``s[i:j]`` | slice of *s* from *i* to *j* | (3)(4) |\n+--------------------+----------------------------------+------------+\n| ``s[i:j:k]`` | slice of *s* from *i* to *j* | (3)(5) |\n| | with step *k* | |\n+--------------------+----------------------------------+------------+\n| ``len(s)`` | length of *s* | |\n+--------------------+----------------------------------+------------+\n| ``min(s)`` | smallest item of *s* | |\n+--------------------+----------------------------------+------------+\n| ``max(s)`` | largest item of *s* | |\n+--------------------+----------------------------------+------------+\n\nSequence types also support comparisons. In particular, tuples and\nlists are compared lexicographically by comparing corresponding\nelements. This means that to compare equal, every element must\ncompare equal and the two sequences must be of the same type and have\nthe same length. (For full details see *Comparisons* in the language\nreference.)\n\nNotes:\n\n1. When *s* is a string object, the ``in`` and ``not in`` operations\n act like a substring test.\n\n2. Values of *n* less than ``0`` are treated as ``0`` (which yields an\n empty sequence of the same type as *s*). Note also that the copies\n are shallow; nested structures are not copied. This often haunts\n new Python programmers; consider:\n\n >>> lists = [[]] * 3\n >>> lists\n [[], [], []]\n >>> lists[0].append(3)\n >>> lists\n [[3], [3], [3]]\n\n What has happened is that ``[[]]`` is a one-element list containing\n an empty list, so all three elements of ``[[]] * 3`` are (pointers\n to) this single empty list. Modifying any of the elements of\n ``lists`` modifies this single list. You can create a list of\n different lists this way:\n\n >>> lists = [[] for i in range(3)]\n >>> lists[0].append(3)\n >>> lists[1].append(5)\n >>> lists[2].append(7)\n >>> lists\n [[3], [5], [7]]\n\n3. If *i* or *j* is negative, the index is relative to the end of the\n string: ``len(s) + i`` or ``len(s) + j`` is substituted. But note\n that ``-0`` is still ``0``.\n\n4. The slice of *s* from *i* to *j* is defined as the sequence of\n items with index *k* such that ``i <= k < j``. If *i* or *j* is\n greater than ``len(s)``, use ``len(s)``. If *i* is omitted or\n ``None``, use ``0``. If *j* is omitted or ``None``, use\n ``len(s)``. If *i* is greater than or equal to *j*, the slice is\n empty.\n\n5. The slice of *s* from *i* to *j* with step *k* is defined as the\n sequence of items with index ``x = i + n*k`` such that ``0 <= n <\n (j-i)/k``. In other words, the indices are ``i``, ``i+k``,\n ``i+2*k``, ``i+3*k`` and so on, stopping when *j* is reached (but\n never including *j*). If *i* or *j* is greater than ``len(s)``,\n use ``len(s)``. If *i* or *j* are omitted or ``None``, they become\n "end" values (which end depends on the sign of *k*). Note, *k*\n cannot be zero. If *k* is ``None``, it is treated like ``1``.\n\n6. If *s* and *t* are both strings, some Python implementations such\n as CPython can usually perform an in-place optimization for\n assignments of the form ``s=s+t`` or ``s+=t``. When applicable,\n this optimization makes quadratic run-time much less likely. This\n optimization is both version and implementation dependent. For\n performance sensitive code, it is preferable to use the\n ``str.join()`` method which assures consistent linear concatenation\n performance across versions and implementations.\n\n\nString Methods\n==============\n\nString objects support the methods listed below. Note that none of\nthese methods take keyword arguments.\n\nIn addition, Python\'s strings support the sequence type methods\ndescribed in the *Sequence Types --- str, bytes, bytearray, list,\ntuple, range* section. To output formatted strings, see the *String\nFormatting* section. Also, see the ``re`` module for string functions\nbased on regular expressions.\n\nstr.capitalize()\n\n Return a copy of the string with only its first character\n capitalized.\n\nstr.center(width[, fillchar])\n\n Return centered in a string of length *width*. Padding is done\n using the specified *fillchar* (default is a space).\n\nstr.count(sub[, start[, end]])\n\n Return the number of occurrences of substring *sub* in the range\n [*start*, *end*]. Optional arguments *start* and *end* are\n interpreted as in slice notation.\n\nstr.encode([encoding[, errors]])\n\n Return an encoded version of the string. Default encoding is the\n current default string encoding. *errors* may be given to set a\n different error handling scheme. The default for *errors* is\n ``\'strict\'``, meaning that encoding errors raise a\n ``UnicodeError``. Other possible values are ``\'ignore\'``,\n ``\'replace\'``, ``\'xmlcharrefreplace\'``, ``\'backslashreplace\'`` and\n any other name registered via ``codecs.register_error()``, see\n section *Codec Base Classes*. For a list of possible encodings, see\n section *Standard Encodings*.\n\nstr.endswith(suffix[, start[, end]])\n\n Return ``True`` if the string ends with the specified *suffix*,\n otherwise return ``False``. *suffix* can also be a tuple of\n suffixes to look for. With optional *start*, test beginning at\n that position. With optional *end*, stop comparing at that\n position.\n\nstr.expandtabs([tabsize])\n\n Return a copy of the string where all tab characters are replaced\n by one or more spaces, depending on the current column and the\n given tab size. The column number is reset to zero after each\n newline occurring in the string. If *tabsize* is not given, a tab\n size of ``8`` characters is assumed. This doesn\'t understand other\n non-printing characters or escape sequences.\n\nstr.find(sub[, start[, end]])\n\n Return the lowest index in the string where substring *sub* is\n found, such that *sub* is contained in the range [*start*, *end*].\n Optional arguments *start* and *end* are interpreted as in slice\n notation. Return ``-1`` if *sub* is not found.\n\nstr.format(format_string, *args, **kwargs)\n\n Perform a string formatting operation. The *format_string*\n argument can contain literal text or replacement fields delimited\n by braces ``{}``. Each replacement field contains either the\n numeric index of a positional argument, or the name of a keyword\n argument. Returns a copy of *format_string* where each replacement\n field is replaced with the string value of the corresponding\n argument.\n\n >>> "The sum of 1 + 2 is {0}".format(1+2)\n \'The sum of 1 + 2 is 3\'\n\n See *Format String Syntax* for a description of the various\n formatting options that can be specified in format strings.\n\nstr.index(sub[, start[, end]])\n\n Like ``find()``, but raise ``ValueError`` when the substring is not\n found.\n\nstr.isalnum()\n\n Return true if all characters in the string are alphanumeric and\n there is at least one character, false otherwise.\n\nstr.isalpha()\n\n Return true if all characters in the string are alphabetic and\n there is at least one character, false otherwise.\n\nstr.isdigit()\n\n Return true if all characters in the string are digits and there is\n at least one character, false otherwise.\n\nstr.isidentifier()\n\n Return true if the string is a valid identifier according to the\n language definition, section *Identifiers and keywords*.\n\nstr.islower()\n\n Return true if all cased characters in the string are lowercase and\n there is at least one cased character, false otherwise.\n\nstr.isspace()\n\n Return true if there are only whitespace characters in the string\n and there is at least one character, false otherwise.\n\nstr.istitle()\n\n Return true if the string is a titlecased string and there is at\n least one character, for example uppercase characters may only\n follow uncased characters and lowercase characters only cased ones.\n Return false otherwise.\n\nstr.isupper()\n\n Return true if all cased characters in the string are uppercase and\n there is at least one cased character, false otherwise.\n\nstr.join(seq)\n\n Return a string which is the concatenation of the values in the\n sequence *seq*. Non-string values in *seq* will be converted to a\n string using their respective ``str()`` value. If there are any\n ``bytes`` objects in *seq*, a ``TypeError`` will be raised. The\n separator between elements is the string providing this method.\n\nstr.ljust(width[, fillchar])\n\n Return the string left justified in a string of length *width*.\n Padding is done using the specified *fillchar* (default is a\n space). The original string is returned if *width* is less than\n ``len(s)``.\n\nstr.lower()\n\n Return a copy of the string converted to lowercase.\n\nstr.lstrip([chars])\n\n Return a copy of the string with leading characters removed. The\n *chars* argument is a string specifying the set of characters to be\n removed. If omitted or ``None``, the *chars* argument defaults to\n removing whitespace. The *chars* argument is not a prefix; rather,\n all combinations of its values are stripped:\n\n >>> \' spacious \'.lstrip()\n \'spacious \'\n >>> \'www.example.com\'.lstrip(\'cmowz.\')\n \'example.com\'\n\nstr.maketrans(x[, y[, z]])\n\n This static method returns a translation table usable for\n ``str.translate()``.\n\n If there is only one argument, it must be a dictionary mapping\n Unicode ordinals (integers) or characters (strings of length 1) to\n Unicode ordinals, strings (of arbitrary lengths) or None.\n Character keys will then be converted to ordinals.\n\n If there are two arguments, they must be strings of equal length,\n and in the resulting dictionary, each character in x will be mapped\n to the character at the same position in y. If there is a third\n argument, it must be a string, whose characters will be mapped to\n None in the result.\n\nstr.partition(sep)\n\n Split the string at the first occurrence of *sep*, and return a\n 3-tuple containing the part before the separator, the separator\n itself, and the part after the separator. If the separator is not\n found, return a 3-tuple containing the string itself, followed by\n two empty strings.\n\nstr.replace(old, new[, count])\n\n Return a copy of the string with all occurrences of substring *old*\n replaced by *new*. If the optional argument *count* is given, only\n the first *count* occurrences are replaced.\n\nstr.rfind(sub[, start[, end]])\n\n Return the highest index in the string where substring *sub* is\n found, such that *sub* is contained within s[start,end]. Optional\n arguments *start* and *end* are interpreted as in slice notation.\n Return ``-1`` on failure.\n\nstr.rindex(sub[, start[, end]])\n\n Like ``rfind()`` but raises ``ValueError`` when the substring *sub*\n is not found.\n\nstr.rjust(width[, fillchar])\n\n Return the string right justified in a string of length *width*.\n Padding is done using the specified *fillchar* (default is a\n space). The original string is returned if *width* is less than\n ``len(s)``.\n\nstr.rpartition(sep)\n\n Split the string at the last occurrence of *sep*, and return a\n 3-tuple containing the part before the separator, the separator\n itself, and the part after the separator. If the separator is not\n found, return a 3-tuple containing two empty strings, followed by\n the string itself.\n\nstr.rsplit([sep[, maxsplit]])\n\n Return a list of the words in the string, using *sep* as the\n delimiter string. If *maxsplit* is given, at most *maxsplit* splits\n are done, the *rightmost* ones. If *sep* is not specified or\n ``None``, any whitespace string is a separator. Except for\n splitting from the right, ``rsplit()`` behaves like ``split()``\n which is described in detail below.\n\nstr.rstrip([chars])\n\n Return a copy of the string with trailing characters removed. The\n *chars* argument is a string specifying the set of characters to be\n removed. If omitted or ``None``, the *chars* argument defaults to\n removing whitespace. The *chars* argument is not a suffix; rather,\n all combinations of its values are stripped:\n\n >>> \' spacious \'.rstrip()\n \' spacious\'\n >>> \'mississippi\'.rstrip(\'ipz\')\n \'mississ\'\n\nstr.split([sep[, maxsplit]])\n\n Return a list of the words in the string, using *sep* as the\n delimiter string. If *maxsplit* is given, at most *maxsplit*\n splits are done (thus, the list will have at most ``maxsplit+1``\n elements). If *maxsplit* is not specified, then there is no limit\n on the number of splits (all possible splits are made).\n\n If *sep* is given, consecutive delimiters are not grouped together\n and are deemed to delimit empty strings (for example,\n ``\'1,,2\'.split(\',\')`` returns ``[\'1\', \'\', \'2\']``). The *sep*\n argument may consist of multiple characters (for example,\n ``\'1<>2<>3\'.split(\'<>\')`` returns ``[\'1\', \'2\', \'3\']``). Splitting\n an empty string with a specified separator returns ``[\'\']``.\n\n If *sep* is not specified or is ``None``, a different splitting\n algorithm is applied: runs of consecutive whitespace are regarded\n as a single separator, and the result will contain no empty strings\n at the start or end if the string has leading or trailing\n whitespace. Consequently, splitting an empty string or a string\n consisting of just whitespace with a ``None`` separator returns\n ``[]``.\n\n For example, ``\' 1 2 3 \'.split()`` returns ``[\'1\', \'2\', \'3\']``,\n and ``\' 1 2 3 \'.split(None, 1)`` returns ``[\'1\', \'2 3 \']``.\n\nstr.splitlines([keepends])\n\n Return a list of the lines in the string, breaking at line\n boundaries. Line breaks are not included in the resulting list\n unless *keepends* is given and true.\n\nstr.startswith(prefix[, start[, end]])\n\n Return ``True`` if string starts with the *prefix*, otherwise\n return ``False``. *prefix* can also be a tuple of prefixes to look\n for. With optional *start*, test string beginning at that\n position. With optional *end*, stop comparing string at that\n position.\n\nstr.strip([chars])\n\n Return a copy of the string with the leading and trailing\n characters removed. The *chars* argument is a string specifying the\n set of characters to be removed. If omitted or ``None``, the\n *chars* argument defaults to removing whitespace. The *chars*\n argument is not a prefix or suffix; rather, all combinations of its\n values are stripped:\n\n >>> \' spacious \'.strip()\n \'spacious\'\n >>> \'www.example.com\'.strip(\'cmowz.\')\n \'example\'\n\nstr.swapcase()\n\n Return a copy of the string with uppercase characters converted to\n lowercase and vice versa.\n\nstr.title()\n\n Return a titlecased version of the string: words start with\n uppercase characters, all remaining cased characters are lowercase.\n\nstr.translate(map)\n\n Return a copy of the *s* where all characters have been mapped\n through the *map* which must be a dictionary of Unicode\n ordinals(integers) to Unicode ordinals, strings or ``None``.\n Unmapped characters are left untouched. Characters mapped to\n ``None`` are deleted.\n\n A *map* for ``translate()`` is usually best created by\n ``str.maketrans()``.\n\n You can use the ``maketrans()`` helper function in the ``string``\n module to create a translation table. For string objects, set the\n *table* argument to ``None`` for translations that only delete\n characters:\n\n Note: An even more flexible approach is to create a custom character\n mapping codec using the ``codecs`` module (see\n ``encodings.cp1251`` for an example).\n\nstr.upper()\n\n Return a copy of the string converted to uppercase.\n\nstr.zfill(width)\n\n Return the numeric string left filled with zeros in a string of\n length *width*. A sign prefix is handled correctly. The original\n string is returned if *width* is less than ``len(s)``.\n\nstr.isnumeric()\n\n Return ``True`` if there are only numeric characters in S,\n ``False`` otherwise. Numeric characters include digit characters,\n and all characters that have the Unicode numeric value property,\n e.g. U+2155, VULGAR FRACTION ONE FIFTH.\n\nstr.isdecimal()\n\n Return ``True`` if there are only decimal characters in S,\n ``False`` otherwise. Decimal characters include digit characters,\n and all characters that that can be used to form decimal-radix\n numbers, e.g. U+0660, ARABIC-INDIC DIGIT ZERO.\n\n\nOld String Formatting Operations\n================================\n\nNote: The formatting operations described here are obsolete and may go\n away in future versions of Python. Use the new *String Formatting*\n in new code.\n\nString objects have one unique built-in operation: the ``%`` operator\n(modulo). This is also known as the string *formatting* or\n*interpolation* operator. Given ``format % values`` (where *format* is\na string), ``%`` conversion specifications in *format* are replaced\nwith zero or more elements of *values*. The effect is similar to the\nusing ``sprintf`` in the C language.\n\nIf *format* requires a single argument, *values* may be a single non-\ntuple object. [4] Otherwise, *values* must be a tuple with exactly\nthe number of items specified by the format string, or a single\nmapping object (for example, a dictionary).\n\nA conversion specifier contains two or more characters and has the\nfollowing components, which must occur in this order:\n\n1. The ``\'%\'`` character, which marks the start of the specifier.\n\n2. Mapping key (optional), consisting of a parenthesised sequence of\n characters (for example, ``(somename)``).\n\n3. Conversion flags (optional), which affect the result of some\n conversion types.\n\n4. Minimum field width (optional). If specified as an ``\'*\'``\n (asterisk), the actual width is read from the next element of the\n tuple in *values*, and the object to convert comes after the\n minimum field width and optional precision.\n\n5. Precision (optional), given as a ``\'.\'`` (dot) followed by the\n precision. If specified as ``\'*\'`` (an asterisk), the actual width\n is read from the next element of the tuple in *values*, and the\n value to convert comes after the precision.\n\n6. Length modifier (optional).\n\n7. Conversion type.\n\nWhen the right argument is a dictionary (or other mapping type), then\nthe formats in the string *must* include a parenthesised mapping key\ninto that dictionary inserted immediately after the ``\'%\'`` character.\nThe mapping key selects the value to be formatted from the mapping.\nFor example:\n\n>>> print(\'%(language)s has %(#)03d quote types.\' % \\\n... {\'language\': "Python", "#": 2})\nPython has 002 quote types.\n\nIn this case no ``*`` specifiers may occur in a format (since they\nrequire a sequential parameter list).\n\nThe conversion flag characters are:\n\n+-----------+-----------------------------------------------------------------------+\n| Flag | Meaning |\n+===========+=======================================================================+\n| ``\'#\'`` | The value conversion will use the "alternate form" (where defined |\n| | below). |\n+-----------+-----------------------------------------------------------------------+\n| ``\'0\'`` | The conversion will be zero padded for numeric values. |\n+-----------+-----------------------------------------------------------------------+\n| ``\'-\'`` | The converted value is left adjusted (overrides the ``\'0\'`` |\n| | conversion if both are given). |\n+-----------+-----------------------------------------------------------------------+\n| ``\' \'`` | (a space) A blank should be left before a positive number (or empty |\n| | string) produced by a signed conversion. |\n+-----------+-----------------------------------------------------------------------+\n| ``\'+\'`` | A sign character (``\'+\'`` or ``\'-\'``) will precede the conversion |\n| | (overrides a "space" flag). |\n+-----------+-----------------------------------------------------------------------+\n\nA length modifier (``h``, ``l``, or ``L``) may be present, but is\nignored as it is not necessary for Python -- so e.g. ``%ld`` is\nidentical to ``%d``.\n\nThe conversion types are:\n\n+--------------+-------------------------------------------------------+---------+\n| Conversion | Meaning | Notes |\n+==============+=======================================================+=========+\n| ``\'d\'`` | Signed integer decimal. | |\n+--------------+-------------------------------------------------------+---------+\n| ``\'i\'`` | Signed integer decimal. | |\n+--------------+-------------------------------------------------------+---------+\n| ``\'o\'`` | Signed octal value. | (1) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'u\'`` | Obselete type -- it is identical to ``\'d\'``. | (7) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'x\'`` | Signed hexadecimal (lowercase). | (2) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'X\'`` | Signed hexadecimal (uppercase). | (2) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'e\'`` | Floating point exponential format (lowercase). | (3) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'E\'`` | Floating point exponential format (uppercase). | (3) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'f\'`` | Floating point decimal format. | (3) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'F\'`` | Floating point decimal format. | (3) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'g\'`` | Floating point format. Uses lowercase exponential | (4) |\n| | format if exponent is less than -4 or not less than | |\n| | precision, decimal format otherwise. | |\n+--------------+-------------------------------------------------------+---------+\n| ``\'G\'`` | Floating point format. Uses uppercase exponential | (4) |\n| | format if exponent is less than -4 or not less than | |\n| | precision, decimal format otherwise. | |\n+--------------+-------------------------------------------------------+---------+\n| ``\'c\'`` | Single character (accepts integer or single character | |\n| | string). | |\n+--------------+-------------------------------------------------------+---------+\n| ``\'r\'`` | String (converts any python object using ``repr()``). | (5) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'s\'`` | String (converts any python object using ``str()``). | |\n+--------------+-------------------------------------------------------+---------+\n| ``\'%\'`` | No argument is converted, results in a ``\'%\'`` | |\n| | character in the result. | |\n+--------------+-------------------------------------------------------+---------+\n\nNotes:\n\n1. The alternate form causes a leading zero (``\'0\'``) to be inserted\n between left-hand padding and the formatting of the number if the\n leading character of the result is not already a zero.\n\n2. The alternate form causes a leading ``\'0x\'`` or ``\'0X\'`` (depending\n on whether the ``\'x\'`` or ``\'X\'`` format was used) to be inserted\n between left-hand padding and the formatting of the number if the\n leading character of the result is not already a zero.\n\n3. The alternate form causes the result to always contain a decimal\n point, even if no digits follow it.\n\n The precision determines the number of digits after the decimal\n point and defaults to 6.\n\n4. The alternate form causes the result to always contain a decimal\n point, and trailing zeroes are not removed as they would otherwise\n be.\n\n The precision determines the number of significant digits before\n and after the decimal point and defaults to 6.\n\n5. The precision determines the maximal number of characters used.\n\n1. See **PEP 237**.\n\nSince Python strings have an explicit length, ``%s`` conversions do\nnot assume that ``\'\\0\'`` is the end of the string.\n\nFor safety reasons, floating point precisions are clipped to 50;\n``%f`` conversions for numbers whose absolute value is over 1e25 are\nreplaced by ``%g`` conversions. [5] All other errors raise\nexceptions.\n\nAdditional string operations are defined in standard modules\n``string`` and ``re``.\n\n\nRange Type\n==========\n\nThe ``range`` type is an immutable sequence which is commonly used for\nlooping. The advantage of the ``range`` type is that an ``range``\nobject will always take the same amount of memory, no matter the size\nof the range it represents. There are no consistent performance\nadvantages.\n\nRange objects have very little behavior: they only support indexing,\niteration, and the ``len()`` function.\n\n\nMutable Sequence Types\n======================\n\nList and bytearray objects support additional operations that allow\nin-place modification of the object. Other mutable sequence types\n(when added to the language) should also support these operations.\nStrings and tuples are immutable sequence types: such objects cannot\nbe modified once created. The following operations are defined on\nmutable sequence types (where *x* is an arbitrary object).\n\nNote that while lists allow their items to be of any type, bytearray\nobject "items" are all integers in the range 0 <= x < 256.\n\n+--------------------------------+----------------------------------+-----------------------+\n| Operation | Result | Notes |\n+================================+==================================+=======================+\n| ``s[i] = x`` | item *i* of *s* is replaced by | |\n| | *x* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s[i:j] = t`` | slice of *s* from *i* to *j* is | |\n| | replaced by the contents of the | |\n| | iterable *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``del s[i:j]`` | same as ``s[i:j] = []`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s[i:j:k] = t`` | the elements of ``s[i:j:k]`` are | (1) |\n| | replaced by those of *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``del s[i:j:k]`` | removes the elements of | |\n| | ``s[i:j:k]`` from the list | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.append(x)`` | same as ``s[len(s):len(s)] = | |\n| | [x]`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.extend(x)`` | same as ``s[len(s):len(s)] = x`` | (2) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.count(x)`` | return number of *i*\'s for which | |\n| | ``s[i] == x`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.index(x[, i[, j]])`` | return smallest *k* such that | (3) |\n| | ``s[k] == x`` and ``i <= k < j`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.insert(i, x)`` | same as ``s[i:i] = [x]`` | (4) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.pop([i])`` | same as ``x = s[i]; del s[i]; | (5) |\n| | return x`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.remove(x)`` | same as ``del s[s.index(x)]`` | (3) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.reverse()`` | reverses the items of *s* in | (6) |\n| | place | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.sort([key[, reverse]])`` | sort the items of *s* in place | (6), (7), (8) |\n+--------------------------------+----------------------------------+-----------------------+\n\nNotes:\n\n1. *t* must have the same length as the slice it is replacing.\n\n2. *x* can be any iterable object.\n\n3. Raises ``ValueError`` when *x* is not found in *s*. When a negative\n index is passed as the second or third parameter to the ``index()``\n method, the sequence length is added, as for slice indices. If it\n is still negative, it is truncated to zero, as for slice indices.\n\n4. When a negative index is passed as the first parameter to the\n ``insert()`` method, the sequence length is added, as for slice\n indices. If it is still negative, it is truncated to zero, as for\n slice indices.\n\n5. The optional argument *i* defaults to ``-1``, so that by default\n the last item is removed and returned.\n\n6. The ``sort()`` and ``reverse()`` methods modify the sequence in\n place for economy of space when sorting or reversing a large\n sequence. To remind you that they operate by side effect, they\n don\'t return the sorted or reversed sequence.\n\n7. The ``sort()`` method takes optional arguments for controlling the\n comparisons. Each must be specified as a keyword argument.\n\n *key* specifies a function of one argument that is used to extract\n a comparison key from each list element: ``key=str.lower``. The\n default value is ``None``.\n\n *reverse* is a boolean value. If set to ``True``, then the list\n elements are sorted as if each comparison were reversed.\n\n The ``sort()`` method is guaranteed to be stable. A sort is stable\n if it guarantees not to change the relative order of elements that\n compare equal --- this is helpful for sorting in multiple passes\n (for example, sort by department, then by salary grade).\n\n While a list is being sorted, the effect of attempting to mutate,\n or even inspect, the list is undefined. The C implementation makes\n the list appear empty for the duration, and raises ``ValueError``\n if it can detect that the list has been mutated during a sort.\n\n8. ``sort()`` is not supported by ``bytearray`` objects.\n\n\nBytes and Byte Array Methods\n============================\n\nBytes and bytearray objects, being "strings of bytes", have all\nmethods found on strings, with the exception of ``encode()``,\n``format()`` and ``isidentifier()``, which do not make sense with\nthese types. For converting the objects to strings, they have a\n``decode()`` method.\n\nWherever one of these methods needs to interpret the bytes as\ncharacters (e.g. the ``is...()`` methods), the ASCII character set is\nassumed.\n\nNote: The methods on bytes and bytearray objects don\'t accept strings as\n their arguments, just as the methods on strings don\'t accept bytes\n as their arguments. For example, you have to write\n\n a = "abc"\n b = a.replace("a", "f")\n\n and\n\n a = b"abc"\n b = a.replace(b"a", b"f")\n\nThe bytes and bytearray types have an additional class method:\n\nbytes.fromhex(string)\n\n This ``bytes`` class method returns a bytes object, decoding the\n given string object. The string must contain two hexadecimal\n digits per byte, spaces are ignored.\n\n Example:\n\n >>> bytes.fromhex(\'f0 f1f2 \')\n b\'\\xf0\\xf1\\xf2\'\n', + 'typesseq-mutable': '\nMutable Sequence Types\n**********************\n\nList and bytearray objects support additional operations that allow\nin-place modification of the object. Other mutable sequence types\n(when added to the language) should also support these operations.\nStrings and tuples are immutable sequence types: such objects cannot\nbe modified once created. The following operations are defined on\nmutable sequence types (where *x* is an arbitrary object).\n\nNote that while lists allow their items to be of any type, bytearray\nobject "items" are all integers in the range 0 <= x < 256.\n\n+--------------------------------+----------------------------------+-----------------------+\n| Operation | Result | Notes |\n+================================+==================================+=======================+\n| ``s[i] = x`` | item *i* of *s* is replaced by | |\n| | *x* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s[i:j] = t`` | slice of *s* from *i* to *j* is | |\n| | replaced by the contents of the | |\n| | iterable *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``del s[i:j]`` | same as ``s[i:j] = []`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s[i:j:k] = t`` | the elements of ``s[i:j:k]`` are | (1) |\n| | replaced by those of *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``del s[i:j:k]`` | removes the elements of | |\n| | ``s[i:j:k]`` from the list | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.append(x)`` | same as ``s[len(s):len(s)] = | |\n| | [x]`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.extend(x)`` | same as ``s[len(s):len(s)] = x`` | (2) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.count(x)`` | return number of *i*\'s for which | |\n| | ``s[i] == x`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.index(x[, i[, j]])`` | return smallest *k* such that | (3) |\n| | ``s[k] == x`` and ``i <= k < j`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.insert(i, x)`` | same as ``s[i:i] = [x]`` | (4) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.pop([i])`` | same as ``x = s[i]; del s[i]; | (5) |\n| | return x`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.remove(x)`` | same as ``del s[s.index(x)]`` | (3) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.reverse()`` | reverses the items of *s* in | (6) |\n| | place | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.sort([key[, reverse]])`` | sort the items of *s* in place | (6), (7), (8) |\n+--------------------------------+----------------------------------+-----------------------+\n\nNotes:\n\n1. *t* must have the same length as the slice it is replacing.\n\n2. *x* can be any iterable object.\n\n3. Raises ``ValueError`` when *x* is not found in *s*. When a negative\n index is passed as the second or third parameter to the ``index()``\n method, the sequence length is added, as for slice indices. If it\n is still negative, it is truncated to zero, as for slice indices.\n\n4. When a negative index is passed as the first parameter to the\n ``insert()`` method, the sequence length is added, as for slice\n indices. If it is still negative, it is truncated to zero, as for\n slice indices.\n\n5. The optional argument *i* defaults to ``-1``, so that by default\n the last item is removed and returned.\n\n6. The ``sort()`` and ``reverse()`` methods modify the sequence in\n place for economy of space when sorting or reversing a large\n sequence. To remind you that they operate by side effect, they\n don\'t return the sorted or reversed sequence.\n\n7. The ``sort()`` method takes optional arguments for controlling the\n comparisons. Each must be specified as a keyword argument.\n\n *key* specifies a function of one argument that is used to extract\n a comparison key from each list element: ``key=str.lower``. The\n default value is ``None``.\n\n *reverse* is a boolean value. If set to ``True``, then the list\n elements are sorted as if each comparison were reversed.\n\n The ``sort()`` method is guaranteed to be stable. A sort is stable\n if it guarantees not to change the relative order of elements that\n compare equal --- this is helpful for sorting in multiple passes\n (for example, sort by department, then by salary grade).\n\n While a list is being sorted, the effect of attempting to mutate,\n or even inspect, the list is undefined. The C implementation makes\n the list appear empty for the duration, and raises ``ValueError``\n if it can detect that the list has been mutated during a sort.\n\n8. ``sort()`` is not supported by ``bytearray`` objects.\n', + 'unary': '\nUnary arithmetic operations\n***************************\n\nAll unary arithmetic (and bitwise) operations have the same priority:\n\n u_expr ::= power | "-" u_expr | "+" u_expr | "~" u_expr\n\nThe unary ``-`` (minus) operator yields the negation of its numeric\nargument.\n\nThe unary ``+`` (plus) operator yields its numeric argument unchanged.\n\nThe unary ``~`` (invert) operator yields the bitwise inversion of its\ninteger argument. The bitwise inversion of ``x`` is defined as\n``-(x+1)``. It only applies to integral numbers.\n\nIn all three cases, if the argument does not have the proper type, a\n``TypeError`` exception is raised.\n', + 'while': '\nThe ``while`` statement\n***********************\n\nThe ``while`` statement is used for repeated execution as long as an\nexpression is true:\n\n while_stmt ::= "while" expression ":" suite\n ["else" ":" suite]\n\nThis repeatedly tests the expression and, if it is true, executes the\nfirst suite; if the expression is false (which may be the first time\nit is tested) the suite of the ``else`` clause, if present, is\nexecuted and the loop terminates.\n\nA ``break`` statement executed in the first suite terminates the loop\nwithout executing the ``else`` clause\'s suite. A ``continue``\nstatement executed in the first suite skips the rest of the suite and\ngoes back to testing the expression.\n', + 'with': '\nThe ``with`` statement\n**********************\n\nThe ``with`` statement is used to wrap the execution of a block with\nmethods defined by a context manager (see section *With Statement\nContext Managers*). This allows common\n``try``...``except``...``finally`` usage patterns to be encapsulated\nfor convenient reuse.\n\n with_stmt ::= "with" expression ["as" target] ":" suite\n\nThe execution of the ``with`` statement proceeds as follows:\n\n1. The context expression is evaluated to obtain a context manager.\n\n2. The context manager\'s ``__enter__()`` method is invoked.\n\n3. If a target was included in the ``with`` statement, the return\n value from ``__enter__()`` is assigned to it.\n\n Note: The ``with`` statement guarantees that if the ``__enter__()``\n method returns without an error, then ``__exit__()`` will always\n be called. Thus, if an error occurs during the assignment to the\n target list, it will be treated the same as an error occurring\n within the suite would be. See step 5 below.\n\n4. The suite is executed.\n\n5. The context manager\'s ``__exit__()`` method is invoked. If an\n exception caused the suite to be exited, its type, value, and\n traceback are passed as arguments to ``__exit__()``. Otherwise,\n three ``None`` arguments are supplied.\n\n If the suite was exited due to an exception, and the return value\n from the ``__exit__()`` method was false, the exception is\n reraised. If the return value was true, the exception is\n suppressed, and execution continues with the statement following\n the ``with`` statement.\n\n If the suite was exited for any reason other than an exception, the\n return value from ``__exit__()`` is ignored, and execution proceeds\n at the normal location for the kind of exit that was taken.\n\nSee also:\n\n **PEP 0343** - The "with" statement\n The specification, background, and examples for the Python\n ``with`` statement.\n', + 'yield': '\nThe ``yield`` statement\n***********************\n\n yield_stmt ::= yield_expression\n\nThe ``yield`` statement is only used when defining a generator\nfunction, and is only used in the body of the generator function.\nUsing a ``yield`` statement in a function definition is sufficient to\ncause that definition to create a generator function instead of a\nnormal function. When a generator function is called, it returns an\niterator known as a generator iterator, or more commonly, a generator.\nThe body of the generator function is executed by calling the\ngenerator\'s ``next()`` method repeatedly until it raises an exception.\n\nWhen a ``yield`` statement is executed, the state of the generator is\nfrozen and the value of **expression_list** is returned to\n``next()``\'s caller. By "frozen" we mean that all local state is\nretained, including the current bindings of local variables, the\ninstruction pointer, and the internal evaluation stack: enough\ninformation is saved so that the next time ``next()`` is invoked, the\nfunction can proceed exactly as if the ``yield`` statement were just\nanother external call.\n\nThe ``yield`` statement is allowed in the ``try`` clause of a ``try``\n... ``finally`` construct. If the generator is not resumed before it\nis finalized (by reaching a zero reference count or by being garbage\ncollected), the generator-iterator\'s ``close()`` method will be\ncalled, allowing any pending ``finally`` clauses to execute.\n\nSee also:\n\n **PEP 0255** - Simple Generators\n The proposal for adding generators and the ``yield`` statement\n to Python.\n\n **PEP 0342** - Coroutines via Enhanced Generators\n The proposal that, among other generator enhancements, proposed\n allowing ``yield`` to appear inside a ``try`` ... ``finally``\n block.\n'} From python-3000-checkins at python.org Sun Jun 1 23:25:56 2008 From: python-3000-checkins at python.org (georg.brandl) Date: Sun, 1 Jun 2008 23:25:56 +0200 (CEST) Subject: [Python-3000-checkins] r63874 - in python/branches/py3k: Doc/library/formatter.rst Doc/library/html.entities.rst Doc/library/html.parser.rst Doc/library/htmllib.rst Doc/library/markup.rst Doc/library/sgmllib.rst Doc/library/urllib.rst Lib/_markupbase.py Lib/htmllib.py Lib/sgmllib.py Lib/test/test___all__.py Lib/test/test_htmllib.py Lib/test/test_sgmllib.py Misc/NEWS Misc/cheatsheet Message-ID: <20080601212556.10DB41E400A@bag.python.org> Author: georg.brandl Date: Sun Jun 1 23:25:55 2008 New Revision: 63874 Log: Remove the htmllib and sgmllib modules as per PEP 3108. Removed: python/branches/py3k/Doc/library/htmllib.rst python/branches/py3k/Doc/library/sgmllib.rst python/branches/py3k/Lib/htmllib.py python/branches/py3k/Lib/sgmllib.py python/branches/py3k/Lib/test/test_htmllib.py python/branches/py3k/Lib/test/test_sgmllib.py Modified: python/branches/py3k/Doc/library/formatter.rst python/branches/py3k/Doc/library/html.entities.rst python/branches/py3k/Doc/library/html.parser.rst python/branches/py3k/Doc/library/markup.rst python/branches/py3k/Doc/library/urllib.rst python/branches/py3k/Lib/_markupbase.py python/branches/py3k/Lib/test/test___all__.py python/branches/py3k/Misc/NEWS python/branches/py3k/Misc/cheatsheet Modified: python/branches/py3k/Doc/library/formatter.rst ============================================================================== --- python/branches/py3k/Doc/library/formatter.rst (original) +++ python/branches/py3k/Doc/library/formatter.rst Sun Jun 1 23:25:55 2008 @@ -1,4 +1,3 @@ - :mod:`formatter` --- Generic output formatting ============================================== @@ -6,12 +5,9 @@ :synopsis: Generic output formatter and device interface. -.. index:: single: HTMLParser (class in htmllib) - This module supports two interface definitions, each with multiple -implementations. The *formatter* interface is used by the :class:`HTMLParser` -class of the :mod:`htmllib` module, and the *writer* interface is required by -the formatter interface. +implementations: The *formatter* interface, and the *writer* interface which is +required by the formatter interface. Formatter objects transform an abstract flow of formatting events into specific output events on writer objects. Formatters manage several stack structures to Modified: python/branches/py3k/Doc/library/html.entities.rst ============================================================================== --- python/branches/py3k/Doc/library/html.entities.rst (original) +++ python/branches/py3k/Doc/library/html.entities.rst Sun Jun 1 23:25:55 2008 @@ -7,11 +7,10 @@ This module defines three dictionaries, ``name2codepoint``, ``codepoint2name``, -and ``entitydefs``. ``entitydefs`` is used by the :mod:`htmllib` module to -provide the :attr:`entitydefs` member of the :class:`html.parser.HTMLParser` -class. The definition provided here contains all the entities defined by XHTML -1.0 that can be handled using simple textual substitution in the Latin-1 -character set (ISO-8859-1). +and ``entitydefs``. ``entitydefs`` is used to provide the :attr:`entitydefs` +member of the :class:`html.parser.HTMLParser` class. The definition provided +here contains all the entities defined by XHTML 1.0 that can be handled using +simple textual substitution in the Latin-1 character set (ISO-8859-1). .. data:: entitydefs Modified: python/branches/py3k/Doc/library/html.parser.rst ============================================================================== --- python/branches/py3k/Doc/library/html.parser.rst (original) +++ python/branches/py3k/Doc/library/html.parser.rst Sun Jun 1 23:25:55 2008 @@ -11,9 +11,6 @@ This module defines a class :class:`HTMLParser` which serves as the basis for parsing text files formatted in HTML (HyperText Mark-up Language) and XHTML. -Unlike the parser in :mod:`htmllib`, this parser is not based on the SGML parser -in :mod:`sgmllib`. - .. class:: HTMLParser() @@ -23,9 +20,8 @@ begin and end. The :class:`HTMLParser` class is meant to be overridden by the user to provide a desired behavior. - Unlike the parser in :mod:`htmllib`, this parser does not check that end tags - match start tags or call the end-tag handler for elements which are closed - implicitly by closing an outer element. + This parser does not check that end tags match start tags or call the end-tag + handler for elements which are closed implicitly by closing an outer element. An exception is defined as well: Deleted: python/branches/py3k/Doc/library/htmllib.rst ============================================================================== --- python/branches/py3k/Doc/library/htmllib.rst Sun Jun 1 23:25:55 2008 +++ (empty file) @@ -1,147 +0,0 @@ - -:mod:`htmllib` --- A parser for HTML documents -============================================== - -.. module:: htmllib - :synopsis: A parser for HTML documents. - - -.. index:: - single: HTML - single: hypertext - -.. index:: - module: sgmllib - module: formatter - single: SGMLParser (in module sgmllib) - -This module defines a class which can serve as a base for parsing text files -formatted in the HyperText Mark-up Language (HTML). The class is not directly -concerned with I/O --- it must be provided with input in string form via a -method, and makes calls to methods of a "formatter" object in order to produce -output. The :class:`HTMLParser` class is designed to be used as a base class -for other classes in order to add functionality, and allows most of its methods -to be extended or overridden. In turn, this class is derived from and extends -the :class:`SGMLParser` class defined in module :mod:`sgmllib`. The -:class:`HTMLParser` implementation supports the HTML 2.0 language as described -in :rfc:`1866`. Two implementations of formatter objects are provided in the -:mod:`formatter` module; refer to the documentation for that module for -information on the formatter interface. - -The following is a summary of the interface defined by -:class:`sgmllib.SGMLParser`: - -* The interface to feed data to an instance is through the :meth:`feed` method, - which takes a string argument. This can be called with as little or as much - text at a time as desired; ``p.feed(a); p.feed(b)`` has the same effect as - ``p.feed(a+b)``. When the data contains complete HTML markup constructs, these - are processed immediately; incomplete constructs are saved in a buffer. To - force processing of all unprocessed data, call the :meth:`close` method. - - For example, to parse the entire contents of a file, use:: - - parser.feed(open('myfile.html').read()) - parser.close() - -* The interface to define semantics for HTML tags is very simple: derive a class - and define methods called :meth:`start_tag`, :meth:`end_tag`, or :meth:`do_tag`. - The parser will call these at appropriate moments: :meth:`start_tag` or - :meth:`do_tag` is called when an opening tag of the form ```` is - encountered; :meth:`end_tag` is called when a closing tag of the form ```` - is encountered. If an opening tag requires a corresponding closing tag, like - ``

`` ... ``

``, the class should define the :meth:`start_tag` method; if - a tag requires no closing tag, like ``

``, the class should define the - :meth:`do_tag` method. - -The module defines a parser class and an exception: - - -.. class:: HTMLParser(formatter) - - This is the basic HTML parser class. It supports all entity names required by - the XHTML 1.0 Recommendation (http://www.w3.org/TR/xhtml1). It also defines - handlers for all HTML 2.0 and many HTML 3.0 and 3.2 elements. - - -.. exception:: HTMLParseError - - Exception raised by the :class:`HTMLParser` class when it encounters an error - while parsing. - - -.. seealso:: - - Module :mod:`formatter` - Interface definition for transforming an abstract flow of formatting events into - specific output events on writer objects. - - Module :mod:`html.parser` - Alternate HTML parser that offers a slightly lower-level view of the input, but - is designed to work with XHTML, and does not implement some of the SGML syntax - not used in "HTML as deployed" and which isn't legal for XHTML. - - Module :mod:`html.entities` - Definition of replacement text for XHTML 1.0 entities. - - Module :mod:`sgmllib` - Base class for :class:`HTMLParser`. - - -.. _html-parser-objects: - -HTMLParser Objects ------------------- - -In addition to tag methods, the :class:`HTMLParser` class provides some -additional methods and instance variables for use within tag methods. - - -.. attribute:: HTMLParser.formatter - - This is the formatter instance associated with the parser. - - -.. attribute:: HTMLParser.nofill - - Boolean flag which should be true when whitespace should not be collapsed, or - false when it should be. In general, this should only be true when character - data is to be treated as "preformatted" text, as within a ``

`` element.
-   The default value is false.  This affects the operation of :meth:`handle_data`
-   and :meth:`save_end`.
-
-
-.. method:: HTMLParser.anchor_bgn(href, name, type)
-
-   This method is called at the start of an anchor region.  The arguments
-   correspond to the attributes of the ```` tag with the same names.  The
-   default implementation maintains a list of hyperlinks (defined by the ``HREF``
-   attribute for ```` tags) within the document.  The list of hyperlinks is
-   available as the data attribute :attr:`anchorlist`.
-
-
-.. method:: HTMLParser.anchor_end()
-
-   This method is called at the end of an anchor region.  The default
-   implementation adds a textual footnote marker using an index into the list of
-   hyperlinks created by :meth:`anchor_bgn`.
-
-
-.. method:: HTMLParser.handle_image(source, alt[, ismap[, align[, width[, height]]]])
-
-   This method is called to handle images.  The default implementation simply
-   passes the *alt* value to the :meth:`handle_data` method.
-
-
-.. method:: HTMLParser.save_bgn()
-
-   Begins saving character data in a buffer instead of sending it to the formatter
-   object.  Retrieve the stored data via :meth:`save_end`. Use of the
-   :meth:`save_bgn` / :meth:`save_end` pair may not be nested.
-
-
-.. method:: HTMLParser.save_end()
-
-   Ends buffering character data and returns all data saved since the preceding
-   call to :meth:`save_bgn`.  If the :attr:`nofill` flag is false, whitespace is
-   collapsed to single spaces.  A call to this method without a preceding call to
-   :meth:`save_bgn` will raise a :exc:`TypeError` exception.

Modified: python/branches/py3k/Doc/library/markup.rst
==============================================================================
--- python/branches/py3k/Doc/library/markup.rst	(original)
+++ python/branches/py3k/Doc/library/markup.rst	Sun Jun  1 23:25:55 2008
@@ -23,8 +23,6 @@
 
    html.parser.rst
    html.entities.rst
-   sgmllib.rst
-   htmllib.rst
    pyexpat.rst
    xml.dom.rst
    xml.dom.minidom.rst

Deleted: python/branches/py3k/Doc/library/sgmllib.rst
==============================================================================
--- python/branches/py3k/Doc/library/sgmllib.rst	Sun Jun  1 23:25:55 2008
+++ (empty file)
@@ -1,253 +0,0 @@
-
-:mod:`sgmllib` --- Simple SGML parser
-=====================================
-
-.. module:: sgmllib
-   :synopsis: Only as much of an SGML parser as needed to parse HTML.
-
-
-.. index:: single: SGML
-
-This module defines a class :class:`SGMLParser` which serves as the basis for
-parsing text files formatted in SGML (Standard Generalized Mark-up Language).
-In fact, it does not provide a full SGML parser --- it only parses SGML insofar
-as it is used by HTML, and the module only exists as a base for the
-:mod:`htmllib` module.  Another HTML parser which supports XHTML and offers a
-somewhat different interface is available in the :mod:`HTMLParser` module.
-
-
-.. class:: SGMLParser()
-
-   The :class:`SGMLParser` class is instantiated without arguments. The parser is
-   hardcoded to recognize the following constructs:
-
-   * Opening and closing tags of the form ```` and
-     ````, respectively.
-
-   * Numeric character references of the form ``&#name;``.
-
-   * Entity references of the form ``&name;``.
-
-   * SGML comments of the form ````.  Note that spaces, tabs, and
-     newlines are allowed between the trailing ``>`` and the immediately preceding
-     ``--``.
-
-A single exception is defined as well:
-
-
-.. exception:: SGMLParseError
-
-   Exception raised by the :class:`SGMLParser` class when it encounters an error
-   while parsing.
-
-:class:`SGMLParser` instances have the following methods:
-
-
-.. method:: SGMLParser.reset()
-
-   Reset the instance.  Loses all unprocessed data.  This is called implicitly at
-   instantiation time.
-
-
-.. method:: SGMLParser.setnomoretags()
-
-   Stop processing tags.  Treat all following input as literal input (CDATA).
-   (This is only provided so the HTML tag ```` can be implemented.)
-
-
-.. method:: SGMLParser.setliteral()
-
-   Enter literal mode (CDATA mode).
-
-
-.. method:: SGMLParser.feed(data)
-
-   Feed some text to the parser.  It is processed insofar as it consists of
-   complete elements; incomplete data is buffered until more data is fed or
-   :meth:`close` is called.
-
-
-.. method:: SGMLParser.close()
-
-   Force processing of all buffered data as if it were followed by an end-of-file
-   mark.  This method may be redefined by a derived class to define additional
-   processing at the end of the input, but the redefined version should always call
-   :meth:`close`.
-
-
-.. method:: SGMLParser.get_starttag_text()
-
-   Return the text of the most recently opened start tag.  This should not normally
-   be needed for structured processing, but may be useful in dealing with HTML "as
-   deployed" or for re-generating input with minimal changes (whitespace between
-   attributes can be preserved, etc.).
-
-
-.. method:: SGMLParser.handle_starttag(tag, method, attributes)
-
-   This method is called to handle start tags for which either a :meth:`start_tag`
-   or :meth:`do_tag` method has been defined.  The *tag* argument is the name of
-   the tag converted to lower case, and the *method* argument is the bound method
-   which should be used to support semantic interpretation of the start tag. The
-   *attributes* argument is a list of ``(name, value)`` pairs containing the
-   attributes found inside the tag's ``<>`` brackets.
-
-   The *name* has been translated to lower case. Double quotes and backslashes in
-   the *value* have been interpreted, as well as known character references and
-   known entity references terminated by a semicolon (normally, entity references
-   can be terminated by any non-alphanumerical character, but this would break the
-   very common case of ``<A HREF="url?spam=1&eggs=2">`` when ``eggs`` is a valid
-   entity name).
-
-   For instance, for the tag ``<A HREF="http://www.cwi.nl/">``, this method would
-   be called as ``unknown_starttag('a', [('href', 'http://www.cwi.nl/')])``.  The
-   base implementation simply calls *method* with *attributes* as the only
-   argument.
-
-
-.. method:: SGMLParser.handle_endtag(tag, method)
-
-   This method is called to handle endtags for which an :meth:`end_tag` method has
-   been defined.  The *tag* argument is the name of the tag converted to lower
-   case, and the *method* argument is the bound method which should be used to
-   support semantic interpretation of the end tag.  If no :meth:`end_tag` method is
-   defined for the closing element, this handler is not called.  The base
-   implementation simply calls *method*.
-
-
-.. method:: SGMLParser.handle_data(data)
-
-   This method is called to process arbitrary data.  It is intended to be
-   overridden by a derived class; the base class implementation does nothing.
-
-
-.. method:: SGMLParser.handle_charref(ref)
-
-   This method is called to process a character reference of the form ``&#ref;``.
-   The base implementation uses :meth:`convert_charref` to convert the reference to
-   a string.  If that method returns a string, it is passed to :meth:`handle_data`,
-   otherwise ``unknown_charref(ref)`` is called to handle the error.
-
-
-.. method:: SGMLParser.convert_charref(ref)
-
-   Convert a character reference to a string, or ``None``.  *ref* is the reference
-   passed in as a string.  In the base implementation, *ref* must be a decimal
-   number in the range 0-255.  It converts the code point found using the
-   :meth:`convert_codepoint` method. If *ref* is invalid or out of range, this
-   method returns ``None``.  This method is called by the default
-   :meth:`handle_charref` implementation and by the attribute value parser.
-
-
-.. method:: SGMLParser.convert_codepoint(codepoint)
-
-   Convert a codepoint to a :class:`str` value.  Encodings can be handled here if
-   appropriate, though the rest of :mod:`sgmllib` is oblivious on this matter.
-
-
-.. method:: SGMLParser.handle_entityref(ref)
-
-   This method is called to process a general entity reference of the form
-   ``&ref;`` where *ref* is an general entity reference.  It converts *ref* by
-   passing it to :meth:`convert_entityref`.  If a translation is returned, it calls
-   the method :meth:`handle_data` with the translation; otherwise, it calls the
-   method ``unknown_entityref(ref)``. The default :attr:`entitydefs` defines
-   translations for ``&amp;``, ``&apos``, ``&gt;``, ``&lt;``, and ``&quot;``.
-
-
-.. method:: SGMLParser.convert_entityref(ref)
-
-   Convert a named entity reference to a :class:`str` value, or ``None``.  The
-   resulting value will not be parsed.  *ref* will be only the name of the entity.
-   The default implementation looks for *ref* in the instance (or class) variable
-   :attr:`entitydefs` which should be a mapping from entity names to corresponding
-   translations.  If no translation is available for *ref*, this method returns
-   ``None``.  This method is called by the default :meth:`handle_entityref`
-   implementation and by the attribute value parser.
-
-
-.. method:: SGMLParser.handle_comment(comment)
-
-   This method is called when a comment is encountered.  The *comment* argument is
-   a string containing the text between the ``<!--`` and ``-->`` delimiters, but
-   not the delimiters themselves.  For example, the comment ``<!--text-->`` will
-   cause this method to be called with the argument ``'text'``.  The default method
-   does nothing.
-
-
-.. method:: SGMLParser.handle_decl(data)
-
-   Method called when an SGML declaration is read by the parser.  In practice, the
-   ``DOCTYPE`` declaration is the only thing observed in HTML, but the parser does
-   not discriminate among different (or broken) declarations.  Internal subsets in
-   a ``DOCTYPE`` declaration are not supported.  The *data* parameter will be the
-   entire contents of the declaration inside the ``<!``...\ ``>`` markup.  The
-   default implementation does nothing.
-
-
-.. method:: SGMLParser.report_unbalanced(tag)
-
-   This method is called when an end tag is found which does not correspond to any
-   open element.
-
-
-.. method:: SGMLParser.unknown_starttag(tag, attributes)
-
-   This method is called to process an unknown start tag.  It is intended to be
-   overridden by a derived class; the base class implementation does nothing.
-
-
-.. method:: SGMLParser.unknown_endtag(tag)
-
-   This method is called to process an unknown end tag.  It is intended to be
-   overridden by a derived class; the base class implementation does nothing.
-
-
-.. method:: SGMLParser.unknown_charref(ref)
-
-   This method is called to process unresolvable numeric character references.
-   Refer to :meth:`handle_charref` to determine what is handled by default.  It is
-   intended to be overridden by a derived class; the base class implementation does
-   nothing.
-
-
-.. method:: SGMLParser.unknown_entityref(ref)
-
-   This method is called to process an unknown entity reference.  It is intended to
-   be overridden by a derived class; the base class implementation does nothing.
-
-Apart from overriding or extending the methods listed above, derived classes may
-also define methods of the following form to define processing of specific tags.
-Tag names in the input stream are case independent; the *tag* occurring in
-method names must be in lower case:
-
-
-.. method:: SGMLParser.start_tag(attributes)
-   :noindex:
-
-   This method is called to process an opening tag *tag*.  It has preference over
-   :meth:`do_tag`.  The *attributes* argument has the same meaning as described for
-   :meth:`handle_starttag` above.
-
-
-.. method:: SGMLParser.do_tag(attributes)
-   :noindex:
-
-   This method is called to process an opening tag *tag*  for which no
-   :meth:`start_tag` method is defined.   The *attributes* argument has the same
-   meaning as described for :meth:`handle_starttag` above.
-
-
-.. method:: SGMLParser.end_tag()
-   :noindex:
-
-   This method is called to process a closing tag *tag*.
-
-Note that the parser maintains a stack of open elements for which no end tag has
-been found yet.  Only tags processed by :meth:`start_tag` are pushed on this
-stack.  Definition of an :meth:`end_tag` method is optional for these tags.  For
-tags processed by :meth:`do_tag` or by :meth:`unknown_tag`, no :meth:`end_tag`
-method must be defined; if defined, it will not be used.  If both
-:meth:`start_tag` and :meth:`do_tag` methods exist for a tag, the
-:meth:`start_tag` method takes precedence.
-

Modified: python/branches/py3k/Doc/library/urllib.rst
==============================================================================
--- python/branches/py3k/Doc/library/urllib.rst	(original)
+++ python/branches/py3k/Doc/library/urllib.rst	Sun Jun  1 23:25:55 2008
@@ -389,14 +389,13 @@
   .. index::
      single: HTML
      pair: HTTP; protocol
-     module: htmllib
 
 * The data returned by :func:`urlopen` or :func:`urlretrieve` is the raw data
   returned by the server.  This may be binary data (such as an image), plain text
   or (for example) HTML.  The HTTP protocol provides type information in the reply
   header, which can be inspected by looking at the :mailheader:`Content-Type`
-  header.  If the returned data is HTML, you can use the module :mod:`htmllib` to
-  parse it.
+  header.  If the returned data is HTML, you can use the module
+  :mod:`html.parser` to parse it.
 
   .. index:: single: FTP
 

Modified: python/branches/py3k/Lib/_markupbase.py
==============================================================================
--- python/branches/py3k/Lib/_markupbase.py	(original)
+++ python/branches/py3k/Lib/_markupbase.py	Sun Jun  1 23:25:55 2008
@@ -1,8 +1,7 @@
 """Shared support for scanning document type declarations in HTML and XHTML.
 
-This module is used as a foundation for the HTMLParser and sgmllib
-modules (indirectly, for htmllib as well).  It has no documented
-public API and should not be used directly.
+This module is used as a foundation for the html.parser module.  It has no
+documented public API and should not be used directly.
 
 """
 

Deleted: python/branches/py3k/Lib/htmllib.py
==============================================================================
--- python/branches/py3k/Lib/htmllib.py	Sun Jun  1 23:25:55 2008
+++ (empty file)
@@ -1,486 +0,0 @@
-"""HTML 2.0 parser.
-
-See the HTML 2.0 specification:
-http://www.w3.org/hypertext/WWW/MarkUp/html-spec/html-spec_toc.html
-"""
-
-import sgmllib
-
-from formatter import AS_IS
-
-__all__ = ["HTMLParser", "HTMLParseError"]
-
-
-class HTMLParseError(sgmllib.SGMLParseError):
-    """Error raised when an HTML document can't be parsed."""
-
-
-class HTMLParser(sgmllib.SGMLParser):
-    """This is the basic HTML parser class.
-
-    It supports all entity names required by the XHTML 1.0 Recommendation.
-    It also defines handlers for all HTML 2.0 and many HTML 3.0 and 3.2
-    elements.
-
-    """
-
-    from html.entities import entitydefs
-
-    def __init__(self, formatter, verbose=0):
-        """Creates an instance of the HTMLParser class.
-
-        The formatter parameter is the formatter instance associated with
-        the parser.
-
-        """
-        sgmllib.SGMLParser.__init__(self, verbose)
-        self.formatter = formatter
-
-    def error(self, message):
-        raise HTMLParseError(message)
-
-    def reset(self):
-        sgmllib.SGMLParser.reset(self)
-        self.savedata = None
-        self.isindex = 0
-        self.title = None
-        self.base = None
-        self.anchor = None
-        self.anchorlist = []
-        self.nofill = 0
-        self.list_stack = []
-
-    # ------ Methods used internally; some may be overridden
-
-    # --- Formatter interface, taking care of 'savedata' mode;
-    # shouldn't need to be overridden
-
-    def handle_data(self, data):
-        if self.savedata is not None:
-            self.savedata = self.savedata + data
-        else:
-            if self.nofill:
-                self.formatter.add_literal_data(data)
-            else:
-                self.formatter.add_flowing_data(data)
-
-    # --- Hooks to save data; shouldn't need to be overridden
-
-    def save_bgn(self):
-        """Begins saving character data in a buffer instead of sending it
-        to the formatter object.
-
-        Retrieve the stored data via the save_end() method.  Use of the
-        save_bgn() / save_end() pair may not be nested.
-
-        """
-        self.savedata = ''
-
-    def save_end(self):
-        """Ends buffering character data and returns all data saved since
-        the preceding call to the save_bgn() method.
-
-        If the nofill flag is false, whitespace is collapsed to single
-        spaces.  A call to this method without a preceding call to the
-        save_bgn() method will raise a TypeError exception.
-
-        """
-        data = self.savedata
-        self.savedata = None
-        if not self.nofill:
-            data = ' '.join(data.split())
-        return data
-
-    # --- Hooks for anchors; should probably be overridden
-
-    def anchor_bgn(self, href, name, type):
-        """This method is called at the start of an anchor region.
-
-        The arguments correspond to the attributes of the <A> tag with
-        the same names.  The default implementation maintains a list of
-        hyperlinks (defined by the HREF attribute for <A> tags) within
-        the document.  The list of hyperlinks is available as the data
-        attribute anchorlist.
-
-        """
-        self.anchor = href
-        if self.anchor:
-            self.anchorlist.append(href)
-
-    def anchor_end(self):
-        """This method is called at the end of an anchor region.
-
-        The default implementation adds a textual footnote marker using an
-        index into the list of hyperlinks created by the anchor_bgn()method.
-
-        """
-        if self.anchor:
-            self.handle_data("[%d]" % len(self.anchorlist))
-            self.anchor = None
-
-    # --- Hook for images; should probably be overridden
-
-    def handle_image(self, src, alt, *args):
-        """This method is called to handle images.
-
-        The default implementation simply passes the alt value to the
-        handle_data() method.
-
-        """
-        self.handle_data(alt)
-
-    # --------- Top level elememts
-
-    def start_html(self, attrs): pass
-    def end_html(self): pass
-
-    def start_head(self, attrs): pass
-    def end_head(self): pass
-
-    def start_body(self, attrs): pass
-    def end_body(self): pass
-
-    # ------ Head elements
-
-    def start_title(self, attrs):
-        self.save_bgn()
-
-    def end_title(self):
-        self.title = self.save_end()
-
-    def do_base(self, attrs):
-        for a, v in attrs:
-            if a == 'href':
-                self.base = v
-
-    def do_isindex(self, attrs):
-        self.isindex = 1
-
-    def do_link(self, attrs):
-        pass
-
-    def do_meta(self, attrs):
-        pass
-
-    def do_nextid(self, attrs): # Deprecated
-        pass
-
-    # ------ Body elements
-
-    # --- Headings
-
-    def start_h1(self, attrs):
-        self.formatter.end_paragraph(1)
-        self.formatter.push_font(('h1', 0, 1, 0))
-
-    def end_h1(self):
-        self.formatter.end_paragraph(1)
-        self.formatter.pop_font()
-
-    def start_h2(self, attrs):
-        self.formatter.end_paragraph(1)
-        self.formatter.push_font(('h2', 0, 1, 0))
-
-    def end_h2(self):
-        self.formatter.end_paragraph(1)
-        self.formatter.pop_font()
-
-    def start_h3(self, attrs):
-        self.formatter.end_paragraph(1)
-        self.formatter.push_font(('h3', 0, 1, 0))
-
-    def end_h3(self):
-        self.formatter.end_paragraph(1)
-        self.formatter.pop_font()
-
-    def start_h4(self, attrs):
-        self.formatter.end_paragraph(1)
-        self.formatter.push_font(('h4', 0, 1, 0))
-
-    def end_h4(self):
-        self.formatter.end_paragraph(1)
-        self.formatter.pop_font()
-
-    def start_h5(self, attrs):
-        self.formatter.end_paragraph(1)
-        self.formatter.push_font(('h5', 0, 1, 0))
-
-    def end_h5(self):
-        self.formatter.end_paragraph(1)
-        self.formatter.pop_font()
-
-    def start_h6(self, attrs):
-        self.formatter.end_paragraph(1)
-        self.formatter.push_font(('h6', 0, 1, 0))
-
-    def end_h6(self):
-        self.formatter.end_paragraph(1)
-        self.formatter.pop_font()
-
-    # --- Block Structuring Elements
-
-    def do_p(self, attrs):
-        self.formatter.end_paragraph(1)
-
-    def start_pre(self, attrs):
-        self.formatter.end_paragraph(1)
-        self.formatter.push_font((AS_IS, AS_IS, AS_IS, 1))
-        self.nofill = self.nofill + 1
-
-    def end_pre(self):
-        self.formatter.end_paragraph(1)
-        self.formatter.pop_font()
-        self.nofill = max(0, self.nofill - 1)
-
-    def start_xmp(self, attrs):
-        self.start_pre(attrs)
-        self.setliteral('xmp') # Tell SGML parser
-
-    def end_xmp(self):
-        self.end_pre()
-
-    def start_listing(self, attrs):
-        self.start_pre(attrs)
-        self.setliteral('listing') # Tell SGML parser
-
-    def end_listing(self):
-        self.end_pre()
-
-    def start_address(self, attrs):
-        self.formatter.end_paragraph(0)
-        self.formatter.push_font((AS_IS, 1, AS_IS, AS_IS))
-
-    def end_address(self):
-        self.formatter.end_paragraph(0)
-        self.formatter.pop_font()
-
-    def start_blockquote(self, attrs):
-        self.formatter.end_paragraph(1)
-        self.formatter.push_margin('blockquote')
-
-    def end_blockquote(self):
-        self.formatter.end_paragraph(1)
-        self.formatter.pop_margin()
-
-    # --- List Elements
-
-    def start_ul(self, attrs):
-        self.formatter.end_paragraph(not self.list_stack)
-        self.formatter.push_margin('ul')
-        self.list_stack.append(['ul', '*', 0])
-
-    def end_ul(self):
-        if self.list_stack: del self.list_stack[-1]
-        self.formatter.end_paragraph(not self.list_stack)
-        self.formatter.pop_margin()
-
-    def do_li(self, attrs):
-        self.formatter.end_paragraph(0)
-        if self.list_stack:
-            [dummy, label, counter] = top = self.list_stack[-1]
-            top[2] = counter = counter+1
-        else:
-            label, counter = '*', 0
-        self.formatter.add_label_data(label, counter)
-
-    def start_ol(self, attrs):
-        self.formatter.end_paragraph(not self.list_stack)
-        self.formatter.push_margin('ol')
-        label = '1.'
-        for a, v in attrs:
-            if a == 'type':
-                if len(v) == 1: v = v + '.'
-                label = v
-        self.list_stack.append(['ol', label, 0])
-
-    def end_ol(self):
-        if self.list_stack: del self.list_stack[-1]
-        self.formatter.end_paragraph(not self.list_stack)
-        self.formatter.pop_margin()
-
-    def start_menu(self, attrs):
-        self.start_ul(attrs)
-
-    def end_menu(self):
-        self.end_ul()
-
-    def start_dir(self, attrs):
-        self.start_ul(attrs)
-
-    def end_dir(self):
-        self.end_ul()
-
-    def start_dl(self, attrs):
-        self.formatter.end_paragraph(1)
-        self.list_stack.append(['dl', '', 0])
-
-    def end_dl(self):
-        self.ddpop(1)
-        if self.list_stack: del self.list_stack[-1]
-
-    def do_dt(self, attrs):
-        self.ddpop()
-
-    def do_dd(self, attrs):
-        self.ddpop()
-        self.formatter.push_margin('dd')
-        self.list_stack.append(['dd', '', 0])
-
-    def ddpop(self, bl=0):
-        self.formatter.end_paragraph(bl)
-        if self.list_stack:
-            if self.list_stack[-1][0] == 'dd':
-                del self.list_stack[-1]
-                self.formatter.pop_margin()
-
-    # --- Phrase Markup
-
-    # Idiomatic Elements
-
-    def start_cite(self, attrs): self.start_i(attrs)
-    def end_cite(self): self.end_i()
-
-    def start_code(self, attrs): self.start_tt(attrs)
-    def end_code(self): self.end_tt()
-
-    def start_em(self, attrs): self.start_i(attrs)
-    def end_em(self): self.end_i()
-
-    def start_kbd(self, attrs): self.start_tt(attrs)
-    def end_kbd(self): self.end_tt()
-
-    def start_samp(self, attrs): self.start_tt(attrs)
-    def end_samp(self): self.end_tt()
-
-    def start_strong(self, attrs): self.start_b(attrs)
-    def end_strong(self): self.end_b()
-
-    def start_var(self, attrs): self.start_i(attrs)
-    def end_var(self): self.end_i()
-
-    # Typographic Elements
-
-    def start_i(self, attrs):
-        self.formatter.push_font((AS_IS, 1, AS_IS, AS_IS))
-    def end_i(self):
-        self.formatter.pop_font()
-
-    def start_b(self, attrs):
-        self.formatter.push_font((AS_IS, AS_IS, 1, AS_IS))
-    def end_b(self):
-        self.formatter.pop_font()
-
-    def start_tt(self, attrs):
-        self.formatter.push_font((AS_IS, AS_IS, AS_IS, 1))
-    def end_tt(self):
-        self.formatter.pop_font()
-
-    def start_a(self, attrs):
-        href = ''
-        name = ''
-        type = ''
-        for attrname, value in attrs:
-            value = value.strip()
-            if attrname == 'href':
-                href = value
-            if attrname == 'name':
-                name = value
-            if attrname == 'type':
-                type = value.lower()
-        self.anchor_bgn(href, name, type)
-
-    def end_a(self):
-        self.anchor_end()
-
-    # --- Line Break
-
-    def do_br(self, attrs):
-        self.formatter.add_line_break()
-
-    # --- Horizontal Rule
-
-    def do_hr(self, attrs):
-        self.formatter.add_hor_rule()
-
-    # --- Image
-
-    def do_img(self, attrs):
-        align = ''
-        alt = '(image)'
-        ismap = ''
-        src = ''
-        width = 0
-        height = 0
-        for attrname, value in attrs:
-            if attrname == 'align':
-                align = value
-            if attrname == 'alt':
-                alt = value
-            if attrname == 'ismap':
-                ismap = value
-            if attrname == 'src':
-                src = value
-            if attrname == 'width':
-                try: width = int(value)
-                except ValueError: pass
-            if attrname == 'height':
-                try: height = int(value)
-                except ValueError: pass
-        self.handle_image(src, alt, ismap, align, width, height)
-
-    # --- Really Old Unofficial Deprecated Stuff
-
-    def do_plaintext(self, attrs):
-        self.start_pre(attrs)
-        self.setnomoretags() # Tell SGML parser
-
-    # --- Unhandled tags
-
-    def unknown_starttag(self, tag, attrs):
-        pass
-
-    def unknown_endtag(self, tag):
-        pass
-
-
-def test(args = None):
-    import sys, formatter
-
-    if not args:
-        args = sys.argv[1:]
-
-    silent = args and args[0] == '-s'
-    if silent:
-        del args[0]
-
-    if args:
-        file = args[0]
-    else:
-        file = 'test.html'
-
-    if file == '-':
-        f = sys.stdin
-    else:
-        try:
-            f = open(file, 'r')
-        except IOError as msg:
-            print(file, ":", msg)
-            sys.exit(1)
-
-    data = f.read()
-
-    if f is not sys.stdin:
-        f.close()
-
-    if silent:
-        f = formatter.NullFormatter()
-    else:
-        f = formatter.AbstractFormatter(formatter.DumbWriter())
-
-    p = HTMLParser(f)
-    p.feed(data)
-    p.close()
-
-
-if __name__ == '__main__':
-    test()

Deleted: python/branches/py3k/Lib/sgmllib.py
==============================================================================
--- python/branches/py3k/Lib/sgmllib.py	Sun Jun  1 23:25:55 2008
+++ (empty file)
@@ -1,548 +0,0 @@
-"""A parser for SGML, using the derived class as a static DTD."""
-
-# XXX This only supports those SGML features used by HTML.
-
-# XXX There should be a way to distinguish between PCDATA (parsed
-# character data -- the normal case), RCDATA (replaceable character
-# data -- only char and entity references and end tags are special)
-# and CDATA (character data -- only end tags are special).  RCDATA is
-# not supported at all.
-
-
-import _markupbase
-import re
-
-__all__ = ["SGMLParser", "SGMLParseError"]
-
-# Regular expressions used for parsing
-
-interesting = re.compile('[&<]')
-incomplete = re.compile('&([a-zA-Z][a-zA-Z0-9]*|#[0-9]*)?|'
-                           '<([a-zA-Z][^<>]*|'
-                              '/([a-zA-Z][^<>]*)?|'
-                              '![^<>]*)?')
-
-entityref = re.compile('&([a-zA-Z][-.a-zA-Z0-9]*)[^a-zA-Z0-9]')
-charref = re.compile('&#([0-9]+)[^0-9]')
-
-starttagopen = re.compile('<[>a-zA-Z]')
-shorttagopen = re.compile('<[a-zA-Z][-.a-zA-Z0-9]*/')
-shorttag = re.compile('<([a-zA-Z][-.a-zA-Z0-9]*)/([^/]*)/')
-piclose = re.compile('>')
-endbracket = re.compile('[<>]')
-tagfind = re.compile('[a-zA-Z][-_.a-zA-Z0-9]*')
-attrfind = re.compile(
-    r'\s*([a-zA-Z_][-:.a-zA-Z_0-9]*)(\s*=\s*'
-    r'(\'[^\']*\'|"[^"]*"|[][\-a-zA-Z0-9./,:;+*%?!&$\(\)_#=~\'"@]*))?')
-
-
-class SGMLParseError(RuntimeError):
-    """Exception raised for all parse errors."""
-    pass
-
-
-# SGML parser base class -- find tags and call handler functions.
-# Usage: p = SGMLParser(); p.feed(data); ...; p.close().
-# The dtd is defined by deriving a class which defines methods
-# with special names to handle tags: start_foo and end_foo to handle
-# <foo> and </foo>, respectively, or do_foo to handle <foo> by itself.
-# (Tags are converted to lower case for this purpose.)  The data
-# between tags is passed to the parser by calling self.handle_data()
-# with some data as argument (the data may be split up in arbitrary
-# chunks).  Entity references are passed by calling
-# self.handle_entityref() with the entity reference as argument.
-
-class SGMLParser(_markupbase.ParserBase):
-    # Definition of entities -- derived classes may override
-    entity_or_charref = re.compile('&(?:'
-      '([a-zA-Z][-.a-zA-Z0-9]*)|#([0-9]+)'
-      ')(;?)')
-
-    def __init__(self, verbose=0):
-        """Initialize and reset this instance."""
-        self.verbose = verbose
-        self.reset()
-
-    def reset(self):
-        """Reset this instance. Loses all unprocessed data."""
-        self.__starttag_text = None
-        self.rawdata = ''
-        self.stack = []
-        self.lasttag = '???'
-        self.nomoretags = 0
-        self.literal = 0
-        _markupbase.ParserBase.reset(self)
-
-    def setnomoretags(self):
-        """Enter literal mode (CDATA) till EOF.
-
-        Intended for derived classes only.
-        """
-        self.nomoretags = self.literal = 1
-
-    def setliteral(self, *args):
-        """Enter literal mode (CDATA).
-
-        Intended for derived classes only.
-        """
-        self.literal = 1
-
-    def feed(self, data):
-        """Feed some data to the parser.
-
-        Call this as often as you want, with as little or as much text
-        as you want (may include '\n').  (This just saves the text,
-        all the processing is done by goahead().)
-        """
-
-        self.rawdata = self.rawdata + data
-        self.goahead(0)
-
-    def close(self):
-        """Handle the remaining data."""
-        self.goahead(1)
-
-    def error(self, message):
-        raise SGMLParseError(message)
-
-    # Internal -- handle data as far as reasonable.  May leave state
-    # and data to be processed by a subsequent call.  If 'end' is
-    # true, force handling all data as if followed by EOF marker.
-    def goahead(self, end):
-        rawdata = self.rawdata
-        i = 0
-        n = len(rawdata)
-        while i < n:
-            if self.nomoretags:
-                self.handle_data(rawdata[i:n])
-                i = n
-                break
-            match = interesting.search(rawdata, i)
-            if match: j = match.start()
-            else: j = n
-            if i < j:
-                self.handle_data(rawdata[i:j])
-            i = j
-            if i == n: break
-            if rawdata[i] == '<':
-                if starttagopen.match(rawdata, i):
-                    if self.literal:
-                        self.handle_data(rawdata[i])
-                        i = i+1
-                        continue
-                    k = self.parse_starttag(i)
-                    if k < 0: break
-                    i = k
-                    continue
-                if rawdata.startswith("</", i):
-                    k = self.parse_endtag(i)
-                    if k < 0: break
-                    i = k
-                    self.literal = 0
-                    continue
-                if self.literal:
-                    if n > (i + 1):
-                        self.handle_data("<")
-                        i = i+1
-                    else:
-                        # incomplete
-                        break
-                    continue
-                if rawdata.startswith("<!--", i):
-                        # Strictly speaking, a comment is --.*--
-                        # within a declaration tag <!...>.
-                        # This should be removed,
-                        # and comments handled only in parse_declaration.
-                    k = self.parse_comment(i)
-                    if k < 0: break
-                    i = k
-                    continue
-                if rawdata.startswith("<?", i):
-                    k = self.parse_pi(i)
-                    if k < 0: break
-                    i = i+k
-                    continue
-                if rawdata.startswith("<!", i):
-                    # This is some sort of declaration; in "HTML as
-                    # deployed," this should only be the document type
-                    # declaration ("<!DOCTYPE html...>").
-                    k = self.parse_declaration(i)
-                    if k < 0: break
-                    i = k
-                    continue
-            elif rawdata[i] == '&':
-                if self.literal:
-                    self.handle_data(rawdata[i])
-                    i = i+1
-                    continue
-                match = charref.match(rawdata, i)
-                if match:
-                    name = match.group(1)
-                    self.handle_charref(name)
-                    i = match.end(0)
-                    if rawdata[i-1] != ';': i = i-1
-                    continue
-                match = entityref.match(rawdata, i)
-                if match:
-                    name = match.group(1)
-                    self.handle_entityref(name)
-                    i = match.end(0)
-                    if rawdata[i-1] != ';': i = i-1
-                    continue
-            else:
-                self.error('neither < nor & ??')
-            # We get here only if incomplete matches but
-            # nothing else
-            match = incomplete.match(rawdata, i)
-            if not match:
-                self.handle_data(rawdata[i])
-                i = i+1
-                continue
-            j = match.end(0)
-            if j == n:
-                break # Really incomplete
-            self.handle_data(rawdata[i:j])
-            i = j
-        # end while
-        if end and i < n:
-            self.handle_data(rawdata[i:n])
-            i = n
-        self.rawdata = rawdata[i:]
-        # XXX if end: check for empty stack
-
-    # Extensions for the DOCTYPE scanner:
-    _decl_otherchars = '='
-
-    # Internal -- parse processing instr, return length or -1 if not terminated
-    def parse_pi(self, i):
-        rawdata = self.rawdata
-        if rawdata[i:i+2] != '<?':
-            self.error('unexpected call to parse_pi()')
-        match = piclose.search(rawdata, i+2)
-        if not match:
-            return -1
-        j = match.start(0)
-        self.handle_pi(rawdata[i+2: j])
-        j = match.end(0)
-        return j-i
-
-    def get_starttag_text(self):
-        return self.__starttag_text
-
-    # Internal -- handle starttag, return length or -1 if not terminated
-    def parse_starttag(self, i):
-        self.__starttag_text = None
-        start_pos = i
-        rawdata = self.rawdata
-        if shorttagopen.match(rawdata, i):
-            # SGML shorthand: <tag/data/ == <tag>data</tag>
-            # XXX Can data contain &... (entity or char refs)?
-            # XXX Can data contain < or > (tag characters)?
-            # XXX Can there be whitespace before the first /?
-            match = shorttag.match(rawdata, i)
-            if not match:
-                return -1
-            tag, data = match.group(1, 2)
-            self.__starttag_text = '<%s/' % tag
-            tag = tag.lower()
-            k = match.end(0)
-            self.finish_shorttag(tag, data)
-            self.__starttag_text = rawdata[start_pos:match.end(1) + 1]
-            return k
-        # XXX The following should skip matching quotes (' or ")
-        # As a shortcut way to exit, this isn't so bad, but shouldn't
-        # be used to locate the actual end of the start tag since the
-        # < or > characters may be embedded in an attribute value.
-        match = endbracket.search(rawdata, i+1)
-        if not match:
-            return -1
-        j = match.start(0)
-        # Now parse the data between i+1 and j into a tag and attrs
-        attrs = []
-        if rawdata[i:i+2] == '<>':
-            # SGML shorthand: <> == <last open tag seen>
-            k = j
-            tag = self.lasttag
-        else:
-            match = tagfind.match(rawdata, i+1)
-            if not match:
-                self.error('unexpected call to parse_starttag')
-            k = match.end(0)
-            tag = rawdata[i+1:k].lower()
-            self.lasttag = tag
-        while k < j:
-            match = attrfind.match(rawdata, k)
-            if not match: break
-            attrname, rest, attrvalue = match.group(1, 2, 3)
-            if not rest:
-                attrvalue = attrname
-            else:
-                if (attrvalue[:1] == "'" == attrvalue[-1:] or
-                    attrvalue[:1] == '"' == attrvalue[-1:]):
-                    # strip quotes
-                    attrvalue = attrvalue[1:-1]
-                attrvalue = self.entity_or_charref.sub(
-                    self._convert_ref, attrvalue)
-            attrs.append((attrname.lower(), attrvalue))
-            k = match.end(0)
-        if rawdata[j] == '>':
-            j = j+1
-        self.__starttag_text = rawdata[start_pos:j]
-        self.finish_starttag(tag, attrs)
-        return j
-
-    # Internal -- convert entity or character reference
-    def _convert_ref(self, match):
-        if match.group(2):
-            return self.convert_charref(match.group(2)) or \
-                '&#%s%s' % match.groups()[1:]
-        elif match.group(3):
-            return self.convert_entityref(match.group(1)) or \
-                '&%s;' % match.group(1)
-        else:
-            return '&%s' % match.group(1)
-
-    # Internal -- parse endtag
-    def parse_endtag(self, i):
-        rawdata = self.rawdata
-        match = endbracket.search(rawdata, i+1)
-        if not match:
-            return -1
-        j = match.start(0)
-        tag = rawdata[i+2:j].strip().lower()
-        if rawdata[j] == '>':
-            j = j+1
-        self.finish_endtag(tag)
-        return j
-
-    # Internal -- finish parsing of <tag/data/ (same as <tag>data</tag>)
-    def finish_shorttag(self, tag, data):
-        self.finish_starttag(tag, [])
-        self.handle_data(data)
-        self.finish_endtag(tag)
-
-    # Internal -- finish processing of start tag
-    # Return -1 for unknown tag, 0 for open-only tag, 1 for balanced tag
-    def finish_starttag(self, tag, attrs):
-        try:
-            method = getattr(self, 'start_' + tag)
-        except AttributeError:
-            try:
-                method = getattr(self, 'do_' + tag)
-            except AttributeError:
-                self.unknown_starttag(tag, attrs)
-                return -1
-            else:
-                self.handle_starttag(tag, method, attrs)
-                return 0
-        else:
-            self.stack.append(tag)
-            self.handle_starttag(tag, method, attrs)
-            return 1
-
-    # Internal -- finish processing of end tag
-    def finish_endtag(self, tag):
-        if not tag:
-            found = len(self.stack) - 1
-            if found < 0:
-                self.unknown_endtag(tag)
-                return
-        else:
-            if tag not in self.stack:
-                try:
-                    method = getattr(self, 'end_' + tag)
-                except AttributeError:
-                    self.unknown_endtag(tag)
-                else:
-                    self.report_unbalanced(tag)
-                return
-            found = len(self.stack)
-            for i in range(found):
-                if self.stack[i] == tag: found = i
-        while len(self.stack) > found:
-            tag = self.stack[-1]
-            try:
-                method = getattr(self, 'end_' + tag)
-            except AttributeError:
-                method = None
-            if method:
-                self.handle_endtag(tag, method)
-            else:
-                self.unknown_endtag(tag)
-            del self.stack[-1]
-
-    # Overridable -- handle start tag
-    def handle_starttag(self, tag, method, attrs):
-        method(attrs)
-
-    # Overridable -- handle end tag
-    def handle_endtag(self, tag, method):
-        method()
-
-    # Example -- report an unbalanced </...> tag.
-    def report_unbalanced(self, tag):
-        if self.verbose:
-            print('*** Unbalanced </' + tag + '>')
-            print('*** Stack:', self.stack)
-
-    def convert_charref(self, name):
-        """Convert character reference, may be overridden."""
-        try:
-            n = int(name)
-        except ValueError:
-            return
-        if not 0 <= n <= 255:
-            return
-        return self.convert_codepoint(n)
-
-    def convert_codepoint(self, codepoint):
-        return chr(codepoint)
-
-    def handle_charref(self, name):
-        """Handle character reference, no need to override."""
-        replacement = self.convert_charref(name)
-        if replacement is None:
-            self.unknown_charref(name)
-        else:
-            self.handle_data(replacement)
-
-    # Definition of entities -- derived classes may override
-    entitydefs = \
-            {'lt': '<', 'gt': '>', 'amp': '&', 'quot': '"', 'apos': '\''}
-
-    def convert_entityref(self, name):
-        """Convert entity references.
-
-        As an alternative to overriding this method; one can tailor the
-        results by setting up the self.entitydefs mapping appropriately.
-        """
-        table = self.entitydefs
-        if name in table:
-            return table[name]
-        else:
-            return
-
-    def handle_entityref(self, name):
-        """Handle entity references, no need to override."""
-        replacement = self.convert_entityref(name)
-        if replacement is None:
-            self.unknown_entityref(name)
-        else:
-            self.handle_data(replacement)
-
-    # Example -- handle data, should be overridden
-    def handle_data(self, data):
-        pass
-
-    # Example -- handle comment, could be overridden
-    def handle_comment(self, data):
-        pass
-
-    # Example -- handle declaration, could be overridden
-    def handle_decl(self, decl):
-        pass
-
-    # Example -- handle processing instruction, could be overridden
-    def handle_pi(self, data):
-        pass
-
-    # To be overridden -- handlers for unknown objects
-    def unknown_starttag(self, tag, attrs): pass
-    def unknown_endtag(self, tag): pass
-    def unknown_charref(self, ref): pass
-    def unknown_entityref(self, ref): pass
-
-
-class TestSGMLParser(SGMLParser):
-
-    def __init__(self, verbose=0):
-        self.testdata = ""
-        SGMLParser.__init__(self, verbose)
-
-    def handle_data(self, data):
-        self.testdata = self.testdata + data
-        if len(repr(self.testdata)) >= 70:
-            self.flush()
-
-    def flush(self):
-        data = self.testdata
-        if data:
-            self.testdata = ""
-            print('data:', repr(data))
-
-    def handle_comment(self, data):
-        self.flush()
-        r = repr(data)
-        if len(r) > 68:
-            r = r[:32] + '...' + r[-32:]
-        print('comment:', r)
-
-    def unknown_starttag(self, tag, attrs):
-        self.flush()
-        if not attrs:
-            print('start tag: <' + tag + '>')
-        else:
-            print('start tag: <' + tag, end=' ')
-            for name, value in attrs:
-                print(name + '=' + '"' + value + '"', end=' ')
-            print('>')
-
-    def unknown_endtag(self, tag):
-        self.flush()
-        print('end tag: </' + tag + '>')
-
-    def unknown_entityref(self, ref):
-        self.flush()
-        print('*** unknown entity ref: &' + ref + ';')
-
-    def unknown_charref(self, ref):
-        self.flush()
-        print('*** unknown char ref: &#' + ref + ';')
-
-    def unknown_decl(self, data):
-        self.flush()
-        print('*** unknown decl: [' + data + ']')
-
-    def close(self):
-        SGMLParser.close(self)
-        self.flush()
-
-
-def test(args = None):
-    import sys
-
-    if args is None:
-        args = sys.argv[1:]
-
-    if args and args[0] == '-s':
-        args = args[1:]
-        klass = SGMLParser
-    else:
-        klass = TestSGMLParser
-
-    if args:
-        file = args[0]
-    else:
-        file = 'test.html'
-
-    if file == '-':
-        f = sys.stdin
-    else:
-        try:
-            f = open(file, 'r')
-        except IOError as msg:
-            print(file, ":", msg)
-            sys.exit(1)
-
-    data = f.read()
-    if f is not sys.stdin:
-        f.close()
-
-    x = klass()
-    for c in data:
-        x.feed(c)
-    x.close()
-
-
-if __name__ == '__main__':
-    test()

Modified: python/branches/py3k/Lib/test/test___all__.py
==============================================================================
--- python/branches/py3k/Lib/test/test___all__.py	(original)
+++ python/branches/py3k/Lib/test/test___all__.py	Sun Jun  1 23:25:55 2008
@@ -73,7 +73,6 @@
         self.check_all("glob")
         self.check_all("gzip")
         self.check_all("heapq")
-        self.check_all("htmllib")
         self.check_all("http.client")
         self.check_all("ihooks")
         self.check_all("imaplib")
@@ -116,7 +115,6 @@
         self.check_all("rlcompleter")
         self.check_all("robotparser")
         self.check_all("sched")
-        self.check_all("sgmllib")
         self.check_all("shelve")
         self.check_all("shlex")
         self.check_all("shutil")

Deleted: python/branches/py3k/Lib/test/test_htmllib.py
==============================================================================
--- python/branches/py3k/Lib/test/test_htmllib.py	Sun Jun  1 23:25:55 2008
+++ (empty file)
@@ -1,69 +0,0 @@
-import formatter
-import htmllib
-import unittest
-
-from test import support
-
-
-class AnchorCollector(htmllib.HTMLParser):
-    def __init__(self, *args, **kw):
-        self.__anchors = []
-        htmllib.HTMLParser.__init__(self, *args, **kw)
-
-    def get_anchor_info(self):
-        return self.__anchors
-
-    def anchor_bgn(self, *args):
-        self.__anchors.append(args)
-
-class DeclCollector(htmllib.HTMLParser):
-    def __init__(self, *args, **kw):
-        self.__decls = []
-        htmllib.HTMLParser.__init__(self, *args, **kw)
-
-    def get_decl_info(self):
-        return self.__decls
-
-    def unknown_decl(self, data):
-        self.__decls.append(data)
-
-
-class HTMLParserTestCase(unittest.TestCase):
-    def test_anchor_collection(self):
-        # See SF bug #467059.
-        parser = AnchorCollector(formatter.NullFormatter(), verbose=1)
-        parser.feed(
-            """<a href='http://foo.org/' name='splat'> </a>
-            <a href='http://www.python.org/'> </a>
-            <a name='frob'> </a>
-            """)
-        parser.close()
-        self.assertEquals(parser.get_anchor_info(),
-                          [('http://foo.org/', 'splat', ''),
-                           ('http://www.python.org/', '', ''),
-                           ('', 'frob', ''),
-                           ])
-
-    def test_decl_collection(self):
-        # See SF patch #545300
-        parser = DeclCollector(formatter.NullFormatter(), verbose=1)
-        parser.feed(
-            """<html>
-            <body>
-            hallo
-            <![if !supportEmptyParas]>&nbsp;<![endif]>
-            </body>
-            </html>
-            """)
-        parser.close()
-        self.assertEquals(parser.get_decl_info(),
-                          ["if !supportEmptyParas",
-                           "endif"
-                           ])
-
-def test_main():
-    support.run_unittest(HTMLParserTestCase)
-
-
-if __name__ == "__main__":
-    test_main()

Deleted: python/branches/py3k/Lib/test/test_sgmllib.py
==============================================================================
--- python/branches/py3k/Lib/test/test_sgmllib.py	Sun Jun  1 23:25:55 2008
+++ (empty file)
@@ -1,438 +0,0 @@
-import pprint
-import re
-import sgmllib
-import unittest
-from test import support
-
-
-class EventCollector(sgmllib.SGMLParser):
-
-    def __init__(self):
-        self.events = []
-        self.append = self.events.append
-        sgmllib.SGMLParser.__init__(self)
-
-    def get_events(self):
-        # Normalize the list of events so that buffer artefacts don't
-        # separate runs of contiguous characters.
-        L = []
-        prevtype = None
-        for event in self.events:
-            type = event[0]
-            if type == prevtype == "data":
-                L[-1] = ("data", L[-1][1] + event[1])
-            else:
-                L.append(event)
-            prevtype = type
-        self.events = L
-        return L
-
-    # structure markup
-
-    def unknown_starttag(self, tag, attrs):
-        self.append(("starttag", tag, attrs))
-
-    def unknown_endtag(self, tag):
-        self.append(("endtag", tag))
-
-    # all other markup
-
-    def handle_comment(self, data):
-        self.append(("comment", data))
-
-    def handle_charref(self, data):
-        self.append(("charref", data))
-
-    def handle_data(self, data):
-        self.append(("data", data))
-
-    def handle_decl(self, decl):
-        self.append(("decl", decl))
-
-    def handle_entityref(self, data):
-        self.append(("entityref", data))
-
-    def handle_pi(self, data):
-        self.append(("pi", data))
-
-    def unknown_decl(self, decl):
-        self.append(("unknown decl", decl))
-
-
-class CDATAEventCollector(EventCollector):
-    def start_cdata(self, attrs):
-        self.append(("starttag", "cdata", attrs))
-        self.setliteral()
-
-
-class HTMLEntityCollector(EventCollector):
-
-    entity_or_charref = re.compile('(?:&([a-zA-Z][-.a-zA-Z0-9]*)'
-        '|&#(x[0-9a-zA-Z]+|[0-9]+))(;?)')
-
-    def convert_charref(self, name):
-        self.append(("charref", "convert", name))
-        if name[0] != "x":
-            return EventCollector.convert_charref(self, name)
-
-    def convert_codepoint(self, codepoint):
-        self.append(("codepoint", "convert", codepoint))
-        EventCollector.convert_codepoint(self, codepoint)
-
-    def convert_entityref(self, name):
-        self.append(("entityref", "convert", name))
-        return EventCollector.convert_entityref(self, name)
-
-    # These to record that they were called, then pass the call along
-    # to the default implementation so that it's actions can be
-    # recorded.
-
-    def handle_charref(self, data):
-        self.append(("charref", data))
-        sgmllib.SGMLParser.handle_charref(self, data)
-
-    def handle_entityref(self, data):
-        self.append(("entityref", data))
-        sgmllib.SGMLParser.handle_entityref(self, data)
-
-
-class SGMLParserTestCase(unittest.TestCase):
-
-    collector = EventCollector
-
-    def get_events(self, source):
-        parser = self.collector()
-        try:
-            for s in source:
-                parser.feed(s)
-            parser.close()
-        except:
-            #self.events = parser.events
-            raise
-        return parser.get_events()
-
-    def check_events(self, source, expected_events):
-        try:
-            events = self.get_events(source)
-        except:
-            #import sys
-            #print >>sys.stderr, pprint.pformat(self.events)
-            raise
-        if events != expected_events:
-            self.fail("received events did not match expected events\n"
-                      "Expected:\n" + pprint.pformat(expected_events) +
-                      "\nReceived:\n" + pprint.pformat(events))
-
-    def check_parse_error(self, source):
-        parser = EventCollector()
-        try:
-            parser.feed(source)
-            parser.close()
-        except sgmllib.SGMLParseError:
-            pass
-        else:
-            self.fail("expected SGMLParseError for %r\nReceived:\n%s"
-                      % (source, pprint.pformat(parser.get_events())))
-
-    def test_doctype_decl_internal(self):
-        inside = """\
-DOCTYPE html PUBLIC '-//W3C//DTD HTML 4.01//EN'
-             SYSTEM 'http://www.w3.org/TR/html401/strict.dtd' [
-  <!ELEMENT html - O EMPTY>
-  <!ATTLIST html
-      version CDATA #IMPLIED
-      profile CDATA 'DublinCore'>
-  <!NOTATION datatype SYSTEM 'http://xml.python.org/notations/python-module'>
-  <!ENTITY myEntity 'internal parsed entity'>
-  <!ENTITY anEntity SYSTEM 'http://xml.python.org/entities/something.xml'>
-  <!ENTITY % paramEntity 'name|name|name'>
-  %paramEntity;
-  <!-- comment -->
-]"""
-        self.check_events(["<!%s>" % inside], [
-            ("decl", inside),
-            ])
-
-    def test_doctype_decl_external(self):
-        inside = "DOCTYPE html PUBLIC '-//W3C//DTD HTML 4.01//EN'"
-        self.check_events("<!%s>" % inside, [
-            ("decl", inside),
-            ])
-
-    def test_underscore_in_attrname(self):
-        # SF bug #436621
-        """Make sure attribute names with underscores are accepted"""
-        self.check_events("<a has_under _under>", [
-            ("starttag", "a", [("has_under", "has_under"),
-                               ("_under", "_under")]),
-            ])
-
-    def test_underscore_in_tagname(self):
-        # SF bug #436621
-        """Make sure tag names with underscores are accepted"""
-        self.check_events("<has_under></has_under>", [
-            ("starttag", "has_under", []),
-            ("endtag", "has_under"),
-            ])
-
-    def test_quotes_in_unquoted_attrs(self):
-        # SF bug #436621
-        """Be sure quotes in unquoted attributes are made part of the value"""
-        self.check_events("<a href=foo'bar\"baz>", [
-            ("starttag", "a", [("href", "foo'bar\"baz")]),
-            ])
-
-    def test_xhtml_empty_tag(self):
-        """Handling of XHTML-style empty start tags"""
-        self.check_events("<br />text<i></i>", [
-            ("starttag", "br", []),
-            ("data", "text"),
-            ("starttag", "i", []),
-            ("endtag", "i"),
-            ])
-
-    def test_processing_instruction_only(self):
-        self.check_events("<?processing instruction>", [
-            ("pi", "processing instruction"),
-            ])
-
-    def test_bad_nesting(self):
-        self.check_events("<a><b></a></b>", [
-            ("starttag", "a", []),
-            ("starttag", "b", []),
-            ("endtag", "a"),
-            ("endtag", "b"),
-            ])
-
-    def test_bare_ampersands(self):
-        self.check_events("this text & contains & ampersands &", [
-            ("data", "this text & contains & ampersands &"),
-            ])
-
-    def test_bare_pointy_brackets(self):
-        self.check_events("this < text > contains < bare>pointy< brackets", [
-            ("data", "this < text > contains < bare>pointy< brackets"),
-            ])
-
-    def test_attr_syntax(self):
-        output = [
-          ("starttag", "a", [("b", "v"), ("c", "v"), ("d", "v"), ("e", "e")])
-          ]
-        self.check_events("""<a b='v' c="v" d=v e>""", output)
-        self.check_events("""<a  b = 'v' c = "v" d = v e>""", output)
-        self.check_events("""<a\nb\n=\n'v'\nc\n=\n"v"\nd\n=\nv\ne>""", output)
-        self.check_events("""<a\tb\t=\t'v'\tc\t=\t"v"\td\t=\tv\te>""", output)
-
-    def test_attr_values(self):
-        self.check_events("""<a b='xxx\n\txxx' c="yyy\t\nyyy" d='\txyz\n'>""",
-                        [("starttag", "a", [("b", "xxx\n\txxx"),
-                                            ("c", "yyy\t\nyyy"),
-                                            ("d", "\txyz\n")])
-                         ])
-        self.check_events("""<a b='' c="">""", [
-            ("starttag", "a", [("b", ""), ("c", "")]),
-            ])
-        # URL construction stuff from RFC 1808:
-        safe = "$-_.+"
-        extra = "!*'(),"
-        reserved = ";/?:@&="
-        url = "http://example.com:8080/path/to/file?%s%s%s" % (
-            safe, extra, reserved)
-        self.check_events("""<e a=%s>""" % url, [
-            ("starttag", "e", [("a", url)]),
-            ])
-        # Regression test for SF patch #669683.
-        self.check_events("<e a=rgb(1,2,3)>", [
-            ("starttag", "e", [("a", "rgb(1,2,3)")]),
-            ])
-
-    def test_attr_values_entities(self):
-        """Substitution of entities and charrefs in attribute values"""
-        # SF bug #1452246
-        self.check_events("""<a b=&lt; c=&lt;&gt; d=&lt-&gt; e='&lt; '
-                                f="&xxx;" g='&#32;&#33;' h='&#500;'
-                                i='x?a=b&c=d;'
-                                j='&amp;#42;' k='&#38;#42;'>""",
-            [("starttag", "a", [("b", "<"),
-                                ("c", "<>"),
-                                ("d", "&lt->"),
-                                ("e", "< "),
-                                ("f", "&xxx;"),
-                                ("g", " !"),
-                                ("h", "&#500;"),
-                                ("i", "x?a=b&c=d;"),
-                                ("j", "&#42;"),
-                                ("k", "&#42;"),
-                                ])])
-
-    def test_convert_overrides(self):
-        # This checks that the character and entity reference
-        # conversion helpers are called at the documented times.  No
-        # attempt is made to really change what the parser accepts.
-        #
-        self.collector = HTMLEntityCollector
-        self.check_events(('<a title="&ldquo;test&#x201d;">foo</a>'
-                           '&foobar;&#42;'), [
-            ('entityref', 'convert', 'ldquo'),
-            ('charref', 'convert', 'x201d'),
-            ('starttag', 'a', [('title', '&ldquo;test&#x201d;')]),
-            ('data', 'foo'),
-            ('endtag', 'a'),
-            ('entityref', 'foobar'),
-            ('entityref', 'convert', 'foobar'),
-            ('charref', '42'),
-            ('charref', 'convert', '42'),
-            ('codepoint', 'convert', 42),
-            ])
-
-    def test_attr_funky_names(self):
-        self.check_events("""<a a.b='v' c:d=v e-f=v>""", [
-            ("starttag", "a", [("a.b", "v"), ("c:d", "v"), ("e-f", "v")]),
-            ])
-
-    def test_attr_value_ip6_url(self):
-        # http://www.python.org/sf/853506
-        self.check_events(("<a href='http://[1080::8:800:200C:417A]/'>"
-                           "<a href=http://[1080::8:800:200C:417A]/>"), [
-            ("starttag", "a", [("href", "http://[1080::8:800:200C:417A]/")]),
-            ("starttag", "a", [("href", "http://[1080::8:800:200C:417A]/")]),
-            ])
-
-    def test_illegal_declarations(self):
-        s = 'abc<!spacer type="block" height="25">def'
-        self.check_events(s, [
-            ("data", "abc"),
-            ("unknown decl", 'spacer type="block" height="25"'),
-            ("data", "def"),
-            ])
-
-    def test_weird_starttags(self):
-        self.check_events("<a<a>", [
-            ("starttag", "a", []),
-            ("starttag", "a", []),
-            ])
-        self.check_events("</a<a>", [
-            ("endtag", "a"),
-            ("starttag", "a", []),
-            ])
-
-    def test_declaration_junk_chars(self):
-        self.check_parse_error("<!DOCTYPE foo $ >")
-
-    def test_get_starttag_text(self):
-        s = """<foobar   \n   one="1"\ttwo=2   >"""
-        self.check_events(s, [
-            ("starttag", "foobar", [("one", "1"), ("two", "2")]),
-            ])
-
-    def test_cdata_content(self):
-        s = ("<cdata> <!-- not a comment --> &not-an-entity-ref; </cdata>"
-             "<notcdata> <!-- comment --> </notcdata>")
-        self.collector = CDATAEventCollector
-        self.check_events(s, [
-            ("starttag", "cdata", []),
-            ("data", " <!-- not a comment --> &not-an-entity-ref; "),
-            ("endtag", "cdata"),
-            ("starttag", "notcdata", []),
-            ("data", " "),
-            ("comment", " comment "),
-            ("data", " "),
-            ("endtag", "notcdata"),
-            ])
-        s = """<cdata> <not a='start tag'> </cdata>"""
-        self.check_events(s, [
-            ("starttag", "cdata", []),
-            ("data", " <not a='start tag'> "),
-            ("endtag", "cdata"),
-            ])
-
-    def test_illegal_declarations(self):
-        s = 'abc<!spacer type="block" height="25">def'
-        self.check_events(s, [
-            ("data", "abc"),
-            ("unknown decl", 'spacer type="block" height="25"'),
-            ("data", "def"),
-            ])
-
-    def test_enumerated_attr_type(self):
-        s = "<!DOCTYPE doc [<!ATTLIST doc attr (a | b) >]>"
-        self.check_events(s, [
-            ('decl', 'DOCTYPE doc [<!ATTLIST doc attr (a | b) >]'),
-            ])
-
-    def test_read_chunks(self):
-        # SF bug #1541697, this caused sgml parser to hang
-        # Just verify this code doesn't cause a hang.
-        CHUNK = 1024  # increasing this to 8212 makes the problem go away
-
-        f = open(support.findfile('sgml_input.html'), encoding="latin-1")
-        fp = sgmllib.SGMLParser()
-        while 1:
-            data = f.read(CHUNK)
-            fp.feed(data)
-            if len(data) != CHUNK:
-                break
-
-    # XXX These tests have been disabled by prefixing their names with
-    # an underscore.  The first two exercise outstanding bugs in the
-    # sgmllib module, and the third exhibits questionable behavior
-    # that needs to be carefully considered before changing it.
-
-    def _test_starttag_end_boundary(self):
-        self.check_events("<a b='<'>", [("starttag", "a", [("b", "<")])])
-        self.check_events("<a b='>'>", [("starttag", "a", [("b", ">")])])
-
-    def _test_buffer_artefacts(self):
-        output = [("starttag", "a", [("b", "<")])]
-        self.check_events(["<a b='<'>"], output)
-        self.check_events(["<a ", "b='<'>"], output)
-        self.check_events(["<a b", "='<'>"], output)
-        self.check_events(["<a b=", "'<'>"], output)
-        self.check_events(["<a b='<", "'>"], output)
-        self.check_events(["<a b='<'", ">"], output)
-
-        output = [("starttag", "a", [("b", ">")])]
-        self.check_events(["<a b='>'>"], output)
-        self.check_events(["<a ", "b='>'>"], output)
-        self.check_events(["<a b", "='>'>"], output)
-        self.check_events(["<a b=", "'>'>"], output)
-        self.check_events(["<a b='>", "'>"], output)
-        self.check_events(["<a b='>'", ">"], output)
-
-        output = [("comment", "abc")]
-        self.check_events(["", "<!--abc-->"], output)
-        self.check_events(["<", "!--abc-->"], output)
-        self.check_events(["<!", "--abc-->"], output)
-        self.check_events(["<!-", "-abc-->"], output)
-        self.check_events(["<!--", "abc-->"], output)
-        self.check_events(["<!--a", "bc-->"], output)
-        self.check_events(["<!--ab", "c-->"], output)
-        self.check_events(["<!--abc", "-->"], output)
-        self.check_events(["<!--abc-", "->"], output)
-        self.check_events(["<!--abc--", ">"], output)
-        self.check_events(["<!--abc-->", ""], output)
-
-    def _test_starttag_junk_chars(self):
-        self.check_parse_error("<")
-        self.check_parse_error("<>")
-        self.check_parse_error("</$>")
-        self.check_parse_error("</")
-        self.check_parse_error("</a")
-        self.check_parse_error("<$")
-        self.check_parse_error("<$>")
-        self.check_parse_error("<!")
-        self.check_parse_error("<a $>")
-        self.check_parse_error("<a")
-        self.check_parse_error("<a foo='bar'")
-        self.check_parse_error("<a foo='bar")
-        self.check_parse_error("<a foo='>'")
-        self.check_parse_error("<a foo='>")
-        self.check_parse_error("<a foo=>")
-
-
-def test_main():
-    support.run_unittest(SGMLParserTestCase)
-
-
-if __name__ == "__main__":
-    test_main()

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Sun Jun  1 23:25:55 2008
@@ -60,6 +60,8 @@
 Library
 -------
 
+- Removed the ``htmllib`` and ``sgmllib`` modules.
+
 - The deprecated ``SmartCookie`` and ``SimpleCookie`` classes have
   been removed from ``http.cookies``.
 

Modified: python/branches/py3k/Misc/cheatsheet
==============================================================================
--- python/branches/py3k/Misc/cheatsheet	(original)
+++ python/branches/py3k/Misc/cheatsheet	Sun Jun  1 23:25:55 2008
@@ -1895,7 +1895,6 @@
 rlcompleter      Word completion for GNU readline 2.0.
 robotparser      Parse robots.txt files, useful for web spiders.
 sched            A generally useful event scheduler class.
-sgmllib          A parser for SGML.
 shelve           Manage shelves of pickled objects.
 shlex            Lexical analyzer class for simple shell-like syntaxes.
 shutil           Utility functions usable in a shell-like program.

From python-3000-checkins at python.org  Sun Jun  1 23:27:22 2008
From: python-3000-checkins at python.org (georg.brandl)
Date: Sun,  1 Jun 2008 23:27:22 +0200 (CEST)
Subject: [Python-3000-checkins] r63876 - python/branches/py3k
Message-ID: <20080601212722.345C21E400A@bag.python.org>

Author: georg.brandl
Date: Sun Jun  1 23:27:21 2008
New Revision: 63876

Log:
Blocked revisions 63873 via svnmerge

........
  r63873 | georg.brandl | 2008-06-01 23:19:14 +0200 (Sun, 01 Jun 2008) | 2 lines
  
  Deprecate htmllib and sgmllib for 3.0.
........


Modified:
   python/branches/py3k/   (props changed)

From python-3000-checkins at python.org  Tue Jun  3 03:32:37 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Tue,  3 Jun 2008 03:32:37 +0200 (CEST)
Subject: [Python-3000-checkins] r63911 - python/branches/py3k
Message-ID: <20080603013237.E173A1E4004@bag.python.org>

Author: benjamin.peterson
Date: Tue Jun  3 03:32:37 2008
New Revision: 63911

Log:
Blocked revisions 63910 via svnmerge

........
  r63910 | benjamin.peterson | 2008-06-02 20:30:37 -0500 (Mon, 02 Jun 2008) | 2 lines
  
  make test_mutex more elegant
........


Modified:
   python/branches/py3k/   (props changed)

From python-3000-checkins at python.org  Tue Jun  3 12:25:48 2008
From: python-3000-checkins at python.org (georg.brandl)
Date: Tue,  3 Jun 2008 12:25:48 +0200 (CEST)
Subject: [Python-3000-checkins] r63915 -
	python/branches/py3k/Lib/tkinter/__init__.py
Message-ID: <20080603102548.63B971E4021@bag.python.org>

Author: georg.brandl
Date: Tue Jun  3 12:25:47 2008
New Revision: 63915

Log:
Fix Tkinter sequence passing. #2906.


Modified:
   python/branches/py3k/Lib/tkinter/__init__.py

Modified: python/branches/py3k/Lib/tkinter/__init__.py
==============================================================================
--- python/branches/py3k/Lib/tkinter/__init__.py	(original)
+++ python/branches/py3k/Lib/tkinter/__init__.py	Tue Jun  3 12:25:47 2008
@@ -1052,11 +1052,16 @@
                 if hasattr(v, '__call__'):
                     v = self._register(v)
                 elif isinstance(v, (tuple, list)):
+                    nv = []
                     for item in v:
-                        if not isinstance(item, (str, int)):
+                        if isinstance(item, int):
+                            nv.append(str(item))
+                        elif isinstance(item, str):
+                            nv.append(('{%s}' if ' ' in item else '%s') % item)
+                        else:
                             break
                     else:
-                        v = ' '.join(map(str, v))
+                        v = ' '.join(nv)
                 res = res + ('-'+k, v)
         return res
     def nametowidget(self, name):

From python-3000-checkins at python.org  Tue Jun  3 13:43:37 2008
From: python-3000-checkins at python.org (walter.doerwald)
Date: Tue,  3 Jun 2008 13:43:37 +0200 (CEST)
Subject: [Python-3000-checkins] r63917 - python/branches/py3k
Message-ID: <20080603114337.719031E4004@bag.python.org>

Author: walter.doerwald
Date: Tue Jun  3 13:43:37 2008
New Revision: 63917

Log:
Blocked revisions 63899 via svnmerge

........
  r63899 | walter.doerwald | 2008-06-02 22:36:03 +0200 (Mon, 02 Jun 2008) | 3 lines
  
  Change all functions that expect one unicode character to accept a pair of
  surrogates in narrow builds. Fixes issue #1706460.
........


Modified:
   python/branches/py3k/   (props changed)

From python-3000-checkins at python.org  Tue Jun  3 13:45:03 2008
From: python-3000-checkins at python.org (walter.doerwald)
Date: Tue,  3 Jun 2008 13:45:03 +0200 (CEST)
Subject: [Python-3000-checkins] r63918 - in python/branches/py3k:
	Lib/test/test_unicodedata.py Modules/unicodedata.c
Message-ID: <20080603114503.065021E4004@bag.python.org>

Author: walter.doerwald
Date: Tue Jun  3 13:45:02 2008
New Revision: 63918

Log:
Change all functions that expect one unicode character to accept a pair of
surrogates in narrow builds. Fixes issue #1706460. (Port of r63899).


Modified:
   python/branches/py3k/Lib/test/test_unicodedata.py
   python/branches/py3k/Modules/unicodedata.c

Modified: python/branches/py3k/Lib/test/test_unicodedata.py
==============================================================================
--- python/branches/py3k/Lib/test/test_unicodedata.py	(original)
+++ python/branches/py3k/Lib/test/test_unicodedata.py	Tue Jun  3 13:45:02 2008
@@ -103,6 +103,7 @@
         self.assertEqual(self.db.digit('9'), 9)
         self.assertEqual(self.db.digit('\u215b', None), None)
         self.assertEqual(self.db.digit('\u2468'), 9)
+        self.assertEqual(self.db.digit('\U00020000', None), None)
 
         self.assertRaises(TypeError, self.db.digit)
         self.assertRaises(TypeError, self.db.digit, 'xx')
@@ -113,6 +114,7 @@
         self.assertEqual(self.db.numeric('9'), 9)
         self.assertEqual(self.db.numeric('\u215b'), 0.125)
         self.assertEqual(self.db.numeric('\u2468'), 9.0)
+        self.assertEqual(self.db.numeric('\U00020000', None), None)
 
         self.assertRaises(TypeError, self.db.numeric)
         self.assertRaises(TypeError, self.db.numeric, 'xx')
@@ -123,6 +125,7 @@
         self.assertEqual(self.db.decimal('9'), 9)
         self.assertEqual(self.db.decimal('\u215b', None), None)
         self.assertEqual(self.db.decimal('\u2468', None), None)
+        self.assertEqual(self.db.decimal('\U00020000', None), None)
 
         self.assertRaises(TypeError, self.db.decimal)
         self.assertRaises(TypeError, self.db.decimal, 'xx')
@@ -132,6 +135,7 @@
         self.assertEqual(self.db.category('\uFFFE'), 'Cn')
         self.assertEqual(self.db.category('a'), 'Ll')
         self.assertEqual(self.db.category('A'), 'Lu')
+        self.assertEqual(self.db.category('\U00020000'), 'Lo')
 
         self.assertRaises(TypeError, self.db.category)
         self.assertRaises(TypeError, self.db.category, 'xx')
@@ -140,6 +144,7 @@
         self.assertEqual(self.db.bidirectional('\uFFFE'), '')
         self.assertEqual(self.db.bidirectional(' '), 'WS')
         self.assertEqual(self.db.bidirectional('A'), 'L')
+        self.assertEqual(self.db.bidirectional('\U00020000'), 'L')
 
         self.assertRaises(TypeError, self.db.bidirectional)
         self.assertRaises(TypeError, self.db.bidirectional, 'xx')
@@ -155,6 +160,7 @@
         self.assertEqual(self.db.mirrored('\uFFFE'), 0)
         self.assertEqual(self.db.mirrored('a'), 0)
         self.assertEqual(self.db.mirrored('\u2201'), 1)
+        self.assertEqual(self.db.mirrored('\U00020000'), 0)
 
         self.assertRaises(TypeError, self.db.mirrored)
         self.assertRaises(TypeError, self.db.mirrored, 'xx')
@@ -163,6 +169,7 @@
         self.assertEqual(self.db.combining('\uFFFE'), 0)
         self.assertEqual(self.db.combining('a'), 0)
         self.assertEqual(self.db.combining('\u20e1'), 230)
+        self.assertEqual(self.db.combining('\U00020000'), 0)
 
         self.assertRaises(TypeError, self.db.combining)
         self.assertRaises(TypeError, self.db.combining, 'xx')
@@ -186,6 +193,7 @@
         self.assertEqual(eaw('\uFF66'), 'H')
         self.assertEqual(eaw('\uFF1F'), 'F')
         self.assertEqual(eaw('\u2010'), 'A')
+        self.assertEqual(eaw('\U00020000'), 'W')
 
 class UnicodeMiscTest(UnicodeDatabaseTest):
 

Modified: python/branches/py3k/Modules/unicodedata.c
==============================================================================
--- python/branches/py3k/Modules/unicodedata.c	(original)
+++ python/branches/py3k/Modules/unicodedata.c	Tue Jun  3 13:45:02 2008
@@ -54,12 +54,6 @@
     return &_PyUnicode_Database_Records[index];
 }
 
-static const _PyUnicode_DatabaseRecord*
-_getrecord(PyUnicodeObject* v)
-{
-    return _getrecord_ex(*PyUnicode_AS_UNICODE(v));
-}
-
 /* ------------- Previous-version API ------------------------------------- */
 typedef struct previous_version {
     PyObject_HEAD
@@ -92,6 +86,24 @@
 	return (PyObject*)self;
 }
 
+
+static Py_UCS4 getuchar(PyUnicodeObject *obj)
+{
+    Py_UNICODE *v = PyUnicode_AS_UNICODE(obj);
+
+    if (PyUnicode_GET_SIZE(obj) == 1)
+	return *v;
+#ifndef Py_UNICODE_WIDE
+    else if ((PyUnicode_GET_SIZE(obj) == 2) &&
+             (0xD800 <= v[0] && v[0] <= 0xDBFF) &&
+             (0xDC00 <= v[1] && v[1] <= 0xDFFF))
+	return (((v[0] & 0x3FF)<<10) | (v[1] & 0x3FF)) + 0x10000;
+#endif
+    PyErr_SetString(PyExc_TypeError,
+                    "need a single Unicode character as parameter");
+    return (Py_UCS4)-1;
+}
+
 /* --- Module API --------------------------------------------------------- */
 
 PyDoc_STRVAR(unicodedata_decimal__doc__,
@@ -108,17 +120,16 @@
     PyObject *defobj = NULL;
     int have_old = 0;
     long rc;
+    Py_UCS4 c;
 
     if (!PyArg_ParseTuple(args, "O!|O:decimal", &PyUnicode_Type, &v, &defobj))
         return NULL;
-    if (PyUnicode_GET_SIZE(v) != 1) {
-	PyErr_SetString(PyExc_TypeError,
-			"need a single Unicode character as parameter");
+    c = getuchar(v);
+    if (c == (Py_UCS4)-1)
         return NULL;
-    }
 
     if (self) {
-        const change_record *old = get_old_record(self, *PyUnicode_AS_UNICODE(v));
+        const change_record *old = get_old_record(self, c);
         if (old->category_changed == 0) {
             /* unassigned */
             have_old = 1;
@@ -131,7 +142,7 @@
     }
 
     if (!have_old)
-        rc = Py_UNICODE_TODECIMAL(*PyUnicode_AS_UNICODE(v));
+        rc = Py_UNICODE_TODECIMAL(c);
     if (rc < 0) {
 	if (defobj == NULL) {
 	    PyErr_SetString(PyExc_ValueError,
@@ -159,15 +170,14 @@
     PyUnicodeObject *v;
     PyObject *defobj = NULL;
     long rc;
+    Py_UCS4 c;
 
     if (!PyArg_ParseTuple(args, "O!|O:digit", &PyUnicode_Type, &v, &defobj))
         return NULL;
-    if (PyUnicode_GET_SIZE(v) != 1) {
-	PyErr_SetString(PyExc_TypeError,
-			"need a single Unicode character as parameter");
+    c = getuchar(v);
+    if (c == (Py_UCS4)-1)
         return NULL;
-    }
-    rc = Py_UNICODE_TODIGIT(*PyUnicode_AS_UNICODE(v));
+    rc = Py_UNICODE_TODIGIT(c);
     if (rc < 0) {
 	if (defobj == NULL) {
 	    PyErr_SetString(PyExc_ValueError, "not a digit");
@@ -195,17 +205,16 @@
     PyObject *defobj = NULL;
     int have_old = 0;
     double rc;
+    Py_UCS4 c;
 
     if (!PyArg_ParseTuple(args, "O!|O:numeric", &PyUnicode_Type, &v, &defobj))
         return NULL;
-    if (PyUnicode_GET_SIZE(v) != 1) {
-	PyErr_SetString(PyExc_TypeError,
-			"need a single Unicode character as parameter");
-	return NULL;
-    }
+    c = getuchar(v);
+    if (c == (Py_UCS4)-1)
+        return NULL;
 
     if (self) {
-        const change_record *old = get_old_record(self, *PyUnicode_AS_UNICODE(v));
+        const change_record *old = get_old_record(self, c);
         if (old->category_changed == 0) {
             /* unassigned */
             have_old = 1;
@@ -218,7 +227,7 @@
     }
 
     if (!have_old)
-        rc = Py_UNICODE_TONUMERIC(*PyUnicode_AS_UNICODE(v));
+        rc = Py_UNICODE_TONUMERIC(c);
     if (rc == -1.0) {
 	if (defobj == NULL) {
 	    PyErr_SetString(PyExc_ValueError, "not a numeric character");
@@ -243,18 +252,17 @@
 {
     PyUnicodeObject *v;
     int index;
+    Py_UCS4 c;
 
     if (!PyArg_ParseTuple(args, "O!:category",
 			  &PyUnicode_Type, &v))
 	return NULL;
-    if (PyUnicode_GET_SIZE(v) != 1) {
-	PyErr_SetString(PyExc_TypeError,
-			"need a single Unicode character as parameter");
-	return NULL;
-    }
-    index = (int) _getrecord(v)->category;
+    c = getuchar(v);
+    if (c == (Py_UCS4)-1)
+        return NULL;
+    index = (int) _getrecord_ex(c)->category;
     if (self) {
-        const change_record *old = get_old_record(self, *PyUnicode_AS_UNICODE(v));
+        const change_record *old = get_old_record(self, c);
         if (old->category_changed != 0xFF)
             index = old->category_changed;
     }
@@ -273,18 +281,17 @@
 {
     PyUnicodeObject *v;
     int index;
+    Py_UCS4 c;
 
     if (!PyArg_ParseTuple(args, "O!:bidirectional",
 			  &PyUnicode_Type, &v))
 	return NULL;
-    if (PyUnicode_GET_SIZE(v) != 1) {
-	PyErr_SetString(PyExc_TypeError,
-			"need a single Unicode character as parameter");
-	return NULL;
-    }
-    index = (int) _getrecord(v)->bidirectional;
+    c = getuchar(v);
+    if (c == (Py_UCS4)-1)
+        return NULL;
+    index = (int) _getrecord_ex(c)->bidirectional;
     if (self) {
-        const change_record *old = get_old_record(self, *PyUnicode_AS_UNICODE(v));
+        const change_record *old = get_old_record(self, c);
         if (old->category_changed == 0)
             index = 0; /* unassigned */
         else if (old->bidir_changed != 0xFF)
@@ -305,18 +312,17 @@
 {
     PyUnicodeObject *v;
     int index;
+    Py_UCS4 c;
 
     if (!PyArg_ParseTuple(args, "O!:combining",
 			  &PyUnicode_Type, &v))
 	return NULL;
-    if (PyUnicode_GET_SIZE(v) != 1) {
-	PyErr_SetString(PyExc_TypeError,
-			"need a single Unicode character as parameter");
-	return NULL;
-    }
-    index = (int) _getrecord(v)->combining;
+    c = getuchar(v);
+    if (c == (Py_UCS4)-1)
+        return NULL;
+    index = (int) _getrecord_ex(c)->combining;
     if (self) {
-        const change_record *old = get_old_record(self, *PyUnicode_AS_UNICODE(v));
+        const change_record *old = get_old_record(self, c);
         if (old->category_changed == 0)
             index = 0; /* unassigned */
     }
@@ -335,18 +341,17 @@
 {
     PyUnicodeObject *v;
     int index;
+    Py_UCS4 c;
 
     if (!PyArg_ParseTuple(args, "O!:mirrored",
 			  &PyUnicode_Type, &v))
 	return NULL;
-    if (PyUnicode_GET_SIZE(v) != 1) {
-	PyErr_SetString(PyExc_TypeError,
-			"need a single Unicode character as parameter");
-	return NULL;
-    }
-    index = (int) _getrecord(v)->mirrored;
+    c = getuchar(v);
+    if (c == (Py_UCS4)-1)
+        return NULL;
+    index = (int) _getrecord_ex(c)->mirrored;
     if (self) {
-        const change_record *old = get_old_record(self, *PyUnicode_AS_UNICODE(v));
+        const change_record *old = get_old_record(self, c);
         if (old->category_changed == 0)
             index = 0; /* unassigned */
     }
@@ -364,18 +369,17 @@
 {
     PyUnicodeObject *v;
     int index;
+    Py_UCS4 c;
 
     if (!PyArg_ParseTuple(args, "O!:east_asian_width",
 			  &PyUnicode_Type, &v))
 	return NULL;
-    if (PyUnicode_GET_SIZE(v) != 1) {
-	PyErr_SetString(PyExc_TypeError,
-			"need a single Unicode character as parameter");
-	return NULL;
-    }
-    index = (int) _getrecord(v)->east_asian_width;
+    c = getuchar(v);
+    if (c == (Py_UCS4)-1)
+        return NULL;
+    index = (int) _getrecord_ex(c)->east_asian_width;
     if (self) {
-        const change_record *old = get_old_record(self, *PyUnicode_AS_UNICODE(v));
+        const change_record *old = get_old_record(self, c);
         if (old->category_changed == 0)
             index = 0; /* unassigned */
     }
@@ -396,20 +400,19 @@
     char decomp[256];
     int code, index, count, i;
     unsigned int prefix_index;
+    Py_UCS4 c;
 
     if (!PyArg_ParseTuple(args, "O!:decomposition",
 			  &PyUnicode_Type, &v))
 	return NULL;
-    if (PyUnicode_GET_SIZE(v) != 1) {
-	PyErr_SetString(PyExc_TypeError,
-			"need a single Unicode character as parameter");
-	return NULL;
-    }
+    c = getuchar(v);
+    if (c == (Py_UCS4)-1)
+        return NULL;
 
-    code = (int) *PyUnicode_AS_UNICODE(v);
+    code = (int)c;
 
     if (self) {
-        const change_record *old = get_old_record(self, *PyUnicode_AS_UNICODE(v));
+        const change_record *old = get_old_record(self, c);
         if (old->category_changed == 0)
             return PyUnicode_FromString(""); /* unassigned */
     }
@@ -1039,20 +1042,18 @@
 unicodedata_name(PyObject* self, PyObject* args)
 {
     char name[NAME_MAXLEN];
+    Py_UCS4 c;
 
     PyUnicodeObject* v;
     PyObject* defobj = NULL;
     if (!PyArg_ParseTuple(args, "O!|O:name", &PyUnicode_Type, &v, &defobj))
         return NULL;
 
-    if (PyUnicode_GET_SIZE(v) != 1) {
-	PyErr_SetString(PyExc_TypeError,
-			"need a single Unicode character as parameter");
-	return NULL;
-    }
+    c = getuchar(v);
+    if (c == (Py_UCS4)-1)
+        return NULL;
 
-    if (!_getucname(self, (Py_UCS4) *PyUnicode_AS_UNICODE(v),
-                    name, sizeof(name))) {
+    if (!_getucname(self, c, name, sizeof(name))) {
 	if (defobj == NULL) {
 	    PyErr_SetString(PyExc_ValueError, "no such name");
             return NULL;

From python-3000-checkins at python.org  Tue Jun  3 20:57:08 2008
From: python-3000-checkins at python.org (martin.v.loewis)
Date: Tue,  3 Jun 2008 20:57:08 +0200 (CEST)
Subject: [Python-3000-checkins] r63889 - in python/branches/py3k:
	Tools/msi/msi.py Tools/msi/msilib.py
Message-ID: <20080603185708.2B08B1E400A@bag.python.org>

Author: martin.v.loewis
Date: Mon Jun  2 12:04:16 2008
New Revision: 63889

Log:
Merged revisions 63625-63629,63631-63633,63635-63638 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/trunk

........
  r63625 | martin.v.loewis | 2008-05-25 13:56:23 +0200 (So, 25 Mai 2008) | 1 line
  
  Include all licenses of the packages that we include.
........
  r63638 | martin.v.loewis | 2008-05-25 18:37:34 +0200 (So, 25 Mai 2008) | 1 line
  
  Create grammar pickle files on installation; remove them on uninstallation.
........


Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Tools/msi/msi.py
   python/branches/py3k/Tools/msi/msilib.py

Modified: python/branches/py3k/Tools/msi/msi.py
==============================================================================
--- python/branches/py3k/Tools/msi/msi.py	(original)
+++ python/branches/py3k/Tools/msi/msi.py	Mon Jun  2 12:04:16 2008
@@ -383,6 +383,7 @@
              ])
 
     compileargs = r'-Wi "[TARGETDIR]Lib\compileall.py" -f -x bad_coding|badsyntax|site-packages|py2_ "[TARGETDIR]Lib"'
+    lib2to3args = r'-c "import lib2to3.pygram, lib2to3.patcomp;lib2to3.patcomp.PatternCompiler()"'
     # See "CustomAction Table"
     add_data(db, "CustomAction", [
         # msidbCustomActionTypeFirstSequence + msidbCustomActionTypeTextData + msidbCustomActionTypeProperty
@@ -396,6 +397,7 @@
         # See "Custom Action Type 18"
         ("CompilePyc", 18, "python.exe", compileargs),
         ("CompilePyo", 18, "python.exe", "-O "+compileargs),
+        ("CompileGrammar", 18, "python.exe", lib2to3args),
         ])
 
     # UI Sequences, see "InstallUISequence Table", "Using a Sequence Table"
@@ -425,12 +427,14 @@
              ("UpdateEditIDLE", None, 1050),
              ("CompilePyc", "COMPILEALL", 6800),
              ("CompilePyo", "COMPILEALL", 6801),
+             ("CompileGrammar", "COMPILEALL", 6802),
             ])
     add_data(db, "AdminExecuteSequence",
             [("InitialTargetDir", 'TARGETDIR=""', 750),
              ("SetDLLDirToTarget", 'DLLDIR=""', 751),
              ("CompilePyc", "COMPILEALL", 6800),
              ("CompilePyo", "COMPILEALL", 6801),
+             ("CompileGrammar", "COMPILEALL", 6802),
             ])
 
     #####################################################################
@@ -841,6 +845,26 @@
         result.append((f, kw))
     return result
 
+def generate_license():
+    import shutil, glob
+    out = open("LICENSE.txt", "w")
+    shutil.copyfileobj(open(os.path.join(srcdir, "LICENSE")), out)
+    for dir, file in (("bzip2","LICENSE"),
+                      ("db", "LICENSE"),
+                      ("openssl", "LICENSE"),
+                      ("tcl", "license.terms"),
+                      ("tk", "license.terms")):
+        out.write("\nThis copy of Python includes a copy of %s, which is licensed under the following terms:\n\n" % dir)
+        dirs = glob.glob(srcdir+"/../"+dir+"-*")
+        if not dirs:
+            raise ValueError, "Could not find "+srcdir+"/../"+dir+"-*"
+        if len(dirs) > 2:
+            raise ValueError, "Multiple copies of "+dir
+        dir = dirs[0]
+        shutil.copyfileobj(open(os.path.join(dir, file)), out)
+    out.close()
+
+
 class PyDirectory(Directory):
     """By default, all components in the Python installer
     can run from source."""
@@ -861,7 +885,8 @@
         root.add_file("%s/w9xpopen.exe" % PCBUILD)
     root.add_file("README.txt", src="README")
     root.add_file("NEWS.txt", src="Misc/NEWS")
-    root.add_file("LICENSE.txt", src="LICENSE")
+    generate_license()
+    root.add_file("LICENSE.txt", src=os.path.abspath("LICENSE.txt"))
     root.start_component("python.exe", keyfile="python.exe")
     root.add_file("%s/python.exe" % PCBUILD)
     root.start_component("pythonw.exe", keyfile="pythonw.exe")
@@ -979,6 +1004,8 @@
         if dir=="setuptools":
             lib.add_file("cli.exe")
             lib.add_file("gui.exe")
+        if dir=="lib2to3":
+            lib.removefile("pickle", "*.pickle")
         if dir=="data" and parent.physical=="test" and parent.basedir.physical=="email":
             # This should contain all non-.svn files listed in subversion
             for f in os.listdir(lib.absolute):

Modified: python/branches/py3k/Tools/msi/msilib.py
==============================================================================
--- python/branches/py3k/Tools/msi/msilib.py	(original)
+++ python/branches/py3k/Tools/msi/msilib.py	Mon Jun  2 12:04:16 2008
@@ -566,6 +566,11 @@
                  [(self.component+"c", self.component, "*.pyc", self.logical, 2),
                   (self.component+"o", self.component, "*.pyo", self.logical, 2)])
 
+    def removefile(self, key, pattern):
+        "Add a RemoveFile entry"
+        add_data(self.db, "RemoveFile", [(self.component+key, self.component, pattern, self.logical, 2)])
+
+
 class Feature:
     def __init__(self, db, id, title, desc, display, level = 1,
                  parent=None, directory = None, attributes=0):

From python-3000-checkins at python.org  Tue Jun  3 20:57:10 2008
From: python-3000-checkins at python.org (martin.v.loewis)
Date: Tue,  3 Jun 2008 20:57:10 +0200 (CEST)
Subject: [Python-3000-checkins] r63890 - in python/branches/py3k:
	Doc/library/msilib.rst PC/_msi.c
Message-ID: <20080603185710.63A9F1E400A@bag.python.org>

Author: martin.v.loewis
Date: Mon Jun  2 12:08:54 2008
New Revision: 63890

Log:
Merged revisions 63888 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/trunk

........
  r63888 | martin.v.loewis | 2008-06-02 10:40:06 +0200 (Mo, 02 Jun 2008) | 2 lines
  
  Patch #2125: Add GetInteger and GetString methods for 
  msilib.Record objects.
........


Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Doc/library/msilib.rst
   python/branches/py3k/PC/_msi.c

Modified: python/branches/py3k/Doc/library/msilib.rst
==============================================================================
--- python/branches/py3k/Doc/library/msilib.rst	(original)
+++ python/branches/py3k/Doc/library/msilib.rst	Mon Jun  2 12:08:54 2008
@@ -262,6 +262,18 @@
    :cfunc:`MsiRecordGetFieldCount`.
 
 
+.. method:: Record.GetInteger(field)
+
+   Return the value of *field* as an integer where possible.  *field* must
+   be an integer.
+
+
+.. method:: Record.GetString(field)
+
+   Return the value of *field* as a string where possible.  *field* must
+   be an integer.
+
+
 .. method:: Record.SetString(field, value)
 
    Set *field* to *value* through :cfunc:`MsiRecordSetString`. *field* must be an
@@ -541,3 +553,4 @@
    This module contains definitions for the UIText and ActionText tables, for the
    standard installer actions.
 
+

Modified: python/branches/py3k/PC/_msi.c
==============================================================================
--- python/branches/py3k/PC/_msi.c	(original)
+++ python/branches/py3k/PC/_msi.c	Mon Jun  2 12:08:54 2008
@@ -339,6 +339,49 @@
 }
 
 static PyObject*
+record_getinteger(msiobj* record, PyObject* args)
+{
+    unsigned int field;
+    int status;
+    
+    if (!PyArg_ParseTuple(args, "I:GetInteger", &field))
+        return NULL;
+    status = MsiRecordGetInteger(record->h, field);
+    if (status == MSI_NULL_INTEGER){
+        PyErr_SetString(MSIError, "could not convert record field to integer");
+        return NULL;
+    }
+    return PyInt_FromLong((long) status);
+}
+
+static PyObject*
+record_getstring(msiobj* record, PyObject* args)
+{
+    unsigned int field;
+    unsigned int status;
+    char buf[2000];
+    char *res = buf;
+    DWORD size = sizeof(buf);
+    PyObject* string;
+    
+    if (!PyArg_ParseTuple(args, "I:GetString", &field))
+        return NULL;
+    status = MsiRecordGetString(record->h, field, res, &size);
+    if (status == ERROR_MORE_DATA) {
+        res = (char*) malloc(size + 1);
+        if (res == NULL)
+            return PyErr_NoMemory();
+        status = MsiRecordGetString(record->h, field, res, &size);
+    }
+    if (status != ERROR_SUCCESS)
+        return msierror((int) status);
+    string = PyString_FromString(res);
+    if (buf != res)
+        free(res);
+    return string;
+}
+
+static PyObject*
 record_cleardata(msiobj* record, PyObject *args)
 {
     int status = MsiRecordClearData(record->h);
@@ -405,6 +448,10 @@
 static PyMethodDef record_methods[] = {
     { "GetFieldCount", (PyCFunction)record_getfieldcount, METH_NOARGS, 
 	PyDoc_STR("GetFieldCount() -> int\nWraps MsiRecordGetFieldCount")},
+    { "GetInteger", (PyCFunction)record_getinteger, METH_VARARGS,
+    PyDoc_STR("GetInteger(field) -> int\nWraps MsiRecordGetInteger")},
+    { "GetString", (PyCFunction)record_getstring, METH_VARARGS,
+    PyDoc_STR("GetString(field) -> string\nWraps MsiRecordGetString")},
     { "SetString", (PyCFunction)record_setstring, METH_VARARGS, 
 	PyDoc_STR("SetString(field,str) -> None\nWraps MsiRecordSetString")},
     { "SetStream", (PyCFunction)record_setstream, METH_VARARGS, 

From python-3000-checkins at python.org  Tue Jun  3 20:57:12 2008
From: python-3000-checkins at python.org (martin.v.loewis)
Date: Tue,  3 Jun 2008 20:57:12 +0200 (CEST)
Subject: [Python-3000-checkins] r63891 - in python/branches/py3k:
	Doc/using/cmdline.rst Lib/test/test_sys.py Modules/main.c
	Python/pythonrun.c
Message-ID: <20080603185712.2B1241E4014@bag.python.org>

Author: martin.v.loewis
Date: Mon Jun  2 13:13:03 2008
New Revision: 63891

Log:
Forward-port PYTHONIOENCODING.


Modified:
   python/branches/py3k/Doc/using/cmdline.rst
   python/branches/py3k/Lib/test/test_sys.py
   python/branches/py3k/Modules/main.c
   python/branches/py3k/Python/pythonrun.c

Modified: python/branches/py3k/Doc/using/cmdline.rst
==============================================================================
--- python/branches/py3k/Doc/using/cmdline.rst	(original)
+++ python/branches/py3k/Doc/using/cmdline.rst	Mon Jun  2 13:13:03 2008
@@ -467,6 +467,13 @@
    If set, Python will dump objects and reference counts still alive after
    shutting down the interpreter.
 
+.. envvar:: PYTHONIOENCODING
+
+   Overrides the encoding used for stdin/stdout/stderr, in the syntax
+   encodingname:errorhandler, with the :errors part being optional.
+
+   .. versionadded:: 2.6
+
 
 .. envvar:: PYTHONMALLOCSTATS
 

Modified: python/branches/py3k/Lib/test/test_sys.py
==============================================================================
--- python/branches/py3k/Lib/test/test_sys.py	(original)
+++ python/branches/py3k/Lib/test/test_sys.py	Mon Jun  2 13:13:03 2008
@@ -349,6 +349,26 @@
         #self.assert_(r[0][1] > 100, r[0][1])
         #self.assert_(r[0][2] > 100, r[0][2])
 
+    def test_ioencoding(self):
+        import subprocess,os
+        env = dict(os.environ)
+
+        # Test character: cent sign, encoded as 0x4A (ASCII J) in CP424,
+        # not representable in ASCII.
+
+        env["PYTHONIOENCODING"] = "cp424"
+        p = subprocess.Popen([sys.executable, "-c", 'print(chr(0xa2))'],
+                             stdout = subprocess.PIPE, env=env)
+        out = p.stdout.read()
+        self.assertEqual(out, "\xa2\n".encode("cp424"))
+
+        env["PYTHONIOENCODING"] = "ascii:replace"
+        p = subprocess.Popen([sys.executable, "-c", 'print(chr(0xa2))'],
+                             stdout = subprocess.PIPE, env=env)
+        out = p.stdout.read().strip()
+        self.assertEqual(out, b'?')
+
+
 def test_main():
     test.support.run_unittest(SysModuleTest)
 

Modified: python/branches/py3k/Modules/main.c
==============================================================================
--- python/branches/py3k/Modules/main.c	(original)
+++ python/branches/py3k/Modules/main.c	Mon Jun  2 13:13:03 2008
@@ -96,6 +96,7 @@
 PYTHONHOME   : alternate <prefix> directory (or <prefix>%c<exec_prefix>).\n\
                The default module search path uses %s.\n\
 PYTHONCASEOK : ignore case in 'import' statements (Windows).\n\
+PYTHONIOENCODING: Encoding[:errors] used for stdin/stdout/stderr.\n\
 ";
 
 #ifndef MS_WINDOWS

Modified: python/branches/py3k/Python/pythonrun.c
==============================================================================
--- python/branches/py3k/Python/pythonrun.c	(original)
+++ python/branches/py3k/Python/pythonrun.c	Mon Jun  2 13:13:03 2008
@@ -701,6 +701,7 @@
 	PyObject *std = NULL;
 	int status = 0, fd;
 	PyObject * encoding_attr;
+	char *encoding, *errors;
 
 	/* Hack to avoid a nasty recursion issue when Python is invoked
 	   in verbose mode: pre-import the Latin-1 and UTF-8 codecs */
@@ -730,6 +731,16 @@
 		goto error;
 	}
 
+	encoding = Py_GETENV("PYTHONIOENCODING");
+	if (encoding) {
+		encoding = strdup(encoding);
+		errors = strchr(encoding, ':');
+		if (errors) {
+			*errors = '\0';
+			errors++;
+		}
+	}
+
 	/* Set sys.stdin */
 	fd = fileno(stdin);
 	/* Under some conditions stdin, stdout and stderr may not be connected
@@ -745,8 +756,8 @@
 #endif
 	}
 	else {
-		if (!(std = PyFile_FromFd(fd, "<stdin>", "r", -1, NULL, NULL,
-					  "\n", 0))) {
+		if (!(std = PyFile_FromFd(fd, "<stdin>", "r", -1, encoding, 
+					  errors, "\n", 0))) {
 			goto error;
 		}
 	} /* if (fd < 0) */
@@ -765,8 +776,8 @@
 #endif
 	}
 	else {
-		if (!(std = PyFile_FromFd(fd, "<stdout>", "w", -1, NULL, NULL,
-					  "\n", 0))) {
+		if (!(std = PyFile_FromFd(fd, "<stdout>", "w", -1, encoding, 
+					  errors, "\n", 0))) {
 			goto error;
 		}
 	} /* if (fd < 0) */
@@ -786,8 +797,8 @@
 #endif
 	}
 	else {
-		if (!(std = PyFile_FromFd(fd, "<stderr>", "w", -1, NULL, NULL,
-					  "\n", 0))) {
+		if (!(std = PyFile_FromFd(fd, "<stderr>", "w", -1, encoding,
+					  errors, "\n", 0))) {
 			goto error;
 		}
 	} /* if (fd < 0) */

From python-3000-checkins at python.org  Tue Jun  3 20:57:13 2008
From: python-3000-checkins at python.org (martin.v.loewis)
Date: Tue,  3 Jun 2008 20:57:13 +0200 (CEST)
Subject: [Python-3000-checkins] r63892 - python/branches/py3k/PC/_msi.c
Message-ID: <20080603185713.78BED1E4011@bag.python.org>

Author: martin.v.loewis
Date: Mon Jun  2 13:32:23 2008
New Revision: 63892

Log:
Port GetInteger and GetString to 3k.


Modified:
   python/branches/py3k/PC/_msi.c

Modified: python/branches/py3k/PC/_msi.c
==============================================================================
--- python/branches/py3k/PC/_msi.c	(original)
+++ python/branches/py3k/PC/_msi.c	Mon Jun  2 13:32:23 2008
@@ -351,7 +351,7 @@
         PyErr_SetString(MSIError, "could not convert record field to integer");
         return NULL;
     }
-    return PyInt_FromLong((long) status);
+    return PyLong_FromLong((long) status);
 }
 
 static PyObject*
@@ -375,7 +375,7 @@
     }
     if (status != ERROR_SUCCESS)
         return msierror((int) status);
-    string = PyString_FromString(res);
+    string = PyUnicode_FromString(res);
     if (buf != res)
         free(res);
     return string;

From python-3000-checkins at python.org  Tue Jun  3 20:57:14 2008
From: python-3000-checkins at python.org (martin.v.loewis)
Date: Tue,  3 Jun 2008 20:57:14 +0200 (CEST)
Subject: [Python-3000-checkins] r63893 -
	python/branches/py3k/Python/pythonrun.c
Message-ID: <20080603185714.D14581E4004@bag.python.org>

Author: martin.v.loewis
Date: Mon Jun  2 14:33:47 2008
New Revision: 63893

Log:
Fix uninitialized variable access, release memory.


Modified:
   python/branches/py3k/Python/pythonrun.c

Modified: python/branches/py3k/Python/pythonrun.c
==============================================================================
--- python/branches/py3k/Python/pythonrun.c	(original)
+++ python/branches/py3k/Python/pythonrun.c	Mon Jun  2 14:33:47 2008
@@ -732,6 +732,7 @@
 	}
 
 	encoding = Py_GETENV("PYTHONIOENCODING");
+	errors = NULL;
 	if (encoding) {
 		encoding = strdup(encoding);
 		errors = strchr(encoding, ':');
@@ -825,6 +826,8 @@
 		status = -1;
 	}
 
+	if (encoding)
+		free(encoding);
 	Py_XDECREF(bimod);
 	Py_XDECREF(iomod);
 	return status;

From python-3000-checkins at python.org  Tue Jun  3 20:57:23 2008
From: python-3000-checkins at python.org (eric.smith)
Date: Tue,  3 Jun 2008 20:57:23 +0200 (CEST)
Subject: [Python-3000-checkins] r63895 -
	python/branches/py3k/Objects/stringlib/string_format.h
Message-ID: <20080603185723.348581E4004@bag.python.org>

Author: eric.smith
Date: Mon Jun  2 16:57:32 2008
New Revision: 63895

Log:
Refactored known type optimization, in anticipation of backporting to 2.6.  I'll probably move this code into PyObject_Format, so everyone benefits.

Modified:
   python/branches/py3k/Objects/stringlib/string_format.h

Modified: python/branches/py3k/Objects/stringlib/string_format.h
==============================================================================
--- python/branches/py3k/Objects/stringlib/string_format.h	(original)
+++ python/branches/py3k/Objects/stringlib/string_format.h	Mon Jun  2 16:57:32 2008
@@ -484,7 +484,7 @@
     int ok = 0;
     PyObject *result = NULL;
     PyObject *format_spec_object = NULL;
-
+    PyObject *(*formatter)(PyObject *, STRINGLIB_CHAR *, Py_ssize_t) = NULL;
     STRINGLIB_CHAR* format_spec_start = format_spec->ptr ?
 	    format_spec->ptr : NULL;
     Py_ssize_t format_spec_len = format_spec->ptr ?
@@ -493,14 +493,20 @@
     /* If we know the type exactly, skip the lookup of __format__ and just
        call the formatter directly. */
     if (PyUnicode_CheckExact(fieldobj))
-	result = _PyUnicode_FormatAdvanced(fieldobj, format_spec_start,
-					format_spec_len);
+	formatter = _PyUnicode_FormatAdvanced;
     else if (PyLong_CheckExact(fieldobj))
-	result = _PyLong_FormatAdvanced(fieldobj, format_spec_start,
-					format_spec_len);
+	formatter =_PyLong_FormatAdvanced;
     else if (PyFloat_CheckExact(fieldobj))
-	result = _PyFloat_FormatAdvanced(fieldobj, format_spec_start,
-					 format_spec_len);
+	formatter = _PyFloat_FormatAdvanced;
+
+    /* XXX: for 2.6, convert format_spec to the appropriate type
+       (unicode, str) */
+
+    if (formatter) {
+	/* we know exactly which formatter will be called when __format__ is
+	   looked up, so call it directly, instead. */
+	result = formatter(fieldobj, format_spec_start, format_spec_len);
+    }
     else {
 	/* We need to create an object out of the pointers we have, because
 	   __format__ takes a string/unicode object for format_spec. */

From python-3000-checkins at python.org  Tue Jun  3 20:57:25 2008
From: python-3000-checkins at python.org (alexandre.vassalotti)
Date: Tue,  3 Jun 2008 20:57:25 +0200 (CEST)
Subject: [Python-3000-checkins] r63896 -
	python/branches/py3k/Modules/cStringIO.c
Message-ID: <20080603185725.E15501E4004@bag.python.org>

Author: alexandre.vassalotti
Date: Mon Jun  2 18:06:56 2008
New Revision: 63896

Log:
Removed the old cStringIO module.


Removed:
   python/branches/py3k/Modules/cStringIO.c

Deleted: python/branches/py3k/Modules/cStringIO.c
==============================================================================
--- python/branches/py3k/Modules/cStringIO.c	Mon Jun  2 18:06:56 2008
+++ (empty file)
@@ -1,754 +0,0 @@
-
-#include "Python.h"
-#include "import.h"
-#include "cStringIO.h"
-#include "structmember.h"
-
-PyDoc_STRVAR(cStringIO_module_documentation,
-"A simple fast partial StringIO replacement.\n"
-"\n"
-"This module provides a simple useful replacement for\n"
-"the StringIO module that is written in C.  It does not provide the\n"
-"full generality of StringIO, but it provides enough for most\n"
-"applications and is especially useful in conjunction with the\n"
-"pickle module.\n"
-"\n"
-"Usage:\n"
-"\n"
-"  from cStringIO import StringIO\n"
-"\n"
-"  an_output_stream=StringIO()\n"
-"  an_output_stream.write(some_stuff)\n"
-"  ...\n"
-"  value=an_output_stream.getvalue()\n"
-"\n"
-"  an_input_stream=StringIO(a_string)\n"
-"  spam=an_input_stream.readline()\n"
-"  spam=an_input_stream.read(5)\n"
-"  an_input_stream.seek(0)           # OK, start over\n"
-"  spam=an_input_stream.read()       # and read it all\n"
-"  \n"
-"If someone else wants to provide a more complete implementation,\n"
-"go for it. :-)  \n"
-"\n"
-"cStringIO.c,v 1.29 1999/06/15 14:10:27 jim Exp\n");
-
-/* Declaration for file-like objects that manage data as strings 
-
-   The IOobject type should be though of as a common base type for
-   Iobjects, which provide input (read-only) StringIO objects and
-   Oobjects, which provide read-write objects.  Most of the methods
-   depend only on common data.
-*/
-
-typedef struct {
-  PyObject_HEAD
-  char *buf;
-  Py_ssize_t pos, string_size;
-} IOobject;
-
-#define IOOOBJECT(O) ((IOobject*)(O))
-
-/* Declarations for objects of type StringO */
-
-typedef struct { /* Subtype of IOobject */
-  PyObject_HEAD
-  char *buf;
-  Py_ssize_t pos, string_size;
-
-  Py_ssize_t buf_size;
-} Oobject;
-
-/* Declarations for objects of type StringI */
-
-typedef struct { /* Subtype of IOobject */
-  PyObject_HEAD
-  char *buf;
-  Py_ssize_t pos, string_size;
-  /* We store a reference to the object here in order to keep
-     the buffer alive during the lifetime of the Iobject. */
-  PyObject *pbuf;
-} Iobject;
-
-/* IOobject (common) methods */
-
-PyDoc_STRVAR(IO_flush__doc__, "flush(): does nothing.");
-
-static int
-IO__opencheck(IOobject *self) {
-        if (!self->buf) {
-                PyErr_SetString(PyExc_ValueError,
-                                "I/O operation on closed file");
-                return 0;
-        }
-        return 1;
-}
-
-static PyObject *
-IO_get_closed(IOobject *self, void *closure)
-{
-	PyObject *result = Py_False;
-
-	if (self->buf == NULL)
-		result = Py_True;
-	Py_INCREF(result);
-	return result;
-}
-
-static PyGetSetDef file_getsetlist[] = {
-	{"closed", (getter)IO_get_closed, NULL, "True if the file is closed"},
-	{0},
-};
-
-static PyObject *
-IO_flush(IOobject *self, PyObject *unused) {
-
-        if (!IO__opencheck(self)) return NULL;
-
-        Py_INCREF(Py_None);
-        return Py_None;
-}
-
-PyDoc_STRVAR(IO_getval__doc__,
-"getvalue([use_pos]) -- Get the string value."
-"\n"
-"If use_pos is specified and is a true value, then the string returned\n"
-"will include only the text up to the current file position.\n");
-
-static PyObject *
-IO_cgetval(PyObject *self) {
-        if (!IO__opencheck(IOOOBJECT(self))) return NULL;
-        return PyBytes_FromStringAndSize(((IOobject*)self)->buf,
-                                          ((IOobject*)self)->pos);
-}
-
-static PyObject *
-IO_getval(IOobject *self, PyObject *args) {
-        PyObject *use_pos=Py_None;
-        Py_ssize_t s;
-
-        if (!IO__opencheck(self)) return NULL;
-        if (!PyArg_UnpackTuple(args,"getval", 0, 1,&use_pos)) return NULL;
-
-        if (PyObject_IsTrue(use_pos)) {
-                  s=self->pos;
-                  if (s > self->string_size) s=self->string_size;
-        }
-        else
-                  s=self->string_size;
-        return PyBytes_FromStringAndSize(self->buf, s);
-}
-
-PyDoc_STRVAR(IO_isatty__doc__, "isatty(): always returns 0");
-
-static PyObject *
-IO_isatty(IOobject *self, PyObject *unused) {
-        if (!IO__opencheck(self)) return NULL;
-        Py_INCREF(Py_False);
-        return Py_False;
-}
-
-PyDoc_STRVAR(IO_read__doc__,
-"read([s]) -- Read s characters, or the rest of the string");
-
-static int
-IO_cread(PyObject *self, char **output, Py_ssize_t  n) {
-        Py_ssize_t l;
-
-        if (!IO__opencheck(IOOOBJECT(self))) return -1;
-        l = ((IOobject*)self)->string_size - ((IOobject*)self)->pos;  
-        if (n < 0 || n > l) {
-                n = l;
-                if (n < 0) n=0;
-        }
-
-        *output=((IOobject*)self)->buf + ((IOobject*)self)->pos;
-        ((IOobject*)self)->pos += n;
-        return n;
-}
-
-static PyObject *
-IO_read(IOobject *self, PyObject *args) {
-        Py_ssize_t n = -1;
-        char *output = NULL;
-
-        if (!PyArg_ParseTuple(args, "|n:read", &n)) return NULL;
-
-        if ( (n=IO_cread((PyObject*)self,&output,n)) < 0) return NULL;
-
-        return PyBytes_FromStringAndSize(output, n);
-}
-
-PyDoc_STRVAR(IO_readline__doc__, "readline() -- Read one line");
-
-static int
-IO_creadline(PyObject *self, char **output) {
-        char *n, *s;
-        Py_ssize_t l;
-
-        if (!IO__opencheck(IOOOBJECT(self))) return -1;
-
-        for (n = ((IOobject*)self)->buf + ((IOobject*)self)->pos,
-               s = ((IOobject*)self)->buf + ((IOobject*)self)->string_size; 
-             n < s && *n != '\n'; n++);
-        if (n < s) n++;
-
-        *output=((IOobject*)self)->buf + ((IOobject*)self)->pos;
-        l = n - ((IOobject*)self)->buf - ((IOobject*)self)->pos;
-	assert(((IOobject*)self)->pos + l < INT_MAX);
-        ((IOobject*)self)->pos += (int)l;
-        return (int)l;
-}
-
-static PyObject *
-IO_readline(IOobject *self, PyObject *args) {
-        int n, m=-1;
-        char *output;
-
-        if (args)
-                if (!PyArg_ParseTuple(args, "|i:readline", &m)) return NULL;
-
-        if( (n=IO_creadline((PyObject*)self,&output)) < 0) return NULL;
-        if (m >= 0 && m < n) {
-                m = n - m;
-                n -= m;
-                self->pos -= m;
-        }
-        return PyBytes_FromStringAndSize(output, n);
-}
-
-PyDoc_STRVAR(IO_readlines__doc__, "readlines() -- Read all lines");
-
-static PyObject *
-IO_readlines(IOobject *self, PyObject *args) {
-	int n;
-	char *output;
-	PyObject *result, *line;
-        int hint = 0, length = 0;
-	
-        if (!PyArg_ParseTuple(args, "|i:readlines", &hint)) return NULL;
-
-	result = PyList_New(0);
-	if (!result)
-		return NULL;
-
-	while (1){
-		if ( (n = IO_creadline((PyObject*)self,&output)) < 0)
-                        goto err;
-		if (n == 0)
-			break;
-		line = PyBytes_FromStringAndSize (output, n);
-		if (!line) 
-                        goto err;
-		if (PyList_Append (result, line) == -1) {
-			Py_DECREF (line);
-			goto err;
-		}
-		Py_DECREF (line);
-                length += n;
-                if (hint > 0 && length >= hint)
-			break;
-	}
-	return result;
- err:
-        Py_DECREF(result);
-        return NULL;
-}
-
-PyDoc_STRVAR(IO_reset__doc__,
-"reset() -- Reset the file position to the beginning");
-
-static PyObject *
-IO_reset(IOobject *self, PyObject *unused) {
-
-        if (!IO__opencheck(self)) return NULL;
-
-        self->pos = 0;
-
-        Py_INCREF(Py_None);
-        return Py_None;
-}
-
-PyDoc_STRVAR(IO_tell__doc__, "tell() -- get the current position.");
-
-static PyObject *
-IO_tell(IOobject *self, PyObject *unused) {
-
-        if (!IO__opencheck(self)) return NULL;
-
-        return PyLong_FromSsize_t(self->pos);
-}
-
-PyDoc_STRVAR(IO_truncate__doc__,
-"truncate(): truncate the file at the current position.");
-
-static PyObject *
-IO_truncate(IOobject *self, PyObject *args) {
-        Py_ssize_t pos = -1;
-	
-        if (!IO__opencheck(self)) return NULL;
-        if (!PyArg_ParseTuple(args, "|n:truncate", &pos)) return NULL;
-
-	if (PyTuple_Size(args) == 0) {
-		/* No argument passed, truncate to current position */
-		pos = self->pos;
-	}
-
-        if (pos < 0) {
-		errno = EINVAL;
-		PyErr_SetFromErrno(PyExc_IOError);
-		return NULL;
-	}
-
-        if (self->string_size > pos) self->string_size = pos;
-        self->pos = self->string_size;
-
-        Py_INCREF(Py_None);
-        return Py_None;
-}
-
-static PyObject *
-IO_iternext(Iobject *self)
-{
-	PyObject *next;
-	next = IO_readline((IOobject *)self, NULL);
-	if (!next)
-		return NULL;
-	if (!PyBytes_GET_SIZE(next)) {
-		Py_DECREF(next);
-		PyErr_SetNone(PyExc_StopIteration);
-		return NULL;
-	}
-	return next;
-}
-
-
-
-
-/* Read-write object methods */
-
-PyDoc_STRVAR(O_seek__doc__,
-"seek(position)       -- set the current position\n"
-"seek(position, mode) -- mode 0: absolute; 1: relative; 2: relative to EOF");
-
-static PyObject *
-O_seek(Oobject *self, PyObject *args) {
-	Py_ssize_t position;
-	int mode = 0;
-
-        if (!IO__opencheck(IOOOBJECT(self))) return NULL;
-        if (!PyArg_ParseTuple(args, "n|i:seek", &position, &mode)) 
-                return NULL;
-
-        if (mode == 2) {
-                position += self->string_size;
-        }
-        else if (mode == 1) {
-                position += self->pos;
-        }
-
-        if (position > self->buf_size) {
-                  char *newbuf;
-                  self->buf_size*=2;
-                  if (self->buf_size <= position) self->buf_size=position+1;
-		  newbuf = (char*) realloc(self->buf,self->buf_size);
-                  if (!newbuf) {
-                      free(self->buf);
-                      self->buf = 0;
-                      self->buf_size=self->pos=0;
-                      return PyErr_NoMemory();
-                    }
-                  self->buf = newbuf;
-          }
-        else if (position < 0) position=0;
-
-        self->pos=position;
-
-        while (--position >= self->string_size) self->buf[position]=0;
-
-        Py_INCREF(Py_None);
-        return Py_None;
-}
-
-PyDoc_STRVAR(O_write__doc__,
-"write(s) -- Write a string to the file"
-"\n\nNote (hack:) writing None resets the buffer");
-
-
-static int
-O_cwrite(PyObject *self, const char *c, Py_ssize_t  l) {
-        Py_ssize_t newl;
-        Oobject *oself;
-        char *newbuf;
-
-        if (!IO__opencheck(IOOOBJECT(self))) return -1;
-        oself = (Oobject *)self;
-
-        newl = oself->pos+l;
-        if (newl >= oself->buf_size) {
-            oself->buf_size *= 2;
-            if (oself->buf_size <= newl) {
-		    assert(newl + 1 < INT_MAX);
-                    oself->buf_size = (int)(newl+1);
-	    }
-            newbuf = (char*)realloc(oself->buf, oself->buf_size);
-	    if (!newbuf) {
-                    PyErr_SetString(PyExc_MemoryError,"out of memory");
-                    free(oself->buf);
-                    oself->buf = 0;
-                    oself->buf_size = oself->pos = 0;
-                    return -1;
-              }
-            oself->buf = newbuf;
-          }
-
-        memcpy(oself->buf+oself->pos,c,l);
-
-	assert(oself->pos + l < INT_MAX);
-        oself->pos += (int)l;
-
-        if (oself->string_size < oself->pos) {
-            oself->string_size = oself->pos;
-        }
-
-        return (int)l;
-}
-
-static PyObject *
-O_write(Oobject *self, PyObject *args) {
-        char *c;
-        int l;
-
-        if (!PyArg_ParseTuple(args, "t#:write", &c, &l)) return NULL;
-
-        if (O_cwrite((PyObject*)self,c,l) < 0) return NULL;
-
-        Py_INCREF(Py_None);
-        return Py_None;
-}
-
-PyDoc_STRVAR(O_close__doc__, "close(): explicitly release resources held.");
-
-static PyObject *
-O_close(Oobject *self, PyObject *unused) {
-        if (self->buf != NULL) free(self->buf);
-        self->buf = NULL;
-
-        self->pos = self->string_size = self->buf_size = 0;
-
-        Py_INCREF(Py_None);
-        return Py_None;
-}
-
-PyDoc_STRVAR(O_writelines__doc__,
-"writelines(sequence_of_strings) -> None.  Write the strings to the file.\n"
-"\n"
-"Note that newlines are not added.  The sequence can be any iterable object\n"
-"producing strings. This is equivalent to calling write() for each string.");
-static PyObject *
-O_writelines(Oobject *self, PyObject *args) {
-	PyObject *it, *s;
-	
-	it = PyObject_GetIter(args);
-	if (it == NULL)
-		return NULL;
-	while ((s = PyIter_Next(it)) != NULL) {
-		Py_ssize_t n;
-		char *c;
-		if (PyBytes_AsStringAndSize(s, &c, &n) == -1) {
-			Py_DECREF(it);
-			Py_DECREF(s);
-			return NULL;
-		}
-		if (O_cwrite((PyObject *)self, c, n) == -1) {
-			Py_DECREF(it);
-			Py_DECREF(s);
-			return NULL;
-               }
-               Py_DECREF(s);
-       }
-
-       Py_DECREF(it);
-
-       /* See if PyIter_Next failed */
-       if (PyErr_Occurred())
-               return NULL;
-
-       Py_RETURN_NONE;
-}
-static struct PyMethodDef O_methods[] = {
-  /* Common methods: */
-  {"flush",     (PyCFunction)IO_flush,    METH_NOARGS,  IO_flush__doc__},
-  {"getvalue",  (PyCFunction)IO_getval,   METH_VARARGS, IO_getval__doc__},
-  {"isatty",    (PyCFunction)IO_isatty,   METH_NOARGS,  IO_isatty__doc__},
-  {"read",	(PyCFunction)IO_read,     METH_VARARGS, IO_read__doc__},
-  {"readline",	(PyCFunction)IO_readline, METH_VARARGS, IO_readline__doc__},
-  {"readlines",	(PyCFunction)IO_readlines,METH_VARARGS, IO_readlines__doc__},
-  {"reset",	(PyCFunction)IO_reset,	  METH_NOARGS,  IO_reset__doc__},
-  {"tell",      (PyCFunction)IO_tell,     METH_NOARGS,  IO_tell__doc__},
-  {"truncate",  (PyCFunction)IO_truncate, METH_VARARGS, IO_truncate__doc__},
-
-  /* Read-write StringIO specific  methods: */
-  {"close",      (PyCFunction)O_close,      METH_NOARGS,  O_close__doc__},
-  {"seek",       (PyCFunction)O_seek,       METH_VARARGS, O_seek__doc__},
-  {"write",	 (PyCFunction)O_write,      METH_VARARGS, O_write__doc__},
-  {"writelines", (PyCFunction)O_writelines, METH_O,	  O_writelines__doc__},
-  {NULL,	 NULL}		/* sentinel */
-};
-
-static void
-O_dealloc(Oobject *self) {
-        if (self->buf != NULL)
-                free(self->buf);
-        PyObject_Del(self);
-}
-
-PyDoc_STRVAR(Otype__doc__, "Simple type for output to strings.");
-
-static PyTypeObject Otype = {
-  PyVarObject_HEAD_INIT(NULL, 0)
-  "cStringIO.StringO",   	/*tp_name*/
-  sizeof(Oobject),       	/*tp_basicsize*/
-  0,	       			/*tp_itemsize*/
-  /* methods */
-  (destructor)O_dealloc,	/*tp_dealloc*/
-  0,				/*tp_print*/
-  0,		 		/*tp_getattr */
-  0,		 		/*tp_setattr */
-  0,				/*tp_compare*/
-  0,				/*tp_repr*/
-  0,				/*tp_as_number*/
-  0,				/*tp_as_sequence*/
-  0,				/*tp_as_mapping*/
-  0,				/*tp_hash*/
-  0	,			/*tp_call*/
-  0,				/*tp_str*/
-  0,				/*tp_getattro */
-  0,				/*tp_setattro */
-  0,				/*tp_as_buffer */
-  Py_TPFLAGS_DEFAULT,		/*tp_flags*/
-  Otype__doc__, 		/*tp_doc */
-  0,				/*tp_traverse */
-  0,				/*tp_clear */
-  0,				/*tp_richcompare */
-  0,				/*tp_weaklistoffset */
-  PyObject_SelfIter,		/*tp_iter */
-  (iternextfunc)IO_iternext,	/*tp_iternext */
-  O_methods,			/*tp_methods */
-  0,				/*tp_members */
-  file_getsetlist,		/*tp_getset */
-};
-
-static PyObject *
-newOobject(int  size) {
-        Oobject *self;
-
-        self = PyObject_New(Oobject, &Otype);
-        if (self == NULL)
-                return NULL;
-        self->pos=0;
-        self->string_size = 0;
-
-        self->buf = (char *)malloc(size);
-	if (!self->buf) {
-                  PyErr_SetString(PyExc_MemoryError,"out of memory");
-                  self->buf_size = 0;
-                  Py_DECREF(self);
-                  return NULL;
-          }
-
-        self->buf_size=size;
-        return (PyObject*)self;
-}
-
-/* End of code for StringO objects */
-/* -------------------------------------------------------- */
-
-static PyObject *
-I_close(Iobject *self, PyObject *unused) {
-        Py_CLEAR(self->pbuf);
-        self->buf = NULL;
-
-        self->pos = self->string_size = 0;
-
-        Py_INCREF(Py_None);
-        return Py_None;
-}
-
-static PyObject *
-I_seek(Iobject *self, PyObject *args) {
-        Py_ssize_t position;
-	int mode = 0;
-
-        if (!IO__opencheck(IOOOBJECT(self))) return NULL;
-        if (!PyArg_ParseTuple(args, "n|i:seek", &position, &mode)) 
-                return NULL;
-
-        if (mode == 2) position += self->string_size;
-        else if (mode == 1) position += self->pos;
-
-        if (position < 0) position=0;
-
-        self->pos=position;
-
-        Py_INCREF(Py_None);
-        return Py_None;
-}
-
-static struct PyMethodDef I_methods[] = {
-  /* Common methods: */
-  {"flush",     (PyCFunction)IO_flush,    METH_NOARGS,  IO_flush__doc__},
-  {"getvalue",  (PyCFunction)IO_getval,   METH_VARARGS, IO_getval__doc__},
-  {"isatty",    (PyCFunction)IO_isatty,   METH_NOARGS,  IO_isatty__doc__},
-  {"read",	(PyCFunction)IO_read,     METH_VARARGS, IO_read__doc__},
-  {"readline",	(PyCFunction)IO_readline, METH_VARARGS, IO_readline__doc__},
-  {"readlines",	(PyCFunction)IO_readlines,METH_VARARGS, IO_readlines__doc__},
-  {"reset",	(PyCFunction)IO_reset,	  METH_NOARGS,  IO_reset__doc__},
-  {"tell",      (PyCFunction)IO_tell,     METH_NOARGS,  IO_tell__doc__},
-  {"truncate",  (PyCFunction)IO_truncate, METH_VARARGS, IO_truncate__doc__},
-
-  /* Read-only StringIO specific  methods: */
-  {"close",     (PyCFunction)I_close,    METH_NOARGS,  O_close__doc__},
-  {"seek",      (PyCFunction)I_seek,     METH_VARARGS, O_seek__doc__},  
-  {NULL,	NULL}
-};
-
-static void
-I_dealloc(Iobject *self) {
-  Py_XDECREF(self->pbuf);
-  PyObject_Del(self);
-}
-
-
-PyDoc_STRVAR(Itype__doc__,
-"Simple type for treating strings as input file streams");
-
-static PyTypeObject Itype = {
-  PyVarObject_HEAD_INIT(NULL, 0)
-  "cStringIO.StringI",			/*tp_name*/
-  sizeof(Iobject),			/*tp_basicsize*/
-  0,					/*tp_itemsize*/
-  /* methods */
-  (destructor)I_dealloc,		/*tp_dealloc*/
-  0,					/*tp_print*/
-  0,		 			/* tp_getattr */
-  0,					/*tp_setattr*/
-  0,					/*tp_compare*/
-  0,					/*tp_repr*/
-  0,					/*tp_as_number*/
-  0,					/*tp_as_sequence*/
-  0,					/*tp_as_mapping*/
-  0,					/*tp_hash*/
-  0,					/*tp_call*/
-  0,					/*tp_str*/
-  0,					/* tp_getattro */
-  0,					/* tp_setattro */
-  0,					/* tp_as_buffer */
-  Py_TPFLAGS_DEFAULT,			/* tp_flags */
-  Itype__doc__,				/* tp_doc */
-  0,					/* tp_traverse */
-  0,					/* tp_clear */
-  0,					/* tp_richcompare */
-  0,					/* tp_weaklistoffset */
-  PyObject_SelfIter,			/* tp_iter */
-  (iternextfunc)IO_iternext,		/* tp_iternext */
-  I_methods,				/* tp_methods */
-  0,					/* tp_members */
-  file_getsetlist,			/* tp_getset */
-};
-
-static PyObject *
-newIobject(PyObject *s) {
-  Iobject *self;
-  char *buf;
-  Py_ssize_t size;
-
-  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;
-  Py_INCREF(s);
-  self->buf=buf;
-  self->string_size=size;
-  self->pbuf=s;
-  self->pos=0;
-  
-  return (PyObject*)self;
-}
-
-/* End of code for StringI objects */
-/* -------------------------------------------------------- */
-
-
-PyDoc_STRVAR(IO_StringIO__doc__,
-"StringIO([s]) -- Return a StringIO-like stream for reading or writing");
-
-static PyObject *
-IO_StringIO(PyObject *self, PyObject *args) {
-  PyObject *s=0;
-
-  if (!PyArg_UnpackTuple(args, "StringIO", 0, 1, &s)) return NULL;
-
-  if (s) return newIobject(s);
-  return newOobject(128);
-}
-
-/* List of methods defined in the module */
-
-static struct PyMethodDef IO_methods[] = {
-  {"StringIO",	(PyCFunction)IO_StringIO,	
-   METH_VARARGS,	IO_StringIO__doc__},
-  {NULL,		NULL}		/* sentinel */
-};
-
-
-/* Initialization function for the module (*must* be called initcStringIO) */
-
-static struct PycStringIO_CAPI CAPI = {
-  IO_cread,
-  IO_creadline,
-  O_cwrite,
-  IO_cgetval,
-  newOobject,
-  newIobject,
-  &Itype,
-  &Otype,
-};
-
-#ifndef PyMODINIT_FUNC	/* declarations for DLL import/export */
-#define PyMODINIT_FUNC void
-#endif
-PyMODINIT_FUNC
-initcStringIO(void) {
-  PyObject *m, *d, *v;
-
-
-  /* Create the module and add the functions */
-  m = Py_InitModule4("cStringIO", IO_methods,
-		     cStringIO_module_documentation,
-		     (PyObject*)NULL,PYTHON_API_VERSION);
-  if (m == NULL) return;
-
-  /* Add some symbolic constants to the module */
-  d = PyModule_GetDict(m);
-  
-  /* Export C API */
-  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",
-		       v = PyCObject_FromVoidPtr(&CAPI,NULL));
-  Py_XDECREF(v);
-
-  /* Export Types */
-  PyDict_SetItemString(d,"InputType",  (PyObject*)&Itype);
-  PyDict_SetItemString(d,"OutputType", (PyObject*)&Otype);
-
-  /* Maybe make certain warnings go away */
-  if (0) PycString_IMPORT;
-}

From python-3000-checkins at python.org  Wed Jun  4 13:30:27 2008
From: python-3000-checkins at python.org (georg.brandl)
Date: Wed,  4 Jun 2008 13:30:27 +0200 (CEST)
Subject: [Python-3000-checkins] r63933 - in python/branches/py3k:
	Doc/c-api/conversion.rst Objects/bytearrayobject.c
	Objects/bytesobject.c
Message-ID: <20080604113027.433D61E401F@bag.python.org>

Author: georg.brandl
Date: Wed Jun  4 13:30:26 2008
New Revision: 63933

Log:
Fix misspelling.


Modified:
   python/branches/py3k/Doc/c-api/conversion.rst
   python/branches/py3k/Objects/bytearrayobject.c
   python/branches/py3k/Objects/bytesobject.c

Modified: python/branches/py3k/Doc/c-api/conversion.rst
==============================================================================
--- python/branches/py3k/Doc/c-api/conversion.rst	(original)
+++ python/branches/py3k/Doc/c-api/conversion.rst	Wed Jun  4 13:30:26 2008
@@ -83,11 +83,11 @@
    
 .. cfunction:: char * PyOS_stricmp(char *s1, char *s2)
 
-   Case insensitive comparsion of strings. The functions works almost
+   Case insensitive comparison of strings. The functions works almost
    identical to :cfunc:`strcmp` except that it ignores the case.
 
 
 .. cfunction:: char * PyOS_strnicmp(char *s1, char *s2, Py_ssize_t  size)
 
-   Case insensitive comparsion of strings. The functions works almost
+   Case insensitive comparison of strings. The functions works almost
    identical to :cfunc:`strncmp` except that it ignores the case.

Modified: python/branches/py3k/Objects/bytearrayobject.c
==============================================================================
--- python/branches/py3k/Objects/bytearrayobject.c	(original)
+++ python/branches/py3k/Objects/bytearrayobject.c	Wed Jun  4 13:30:26 2008
@@ -947,7 +947,7 @@
         PyObject_IsInstance(other, (PyObject*)&PyUnicode_Type)) {
         if (Py_BytesWarningFlag && op == Py_EQ) {
             if (PyErr_WarnEx(PyExc_BytesWarning,
-                            "Comparsion between bytearray and string", 1))
+                            "Comparison between bytearray and string", 1))
                 return NULL;
         }
 

Modified: python/branches/py3k/Objects/bytesobject.c
==============================================================================
--- python/branches/py3k/Objects/bytesobject.c	(original)
+++ python/branches/py3k/Objects/bytesobject.c	Wed Jun  4 13:30:26 2008
@@ -818,7 +818,7 @@
 		    PyObject_IsInstance((PyObject*)b,
 					 (PyObject*)&PyUnicode_Type))) {
 			if (PyErr_WarnEx(PyExc_BytesWarning,
-				    "Comparsion between bytes and string", 1))
+				    "Comparison between bytes and string", 1))
 				return NULL;
 		}
 		result = Py_NotImplemented;

From python-3000-checkins at python.org  Wed Jun  4 13:41:34 2008
From: python-3000-checkins at python.org (georg.brandl)
Date: Wed,  4 Jun 2008 13:41:34 +0200 (CEST)
Subject: [Python-3000-checkins] r63934 - in python/branches/py3k:
	Doc/c-api/unicode.rst Doc/library/functions.rst
	Doc/library/stdtypes.rst Doc/library/sys.rst
	Doc/using/cmdline.rst Include/pydebug.h
	Include/unicodeobject.h Lib/doctest.py Lib/test/test_array.py
	Lib/test/test_builtin.py Lib/test/test_exceptions.py
	Lib/test/test_format.py Lib/test/test_pyexpat.py
	Lib/test/test_unicode.py
	Mac/BuildScript/scripts/postflight.framework Mac/Makefile.in
	Makefile.pre.in Misc/NEWS Misc/build.sh Misc/cheatsheet
	Misc/python.man Misc/valgrind-python.supp Modules/main.c
	Objects/unicodectype.c Objects/unicodeobject.c
	Objects/unicodetype_db.h PC/VC6/rt.bat PC/VS7.1/rt.bat
	PC/VS8.0/rt.bat PC/os2emx/Makefile PC/os2emx/python26.def
	PC/os2vacpp/python.def PCbuild/rt.bat Parser/parsetok.c
	Python/bltinmodule.c Python/sysmodule.c
	Tools/unicode/makeunicodedata.py
Message-ID: <20080604114134.CEDD71E4007@bag.python.org>

Author: georg.brandl
Date: Wed Jun  4 13:41:32 2008
New Revision: 63934

Log:
Remove meaning of -ttt, but still accept -t option on cmdline for compatibility.


Modified:
   python/branches/py3k/Doc/c-api/unicode.rst
   python/branches/py3k/Doc/library/functions.rst
   python/branches/py3k/Doc/library/stdtypes.rst
   python/branches/py3k/Doc/library/sys.rst
   python/branches/py3k/Doc/using/cmdline.rst
   python/branches/py3k/Include/pydebug.h
   python/branches/py3k/Include/unicodeobject.h
   python/branches/py3k/Lib/doctest.py
   python/branches/py3k/Lib/test/test_array.py
   python/branches/py3k/Lib/test/test_builtin.py
   python/branches/py3k/Lib/test/test_exceptions.py
   python/branches/py3k/Lib/test/test_format.py
   python/branches/py3k/Lib/test/test_pyexpat.py
   python/branches/py3k/Lib/test/test_unicode.py
   python/branches/py3k/Mac/BuildScript/scripts/postflight.framework
   python/branches/py3k/Mac/Makefile.in
   python/branches/py3k/Makefile.pre.in
   python/branches/py3k/Misc/NEWS
   python/branches/py3k/Misc/build.sh
   python/branches/py3k/Misc/cheatsheet
   python/branches/py3k/Misc/python.man
   python/branches/py3k/Misc/valgrind-python.supp
   python/branches/py3k/Modules/main.c
   python/branches/py3k/Objects/unicodectype.c
   python/branches/py3k/Objects/unicodeobject.c
   python/branches/py3k/Objects/unicodetype_db.h
   python/branches/py3k/PC/VC6/rt.bat
   python/branches/py3k/PC/VS7.1/rt.bat
   python/branches/py3k/PC/VS8.0/rt.bat
   python/branches/py3k/PC/os2emx/Makefile
   python/branches/py3k/PC/os2emx/python26.def
   python/branches/py3k/PC/os2vacpp/python.def
   python/branches/py3k/PCbuild/rt.bat
   python/branches/py3k/Parser/parsetok.c
   python/branches/py3k/Python/bltinmodule.c
   python/branches/py3k/Python/sysmodule.c
   python/branches/py3k/Tools/unicode/makeunicodedata.py

Modified: python/branches/py3k/Doc/c-api/unicode.rst
==============================================================================
--- python/branches/py3k/Doc/c-api/unicode.rst	(original)
+++ python/branches/py3k/Doc/c-api/unicode.rst	Wed Jun  4 13:41:32 2008
@@ -144,6 +144,13 @@
 
    Return 1 or 0 depending on whether *ch* is an alphanumeric character.
 
+.. cfunction:: int Py_UNICODE_ISPRINTABLE(Py_UNICODE ch)
+
+   Return 1 or 0 depending on whether *ch* is a printable character.
+   Characters defined in the Unicode character database as "Other"
+   or "Separator" other than ASCII space(0x20) are not considered
+   printable.
+
 These APIs can be used for fast direct character conversions:
 
 
@@ -228,6 +235,9 @@
    +===================+=====================+================================+
    | :attr:`%%`        | *n/a*               | The literal % character.       |
    +-------------------+---------------------+--------------------------------+
+   | :attr:`%a`        | PyObject\*          | The result of calling          |
+   |                   |                     | :func:`ascii`.                 |
+   +-------------------+---------------------+--------------------------------+
    | :attr:`%c`        | int                 | A single character,            |
    |                   |                     | represented as an C int.       |
    +-------------------+---------------------+--------------------------------+

Modified: python/branches/py3k/Doc/library/functions.rst
==============================================================================
--- python/branches/py3k/Doc/library/functions.rst	(original)
+++ python/branches/py3k/Doc/library/functions.rst	Wed Jun  4 13:41:32 2008
@@ -91,6 +91,14 @@
           return False
 
 
+.. function:: ascii(object)
+
+   As :func:`repr`, return a string containing a printable
+   representation of an object. But unlike :func:`repr`, the non-ASCII
+   characters in the string returned by :func:`ascii`() are hex-escaped
+   to generate a same string as :func:`repr` in Python 2.
+
+
 .. function:: bin(x)
 
    Convert an integer number to a binary string. The result is a valid Python

Modified: python/branches/py3k/Doc/library/stdtypes.rst
==============================================================================
--- python/branches/py3k/Doc/library/stdtypes.rst	(original)
+++ python/branches/py3k/Doc/library/stdtypes.rst	Wed Jun  4 13:41:32 2008
@@ -774,6 +774,14 @@
    least one cased character, false otherwise.
 
 
+.. method:: str.isprintable()
+
+   Return true if all characters in the string are printable and there is at
+   least one character, false otherwise. Characters defined in the Unicode 
+   character database as "Other" or "Separator" other than ASCII space(0x20) are 
+   not considered printable.
+
+
 .. method:: str.isspace()
 
    Return true if there are only whitespace characters in the string and there is

Modified: python/branches/py3k/Doc/library/sys.rst
==============================================================================
--- python/branches/py3k/Doc/library/sys.rst	(original)
+++ python/branches/py3k/Doc/library/sys.rst	Wed Jun  4 13:41:32 2008
@@ -231,8 +231,6 @@
    +------------------------------+------------------------------------------+
    | :const:`ignore_environment`  | -E                                       |
    +------------------------------+------------------------------------------+
-   | :const:`tabcheck`            | -t or -tt                                |
-   +------------------------------+------------------------------------------+
    | :const:`verbose`             | -v                                       |
    +------------------------------+------------------------------------------+
    | :const:`unicode`             | -U                                       |

Modified: python/branches/py3k/Doc/using/cmdline.rst
==============================================================================
--- python/branches/py3k/Doc/using/cmdline.rst	(original)
+++ python/branches/py3k/Doc/using/cmdline.rst	Wed Jun  4 13:41:32 2008
@@ -222,13 +222,6 @@
    manipulations of :data:`sys.path` that it entails.
 
 
-.. cmdoption:: -t
-
-   Issue a warning when a source file mixes tabs and spaces for indentation in a
-   way that makes it depend on the worth of a tab expressed in spaces.  Issue an
-   error when the option is given twice (:option:`-tt`).
-
-
 .. cmdoption:: -u
    
    Force stdin, stdout and stderr to be totally unbuffered.  On systems where it

Modified: python/branches/py3k/Include/pydebug.h
==============================================================================
--- python/branches/py3k/Include/pydebug.h	(original)
+++ python/branches/py3k/Include/pydebug.h	Wed Jun  4 13:41:32 2008
@@ -14,7 +14,6 @@
 PyAPI_DATA(int) Py_BytesWarningFlag;
 PyAPI_DATA(int) Py_UseClassExceptionsFlag;
 PyAPI_DATA(int) Py_FrozenFlag;
-PyAPI_DATA(int) Py_TabcheckFlag;
 PyAPI_DATA(int) Py_IgnoreEnvironmentFlag;
 PyAPI_DATA(int) Py_DivisionWarningFlag;
 PyAPI_DATA(int) Py_DontWriteBytecodeFlag;

Modified: python/branches/py3k/Include/unicodeobject.h
==============================================================================
--- python/branches/py3k/Include/unicodeobject.h	(original)
+++ python/branches/py3k/Include/unicodeobject.h	Wed Jun  4 13:41:32 2008
@@ -217,6 +217,7 @@
 # define _PyUnicode_IsLinebreak _PyUnicodeUCS2_IsLinebreak
 # define _PyUnicode_IsLowercase _PyUnicodeUCS2_IsLowercase
 # define _PyUnicode_IsNumeric _PyUnicodeUCS2_IsNumeric
+# define _PyUnicode_IsPrintable _PyUnicodeUCS2_IsPrintable
 # define _PyUnicode_IsTitlecase _PyUnicodeUCS2_IsTitlecase
 # define _PyUnicode_IsXidStart _PyUnicodeUCS2_IsXidStart
 # define _PyUnicode_IsXidContinue _PyUnicodeUCS2_IsXidContinue
@@ -311,6 +312,7 @@
 # define _PyUnicode_IsLinebreak _PyUnicodeUCS4_IsLinebreak
 # define _PyUnicode_IsLowercase _PyUnicodeUCS4_IsLowercase
 # define _PyUnicode_IsNumeric _PyUnicodeUCS4_IsNumeric
+# define _PyUnicode_IsPrintable _PyUnicodeUCS4_IsPrintable
 # define _PyUnicode_IsTitlecase _PyUnicodeUCS4_IsTitlecase
 # define _PyUnicode_IsXidStart _PyUnicodeUCS4_IsXidStart
 # define _PyUnicode_IsXidContinue _PyUnicodeUCS4_IsXidContinue
@@ -351,6 +353,7 @@
 #define Py_UNICODE_ISDECIMAL(ch) _PyUnicode_IsDecimalDigit(ch)
 #define Py_UNICODE_ISDIGIT(ch) _PyUnicode_IsDigit(ch)
 #define Py_UNICODE_ISNUMERIC(ch) _PyUnicode_IsNumeric(ch)
+#define Py_UNICODE_ISPRINTABLE(ch) _PyUnicode_IsPrintable(ch)
 
 #define Py_UNICODE_TODECIMAL(ch) _PyUnicode_ToDecimalDigit(ch)
 #define Py_UNICODE_TODIGIT(ch) _PyUnicode_ToDigit(ch)
@@ -381,6 +384,7 @@
 #define Py_UNICODE_ISDECIMAL(ch) _PyUnicode_IsDecimalDigit(ch)
 #define Py_UNICODE_ISDIGIT(ch) _PyUnicode_IsDigit(ch)
 #define Py_UNICODE_ISNUMERIC(ch) _PyUnicode_IsNumeric(ch)
+#define Py_UNICODE_ISPRINTABLE(ch) _PyUnicode_IsPrintable(ch)
 
 #define Py_UNICODE_TODECIMAL(ch) _PyUnicode_ToDecimalDigit(ch)
 #define Py_UNICODE_TODIGIT(ch) _PyUnicode_ToDigit(ch)
@@ -1499,6 +1503,10 @@
     Py_UNICODE ch 	/* Unicode character */
     );
 
+PyAPI_FUNC(int) _PyUnicode_IsPrintable(
+    Py_UNICODE ch 	/* Unicode character */
+    );
+
 PyAPI_FUNC(int) _PyUnicode_IsAlpha(
     Py_UNICODE ch 	/* Unicode character */
     );

Modified: python/branches/py3k/Lib/doctest.py
==============================================================================
--- python/branches/py3k/Lib/doctest.py	(original)
+++ python/branches/py3k/Lib/doctest.py	Wed Jun  4 13:41:32 2008
@@ -1441,6 +1441,13 @@
     and returns true if they match; and `output_difference`, which
     returns a string describing the differences between two outputs.
     """
+
+    def _toAscii(self, s):
+        """
+        Convert string to hex-escaped ASCII string.
+        """
+        return str(s.encode('ASCII', 'backslashreplace'), "ASCII")
+
     def check_output(self, want, got, optionflags):
         """
         Return True iff the actual output from an example (`got`)
@@ -1451,6 +1458,15 @@
         documentation for `TestRunner` for more information about
         option flags.
         """
+
+        # If `want` contains hex-escaped character such as "\u1234",
+        # then `want` is a string of six characters(e.g. [\,u,1,2,3,4]).
+        # On the other hand, `got` could be an another sequence of
+        # characters such as [\u1234], so `want` and `got` should
+        # be folded to hex-escaped ASCII string to compare.
+        got = self._toAscii(got)
+        want = self._toAscii(want)
+
         # Handle the common case first, for efficiency:
         # if they're string-identical, always return true.
         if got == want:

Modified: python/branches/py3k/Lib/test/test_array.py
==============================================================================
--- python/branches/py3k/Lib/test/test_array.py	(original)
+++ python/branches/py3k/Lib/test/test_array.py	Wed Jun  4 13:41:32 2008
@@ -768,7 +768,7 @@
         a = array.array('u', s)
         self.assertEqual(
             repr(a),
-            "array('u', '\\x00=\"\\'a\\\\b\\x80\\xff\\x00\\x01\\u1234')")
+            "array('u', '\\x00=\"\\'a\\\\b\\x80\xff\\x00\\x01\u1234')")
 
         self.assertRaises(TypeError, a.fromunicode)
 

Modified: python/branches/py3k/Lib/test/test_builtin.py
==============================================================================
--- python/branches/py3k/Lib/test/test_builtin.py	(original)
+++ python/branches/py3k/Lib/test/test_builtin.py	Wed Jun  4 13:41:32 2008
@@ -159,6 +159,9 @@
         S = [10, 20, 30]
         self.assertEqual(any(x > 42 for x in S), False)
 
+    def test_ascii(self):
+        self.assertEqual(ascii("\u0370"), "'\\u0370'")
+
     def test_neg(self):
         x = -sys.maxsize-1
         self.assert_(isinstance(x, int))

Modified: python/branches/py3k/Lib/test/test_exceptions.py
==============================================================================
--- python/branches/py3k/Lib/test/test_exceptions.py	(original)
+++ python/branches/py3k/Lib/test/test_exceptions.py	Wed Jun  4 13:41:32 2008
@@ -80,10 +80,10 @@
         self.raise_catch(IndentationError, "IndentationError")
 
         self.raise_catch(TabError, "TabError")
-        # can only be tested under -tt, and is the only test for -tt
-        #try: compile("try:\n\t1/0\n    \t1/0\nfinally:\n pass\n", '<string>', 'exec')
-        #except TabError: pass
-        #else: self.fail("TabError not raised")
+        try: compile("try:\n\t1/0\n    \t1/0\nfinally:\n pass\n",
+                     '<string>', 'exec')
+        except TabError: pass
+        else: self.fail("TabError not raised")
 
         self.raise_catch(SystemError, "SystemError")
 

Modified: python/branches/py3k/Lib/test/test_format.py
==============================================================================
--- python/branches/py3k/Lib/test/test_format.py	(original)
+++ python/branches/py3k/Lib/test/test_format.py	Wed Jun  4 13:41:32 2008
@@ -216,6 +216,8 @@
         testformat("%o", 0o42, "42")
         testformat("%o", -0o42, "-42")
         testformat("%o", float(0o42), "42")
+        testformat("%r", "\u0370", "'\u0370'")
+        testformat("%a", "\u0370", "'\\u0370'")
         # Test exception for unknown format characters
         if verbose:
             print('Testing exceptions')
@@ -235,8 +237,8 @@
                 raise
             else:
                 raise TestFailed('did not get expected exception: %s' % excmsg)
-        test_exc('abc %a', 1, ValueError,
-                 "unsupported format character 'a' (0x61) at index 5")
+        test_exc('abc %b', 1, ValueError,
+                 "unsupported format character 'b' (0x62) at index 5")
         #test_exc(unicode('abc %\u3000','raw-unicode-escape'), 1, ValueError,
         #         "unsupported format character '?' (0x3000) at index 5")
         test_exc('%d', '1', TypeError, "%d format: a number is required, not str")

Modified: python/branches/py3k/Lib/test/test_pyexpat.py
==============================================================================
--- python/branches/py3k/Lib/test/test_pyexpat.py	(original)
+++ python/branches/py3k/Lib/test/test_pyexpat.py	Wed Jun  4 13:41:32 2008
@@ -131,7 +131,7 @@
         self.assertEquals(op[1], "Comment: ' comment data '")
         self.assertEquals(op[2], "Notation declared: ('notation', None, 'notation.jpeg', None)")
         self.assertEquals(op[3], "Unparsed entity decl: ('unparsed_entity', None, 'entity.file', None, 'notation')")
-        self.assertEquals(op[4], "Start element: 'root' {'attr1': 'value1', 'attr2': 'value2\\u1f40'}")
+        self.assertEquals(op[4], "Start element: 'root' {'attr1': 'value1', 'attr2': 'value2\u1f40'}")
         self.assertEquals(op[5], "NS decl: 'myns' 'http://www.python.org/namespace'")
         self.assertEquals(op[6], "Start element: 'http://www.python.org/namespace!subelement' {}")
         self.assertEquals(op[7], "Character data: 'Contents of subelements'")

Modified: python/branches/py3k/Lib/test/test_unicode.py
==============================================================================
--- python/branches/py3k/Lib/test/test_unicode.py	(original)
+++ python/branches/py3k/Lib/test/test_unicode.py	Wed Jun  4 13:41:32 2008
@@ -94,14 +94,14 @@
                 "JKLMNOPQRSTUVWXYZ[\\\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\\x7f"
                 "\\x80\\x81\\x82\\x83\\x84\\x85\\x86\\x87\\x88\\x89\\x8a\\x8b\\x8c\\x8d"
                 "\\x8e\\x8f\\x90\\x91\\x92\\x93\\x94\\x95\\x96\\x97\\x98\\x99\\x9a\\x9b"
-                "\\x9c\\x9d\\x9e\\x9f\\xa0\\xa1\\xa2\\xa3\\xa4\\xa5\\xa6\\xa7\\xa8\\xa9"
-                "\\xaa\\xab\\xac\\xad\\xae\\xaf\\xb0\\xb1\\xb2\\xb3\\xb4\\xb5\\xb6\\xb7"
-                "\\xb8\\xb9\\xba\\xbb\\xbc\\xbd\\xbe\\xbf\\xc0\\xc1\\xc2\\xc3\\xc4\\xc5"
-                "\\xc6\\xc7\\xc8\\xc9\\xca\\xcb\\xcc\\xcd\\xce\\xcf\\xd0\\xd1\\xd2\\xd3"
-                "\\xd4\\xd5\\xd6\\xd7\\xd8\\xd9\\xda\\xdb\\xdc\\xdd\\xde\\xdf\\xe0\\xe1"
-                "\\xe2\\xe3\\xe4\\xe5\\xe6\\xe7\\xe8\\xe9\\xea\\xeb\\xec\\xed\\xee\\xef"
-                "\\xf0\\xf1\\xf2\\xf3\\xf4\\xf5\\xf6\\xf7\\xf8\\xf9\\xfa\\xfb\\xfc\\xfd"
-                "\\xfe\\xff'")
+                "\\x9c\\x9d\\x9e\\x9f\\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9"
+                "\xaa\xab\xac\\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
+                "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5"
+                "\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3"
+                "\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1"
+                "\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+                "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd"
+                "\xfe\xff'")
             testrepr = repr(''.join(map(chr, range(256))))
             self.assertEqual(testrepr, latin1repr)
             # Test repr works on wide unicode escapes without overflow.
@@ -374,6 +374,12 @@
         self.assertFalse("[".isidentifier())
         self.assertFalse("?".isidentifier())
 
+    def test_isprintable(self):
+        self.assertTrue("abcdefg".isprintable())
+        self.assertFalse("abcdefg\n".isprintable())
+        self.assertTrue("\u0370".isprintable())
+        self.assertFalse("\ud800".isprintable())
+
     def test_contains(self):
         # Testing Unicode contains method
         self.assert_('a' in 'abdb')

Modified: python/branches/py3k/Mac/BuildScript/scripts/postflight.framework
==============================================================================
--- python/branches/py3k/Mac/BuildScript/scripts/postflight.framework	(original)
+++ python/branches/py3k/Mac/BuildScript/scripts/postflight.framework	Wed Jun  4 13:41:32 2008
@@ -6,22 +6,22 @@
 PYVER="@PYVER@"
 FWK="/Library/Frameworks/Python.framework/Versions/@PYVER@"
 
-"${FWK}/bin/python" -Wi -tt \
+"${FWK}/bin/python" -Wi \
     "${FWK}/lib/python${PYVER}/compileall.py" \
     -x badsyntax -x site-packages \
     "${FWK}/lib/python${PYVER}"
 
-"${FWK}/bin/python" -Wi -tt -O \
+"${FWK}/bin/python" -Wi -O \
     "${FWK}/lib/python${PYVER}/compileall.py" \
     -x badsyntax -x site-packages \
     "${FWK}/lib/python${PYVER}"
 
-"${FWK}/bin/python" -Wi -tt \
+"${FWK}/bin/python" -Wi \
     "${FWK}/lib/python${PYVER}/compileall.py" \
     -x badsyntax -x site-packages \
     "${FWK}/Mac/Tools"
 
-"${FWK}/bin/python" -Wi -tt -O \
+"${FWK}/bin/python" -Wi -O \
     "${FWK}/lib/python${PYVER}/compileall.py" \
     -x badsyntax -x site-packages \
     "${FWK}/Mac/Tools"

Modified: python/branches/py3k/Mac/Makefile.in
==============================================================================
--- python/branches/py3k/Mac/Makefile.in	(original)
+++ python/branches/py3k/Mac/Makefile.in	Wed Jun  4 13:41:32 2008
@@ -226,8 +226,8 @@
 
 
 	$(RUNSHARED) $(BUILDPYTHON) $(CACHERSRC) -v $(DESTDIR)$(MACLIBDEST) $(DESTDIR)$(MACTOOLSDEST)
-	$(RUNSHARED) $(BUILDPYTHON) -Wi -tt $(compileall) -d $(MACTOOLSDEST) -x badsyntax $(DESTDIR)$(MACTOOLSDEST)
-	$(RUNSHARED) $(BUILDPYTHON) -O -Wi -tt $(compileall) -d $(MACTOOLSDEST) -x badsyntax $(DESTDIR)$(MACTOOLSDEST)
+	$(RUNSHARED) $(BUILDPYTHON) -Wi $(compileall) -d $(MACTOOLSDEST) -x badsyntax $(DESTDIR)$(MACTOOLSDEST)
+	$(RUNSHARED) $(BUILDPYTHON) -O -Wi $(compileall) -d $(MACTOOLSDEST) -x badsyntax $(DESTDIR)$(MACTOOLSDEST)
 
 $(INSTALLED_PYTHONAPP): install_Python
 

Modified: python/branches/py3k/Makefile.pre.in
==============================================================================
--- python/branches/py3k/Makefile.pre.in	(original)
+++ python/branches/py3k/Makefile.pre.in	Wed Jun  4 13:41:32 2008
@@ -664,7 +664,7 @@
 
 TESTOPTS=	-l $(EXTRATESTOPTS)
 TESTPROG=	$(srcdir)/Lib/test/regrtest.py
-TESTPYTHON=	$(RUNSHARED) ./$(BUILDPYTHON) -E -tt -bb
+TESTPYTHON=	$(RUNSHARED) ./$(BUILDPYTHON) -E -bb
 test:		all platform
 		-find $(srcdir)/Lib -name '*.py[co]' -print | xargs rm -f
 		-$(TESTPYTHON) $(TESTPROG) $(TESTOPTS)
@@ -687,7 +687,7 @@
 		-find $(srcdir)/Lib -name '*.py[co]' -print | xargs rm -f
 		-$(TESTPYTHON) $(TESTPROG) $(TESTOPTS) -uall
 		$(TESTPYTHON) $(TESTPROG) $(TESTOPTS) -uall
-		$(RUNSHARED) /usr/libexec/oah/translate ./$(BUILDPYTHON) -E -tt $(TESTPROG) $(TESTOPTS) -uall
+		$(RUNSHARED) /usr/libexec/oah/translate ./$(BUILDPYTHON) -E $(TESTPROG) $(TESTOPTS) -uall
 
 
 # Like testall, but with a single pass only
@@ -872,23 +872,23 @@
 	done
 	$(INSTALL_DATA) $(srcdir)/LICENSE $(DESTDIR)$(LIBDEST)/LICENSE.txt
 	-PYTHONPATH=$(DESTDIR)$(LIBDEST)  $(RUNSHARED) \
-		./$(BUILDPYTHON) -Wi -tt $(DESTDIR)$(LIBDEST)/compileall.py \
+		./$(BUILDPYTHON) -Wi $(DESTDIR)$(LIBDEST)/compileall.py \
 		-d $(LIBDEST) -f \
 		-x 'bad_coding|badsyntax|site-packages' $(DESTDIR)$(LIBDEST)
 	-PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
-		./$(BUILDPYTHON) -Wi -tt -O $(DESTDIR)$(LIBDEST)/compileall.py \
+		./$(BUILDPYTHON) -Wi -O $(DESTDIR)$(LIBDEST)/compileall.py \
 		-d $(LIBDEST) -f \
 		-x 'bad_coding|badsyntax|site-packages' $(DESTDIR)$(LIBDEST)
 	-PYTHONPATH=$(DESTDIR)$(LIBDEST)  $(RUNSHARED) \
-		./$(BUILDPYTHON) -Wi -t $(DESTDIR)$(LIBDEST)/compileall.py \
+		./$(BUILDPYTHON) -Wi $(DESTDIR)$(LIBDEST)/compileall.py \
 		-d $(LIBDEST)/site-packages -f \
 		-x badsyntax $(DESTDIR)$(LIBDEST)/site-packages
 	-PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
-		./$(BUILDPYTHON) -Wi -t -O $(DESTDIR)$(LIBDEST)/compileall.py \
+		./$(BUILDPYTHON) -Wi -O $(DESTDIR)$(LIBDEST)/compileall.py \
 		-d $(LIBDEST)/site-packages -f \
 		-x badsyntax $(DESTDIR)$(LIBDEST)/site-packages
 	-PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
-		./$(BUILDPYTHON) -Wi -t -c "import lib2to3.pygram"
+		./$(BUILDPYTHON) -Wi -c "import lib2to3.pygram"
 
 # Create the PLATDIR source directory, if one wasn't distributed..
 $(srcdir)/Lib/$(PLATDIR):

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Wed Jun  4 13:41:32 2008
@@ -12,6 +12,8 @@
 Core and Builtins
 -----------------
 
+- Removed the already-defunct ``-t`` option.
+
 - Issue #2957: Corrected a ValueError "recursion limit exceeded", when
   unmarshalling many code objects, which happens when importing a
   large .pyc file (~1000 functions).

Modified: python/branches/py3k/Misc/build.sh
==============================================================================
--- python/branches/py3k/Misc/build.sh	(original)
+++ python/branches/py3k/Misc/build.sh	Wed Jun  4 13:41:32 2008
@@ -59,7 +59,7 @@
 PYTHON=$INSTALL_DIR/bin/python
 
 # Python options and regression test program that should always be run.
-REGRTEST_ARGS="-E -tt $INSTALL_DIR/lib/python3.0/test/regrtest.py"
+REGRTEST_ARGS="-E $INSTALL_DIR/lib/python3.0/test/regrtest.py"
 
 REFLOG="build/reflog.txt.out"
 # These tests are not stable and falsely report leaks sometimes.

Modified: python/branches/py3k/Misc/cheatsheet
==============================================================================
--- python/branches/py3k/Misc/cheatsheet	(original)
+++ python/branches/py3k/Misc/cheatsheet	Wed Jun  4 13:41:32 2008
@@ -46,7 +46,6 @@
 -OO     remove doc-strings in addition to the -O optimizations
 -Q arg  division options: -Qold (default), -Qwarn, -Qwarnall, -Qnew
 -S      Don't perform 'import site' on initialization
--t      Issue warnings about inconsistent tab usage (-tt: issue errors)
 -u      Unbuffered binary stdout and stderr (also PYTHONUNBUFFERED=x).
 -v      Verbose (trace import statements) (also PYTHONVERBOSE=x)
 -W arg : warning control (arg is action:message:category:module:lineno)

Modified: python/branches/py3k/Misc/python.man
==============================================================================
--- python/branches/py3k/Misc/python.man	(original)
+++ python/branches/py3k/Misc/python.man	Wed Jun  4 13:41:32 2008
@@ -35,9 +35,6 @@
 .B \-S
 ]
 [
-.B \-t
-]
-[
 .B \-u
 ]
 .br
@@ -144,11 +141,6 @@
 .I sys.path
 that it entails.
 .TP
-.B \-t
-Issue a warning when a source file mixes tabs and spaces for
-indentation in a way that makes it depend on the worth of a tab
-expressed in spaces.  Issue an error when the option is given twice.
-.TP
 .B \-u
 Force stdin, stdout and stderr to be totally unbuffered.  On systems
 where it matters, also put stdin, stdout and stderr in binary mode.

Modified: python/branches/py3k/Misc/valgrind-python.supp
==============================================================================
--- python/branches/py3k/Misc/valgrind-python.supp	(original)
+++ python/branches/py3k/Misc/valgrind-python.supp	Wed Jun  4 13:41:32 2008
@@ -5,7 +5,7 @@
 #
 #	cd python/dist/src
 #	valgrind --tool=memcheck --suppressions=Misc/valgrind-python.supp \
-#		./python -E -tt ./Lib/test/regrtest.py -u bsddb,network
+#		./python -E ./Lib/test/regrtest.py -u bsddb,network
 #
 # You must edit Objects/obmalloc.c and uncomment Py_USING_MEMORY_DEBUGGER
 # to use the preferred suppressions with Py_ADDRESS_IN_RANGE.

Modified: python/branches/py3k/Modules/main.c
==============================================================================
--- python/branches/py3k/Modules/main.c	(original)
+++ python/branches/py3k/Modules/main.c	Wed Jun  4 13:41:32 2008
@@ -72,7 +72,6 @@
 -OO    : remove doc-strings in addition to the -O optimizations\n\
 -s     : don't add user site directory to sys.path; also PYTHONNOUSERSITE\n\
 -S     : don't imply 'import site' on initialization\n\
--t     : issue warnings about inconsistent tab usage (-tt: issue errors)\n\
 ";
 static char *usage_3 = "\
 -u     : unbuffered binary stdout and stderr; also PYTHONUNBUFFERED=x\n\
@@ -370,7 +369,7 @@
 			break;
 
 		case 't':
-			Py_TabcheckFlag++;
+			/* ignored for backwards compatibility */
 			break;
 
 		case 'u':

Modified: python/branches/py3k/Objects/unicodectype.c
==============================================================================
--- python/branches/py3k/Objects/unicodectype.c	(original)
+++ python/branches/py3k/Objects/unicodectype.c	Wed Jun  4 13:41:32 2008
@@ -21,6 +21,7 @@
 #define UPPER_MASK 0x80
 #define XID_START_MASK 0x100
 #define XID_CONTINUE_MASK 0x200
+#define NONPRINTABLE_MASK 0x400
 
 typedef struct {
     const Py_UNICODE upper;
@@ -675,6 +676,26 @@
     return _PyUnicode_ToNumeric(ch) != -1.0;
 }
 
+/* Returns 1 for Unicode characters to be hex-escaped when repr()ed,
+   0 otherwise.
+   Characters defined in the Unicode character database as following
+   categories are not considered printable.
+      * Cc (Other, Control)
+      * Cf (Other, Format)
+      * Cs (Other, Surrogate)
+      * Co (Other, Private Use)
+      * Cn (Other, Not Assigned)
+      * Zl Separator, Line ('\u2028', LINE SEPARATOR)
+      * Zp Separator, Paragraph ('\u2029', PARAGRAPH SEPARATOR)
+      * Zs (Separator, Space) other than ASCII space('\x20').
+*/
+int _PyUnicode_IsPrintable(Py_UNICODE ch)
+{
+    const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
+
+    return (ctype->flags & NONPRINTABLE_MASK) == 0;
+}
+
 #ifndef WANT_WCTYPE_FUNCTIONS
 
 /* Returns 1 for Unicode characters having the bidirectional type

Modified: python/branches/py3k/Objects/unicodeobject.c
==============================================================================
--- python/branches/py3k/Objects/unicodeobject.c	(original)
+++ python/branches/py3k/Objects/unicodeobject.c	Wed Jun  4 13:41:32 2008
@@ -7149,6 +7149,36 @@
     return PyBool_FromLong(PyUnicode_IsIdentifier(self));
 }
 
+PyDoc_STRVAR(isprintable__doc__,
+"S.isprintable() -> bool\n\
+\n\
+Return True if all characters in S are considered\n\
+printable in repr() and there is at least one character\n\
+in S, False otherwise.");
+
+static PyObject*
+unicode_isprintable(PyObject *self)
+{
+    register const Py_UNICODE *p = PyUnicode_AS_UNICODE(self);
+    register const Py_UNICODE *e;
+
+    /* Shortcut for single character strings */
+    if (PyUnicode_GET_SIZE(self) == 1 &&
+	Py_UNICODE_ISPRINTABLE(*p))
+	return PyBool_FromLong(1);
+
+    /* Special case for empty strings */
+    if (PyUnicode_GET_SIZE(self) == 0)
+	return PyBool_FromLong(0);
+
+    e = p + PyUnicode_GET_SIZE(self);
+    for (; p < e; p++) {
+	if (!Py_UNICODE_ISPRINTABLE(*p))
+	    return PyBool_FromLong(0);
+    }
+    return PyBool_FromLong(1);
+}
+
 PyDoc_STRVAR(join__doc__,
 "S.join(sequence) -> str\n\
 \n\
@@ -7526,61 +7556,8 @@
             continue;
         }
 
-#ifdef Py_UNICODE_WIDE
-        /* Map 21-bit characters to '\U00xxxxxx' */
-        else if (ch >= 0x10000) {
-            *p++ = '\\';
-            *p++ = 'U';
-            *p++ = hexdigits[(ch >> 28) & 0x0000000F];
-            *p++ = hexdigits[(ch >> 24) & 0x0000000F];
-            *p++ = hexdigits[(ch >> 20) & 0x0000000F];
-            *p++ = hexdigits[(ch >> 16) & 0x0000000F];
-            *p++ = hexdigits[(ch >> 12) & 0x0000000F];
-            *p++ = hexdigits[(ch >> 8) & 0x0000000F];
-            *p++ = hexdigits[(ch >> 4) & 0x0000000F];
-            *p++ = hexdigits[ch & 0x0000000F];
-	    continue;
-        }
-#else
-	/* Map UTF-16 surrogate pairs to '\U00xxxxxx' */
-	else if (ch >= 0xD800 && ch < 0xDC00) {
-	    Py_UNICODE ch2;
-	    Py_UCS4 ucs;
-
-	    ch2 = *s++;
-	    size--;
-	    if (ch2 >= 0xDC00 && ch2 <= 0xDFFF) {
-		ucs = (((ch & 0x03FF) << 10) | (ch2 & 0x03FF)) + 0x00010000;
-		*p++ = '\\';
-		*p++ = 'U';
-		*p++ = hexdigits[(ucs >> 28) & 0x0000000F];
-		*p++ = hexdigits[(ucs >> 24) & 0x0000000F];
-		*p++ = hexdigits[(ucs >> 20) & 0x0000000F];
-		*p++ = hexdigits[(ucs >> 16) & 0x0000000F];
-		*p++ = hexdigits[(ucs >> 12) & 0x0000000F];
-		*p++ = hexdigits[(ucs >> 8) & 0x0000000F];
-		*p++ = hexdigits[(ucs >> 4) & 0x0000000F];
-		*p++ = hexdigits[ucs & 0x0000000F];
-		continue;
-	    }
-	    /* Fall through: isolated surrogates are copied as-is */
-	    s--;
-	    size++;
-	}
-#endif
-
-        /* Map 16-bit characters to '\uxxxx' */
-        if (ch >= 256) {
-            *p++ = '\\';
-            *p++ = 'u';
-            *p++ = hexdigits[(ch >> 12) & 0x000F];
-            *p++ = hexdigits[(ch >> 8) & 0x000F];
-            *p++ = hexdigits[(ch >> 4) & 0x000F];
-            *p++ = hexdigits[ch & 0x000F];
-        }
-
-        /* Map special whitespace to '\t', \n', '\r' */
-        else if (ch == '\t') {
+	/* Map special whitespace to '\t', \n', '\r' */
+        if (ch == '\t') {
             *p++ = '\\';
             *p++ = 't';
         }
@@ -7594,16 +7571,79 @@
         }
 
         /* Map non-printable US ASCII to '\xhh' */
-        else if (ch < ' ' || ch >= 0x7F) {
+        else if (ch < ' ' || ch == 0x7F) {
             *p++ = '\\';
             *p++ = 'x';
             *p++ = hexdigits[(ch >> 4) & 0x000F];
             *p++ = hexdigits[ch & 0x000F];
         }
 
-        /* Copy everything else as-is */
-        else
-            *p++ = (char) ch;
+        /* Copy ASCII characters as-is */
+        else if (ch < 0x7F) {
+            *p++ = ch;
+        }
+
+	/* Non-ASCII characters */
+        else {
+            Py_UCS4 ucs = ch;
+
+#ifndef Py_UNICODE_WIDE
+            Py_UNICODE ch2 = 0;
+            /* Get code point from surrogate pair */
+            if (size > 0) {
+                ch2 = *s;
+                if (ch >= 0xD800 && ch < 0xDC00 && ch2 >= 0xDC00
+                            && ch2 <= 0xDFFF) {
+                    ucs = (((ch & 0x03FF) << 10) | (ch2 & 0x03FF)) 
+                            + 0x00010000;
+                    s++; 
+                    size--;
+                }
+            }
+#endif
+            /* Map Unicode whitespace and control characters 
+               (categories Z* and C* except ASCII space)
+            */
+            if (!Py_UNICODE_ISPRINTABLE(ucs)) {
+                /* Map 8-bit characters to '\xhh' */
+                if (ucs <= 0xff) {
+                    *p++ = '\\';
+                    *p++ = 'x';
+                    *p++ = hexdigits[(ch >> 4) & 0x000F];
+                    *p++ = hexdigits[ch & 0x000F];
+                }
+                /* Map 21-bit characters to '\U00xxxxxx' */
+                else if (ucs >= 0x10000) {
+                    *p++ = '\\';
+                    *p++ = 'U';
+                    *p++ = hexdigits[(ucs >> 28) & 0x0000000F];
+                    *p++ = hexdigits[(ucs >> 24) & 0x0000000F];
+                    *p++ = hexdigits[(ucs >> 20) & 0x0000000F];
+                    *p++ = hexdigits[(ucs >> 16) & 0x0000000F];
+                    *p++ = hexdigits[(ucs >> 12) & 0x0000000F];
+                    *p++ = hexdigits[(ucs >> 8) & 0x0000000F];
+                    *p++ = hexdigits[(ucs >> 4) & 0x0000000F];
+                    *p++ = hexdigits[ucs & 0x0000000F];
+                }
+                /* Map 16-bit characters to '\uxxxx' */
+                else {
+                    *p++ = '\\';
+                    *p++ = 'u';
+                    *p++ = hexdigits[(ucs >> 12) & 0x000F];
+                    *p++ = hexdigits[(ucs >> 8) & 0x000F];
+                    *p++ = hexdigits[(ucs >> 4) & 0x000F];
+                    *p++ = hexdigits[ucs & 0x000F];
+                }
+            }
+            /* Copy characters as-is */
+            else {
+                *p++ = ch;
+#ifndef Py_UNICODE_WIDE
+                if (ucs >= 0x10000)
+                    *p++ = ch2;
+#endif
+            }
+        }
     }
     /* Add quote */
     *p++ = PyUnicode_AS_UNICODE(repr)[0];
@@ -8268,6 +8308,7 @@
     {"isalpha", (PyCFunction) unicode_isalpha, METH_NOARGS, isalpha__doc__},
     {"isalnum", (PyCFunction) unicode_isalnum, METH_NOARGS, isalnum__doc__},
     {"isidentifier", (PyCFunction) unicode_isidentifier, METH_NOARGS, isidentifier__doc__},
+    {"isprintable", (PyCFunction) unicode_isprintable, METH_NOARGS, isprintable__doc__},
     {"zfill", (PyCFunction) unicode_zfill, METH_VARARGS, zfill__doc__},
     {"format", (PyCFunction) do_string_format, METH_VARARGS | METH_KEYWORDS, format__doc__},
     {"__format__", (PyCFunction) unicode__format__, METH_VARARGS, p_format__doc__},
@@ -8853,6 +8894,7 @@
 
 	    case 's':
 	    case 'r':
+	    case 'a':
 		if (PyUnicode_Check(v) && c == 's') {
 		    temp = v;
 		    Py_INCREF(temp);
@@ -8872,6 +8914,22 @@
 					"%s argument has non-string str()");
 			goto onError;
 		    }
+		    if (c == 'a') {
+		        PyObject *ascii = PyUnicode_EncodeASCII(
+				PyUnicode_AS_UNICODE(temp),
+				PyUnicode_GET_SIZE(temp),
+				"backslashreplace");
+
+			Py_DECREF(temp);
+			if (ascii == NULL) 
+			    goto onError;
+
+			temp = PyUnicode_FromEncodedObject(ascii, 
+				    "ASCII", NULL);
+			Py_DECREF(ascii);
+			if (temp == NULL)
+			    goto onError;
+		    }
 		}
 		pbuf = PyUnicode_AS_UNICODE(temp);
 		len = PyUnicode_GET_SIZE(temp);

Modified: python/branches/py3k/Objects/unicodetype_db.h
==============================================================================
--- python/branches/py3k/Objects/unicodetype_db.h	(original)
+++ python/branches/py3k/Objects/unicodetype_db.h	Wed Jun  4 13:41:32 2008
@@ -1,11 +1,12 @@
-/* this file was generated by Tools/unicode/makeunicodedata.py 2.5 */
+/* this file was generated by Tools\unicode\makeunicodedata.py 2.5 */
 
 /* a list of unique character type descriptors */
 const _PyUnicode_TypeRecord _PyUnicode_TypeRecords[] = {
     {0, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 1024},
+    {0, 0, 0, 0, 0, 1056},
+    {0, 0, 0, 0, 0, 1072},
     {0, 0, 0, 0, 0, 0},
-    {0, 0, 0, 0, 0, 32},
-    {0, 0, 0, 0, 0, 48},
     {0, 0, 0, 0, 0, 518},
     {0, 0, 0, 1, 1, 518},
     {0, 0, 0, 2, 2, 518},
@@ -162,10 +163,10 @@
     21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 46, 21, 21, 21, 21, 47, 8, 8, 
     48, 49, 8, 8, 8, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
     21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
-    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 50, 32, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 21, 51, 52, 53, 54, 55, 56, 57, 58, 
-    8, 59, 60, 8, 8, 8, 61, 8, 62, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 50, 51, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 21, 52, 53, 54, 55, 56, 57, 58, 59, 
+    8, 60, 61, 8, 8, 8, 62, 8, 63, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
@@ -173,8 +174,8 @@
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 63, 64, 65, 66, 67, 68, 69, 
-    70, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 64, 65, 66, 67, 68, 69, 70, 
+    71, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 21, 21, 21, 21, 21, 
     21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
     21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
@@ -184,11 +185,11 @@
     21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
     21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
     21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
-    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 71, 
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 72, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 21, 21, 72, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 21, 21, 73, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
@@ -306,7 +307,7 @@
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 73, 74, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 74, 75, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
@@ -316,144 +317,143 @@
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 75, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
-    32, 32, 75, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 76, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
+    51, 51, 76, 
 };
 
 static unsigned char index2[] = {
     1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 2, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 3, 3, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 1, 1, 1, 1, 1, 1, 14, 14, 14, 14, 
-    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
-    14, 14, 14, 14, 1, 1, 1, 1, 15, 1, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
-    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 17, 1, 1, 
-    1, 1, 1, 1, 1, 18, 19, 1, 20, 1, 15, 1, 21, 17, 1, 1, 1, 1, 1, 14, 14, 
-    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
-    14, 14, 14, 1, 14, 14, 14, 14, 14, 14, 14, 17, 16, 16, 16, 16, 16, 16, 
-    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 1, 
-    16, 16, 16, 16, 16, 16, 16, 22, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
-    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
-    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
-    23, 24, 25, 26, 23, 24, 23, 24, 23, 24, 17, 23, 24, 23, 24, 23, 24, 23, 
-    24, 23, 24, 23, 24, 23, 24, 23, 24, 17, 23, 24, 23, 24, 23, 24, 23, 24, 
-    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
-    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
-    23, 24, 27, 23, 24, 23, 24, 23, 24, 28, 17, 29, 23, 24, 23, 24, 30, 23, 
-    24, 31, 31, 23, 24, 17, 32, 33, 34, 23, 24, 31, 35, 36, 37, 38, 23, 24, 
-    39, 17, 37, 40, 41, 42, 23, 24, 23, 24, 23, 24, 43, 23, 24, 43, 17, 17, 
-    23, 24, 43, 23, 24, 44, 44, 23, 24, 23, 24, 45, 23, 24, 17, 46, 23, 24, 
-    17, 47, 46, 46, 46, 46, 48, 49, 50, 48, 49, 50, 48, 49, 50, 23, 24, 23, 
-    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 51, 23, 24, 23, 24, 
-    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 17, 48, 49, 50, 
-    23, 24, 52, 53, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
-    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
-    23, 24, 23, 24, 23, 24, 23, 24, 54, 17, 23, 24, 23, 24, 23, 24, 23, 24, 
-    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 17, 17, 17, 17, 17, 17, 55, 23, 
-    24, 56, 55, 17, 17, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 
-    17, 58, 59, 17, 60, 60, 17, 61, 17, 62, 17, 17, 17, 17, 60, 17, 17, 63, 
-    17, 17, 17, 17, 64, 65, 17, 17, 17, 17, 17, 65, 17, 17, 66, 17, 17, 67, 
-    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 68, 17, 17, 68, 17, 17, 17, 17, 
-    68, 17, 69, 69, 17, 17, 17, 17, 17, 17, 70, 17, 71, 17, 17, 17, 17, 17, 
-    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
-    17, 17, 17, 17, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 1, 1, 1, 1, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 46, 46, 46, 46, 46, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 46, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 72, 15, 
+    1, 1, 1, 1, 3, 3, 3, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 4, 4, 4, 4, 4, 4, 4, 15, 15, 15, 15, 
     15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
+    15, 15, 15, 15, 4, 4, 4, 4, 16, 4, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 4, 4, 
+    4, 4, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 18, 4, 4, 
+    1, 4, 4, 4, 4, 19, 20, 4, 21, 4, 16, 4, 22, 18, 4, 4, 4, 4, 4, 15, 15, 
     15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
-    15, 15, 15, 15, 15, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 73, 0, 0, 0, 1, 0, 0, 
-    0, 0, 0, 1, 1, 74, 1, 75, 75, 75, 0, 76, 0, 77, 77, 17, 14, 14, 14, 14, 
-    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 14, 14, 14, 14, 
-    14, 14, 14, 14, 14, 78, 79, 79, 79, 17, 16, 16, 16, 16, 16, 16, 16, 16, 
-    16, 16, 16, 16, 16, 16, 16, 16, 16, 80, 16, 16, 16, 16, 16, 16, 16, 16, 
-    16, 81, 82, 82, 0, 83, 84, 55, 55, 55, 85, 86, 17, 23, 24, 23, 24, 23, 
-    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
-    24, 87, 88, 89, 17, 90, 91, 1, 23, 24, 92, 23, 24, 17, 55, 55, 55, 93, 
-    93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 14, 14, 14, 
-    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
-    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 16, 16, 16, 16, 16, 16, 16, 
+    15, 15, 15, 4, 15, 15, 15, 15, 15, 15, 15, 18, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 4, 
+    17, 17, 17, 17, 17, 17, 17, 23, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
+    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
+    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
+    24, 25, 26, 27, 24, 25, 24, 25, 24, 25, 18, 24, 25, 24, 25, 24, 25, 24, 
+    25, 24, 25, 24, 25, 24, 25, 24, 25, 18, 24, 25, 24, 25, 24, 25, 24, 25, 
+    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
+    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
+    24, 25, 28, 24, 25, 24, 25, 24, 25, 29, 18, 30, 24, 25, 24, 25, 31, 24, 
+    25, 32, 32, 24, 25, 18, 33, 34, 35, 24, 25, 32, 36, 37, 38, 39, 24, 25, 
+    40, 18, 38, 41, 42, 43, 24, 25, 24, 25, 24, 25, 44, 24, 25, 44, 18, 18, 
+    24, 25, 44, 24, 25, 45, 45, 24, 25, 24, 25, 46, 24, 25, 18, 47, 24, 25, 
+    18, 48, 47, 47, 47, 47, 49, 50, 51, 49, 50, 51, 49, 50, 51, 24, 25, 24, 
+    25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 52, 24, 25, 24, 25, 
+    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 18, 49, 50, 51, 
+    24, 25, 53, 54, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
+    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
+    24, 25, 24, 25, 24, 25, 24, 25, 55, 18, 24, 25, 24, 25, 24, 25, 24, 25, 
+    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 18, 18, 18, 18, 18, 18, 56, 24, 
+    25, 57, 56, 18, 18, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 18, 
+    18, 59, 60, 18, 61, 61, 18, 62, 18, 63, 18, 18, 18, 18, 61, 18, 18, 64, 
+    18, 18, 18, 18, 65, 66, 18, 18, 18, 18, 18, 66, 18, 18, 67, 18, 18, 68, 
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 69, 18, 18, 69, 18, 18, 18, 18, 
+    69, 18, 70, 70, 18, 18, 18, 18, 18, 18, 71, 18, 72, 18, 18, 18, 18, 18, 
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
+    18, 18, 18, 18, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 4, 4, 4, 4, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 47, 47, 47, 47, 47, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 47, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
     16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
-    16, 16, 16, 16, 16, 16, 16, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 
-    88, 88, 88, 88, 88, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
-    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
-    24, 23, 24, 1, 15, 15, 15, 15, 0, 1, 1, 23, 24, 23, 24, 23, 24, 23, 24, 
-    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
-    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
-    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 55, 23, 24, 23, 24, 23, 24, 23, 
-    24, 23, 24, 23, 24, 23, 24, 0, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
-    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
-    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 0, 0, 0, 0, 0, 0, 
-    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 0, 0, 46, 1, 1, 1, 1, 1, 1, 0, 95, 95, 95, 95, 
-    95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 
-    95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 17, 0, 1, 
-    1, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 1, 15, 1, 15, 15, 
-    1, 15, 15, 1, 15, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 0, 0, 0, 0, 0, 46, 46, 46, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 
-    1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 15, 15, 15, 15, 15, 15, 0, 
-    0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 
-    0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 15, 15, 15, 15, 15, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 4, 5, 6, 7, 8, 
-    9, 10, 11, 12, 13, 1, 1, 1, 1, 46, 46, 15, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 1, 46, 15, 15, 15, 15, 15, 15, 15, 1, 1, 15, 15, 15, 15, 15, 15, 
-    46, 46, 15, 15, 1, 15, 15, 15, 15, 46, 46, 4, 5, 6, 7, 8, 9, 10, 11, 12, 
-    13, 46, 46, 46, 1, 1, 46, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 
-    46, 15, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 15, 15, 15, 15, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 73, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 0, 0, 0, 0, 4, 4, 0, 0, 0, 0, 74, 0, 0, 0, 4, 0, 0, 
+    0, 0, 0, 4, 4, 75, 4, 76, 76, 76, 0, 77, 0, 78, 78, 18, 15, 15, 15, 15, 
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 
+    15, 15, 15, 15, 15, 79, 80, 80, 80, 18, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 81, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 82, 83, 83, 0, 84, 85, 56, 56, 56, 86, 87, 18, 24, 25, 24, 25, 24, 
+    25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 
+    25, 88, 89, 90, 18, 91, 92, 4, 24, 25, 93, 24, 25, 18, 56, 56, 56, 94, 
+    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 15, 15, 15, 
     15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
-    15, 15, 15, 15, 15, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 46, 0, 0, 0, 0, 0, 0, 0, 0, 
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 
+    89, 89, 89, 89, 89, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 
+    25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 
+    25, 24, 25, 4, 16, 16, 16, 16, 0, 4, 4, 24, 25, 24, 25, 24, 25, 24, 25, 
+    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
+    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
+    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 56, 24, 25, 24, 25, 24, 25, 24, 
+    25, 24, 25, 24, 25, 24, 25, 0, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
+    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
+    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 0, 0, 0, 0, 0, 0, 
+    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 
+    95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 
+    95, 95, 95, 95, 95, 95, 0, 0, 47, 4, 4, 4, 4, 4, 4, 0, 96, 96, 96, 96, 
+    96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 
+    96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 18, 0, 4, 
+    4, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 16, 16, 16, 4, 16, 4, 16, 16, 
+    4, 16, 16, 4, 16, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 0, 0, 0, 0, 0, 47, 47, 47, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 
+    1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 16, 16, 16, 16, 16, 16, 0, 
+    0, 0, 0, 0, 4, 0, 0, 4, 4, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 
+    0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 5, 6, 7, 8, 9, 
+    10, 11, 12, 13, 14, 4, 4, 4, 4, 47, 47, 16, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 4, 47, 16, 16, 16, 16, 16, 16, 16, 1, 4, 16, 16, 16, 16, 16, 16, 
+    47, 47, 16, 16, 4, 16, 16, 16, 16, 47, 47, 5, 6, 7, 8, 9, 10, 11, 12, 13, 
+    14, 47, 47, 47, 4, 4, 47, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 1, 
+    47, 16, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 47, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
@@ -466,232 +466,232 @@
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 15, 46, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 46, 15, 
-    15, 15, 15, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 15, 15, 1, 
-    1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 46, 0, 0, 0, 15, 15, 15, 0, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 46, 
-    46, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 0, 46, 0, 0, 0, 
-    46, 46, 46, 46, 0, 0, 15, 46, 15, 15, 15, 15, 15, 15, 15, 0, 0, 15, 15, 
-    0, 0, 15, 15, 15, 46, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 46, 46, 0, 
-    46, 46, 46, 15, 15, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 46, 46, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 15, 15, 15, 0, 46, 46, 46, 46, 46, 
-    46, 0, 0, 0, 0, 46, 46, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 46, 
-    46, 0, 46, 46, 0, 46, 46, 0, 46, 46, 0, 0, 15, 0, 15, 15, 15, 15, 15, 0, 
-    0, 0, 0, 15, 15, 0, 0, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 
-    46, 46, 46, 0, 46, 0, 0, 0, 0, 0, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 
-    15, 15, 46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 0, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 0, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 
-    46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 0, 46, 46, 46, 46, 46, 0, 0, 15, 
-    46, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 0, 15, 15, 15, 0, 0, 
-    46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 15, 15, 0, 0, 4, 
-    5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 15, 15, 15, 0, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 46, 46, 0, 
-    0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 0, 46, 46, 
-    46, 46, 46, 0, 0, 15, 46, 15, 15, 15, 15, 15, 15, 0, 0, 0, 15, 15, 0, 0, 
-    15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 46, 46, 0, 46, 
-    46, 46, 0, 0, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 46, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 46, 0, 46, 46, 46, 46, 46, 46, 0, 
-    0, 0, 46, 46, 46, 0, 46, 46, 46, 46, 0, 0, 0, 46, 46, 0, 46, 0, 46, 46, 
-    0, 0, 0, 46, 46, 0, 0, 0, 46, 46, 46, 0, 0, 0, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 15, 15, 15, 15, 15, 0, 0, 0, 15, 15, 
-    15, 0, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 15, 15, 15, 0, 46, 46, 46, 46, 46, 
-    46, 46, 46, 0, 46, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 0, 0, 0, 0, 15, 15, 15, 15, 
-    15, 15, 15, 0, 15, 15, 15, 0, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 15, 
-    15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 0, 0, 0, 0, 4, 5, 6, 7, 8, 9, 10, 
-    11, 12, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 
-    0, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 0, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 0, 0, 
-    15, 46, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 0, 15, 15, 15, 15, 0, 
-    0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 46, 0, 46, 46, 0, 0, 0, 0, 
-    4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 15, 15, 0, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 
-    0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 0, 0, 15, 15, 15, 
-    0, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 
-    46, 46, 0, 0, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 0, 0, 46, 46, 46, 
-    46, 46, 46, 46, 0, 0, 0, 15, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 0, 15, 
-    0, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 15, 15, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 15, 46, 96, 15, 15, 15, 15, 15, 15, 
-    15, 0, 0, 0, 0, 1, 46, 46, 46, 46, 46, 46, 46, 15, 15, 15, 15, 15, 15, 
-    15, 15, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 1, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 46, 46, 0, 46, 0, 0, 46, 46, 0, 46, 0, 0, 46, 0, 0, 0, 
-    0, 0, 0, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 0, 
-    46, 0, 46, 0, 0, 46, 46, 0, 46, 46, 46, 46, 15, 46, 96, 15, 15, 15, 15, 
-    15, 15, 0, 15, 15, 46, 0, 0, 46, 46, 46, 46, 46, 0, 46, 0, 15, 15, 15, 
-    15, 15, 15, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 46, 46, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 46, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 15, 15, 1, 1, 1, 1, 1, 1, 4, 5, 6, 7, 8, 9, 10, 
-    11, 12, 13, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 15, 1, 15, 1, 15, 1, 1, 1, 
-    1, 15, 15, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 1, 15, 15, 
-    46, 46, 46, 46, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 1, 1, 
-    1, 1, 1, 1, 1, 1, 15, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 0, 46, 46, 
-    0, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 
-    4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 1, 1, 1, 1, 1, 46, 46, 46, 46, 46, 
-    46, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 
-    97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 
-    97, 97, 97, 97, 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 1, 46, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 0, 0, 46, 46, 46, 46, 46, 46, 
-    46, 0, 46, 0, 46, 46, 46, 46, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 
-    46, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 
-    46, 46, 46, 46, 0, 0, 46, 46, 46, 46, 46, 46, 46, 0, 46, 0, 46, 46, 46, 
-    46, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 0, 46, 46, 46, 46, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 0, 0, 0, 0, 15, 1, 1, 1, 1, 1, 1, 1, 1, 1, 98, 99, 100, 
-    101, 102, 103, 104, 105, 106, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 1, 1, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 2, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 1, 1, 0, 0, 0, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    1, 1, 1, 107, 107, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 15, 
-    15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 15, 15, 15, 1, 1, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 0, 15, 15, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 1, 1, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 1, 1, 
-    1, 46, 1, 1, 1, 1, 46, 15, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 
-    0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 15, 15, 15, 2, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 
-    0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 15, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 
-    0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 15, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 4, 
-    5, 6, 7, 8, 9, 10, 11, 12, 13, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 0, 0, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 46, 46, 46, 46, 46, 46, 46, 15, 15, 0, 0, 
-    0, 0, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 0, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 15, 15, 15, 15, 15, 0, 0, 1, 1, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 16, 47, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 0, 47, 16, 
+    16, 16, 16, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 16, 16, 4, 
+    4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 47, 0, 0, 0, 16, 16, 16, 0, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 47, 
+    47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 0, 0, 0, 
+    47, 47, 47, 47, 0, 0, 16, 47, 16, 16, 16, 16, 16, 16, 16, 0, 0, 16, 16, 
+    0, 0, 16, 16, 16, 47, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 47, 47, 0, 
+    47, 47, 47, 16, 16, 0, 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 47, 47, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 16, 16, 16, 0, 47, 47, 47, 47, 
+    47, 47, 0, 0, 0, 0, 47, 47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 
+    47, 47, 0, 47, 47, 0, 47, 47, 0, 47, 47, 0, 0, 16, 0, 16, 16, 16, 16, 16, 
+    0, 0, 0, 0, 16, 16, 0, 0, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    47, 47, 47, 47, 0, 47, 0, 0, 0, 0, 0, 0, 0, 5, 6, 7, 8, 9, 10, 11, 12, 
+    13, 14, 16, 16, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 
+    16, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 0, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 0, 47, 47, 47, 47, 47, 0, 
+    0, 16, 47, 16, 16, 16, 16, 16, 16, 16, 16, 0, 16, 16, 16, 0, 16, 16, 16, 
+    0, 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 16, 16, 0, 
+    0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 16, 16, 16, 0, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 47, 
+    47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 0, 47, 
+    47, 47, 47, 47, 0, 0, 16, 47, 16, 16, 16, 16, 16, 16, 0, 0, 0, 16, 16, 0, 
+    0, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 47, 47, 0, 47, 
+    47, 47, 0, 0, 0, 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 4, 47, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 47, 0, 47, 47, 47, 47, 47, 47, 0, 
+    0, 0, 47, 47, 47, 0, 47, 47, 47, 47, 0, 0, 0, 47, 47, 0, 47, 0, 47, 47, 
+    0, 0, 0, 47, 47, 0, 0, 0, 47, 47, 47, 0, 0, 0, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 16, 16, 16, 16, 16, 0, 0, 0, 16, 16, 
+    16, 0, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 16, 16, 16, 0, 47, 47, 47, 47, 47, 
+    47, 47, 47, 0, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 0, 0, 0, 0, 16, 16, 16, 16, 
+    16, 16, 16, 0, 16, 16, 16, 0, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 16, 
+    16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 0, 0, 0, 0, 5, 6, 7, 8, 9, 10, 11, 
+    12, 13, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 
+    0, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 0, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 0, 0, 
+    16, 47, 16, 16, 16, 16, 16, 16, 16, 0, 16, 16, 16, 0, 16, 16, 16, 16, 0, 
+    0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 47, 0, 47, 47, 0, 0, 0, 0, 
+    5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 16, 16, 0, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 
+    0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 0, 0, 16, 16, 16, 
+    0, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 
+    47, 47, 0, 0, 0, 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 0, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 0, 0, 47, 47, 47, 
+    47, 47, 47, 47, 0, 0, 0, 16, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 0, 16, 
+    0, 16, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 16, 16, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 16, 47, 97, 16, 16, 16, 16, 16, 16, 
+    16, 0, 0, 0, 0, 4, 47, 47, 47, 47, 47, 47, 47, 16, 16, 16, 16, 16, 16, 
+    16, 16, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 4, 4, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 47, 47, 0, 47, 0, 0, 47, 47, 0, 47, 0, 0, 47, 0, 0, 0, 
+    0, 0, 0, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 0, 
+    47, 0, 47, 0, 0, 47, 47, 0, 47, 47, 47, 47, 16, 47, 97, 16, 16, 16, 16, 
+    16, 16, 0, 16, 16, 47, 0, 0, 47, 47, 47, 47, 47, 0, 47, 0, 16, 16, 16, 
+    16, 16, 16, 0, 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, 0, 47, 47, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 47, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 16, 16, 4, 4, 4, 4, 4, 4, 5, 6, 7, 8, 9, 10, 11, 
+    12, 13, 14, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 16, 4, 16, 4, 16, 4, 4, 4, 
+    4, 16, 16, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 4, 16, 16, 
+    47, 47, 47, 47, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 16, 16, 0, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 4, 4, 
+    4, 4, 4, 4, 4, 4, 16, 4, 4, 4, 4, 4, 4, 0, 0, 4, 4, 4, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 0, 47, 47, 
+    0, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 
+    5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 4, 4, 4, 4, 4, 4, 47, 47, 47, 47, 47, 
+    47, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 
+    98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 
+    98, 98, 98, 98, 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 4, 47, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 0, 0, 47, 47, 47, 47, 47, 47, 
+    47, 0, 47, 0, 47, 47, 47, 47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 
+    47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 
+    47, 47, 47, 47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 0, 47, 47, 47, 
+    47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 0, 47, 47, 47, 47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 0, 0, 0, 0, 16, 4, 4, 4, 4, 4, 4, 4, 4, 4, 99, 100, 101, 
+    102, 103, 104, 105, 106, 107, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 4, 4, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 2, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 4, 4, 0, 0, 0, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    4, 4, 4, 108, 108, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 16, 
+    16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 16, 16, 16, 4, 4, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 0, 16, 16, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 1, 1, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 4, 4, 
+    4, 47, 4, 4, 4, 4, 47, 16, 0, 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, 0, 
+    0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 16, 16, 16, 2, 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 
+    0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 16, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 
+    0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 4, 0, 0, 0, 4, 4, 5, 
+    6, 7, 8, 9, 10, 11, 12, 13, 14, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 0, 0, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 47, 47, 47, 47, 47, 47, 47, 16, 16, 0, 0, 
+    0, 0, 0, 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, 0, 0, 0, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 16, 16, 16, 16, 16, 0, 0, 4, 4, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
@@ -700,132 +700,133 @@
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
-    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
-    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 17, 17, 17, 17, 17, 17, 
-    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 46, 17, 
-    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
-    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 15, 15, 
-    15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 24, 23, 24, 23, 24, 23, 24, 
-    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
-    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
-    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
-    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
-    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
-    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
-    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
-    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 17, 17, 
-    17, 17, 17, 108, 0, 0, 0, 0, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
-    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
-    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
-    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
-    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
-    24, 23, 24, 23, 24, 23, 24, 0, 0, 0, 0, 0, 0, 109, 109, 109, 109, 109, 
-    109, 109, 109, 110, 110, 110, 110, 110, 110, 110, 110, 109, 109, 109, 
-    109, 109, 109, 0, 0, 110, 110, 110, 110, 110, 110, 0, 0, 109, 109, 109, 
-    109, 109, 109, 109, 109, 110, 110, 110, 110, 110, 110, 110, 110, 109, 
-    109, 109, 109, 109, 109, 109, 109, 110, 110, 110, 110, 110, 110, 110, 
-    110, 109, 109, 109, 109, 109, 109, 0, 0, 110, 110, 110, 110, 110, 110, 0, 
-    0, 17, 109, 17, 109, 17, 109, 17, 109, 0, 110, 0, 110, 0, 110, 0, 110, 
-    109, 109, 109, 109, 109, 109, 109, 109, 110, 110, 110, 110, 110, 110, 
-    110, 110, 111, 111, 112, 112, 112, 112, 113, 113, 114, 114, 115, 115, 
-    116, 116, 0, 0, 109, 109, 109, 109, 109, 109, 109, 109, 117, 117, 117, 
-    117, 117, 117, 117, 117, 109, 109, 109, 109, 109, 109, 109, 109, 117, 
-    117, 117, 117, 117, 117, 117, 117, 109, 109, 109, 109, 109, 109, 109, 
-    109, 117, 117, 117, 117, 117, 117, 117, 117, 109, 109, 17, 118, 17, 0, 
-    17, 17, 110, 110, 119, 119, 120, 1, 121, 1, 1, 1, 17, 118, 17, 0, 17, 17, 
-    122, 122, 122, 122, 120, 1, 1, 1, 109, 109, 17, 17, 0, 0, 17, 17, 110, 
-    110, 123, 123, 0, 1, 1, 1, 109, 109, 17, 17, 17, 89, 17, 17, 110, 110, 
-    124, 124, 92, 1, 1, 1, 0, 0, 17, 118, 17, 0, 17, 17, 125, 125, 126, 126, 
-    120, 1, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 
-    1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 15, 15, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 15, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 127, 17, 0, 
-    0, 128, 129, 130, 131, 132, 133, 1, 1, 1, 1, 1, 17, 127, 21, 18, 19, 128, 
-    129, 130, 131, 132, 133, 1, 1, 1, 1, 1, 0, 46, 46, 46, 46, 46, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
-    15, 1, 1, 1, 1, 15, 1, 1, 1, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 55, 1, 1, 1, 1, 55, 1, 
-    1, 17, 55, 55, 55, 17, 17, 55, 55, 55, 17, 1, 55, 1, 1, 107, 55, 55, 55, 
-    55, 55, 1, 1, 1, 1, 1, 1, 55, 1, 134, 1, 55, 1, 135, 136, 55, 55, 107, 
-    17, 55, 55, 1, 55, 17, 46, 46, 46, 46, 17, 1, 1, 17, 17, 55, 55, 1, 1, 1, 
-    1, 1, 55, 17, 17, 17, 17, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 
-    137, 137, 137, 137, 137, 138, 138, 138, 138, 138, 138, 138, 138, 138, 
-    138, 138, 138, 138, 138, 138, 138, 107, 107, 107, 107, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 21, 18, 19, 128, 129, 130, 131, 132, 133, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 21, 18, 19, 128, 129, 130, 131, 132, 133, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 21, 18, 19, 128, 129, 130, 131, 132, 133, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 139, 139, 139, 139, 139, 139, 139, 139, 
-    139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 
-    139, 139, 139, 139, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 
+    0, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 18, 18, 18, 18, 18, 18, 
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 47, 18, 
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 16, 16, 
+    16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 25, 24, 25, 24, 25, 24, 25, 
+    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
+    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
+    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
+    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
+    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
+    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
+    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
+    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 18, 18, 
+    18, 18, 18, 109, 0, 0, 0, 0, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 
+    25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 
+    25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 
+    25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 
+    25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 
+    25, 24, 25, 24, 25, 24, 25, 0, 0, 0, 0, 0, 0, 110, 110, 110, 110, 110, 
+    110, 110, 110, 111, 111, 111, 111, 111, 111, 111, 111, 110, 110, 110, 
+    110, 110, 110, 0, 0, 111, 111, 111, 111, 111, 111, 0, 0, 110, 110, 110, 
+    110, 110, 110, 110, 110, 111, 111, 111, 111, 111, 111, 111, 111, 110, 
+    110, 110, 110, 110, 110, 110, 110, 111, 111, 111, 111, 111, 111, 111, 
+    111, 110, 110, 110, 110, 110, 110, 0, 0, 111, 111, 111, 111, 111, 111, 0, 
+    0, 18, 110, 18, 110, 18, 110, 18, 110, 0, 111, 0, 111, 0, 111, 0, 111, 
+    110, 110, 110, 110, 110, 110, 110, 110, 111, 111, 111, 111, 111, 111, 
+    111, 111, 112, 112, 113, 113, 113, 113, 114, 114, 115, 115, 116, 116, 
+    117, 117, 0, 0, 110, 110, 110, 110, 110, 110, 110, 110, 118, 118, 118, 
+    118, 118, 118, 118, 118, 110, 110, 110, 110, 110, 110, 110, 110, 118, 
+    118, 118, 118, 118, 118, 118, 118, 110, 110, 110, 110, 110, 110, 110, 
+    110, 118, 118, 118, 118, 118, 118, 118, 118, 110, 110, 18, 119, 18, 0, 
+    18, 18, 111, 111, 120, 120, 121, 4, 122, 4, 4, 4, 18, 119, 18, 0, 18, 18, 
+    123, 123, 123, 123, 121, 4, 4, 4, 110, 110, 18, 18, 0, 0, 18, 18, 111, 
+    111, 124, 124, 0, 4, 4, 4, 110, 110, 18, 18, 18, 90, 18, 18, 111, 111, 
+    125, 125, 93, 4, 4, 4, 0, 0, 18, 119, 18, 0, 18, 18, 126, 126, 127, 127, 
+    121, 4, 4, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 1, 1, 
+    1, 1, 1, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 16, 16, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 16, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 128, 18, 0, 
+    0, 129, 130, 131, 132, 133, 134, 4, 4, 4, 4, 4, 18, 128, 22, 19, 20, 129, 
+    130, 131, 132, 133, 134, 4, 4, 4, 4, 4, 0, 47, 47, 47, 47, 47, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 4, 4, 4, 4, 16, 4, 4, 4, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 56, 4, 4, 4, 4, 56, 4, 
+    4, 18, 56, 56, 56, 18, 18, 56, 56, 56, 18, 4, 56, 4, 4, 108, 56, 56, 56, 
+    56, 56, 4, 4, 4, 4, 4, 4, 56, 4, 135, 4, 56, 4, 136, 137, 56, 56, 108, 
+    18, 56, 56, 4, 56, 18, 47, 47, 47, 47, 18, 4, 4, 18, 18, 56, 56, 4, 4, 4, 
+    4, 4, 56, 18, 18, 18, 18, 4, 4, 4, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 
+    138, 138, 138, 138, 138, 139, 139, 139, 139, 139, 139, 139, 139, 139, 
+    139, 139, 139, 139, 139, 139, 139, 108, 108, 108, 108, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 22, 19, 20, 129, 130, 131, 132, 133, 134, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 22, 19, 20, 129, 130, 131, 132, 133, 134, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 22, 19, 20, 129, 130, 131, 132, 133, 134, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 140, 140, 140, 140, 140, 140, 140, 140, 
     140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 
-    140, 140, 127, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 21, 18, 19, 128, 129, 130, 
-    131, 132, 133, 1, 127, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 
+    140, 140, 140, 140, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 
+    141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 
+    141, 141, 128, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 22, 19, 20, 129, 130, 131, 
+    132, 133, 134, 4, 128, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 21, 18, 
-    19, 128, 129, 130, 131, 132, 133, 1, 21, 18, 19, 128, 129, 130, 131, 132, 
-    133, 1, 21, 18, 19, 128, 129, 130, 131, 132, 133, 1, 1, 0, 0, 0, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    4, 4, 4, 4, 0, 4, 4, 4, 4, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 0, 4, 0, 4, 4, 4, 4, 0, 0, 0, 4, 0, 4, 4, 4, 4, 4, 4, 4, 0, 0, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 22, 19, 
+    20, 129, 130, 131, 132, 133, 134, 4, 22, 19, 20, 129, 130, 131, 132, 133, 
+    134, 4, 22, 19, 20, 129, 130, 131, 132, 133, 134, 4, 4, 0, 0, 0, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
@@ -834,134 +835,133 @@
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 0, 95, 95, 95, 95, 95, 95, 95, 95, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 95, 
     95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 
     95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 
-    95, 95, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 24, 23, 24, 23, 24, 23, 24, 
-    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
-    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
-    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
-    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
-    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
-    23, 24, 17, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    1, 1, 1, 1, 1, 1, 1, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 
-    141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 
-    141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 0, 46, 
-    46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 
-    46, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 
-    0, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 
-    1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 
-    0, 0, 0, 2, 1, 1, 1, 1, 46, 46, 107, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 107, 107, 107, 107, 107, 107, 107, 
-    107, 107, 15, 15, 15, 15, 15, 15, 1, 46, 46, 46, 46, 46, 1, 1, 107, 107, 
-    107, 46, 46, 1, 1, 1, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 0, 0, 15, 15, 1, 1, 46, 46, 46, 1, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 1, 46, 46, 46, 46, 0, 0, 0, 
-    0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 
-    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    95, 95, 95, 95, 95, 95, 95, 95, 95, 0, 96, 96, 96, 96, 96, 96, 96, 96, 
+    96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 
+    96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 
+    96, 96, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 25, 24, 25, 24, 25, 24, 25, 
+    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
+    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
+    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
+    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
+    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
+    24, 25, 18, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    4, 4, 4, 4, 4, 4, 4, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 
+    142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 
+    142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 
+    47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 
+    47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 
+    0, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 4, 
+    4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 
+    0, 0, 0, 2, 4, 4, 4, 4, 47, 47, 108, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 108, 108, 108, 108, 108, 108, 108, 
+    108, 108, 16, 16, 16, 16, 16, 16, 4, 47, 47, 47, 47, 47, 4, 4, 108, 108, 
+    108, 47, 47, 4, 4, 4, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 0, 0, 16, 16, 4, 4, 47, 47, 47, 4, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 4, 47, 47, 47, 47, 0, 0, 0, 
+    0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 
+    0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
@@ -970,10 +970,10 @@
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 46, 46, 15, 46, 46, 46, 15, 46, 46, 46, 46, 15, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 15, 15, 15, 15, 15, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 47, 47, 16, 47, 47, 47, 16, 47, 47, 47, 47, 16, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 16, 16, 16, 16, 16, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
@@ -981,290 +981,302 @@
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 
-    17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 
-    17, 17, 0, 0, 0, 0, 0, 46, 15, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 1, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 
-    46, 0, 46, 0, 46, 46, 0, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 73, 73, 73, 73, 73, 73, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 73, 73, 1, 1, 0, 0, 15, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 1, 1, 1, 15, 15, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 15, 15, 15, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 73, 46, 73, 
-    46, 73, 0, 73, 46, 73, 46, 73, 46, 73, 46, 73, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 1, 0, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 1, 
-    1, 1, 1, 1, 1, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
-    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 1, 1, 1, 1, 15, 1, 16, 
-    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
-    16, 16, 16, 16, 16, 16, 16, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 96, 
-    96, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 46, 46, 
-    46, 46, 46, 46, 0, 0, 46, 46, 46, 46, 46, 46, 0, 0, 46, 46, 46, 46, 46, 
-    46, 0, 0, 46, 46, 46, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 
-    1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    0, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 107, 
-    107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 
-    107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 
-    107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 
-    107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 
+    0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 47, 
+    16, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 4, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 0, 47, 0, 47, 47, 0, 
+    47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 74, 74, 74, 74, 74, 74, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 4, 4, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 74, 74, 4, 4, 0, 0, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 
+    0, 0, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 16, 
+    16, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 16, 16, 16, 4, 4, 4, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 0, 4, 4, 4, 4, 0, 0, 0, 0, 74, 47, 74, 47, 74, 0, 74, 47, 74, 
+    47, 74, 47, 74, 47, 74, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 0, 0, 1, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 4, 4, 4, 4, 4, 4, 4, 15, 15, 
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
+    15, 15, 15, 15, 15, 15, 4, 4, 4, 4, 16, 4, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 97, 97, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 47, 47, 47, 47, 47, 47, 0, 0, 
+    47, 47, 47, 47, 47, 47, 0, 0, 47, 47, 47, 47, 47, 47, 0, 0, 47, 47, 47, 
+    0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 0, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 1, 1, 1, 4, 4, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 0, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 4, 
+    4, 4, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 108, 108, 108, 108, 108, 
+    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
+    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
+    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
+    108, 108, 108, 108, 108, 108, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 0, 1, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 1, 107, 
-    107, 107, 107, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 
-    142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 
-    142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 143, 143, 
+    0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 4, 
+    4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    0, 4, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 4, 108, 108, 108, 108, 
+    108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 143, 143, 143, 
     143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 
     143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 
-    143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    143, 143, 143, 143, 143, 143, 143, 143, 143, 144, 144, 144, 144, 144, 
+    144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 
+    144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 
+    144, 144, 144, 144, 144, 144, 144, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 5, 6, 
+    7, 8, 9, 10, 11, 12, 13, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 
+    47, 47, 47, 47, 47, 0, 0, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 
+    47, 0, 0, 0, 47, 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 46, 46, 46, 46, 46, 46, 0, 0, 46, 0, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 0, 46, 46, 0, 0, 0, 46, 0, 0, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 16, 16, 16, 0, 16, 16, 0, 0, 0, 0, 0, 16, 
+    16, 16, 16, 47, 47, 47, 47, 0, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 0, 0, 0, 0, 16, 16, 16, 0, 0, 0, 0, 16, 22, 19, 20, 129, 4, 4, 4, 
+    4, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 15, 15, 15, 0, 15, 15, 0, 0, 0, 
-    0, 0, 15, 15, 15, 15, 46, 46, 46, 46, 0, 46, 46, 46, 0, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 0, 0, 0, 0, 15, 15, 15, 0, 0, 0, 0, 15, 21, 18, 19, 
-    128, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 16, 16, 16, 16, 16, 4, 4, 4, 
+    16, 16, 16, 16, 16, 16, 1, 1, 1, 1, 1, 1, 1, 1, 16, 16, 16, 16, 16, 16, 
+    16, 16, 4, 4, 16, 16, 16, 16, 16, 16, 16, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 16, 16, 16, 
+    16, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 16, 16, 16, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 15, 15, 15, 15, 15, 
-    1, 1, 1, 15, 15, 15, 15, 15, 15, 1, 1, 1, 1, 1, 1, 1, 1, 15, 15, 15, 15, 
-    15, 15, 15, 15, 1, 1, 15, 15, 15, 15, 15, 15, 15, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 15, 15, 
-    15, 15, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 15, 15, 15, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 
+    0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 
-    55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 
-    55, 55, 55, 55, 55, 55, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
-    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 55, 55, 55, 55, 
-    55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 
-    55, 55, 55, 55, 17, 17, 17, 17, 17, 17, 17, 0, 17, 17, 17, 17, 17, 17, 
-    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 55, 55, 55, 55, 55, 55, 
-    55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 
-    55, 55, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
-    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 55, 0, 55, 55, 0, 0, 55, 0, 0, 
-    55, 55, 0, 0, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 17, 17, 
-    17, 17, 0, 17, 0, 17, 17, 17, 17, 17, 17, 17, 0, 17, 17, 17, 17, 17, 17, 
-    17, 17, 17, 17, 17, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 
-    55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 17, 17, 17, 17, 17, 
-    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
-    17, 17, 17, 55, 55, 0, 55, 55, 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, 
-    55, 0, 55, 55, 55, 55, 55, 55, 55, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
-    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 55, 
-    55, 0, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 0, 55, 0, 0, 0, 55, 55, 55, 
-    55, 55, 55, 55, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
-    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 55, 55, 55, 55, 55, 
-    55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 
-    55, 55, 55, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
-    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 55, 55, 55, 55, 55, 55, 55, 
-    55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 
-    55, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
-    17, 17, 17, 17, 17, 17, 17, 17, 17, 55, 55, 55, 55, 55, 55, 55, 55, 55, 
-    55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 17, 
-    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
-    17, 17, 17, 17, 17, 17, 17, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 
-    55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 17, 17, 17, 
-    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
-    17, 17, 17, 17, 17, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 
-    55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 17, 17, 17, 17, 17, 
-    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
-    17, 17, 17, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 
-    55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 17, 17, 17, 17, 17, 17, 17, 
-    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
-    17, 17, 17, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 
-    55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 1, 17, 17, 17, 17, 17, 17, 
-    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
-    17, 1, 17, 17, 17, 17, 17, 17, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 
-    55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 1, 17, 17, 
-    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
-    17, 17, 17, 17, 17, 1, 17, 17, 17, 17, 17, 17, 55, 55, 55, 55, 55, 55, 
-    55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 
-    55, 1, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
-    17, 17, 17, 17, 17, 17, 17, 17, 17, 1, 17, 17, 17, 17, 17, 17, 55, 55, 
-    55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 
-    55, 55, 55, 55, 55, 1, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
-    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 1, 17, 17, 17, 17, 
-    17, 17, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 
-    55, 55, 55, 55, 55, 55, 55, 55, 55, 1, 17, 17, 17, 17, 17, 17, 17, 17, 
-    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 1, 
-    17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 4, 
-    5, 6, 7, 8, 9, 10, 11, 12, 13, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 4, 5, 6, 
-    7, 8, 9, 10, 11, 12, 13, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 56, 56, 
+    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
+    56, 56, 56, 56, 56, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 56, 56, 56, 56, 56, 
+    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
+    56, 56, 56, 18, 18, 18, 18, 18, 18, 18, 0, 18, 18, 18, 18, 18, 18, 18, 
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 56, 56, 56, 56, 56, 56, 56, 
+    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
+    56, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 56, 0, 56, 56, 0, 0, 56, 0, 0, 56, 
+    56, 0, 0, 56, 56, 56, 56, 0, 56, 56, 56, 56, 56, 56, 56, 56, 18, 18, 18, 
+    18, 0, 18, 0, 18, 18, 18, 18, 18, 18, 18, 0, 18, 18, 18, 18, 18, 18, 18, 
+    18, 18, 18, 18, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
+    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 18, 18, 18, 18, 18, 18, 
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
+    18, 18, 56, 56, 0, 56, 56, 56, 56, 0, 0, 56, 56, 56, 56, 56, 56, 56, 56, 
+    0, 56, 56, 56, 56, 56, 56, 56, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 56, 56, 
+    0, 56, 56, 56, 56, 0, 56, 56, 56, 56, 56, 0, 56, 0, 0, 0, 56, 56, 56, 56, 
+    56, 56, 56, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 56, 56, 56, 56, 56, 56, 
+    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
+    56, 56, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 56, 56, 56, 56, 56, 56, 56, 56, 
+    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
+    18, 18, 18, 18, 18, 18, 18, 18, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
+    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 18, 18, 
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
+    18, 18, 18, 18, 18, 18, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
+    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 18, 18, 18, 18, 
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
+    18, 18, 18, 18, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
+    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 18, 18, 18, 18, 18, 18, 
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
+    18, 18, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
+    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 18, 18, 18, 18, 18, 18, 18, 18, 
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
+    18, 18, 0, 0, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
+    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 4, 18, 18, 18, 18, 18, 18, 18, 
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
+    4, 18, 18, 18, 18, 18, 18, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
+    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 4, 18, 18, 18, 
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
+    18, 18, 18, 18, 4, 18, 18, 18, 18, 18, 18, 56, 56, 56, 56, 56, 56, 56, 
+    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
+    4, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
+    18, 18, 18, 18, 18, 18, 18, 18, 4, 18, 18, 18, 18, 18, 18, 56, 56, 56, 
+    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
+    56, 56, 56, 56, 4, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 4, 18, 18, 18, 18, 18, 
+    18, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
+    56, 56, 56, 56, 56, 56, 56, 56, 4, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 4, 18, 
+    18, 18, 18, 18, 18, 0, 0, 0, 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 5, 6, 
+    7, 8, 9, 10, 11, 12, 13, 14, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 5, 6, 7, 
+    8, 9, 10, 11, 12, 13, 14, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
@@ -1284,20 +1296,20 @@
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 

Modified: python/branches/py3k/PC/VC6/rt.bat
==============================================================================
--- python/branches/py3k/PC/VC6/rt.bat	(original)
+++ python/branches/py3k/PC/VC6/rt.bat	Wed Jun  4 13:41:32 2008
@@ -31,11 +31,11 @@
 @if "%_qmode%"=="yes" goto Qmode
 @echo Deleting .pyc/.pyo files ...
 @%_exe% rmpyc.py
-%_exe% %_dashO% -E -tt ../../lib/test/regrtest.py %1 %2 %3 %4 %5 %6 %7 %8 %9
+%_exe% %_dashO% -E ../../lib/test/regrtest.py %1 %2 %3 %4 %5 %6 %7 %8 %9
 @echo About to run again without deleting .pyc/.pyo first:
 @pause
 :Qmode
-%_exe% %_dashO% -E -tt ../../lib/test/regrtest.py %1 %2 %3 %4 %5 %6 %7 %8 %9
+%_exe% %_dashO% -E ../../lib/test/regrtest.py %1 %2 %3 %4 %5 %6 %7 %8 %9
 @set _exe=
 @set _qmode=
 @set _dashO=

Modified: python/branches/py3k/PC/VS7.1/rt.bat
==============================================================================
--- python/branches/py3k/PC/VS7.1/rt.bat	(original)
+++ python/branches/py3k/PC/VS7.1/rt.bat	Wed Jun  4 13:41:32 2008
@@ -34,7 +34,7 @@
 if "%1"=="-q" (set qmode=yes)    & shift & goto CheckOpts
 if "%1"=="-d" (set exe=python_d) & shift & goto CheckOpts
 
-set cmd=%exe% %dashO% -E -tt ../../lib/test/regrtest.py %1 %2 %3 %4 %5 %6 %7 %8 %9
+set cmd=%exe% %dashO% -E ../../lib/test/regrtest.py %1 %2 %3 %4 %5 %6 %7 %8 %9
 if defined qmode goto Qmode
 
 echo Deleting .pyc/.pyo files ...

Modified: python/branches/py3k/PC/VS8.0/rt.bat
==============================================================================
--- python/branches/py3k/PC/VS8.0/rt.bat	(original)
+++ python/branches/py3k/PC/VS8.0/rt.bat	Wed Jun  4 13:41:32 2008
@@ -34,7 +34,7 @@
 if "%1"=="-q" (set qmode=yes)    & shift & goto CheckOpts
 if "%1"=="-d" (set exe=python_d) & shift & goto CheckOpts
 
-set cmd=%exe% %dashO% -E -tt ../../lib/test/regrtest.py %1 %2 %3 %4 %5 %6 %7 %8 %9
+set cmd=%exe% %dashO% -E ../../lib/test/regrtest.py %1 %2 %3 %4 %5 %6 %7 %8 %9
 if defined qmode goto Qmode
 
 echo Deleting .pyc/.pyo files ...

Modified: python/branches/py3k/PC/os2emx/Makefile
==============================================================================
--- python/branches/py3k/PC/os2emx/Makefile	(original)
+++ python/branches/py3k/PC/os2emx/Makefile	Wed Jun  4 13:41:32 2008
@@ -666,7 +666,7 @@
 # the test target
 test:
 	-find ../../Lib -name "*.py[co]" -exec rm {} ";"
-	-./python -E -tt ../../lib/test/regrtest.py -l -u "network"
-	./python -E -tt ../../lib/test/regrtest.py -l -u "network"
+	-./python -E ../../lib/test/regrtest.py -l -u "network"
+	./python -E ../../lib/test/regrtest.py -l -u "network"
 
 -include $(OUTBASE)python.dep

Modified: python/branches/py3k/PC/os2emx/python26.def
==============================================================================
--- python/branches/py3k/PC/os2emx/python26.def	(original)
+++ python/branches/py3k/PC/os2emx/python26.def	Wed Jun  4 13:41:32 2008
@@ -49,7 +49,6 @@
   "PyParser_Delete"
 
 ; From python26_s.lib(parsetok)
-  "Py_TabcheckFlag"
   "PyParser_ParseString"
   "PyParser_ParseStringFlagsFilename"
   "PyParser_ParseFile"

Modified: python/branches/py3k/PC/os2vacpp/python.def
==============================================================================
--- python/branches/py3k/PC/os2vacpp/python.def	(original)
+++ python/branches/py3k/PC/os2vacpp/python.def	Wed Jun  4 13:41:32 2008
@@ -61,7 +61,6 @@
                Py_InteractiveFlag
                Py_NoSiteFlag
                Py_OptimizeFlag
-               Py_TabcheckFlag
                Py_UseClassExceptionsFlag
                Py_VerboseFlag
                _PyImport_Filetab

Modified: python/branches/py3k/PCbuild/rt.bat
==============================================================================
--- python/branches/py3k/PCbuild/rt.bat	(original)
+++ python/branches/py3k/PCbuild/rt.bat	Wed Jun  4 13:41:32 2008
@@ -40,7 +40,7 @@
 
 PATH %PATH%;..\..\%tcltk%\bin
 set exe=%prefix%\python%suffix%
-set cmd=%exe% %dashO% -E -tt ../lib/test/regrtest.py %1 %2 %3 %4 %5 %6 %7 %8 %9
+set cmd=%exe% %dashO% -E ../lib/test/regrtest.py %1 %2 %3 %4 %5 %6 %7 %8 %9
 if defined qmode goto Qmode
 
 echo Deleting .pyc/.pyo files ...

Modified: python/branches/py3k/Parser/parsetok.c
==============================================================================
--- python/branches/py3k/Parser/parsetok.c	(original)
+++ python/branches/py3k/Parser/parsetok.c	Wed Jun  4 13:41:32 2008
@@ -10,8 +10,6 @@
 #include "errcode.h"
 #include "graminit.h"
 
-int Py_TabcheckFlag;
-
 
 /* Forward */
 static node *parsetok(struct tok_state *, grammar *, int, perrdetail *, int *);
@@ -57,9 +55,6 @@
 	}
 
         tok->filename = filename ? filename : "<string>";
-	if (Py_TabcheckFlag >= 3)
-		tok->alterror = 0;
-
 	return parsetok(tok, g, start, err_ret, flags);
 }
 
@@ -97,9 +92,6 @@
 		return NULL;
 	}
 	tok->filename = filename;
-	if (Py_TabcheckFlag >= 3)
-		tok->alterror = 0;
-
 	return parsetok(tok, g, start, err_ret, flags);
 }
 

Modified: python/branches/py3k/Python/bltinmodule.c
==============================================================================
--- python/branches/py3k/Python/bltinmodule.c	(original)
+++ python/branches/py3k/Python/bltinmodule.c	Wed Jun  4 13:41:32 2008
@@ -265,6 +265,38 @@
 \n\
 Return True if bool(x) is True for any x in the iterable.");
 
+static PyObject *
+builtin_ascii(PyObject *self, PyObject *v)
+{
+	PyObject *repr, *bytes, *ascii;
+	repr = PyObject_Repr(v);
+	if (!repr)
+	    return NULL;
+
+        bytes = PyUnicode_EncodeASCII(
+		PyUnicode_AS_UNICODE(repr),
+		PyUnicode_GET_SIZE(repr),
+		"backslashreplace");
+
+	Py_DECREF(repr);
+	if (bytes == NULL) 
+	    return NULL;
+
+	ascii = PyUnicode_FromEncodedObject(bytes, 
+		    "ASCII", NULL);
+	Py_DECREF(bytes);
+	if (ascii == NULL)
+	    return NULL;
+
+	return ascii;
+}
+
+PyDoc_STRVAR(ascii_doc,
+"ascii(object) -> string\n\
+\n\
+Return the canonical string representation of the object as repr(),\n\
+but non-ASCII characters in the string are hex-escaped");
+
 
 static PyObject *
 builtin_bin(PyObject *self, PyObject *v)
@@ -2188,6 +2220,7 @@
  	{"abs",		builtin_abs,        METH_O, abs_doc},
  	{"all",		builtin_all,        METH_O, all_doc},
  	{"any",		builtin_any,        METH_O, any_doc},
+ 	{"ascii",	builtin_ascii,      METH_O, ascii_doc},
 	{"bin",		builtin_bin,	    METH_O, bin_doc},
  	{"chr",		builtin_chr,        METH_VARARGS, chr_doc},
  	{"cmp",		builtin_cmp,        METH_VARARGS, cmp_doc},

Modified: python/branches/py3k/Python/sysmodule.c
==============================================================================
--- python/branches/py3k/Python/sysmodule.c	(original)
+++ python/branches/py3k/Python/sysmodule.c	Wed Jun  4 13:41:32 2008
@@ -1100,7 +1100,6 @@
 	{"no_user_site",	"-s"},
 	{"no_site",		"-S"},
 	{"ignore_environment",	"-E"},
-	{"tabcheck",		"-t or -tt"},
 	{"verbose",		"-v"},
 #ifdef RISCOS
 	{"riscos_wimp",		"???"},
@@ -1116,9 +1115,9 @@
 	flags__doc__,	/* doc */
 	flags_fields,	/* fields */
 #ifdef RISCOS
-	12
-#else
 	11
+#else
+	10
 #endif
 };
 
@@ -1144,7 +1143,6 @@
 	SetFlag(Py_NoUserSiteDirectory);
 	SetFlag(Py_NoSiteFlag);
 	SetFlag(Py_IgnoreEnvironmentFlag);
-	SetFlag(Py_TabcheckFlag);
 	SetFlag(Py_VerboseFlag);
 #ifdef RISCOS
 	SetFlag(Py_RISCOSWimpFlag);

Modified: python/branches/py3k/Tools/unicode/makeunicodedata.py
==============================================================================
--- python/branches/py3k/Tools/unicode/makeunicodedata.py	(original)
+++ python/branches/py3k/Tools/unicode/makeunicodedata.py	Wed Jun  4 13:41:32 2008
@@ -60,6 +60,7 @@
 UPPER_MASK = 0x80
 XID_START_MASK = 0x100
 XID_CONTINUE_MASK = 0x200
+NONPRINTABLE_MASK = 0x400
 
 def maketables(trace=0):
 
@@ -71,7 +72,7 @@
                           EASTASIAN_WIDTH % version,
                           DERIVED_CORE_PROPERTIES % version)
 
-    print(len(filter(None, unicode.table)), "characters")
+    print(len(list(filter(None, unicode.table))), "characters")
 
     for version in old_versions:
         print("--- Reading", UNICODE_DATA % ("-"+version), "...")
@@ -79,7 +80,7 @@
                                   COMPOSITION_EXCLUSIONS % ("-"+version),
                                   EASTASIAN_WIDTH % ("-"+version),
                                   DERIVED_CORE_PROPERTIES % ("-"+version))
-        print(len(filter(None, old_unicode.table)), "characters")
+        print(len(list(filter(None, old_unicode.table))), "characters")
         merge_old_version(version, unicode, old_unicode)
 
     makeunicodename(unicode, trace)
@@ -371,6 +372,10 @@
                 flags |= TITLE_MASK
             if category == "Lu":
                 flags |= UPPER_MASK
+            if category[0] == "C":
+                flags |= NONPRINTABLE_MASK
+            if category[0] == "Z" and char != " ":
+                flags |= NONPRINTABLE_MASK
             if "XID_Start" in properties:
                 flags |= XID_START_MASK
             if "XID_Continue" in properties:
@@ -465,7 +470,7 @@
             if name and name[0] != "<":
                 names[char] = name + chr(0)
 
-    print(len(n for n in names if n is not None), "distinct names")
+    print(len(list(n for n in names if n is not None)), "distinct names")
 
     # collect unique words from names (note that we differ between
     # words inside a sentence, and words ending a sentence.  the

From ncoghlan at gmail.com  Wed Jun  4 14:50:38 2008
From: ncoghlan at gmail.com (Nick Coghlan)
Date: Wed, 04 Jun 2008 22:50:38 +1000
Subject: [Python-3000-checkins] r63934 - in
 python/branches/py3k:	Doc/c-api/unicode.rst
 Doc/library/functions.rst	Doc/library/stdtypes.rst
 Doc/library/sys.rst	Doc/using/cmdline.rst
 Include/pydebug.h	Include/unicodeobject.h Lib/doctest.py
 Lib/test/test_array.py Lib/test/test_builtin.py
 Lib/test/test_exceptions.py	Lib/test/test_format.py
 Lib/test/test_pyexpat.py	Lib/test/test_unicode.py	Mac/BuildScript/scripts/postflight.framework
 Mac/Makefile.in	Makefile.pre.in Misc/NEWS Misc/build.sh
 Misc/cheatsheet	Misc/python.man Misc/valgrind-python.supp
 Modules/main.c	Objects/unicodectype.c Objects/unicodeobject.c
 Objects/unicodetype_db.h PC/VC6/rt.bat PC/VS7.1/rt.bat	PC/VS8.0/rt.bat
 PC/os2emx/Makefile PC/os2emx/python26.def	PC/os2vacpp/python.def
 PCbuild/rt.bat Parser/parsetok.c Python/bltinmodule.c
 Python/sysmodule.c	Tools/unicode/makeunicodedata.py
In-Reply-To: <20080604114134.CEDD71E4007@bag.python.org>
References: <20080604114134.CEDD71E4007@bag.python.org>
Message-ID: <48468F9E.8040305@gmail.com>

georg.brandl wrote:

> Author: georg.brandl
> Date: Wed Jun  4 13:41:32 2008
> New Revision: 63934
> 
> Log:
> Remove meaning of -ttt, but still accept -t option on cmdline for compatibility.

Hmm, given this checkin comment... did you actually mean to commit the 
PEP 3138 implementation?

It may be worth reverting this one and splitting the two checkins :)

Some comments on the PEP 3138 documentation anyway:

> +.. cfunction:: int Py_UNICODE_ISPRINTABLE(Py_UNICODE ch)
> +
> +   Return 1 or 0 depending on whether *ch* is a printable character.
> +   Characters defined in the Unicode character database as "Other"
> +   or "Separator" other than ASCII space(0x20) are not considered
> +   printable.

It may be worth putting something in parentheses along the lines of:

"""(Note that printable characters in this context are those which 
should not be escaped when repr() is invoked on a string. It has no 
bearing on the handling of strings written to sys.stdout or sys.stderr)"""

> +.. function:: ascii(object)
> +
> +   As :func:`repr`, return a string containing a printable
> +   representation of an object. But unlike :func:`repr`, the non-ASCII
> +   characters in the string returned by :func:`ascii`() are hex-escaped
> +   to generate a same string as :func:`repr` in Python 2.

Perhaps the following for that last line:

"""to generate a similar string to that returned by :func:`repr` in 
Python 2."""

> +.. method:: str.isprintable()
> +
> +   Return true if all characters in the string are printable and there is at
> +   least one character, false otherwise. Characters defined in the Unicode 
> +   character database as "Other" or "Separator" other than ASCII space(0x20) are 
> +   not considered printable.

See comment above for the corresponding C API documentation.

Cheers,
Nick.

-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia
---------------------------------------------------------------
             http://www.boredomandlaziness.org

From python-3000-checkins at python.org  Wed Jun  4 15:01:31 2008
From: python-3000-checkins at python.org (georg.brandl)
Date: Wed,  4 Jun 2008 15:01:31 +0200 (CEST)
Subject: [Python-3000-checkins] r63935 - in python/branches/py3k:
	Doc/c-api/unicode.rst Doc/library/functions.rst
	Doc/library/stdtypes.rst Doc/library/sys.rst
	Doc/using/cmdline.rst Include/pydebug.h
	Include/unicodeobject.h Lib/doctest.py Lib/test/test_array.py
	Lib/test/test_builtin.py Lib/test/test_exceptions.py
	Lib/test/test_format.py Lib/test/test_pyexpat.py
	Lib/test/test_unicode.py
	Mac/BuildScript/scripts/postflight.framework Mac/Makefile.in
	Makefile.pre.in Misc/NEWS Misc/build.sh Misc/cheatsheet
	Misc/python.man Misc/valgrind-python.supp Modules/main.c
	Objects/unicodectype.c Objects/unicodeobject.c
	Objects/unicodetype_db.h PC/VC6/rt.bat PC/VS7.1/rt.bat
	PC/VS8.0/rt.bat PC/os2emx/Makefile PC/os2emx/python26.def
	PC/os2vacpp/python.def PCbuild/rt.bat Parser/parsetok.c
	Python/bltinmodule.c Python/sysmodule.c
	Tools/unicode/makeunicodedata.py
Message-ID: <20080604130131.ED3AD1E401B@bag.python.org>

Author: georg.brandl
Date: Wed Jun  4 15:01:30 2008
New Revision: 63935

Log:
Revert r63934 -- it was mixing two patches.


Modified:
   python/branches/py3k/Doc/c-api/unicode.rst
   python/branches/py3k/Doc/library/functions.rst
   python/branches/py3k/Doc/library/stdtypes.rst
   python/branches/py3k/Doc/library/sys.rst
   python/branches/py3k/Doc/using/cmdline.rst
   python/branches/py3k/Include/pydebug.h
   python/branches/py3k/Include/unicodeobject.h
   python/branches/py3k/Lib/doctest.py
   python/branches/py3k/Lib/test/test_array.py
   python/branches/py3k/Lib/test/test_builtin.py
   python/branches/py3k/Lib/test/test_exceptions.py
   python/branches/py3k/Lib/test/test_format.py
   python/branches/py3k/Lib/test/test_pyexpat.py
   python/branches/py3k/Lib/test/test_unicode.py
   python/branches/py3k/Mac/BuildScript/scripts/postflight.framework
   python/branches/py3k/Mac/Makefile.in
   python/branches/py3k/Makefile.pre.in
   python/branches/py3k/Misc/NEWS
   python/branches/py3k/Misc/build.sh
   python/branches/py3k/Misc/cheatsheet
   python/branches/py3k/Misc/python.man
   python/branches/py3k/Misc/valgrind-python.supp
   python/branches/py3k/Modules/main.c
   python/branches/py3k/Objects/unicodectype.c
   python/branches/py3k/Objects/unicodeobject.c
   python/branches/py3k/Objects/unicodetype_db.h
   python/branches/py3k/PC/VC6/rt.bat
   python/branches/py3k/PC/VS7.1/rt.bat
   python/branches/py3k/PC/VS8.0/rt.bat
   python/branches/py3k/PC/os2emx/Makefile
   python/branches/py3k/PC/os2emx/python26.def
   python/branches/py3k/PC/os2vacpp/python.def
   python/branches/py3k/PCbuild/rt.bat
   python/branches/py3k/Parser/parsetok.c
   python/branches/py3k/Python/bltinmodule.c
   python/branches/py3k/Python/sysmodule.c
   python/branches/py3k/Tools/unicode/makeunicodedata.py

Modified: python/branches/py3k/Doc/c-api/unicode.rst
==============================================================================
--- python/branches/py3k/Doc/c-api/unicode.rst	(original)
+++ python/branches/py3k/Doc/c-api/unicode.rst	Wed Jun  4 15:01:30 2008
@@ -144,13 +144,6 @@
 
    Return 1 or 0 depending on whether *ch* is an alphanumeric character.
 
-.. cfunction:: int Py_UNICODE_ISPRINTABLE(Py_UNICODE ch)
-
-   Return 1 or 0 depending on whether *ch* is a printable character.
-   Characters defined in the Unicode character database as "Other"
-   or "Separator" other than ASCII space(0x20) are not considered
-   printable.
-
 These APIs can be used for fast direct character conversions:
 
 
@@ -235,9 +228,6 @@
    +===================+=====================+================================+
    | :attr:`%%`        | *n/a*               | The literal % character.       |
    +-------------------+---------------------+--------------------------------+
-   | :attr:`%a`        | PyObject\*          | The result of calling          |
-   |                   |                     | :func:`ascii`.                 |
-   +-------------------+---------------------+--------------------------------+
    | :attr:`%c`        | int                 | A single character,            |
    |                   |                     | represented as an C int.       |
    +-------------------+---------------------+--------------------------------+

Modified: python/branches/py3k/Doc/library/functions.rst
==============================================================================
--- python/branches/py3k/Doc/library/functions.rst	(original)
+++ python/branches/py3k/Doc/library/functions.rst	Wed Jun  4 15:01:30 2008
@@ -91,14 +91,6 @@
           return False
 
 
-.. function:: ascii(object)
-
-   As :func:`repr`, return a string containing a printable
-   representation of an object. But unlike :func:`repr`, the non-ASCII
-   characters in the string returned by :func:`ascii`() are hex-escaped
-   to generate a same string as :func:`repr` in Python 2.
-
-
 .. function:: bin(x)
 
    Convert an integer number to a binary string. The result is a valid Python

Modified: python/branches/py3k/Doc/library/stdtypes.rst
==============================================================================
--- python/branches/py3k/Doc/library/stdtypes.rst	(original)
+++ python/branches/py3k/Doc/library/stdtypes.rst	Wed Jun  4 15:01:30 2008
@@ -774,14 +774,6 @@
    least one cased character, false otherwise.
 
 
-.. method:: str.isprintable()
-
-   Return true if all characters in the string are printable and there is at
-   least one character, false otherwise. Characters defined in the Unicode 
-   character database as "Other" or "Separator" other than ASCII space(0x20) are 
-   not considered printable.
-
-
 .. method:: str.isspace()
 
    Return true if there are only whitespace characters in the string and there is

Modified: python/branches/py3k/Doc/library/sys.rst
==============================================================================
--- python/branches/py3k/Doc/library/sys.rst	(original)
+++ python/branches/py3k/Doc/library/sys.rst	Wed Jun  4 15:01:30 2008
@@ -231,6 +231,8 @@
    +------------------------------+------------------------------------------+
    | :const:`ignore_environment`  | -E                                       |
    +------------------------------+------------------------------------------+
+   | :const:`tabcheck`            | -t or -tt                                |
+   +------------------------------+------------------------------------------+
    | :const:`verbose`             | -v                                       |
    +------------------------------+------------------------------------------+
    | :const:`unicode`             | -U                                       |

Modified: python/branches/py3k/Doc/using/cmdline.rst
==============================================================================
--- python/branches/py3k/Doc/using/cmdline.rst	(original)
+++ python/branches/py3k/Doc/using/cmdline.rst	Wed Jun  4 15:01:30 2008
@@ -222,6 +222,13 @@
    manipulations of :data:`sys.path` that it entails.
 
 
+.. cmdoption:: -t
+
+   Issue a warning when a source file mixes tabs and spaces for indentation in a
+   way that makes it depend on the worth of a tab expressed in spaces.  Issue an
+   error when the option is given twice (:option:`-tt`).
+
+
 .. cmdoption:: -u
    
    Force stdin, stdout and stderr to be totally unbuffered.  On systems where it

Modified: python/branches/py3k/Include/pydebug.h
==============================================================================
--- python/branches/py3k/Include/pydebug.h	(original)
+++ python/branches/py3k/Include/pydebug.h	Wed Jun  4 15:01:30 2008
@@ -14,6 +14,7 @@
 PyAPI_DATA(int) Py_BytesWarningFlag;
 PyAPI_DATA(int) Py_UseClassExceptionsFlag;
 PyAPI_DATA(int) Py_FrozenFlag;
+PyAPI_DATA(int) Py_TabcheckFlag;
 PyAPI_DATA(int) Py_IgnoreEnvironmentFlag;
 PyAPI_DATA(int) Py_DivisionWarningFlag;
 PyAPI_DATA(int) Py_DontWriteBytecodeFlag;

Modified: python/branches/py3k/Include/unicodeobject.h
==============================================================================
--- python/branches/py3k/Include/unicodeobject.h	(original)
+++ python/branches/py3k/Include/unicodeobject.h	Wed Jun  4 15:01:30 2008
@@ -217,7 +217,6 @@
 # define _PyUnicode_IsLinebreak _PyUnicodeUCS2_IsLinebreak
 # define _PyUnicode_IsLowercase _PyUnicodeUCS2_IsLowercase
 # define _PyUnicode_IsNumeric _PyUnicodeUCS2_IsNumeric
-# define _PyUnicode_IsPrintable _PyUnicodeUCS2_IsPrintable
 # define _PyUnicode_IsTitlecase _PyUnicodeUCS2_IsTitlecase
 # define _PyUnicode_IsXidStart _PyUnicodeUCS2_IsXidStart
 # define _PyUnicode_IsXidContinue _PyUnicodeUCS2_IsXidContinue
@@ -312,7 +311,6 @@
 # define _PyUnicode_IsLinebreak _PyUnicodeUCS4_IsLinebreak
 # define _PyUnicode_IsLowercase _PyUnicodeUCS4_IsLowercase
 # define _PyUnicode_IsNumeric _PyUnicodeUCS4_IsNumeric
-# define _PyUnicode_IsPrintable _PyUnicodeUCS4_IsPrintable
 # define _PyUnicode_IsTitlecase _PyUnicodeUCS4_IsTitlecase
 # define _PyUnicode_IsXidStart _PyUnicodeUCS4_IsXidStart
 # define _PyUnicode_IsXidContinue _PyUnicodeUCS4_IsXidContinue
@@ -353,7 +351,6 @@
 #define Py_UNICODE_ISDECIMAL(ch) _PyUnicode_IsDecimalDigit(ch)
 #define Py_UNICODE_ISDIGIT(ch) _PyUnicode_IsDigit(ch)
 #define Py_UNICODE_ISNUMERIC(ch) _PyUnicode_IsNumeric(ch)
-#define Py_UNICODE_ISPRINTABLE(ch) _PyUnicode_IsPrintable(ch)
 
 #define Py_UNICODE_TODECIMAL(ch) _PyUnicode_ToDecimalDigit(ch)
 #define Py_UNICODE_TODIGIT(ch) _PyUnicode_ToDigit(ch)
@@ -384,7 +381,6 @@
 #define Py_UNICODE_ISDECIMAL(ch) _PyUnicode_IsDecimalDigit(ch)
 #define Py_UNICODE_ISDIGIT(ch) _PyUnicode_IsDigit(ch)
 #define Py_UNICODE_ISNUMERIC(ch) _PyUnicode_IsNumeric(ch)
-#define Py_UNICODE_ISPRINTABLE(ch) _PyUnicode_IsPrintable(ch)
 
 #define Py_UNICODE_TODECIMAL(ch) _PyUnicode_ToDecimalDigit(ch)
 #define Py_UNICODE_TODIGIT(ch) _PyUnicode_ToDigit(ch)
@@ -1503,10 +1499,6 @@
     Py_UNICODE ch 	/* Unicode character */
     );
 
-PyAPI_FUNC(int) _PyUnicode_IsPrintable(
-    Py_UNICODE ch 	/* Unicode character */
-    );
-
 PyAPI_FUNC(int) _PyUnicode_IsAlpha(
     Py_UNICODE ch 	/* Unicode character */
     );

Modified: python/branches/py3k/Lib/doctest.py
==============================================================================
--- python/branches/py3k/Lib/doctest.py	(original)
+++ python/branches/py3k/Lib/doctest.py	Wed Jun  4 15:01:30 2008
@@ -1441,13 +1441,6 @@
     and returns true if they match; and `output_difference`, which
     returns a string describing the differences between two outputs.
     """
-
-    def _toAscii(self, s):
-        """
-        Convert string to hex-escaped ASCII string.
-        """
-        return str(s.encode('ASCII', 'backslashreplace'), "ASCII")
-
     def check_output(self, want, got, optionflags):
         """
         Return True iff the actual output from an example (`got`)
@@ -1458,15 +1451,6 @@
         documentation for `TestRunner` for more information about
         option flags.
         """
-
-        # If `want` contains hex-escaped character such as "\u1234",
-        # then `want` is a string of six characters(e.g. [\,u,1,2,3,4]).
-        # On the other hand, `got` could be an another sequence of
-        # characters such as [\u1234], so `want` and `got` should
-        # be folded to hex-escaped ASCII string to compare.
-        got = self._toAscii(got)
-        want = self._toAscii(want)
-
         # Handle the common case first, for efficiency:
         # if they're string-identical, always return true.
         if got == want:

Modified: python/branches/py3k/Lib/test/test_array.py
==============================================================================
--- python/branches/py3k/Lib/test/test_array.py	(original)
+++ python/branches/py3k/Lib/test/test_array.py	Wed Jun  4 15:01:30 2008
@@ -768,7 +768,7 @@
         a = array.array('u', s)
         self.assertEqual(
             repr(a),
-            "array('u', '\\x00=\"\\'a\\\\b\\x80\xff\\x00\\x01\u1234')")
+            "array('u', '\\x00=\"\\'a\\\\b\\x80\\xff\\x00\\x01\\u1234')")
 
         self.assertRaises(TypeError, a.fromunicode)
 

Modified: python/branches/py3k/Lib/test/test_builtin.py
==============================================================================
--- python/branches/py3k/Lib/test/test_builtin.py	(original)
+++ python/branches/py3k/Lib/test/test_builtin.py	Wed Jun  4 15:01:30 2008
@@ -159,9 +159,6 @@
         S = [10, 20, 30]
         self.assertEqual(any(x > 42 for x in S), False)
 
-    def test_ascii(self):
-        self.assertEqual(ascii("\u0370"), "'\\u0370'")
-
     def test_neg(self):
         x = -sys.maxsize-1
         self.assert_(isinstance(x, int))

Modified: python/branches/py3k/Lib/test/test_exceptions.py
==============================================================================
--- python/branches/py3k/Lib/test/test_exceptions.py	(original)
+++ python/branches/py3k/Lib/test/test_exceptions.py	Wed Jun  4 15:01:30 2008
@@ -80,10 +80,10 @@
         self.raise_catch(IndentationError, "IndentationError")
 
         self.raise_catch(TabError, "TabError")
-        try: compile("try:\n\t1/0\n    \t1/0\nfinally:\n pass\n",
-                     '<string>', 'exec')
-        except TabError: pass
-        else: self.fail("TabError not raised")
+        # can only be tested under -tt, and is the only test for -tt
+        #try: compile("try:\n\t1/0\n    \t1/0\nfinally:\n pass\n", '<string>', 'exec')
+        #except TabError: pass
+        #else: self.fail("TabError not raised")
 
         self.raise_catch(SystemError, "SystemError")
 

Modified: python/branches/py3k/Lib/test/test_format.py
==============================================================================
--- python/branches/py3k/Lib/test/test_format.py	(original)
+++ python/branches/py3k/Lib/test/test_format.py	Wed Jun  4 15:01:30 2008
@@ -216,8 +216,6 @@
         testformat("%o", 0o42, "42")
         testformat("%o", -0o42, "-42")
         testformat("%o", float(0o42), "42")
-        testformat("%r", "\u0370", "'\u0370'")
-        testformat("%a", "\u0370", "'\\u0370'")
         # Test exception for unknown format characters
         if verbose:
             print('Testing exceptions')
@@ -237,8 +235,8 @@
                 raise
             else:
                 raise TestFailed('did not get expected exception: %s' % excmsg)
-        test_exc('abc %b', 1, ValueError,
-                 "unsupported format character 'b' (0x62) at index 5")
+        test_exc('abc %a', 1, ValueError,
+                 "unsupported format character 'a' (0x61) at index 5")
         #test_exc(unicode('abc %\u3000','raw-unicode-escape'), 1, ValueError,
         #         "unsupported format character '?' (0x3000) at index 5")
         test_exc('%d', '1', TypeError, "%d format: a number is required, not str")

Modified: python/branches/py3k/Lib/test/test_pyexpat.py
==============================================================================
--- python/branches/py3k/Lib/test/test_pyexpat.py	(original)
+++ python/branches/py3k/Lib/test/test_pyexpat.py	Wed Jun  4 15:01:30 2008
@@ -131,7 +131,7 @@
         self.assertEquals(op[1], "Comment: ' comment data '")
         self.assertEquals(op[2], "Notation declared: ('notation', None, 'notation.jpeg', None)")
         self.assertEquals(op[3], "Unparsed entity decl: ('unparsed_entity', None, 'entity.file', None, 'notation')")
-        self.assertEquals(op[4], "Start element: 'root' {'attr1': 'value1', 'attr2': 'value2\u1f40'}")
+        self.assertEquals(op[4], "Start element: 'root' {'attr1': 'value1', 'attr2': 'value2\\u1f40'}")
         self.assertEquals(op[5], "NS decl: 'myns' 'http://www.python.org/namespace'")
         self.assertEquals(op[6], "Start element: 'http://www.python.org/namespace!subelement' {}")
         self.assertEquals(op[7], "Character data: 'Contents of subelements'")

Modified: python/branches/py3k/Lib/test/test_unicode.py
==============================================================================
--- python/branches/py3k/Lib/test/test_unicode.py	(original)
+++ python/branches/py3k/Lib/test/test_unicode.py	Wed Jun  4 15:01:30 2008
@@ -94,14 +94,14 @@
                 "JKLMNOPQRSTUVWXYZ[\\\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\\x7f"
                 "\\x80\\x81\\x82\\x83\\x84\\x85\\x86\\x87\\x88\\x89\\x8a\\x8b\\x8c\\x8d"
                 "\\x8e\\x8f\\x90\\x91\\x92\\x93\\x94\\x95\\x96\\x97\\x98\\x99\\x9a\\x9b"
-                "\\x9c\\x9d\\x9e\\x9f\\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9"
-                "\xaa\xab\xac\\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
-                "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5"
-                "\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3"
-                "\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1"
-                "\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef"
-                "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd"
-                "\xfe\xff'")
+                "\\x9c\\x9d\\x9e\\x9f\\xa0\\xa1\\xa2\\xa3\\xa4\\xa5\\xa6\\xa7\\xa8\\xa9"
+                "\\xaa\\xab\\xac\\xad\\xae\\xaf\\xb0\\xb1\\xb2\\xb3\\xb4\\xb5\\xb6\\xb7"
+                "\\xb8\\xb9\\xba\\xbb\\xbc\\xbd\\xbe\\xbf\\xc0\\xc1\\xc2\\xc3\\xc4\\xc5"
+                "\\xc6\\xc7\\xc8\\xc9\\xca\\xcb\\xcc\\xcd\\xce\\xcf\\xd0\\xd1\\xd2\\xd3"
+                "\\xd4\\xd5\\xd6\\xd7\\xd8\\xd9\\xda\\xdb\\xdc\\xdd\\xde\\xdf\\xe0\\xe1"
+                "\\xe2\\xe3\\xe4\\xe5\\xe6\\xe7\\xe8\\xe9\\xea\\xeb\\xec\\xed\\xee\\xef"
+                "\\xf0\\xf1\\xf2\\xf3\\xf4\\xf5\\xf6\\xf7\\xf8\\xf9\\xfa\\xfb\\xfc\\xfd"
+                "\\xfe\\xff'")
             testrepr = repr(''.join(map(chr, range(256))))
             self.assertEqual(testrepr, latin1repr)
             # Test repr works on wide unicode escapes without overflow.
@@ -374,12 +374,6 @@
         self.assertFalse("[".isidentifier())
         self.assertFalse("?".isidentifier())
 
-    def test_isprintable(self):
-        self.assertTrue("abcdefg".isprintable())
-        self.assertFalse("abcdefg\n".isprintable())
-        self.assertTrue("\u0370".isprintable())
-        self.assertFalse("\ud800".isprintable())
-
     def test_contains(self):
         # Testing Unicode contains method
         self.assert_('a' in 'abdb')

Modified: python/branches/py3k/Mac/BuildScript/scripts/postflight.framework
==============================================================================
--- python/branches/py3k/Mac/BuildScript/scripts/postflight.framework	(original)
+++ python/branches/py3k/Mac/BuildScript/scripts/postflight.framework	Wed Jun  4 15:01:30 2008
@@ -6,22 +6,22 @@
 PYVER="@PYVER@"
 FWK="/Library/Frameworks/Python.framework/Versions/@PYVER@"
 
-"${FWK}/bin/python" -Wi \
+"${FWK}/bin/python" -Wi -tt \
     "${FWK}/lib/python${PYVER}/compileall.py" \
     -x badsyntax -x site-packages \
     "${FWK}/lib/python${PYVER}"
 
-"${FWK}/bin/python" -Wi -O \
+"${FWK}/bin/python" -Wi -tt -O \
     "${FWK}/lib/python${PYVER}/compileall.py" \
     -x badsyntax -x site-packages \
     "${FWK}/lib/python${PYVER}"
 
-"${FWK}/bin/python" -Wi \
+"${FWK}/bin/python" -Wi -tt \
     "${FWK}/lib/python${PYVER}/compileall.py" \
     -x badsyntax -x site-packages \
     "${FWK}/Mac/Tools"
 
-"${FWK}/bin/python" -Wi -O \
+"${FWK}/bin/python" -Wi -tt -O \
     "${FWK}/lib/python${PYVER}/compileall.py" \
     -x badsyntax -x site-packages \
     "${FWK}/Mac/Tools"

Modified: python/branches/py3k/Mac/Makefile.in
==============================================================================
--- python/branches/py3k/Mac/Makefile.in	(original)
+++ python/branches/py3k/Mac/Makefile.in	Wed Jun  4 15:01:30 2008
@@ -226,8 +226,8 @@
 
 
 	$(RUNSHARED) $(BUILDPYTHON) $(CACHERSRC) -v $(DESTDIR)$(MACLIBDEST) $(DESTDIR)$(MACTOOLSDEST)
-	$(RUNSHARED) $(BUILDPYTHON) -Wi $(compileall) -d $(MACTOOLSDEST) -x badsyntax $(DESTDIR)$(MACTOOLSDEST)
-	$(RUNSHARED) $(BUILDPYTHON) -O -Wi $(compileall) -d $(MACTOOLSDEST) -x badsyntax $(DESTDIR)$(MACTOOLSDEST)
+	$(RUNSHARED) $(BUILDPYTHON) -Wi -tt $(compileall) -d $(MACTOOLSDEST) -x badsyntax $(DESTDIR)$(MACTOOLSDEST)
+	$(RUNSHARED) $(BUILDPYTHON) -O -Wi -tt $(compileall) -d $(MACTOOLSDEST) -x badsyntax $(DESTDIR)$(MACTOOLSDEST)
 
 $(INSTALLED_PYTHONAPP): install_Python
 

Modified: python/branches/py3k/Makefile.pre.in
==============================================================================
--- python/branches/py3k/Makefile.pre.in	(original)
+++ python/branches/py3k/Makefile.pre.in	Wed Jun  4 15:01:30 2008
@@ -664,7 +664,7 @@
 
 TESTOPTS=	-l $(EXTRATESTOPTS)
 TESTPROG=	$(srcdir)/Lib/test/regrtest.py
-TESTPYTHON=	$(RUNSHARED) ./$(BUILDPYTHON) -E -bb
+TESTPYTHON=	$(RUNSHARED) ./$(BUILDPYTHON) -E -tt -bb
 test:		all platform
 		-find $(srcdir)/Lib -name '*.py[co]' -print | xargs rm -f
 		-$(TESTPYTHON) $(TESTPROG) $(TESTOPTS)
@@ -687,7 +687,7 @@
 		-find $(srcdir)/Lib -name '*.py[co]' -print | xargs rm -f
 		-$(TESTPYTHON) $(TESTPROG) $(TESTOPTS) -uall
 		$(TESTPYTHON) $(TESTPROG) $(TESTOPTS) -uall
-		$(RUNSHARED) /usr/libexec/oah/translate ./$(BUILDPYTHON) -E $(TESTPROG) $(TESTOPTS) -uall
+		$(RUNSHARED) /usr/libexec/oah/translate ./$(BUILDPYTHON) -E -tt $(TESTPROG) $(TESTOPTS) -uall
 
 
 # Like testall, but with a single pass only
@@ -872,23 +872,23 @@
 	done
 	$(INSTALL_DATA) $(srcdir)/LICENSE $(DESTDIR)$(LIBDEST)/LICENSE.txt
 	-PYTHONPATH=$(DESTDIR)$(LIBDEST)  $(RUNSHARED) \
-		./$(BUILDPYTHON) -Wi $(DESTDIR)$(LIBDEST)/compileall.py \
+		./$(BUILDPYTHON) -Wi -tt $(DESTDIR)$(LIBDEST)/compileall.py \
 		-d $(LIBDEST) -f \
 		-x 'bad_coding|badsyntax|site-packages' $(DESTDIR)$(LIBDEST)
 	-PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
-		./$(BUILDPYTHON) -Wi -O $(DESTDIR)$(LIBDEST)/compileall.py \
+		./$(BUILDPYTHON) -Wi -tt -O $(DESTDIR)$(LIBDEST)/compileall.py \
 		-d $(LIBDEST) -f \
 		-x 'bad_coding|badsyntax|site-packages' $(DESTDIR)$(LIBDEST)
 	-PYTHONPATH=$(DESTDIR)$(LIBDEST)  $(RUNSHARED) \
-		./$(BUILDPYTHON) -Wi $(DESTDIR)$(LIBDEST)/compileall.py \
+		./$(BUILDPYTHON) -Wi -t $(DESTDIR)$(LIBDEST)/compileall.py \
 		-d $(LIBDEST)/site-packages -f \
 		-x badsyntax $(DESTDIR)$(LIBDEST)/site-packages
 	-PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
-		./$(BUILDPYTHON) -Wi -O $(DESTDIR)$(LIBDEST)/compileall.py \
+		./$(BUILDPYTHON) -Wi -t -O $(DESTDIR)$(LIBDEST)/compileall.py \
 		-d $(LIBDEST)/site-packages -f \
 		-x badsyntax $(DESTDIR)$(LIBDEST)/site-packages
 	-PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
-		./$(BUILDPYTHON) -Wi -c "import lib2to3.pygram"
+		./$(BUILDPYTHON) -Wi -t -c "import lib2to3.pygram"
 
 # Create the PLATDIR source directory, if one wasn't distributed..
 $(srcdir)/Lib/$(PLATDIR):

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Wed Jun  4 15:01:30 2008
@@ -12,8 +12,6 @@
 Core and Builtins
 -----------------
 
-- Removed the already-defunct ``-t`` option.
-
 - Issue #2957: Corrected a ValueError "recursion limit exceeded", when
   unmarshalling many code objects, which happens when importing a
   large .pyc file (~1000 functions).

Modified: python/branches/py3k/Misc/build.sh
==============================================================================
--- python/branches/py3k/Misc/build.sh	(original)
+++ python/branches/py3k/Misc/build.sh	Wed Jun  4 15:01:30 2008
@@ -59,7 +59,7 @@
 PYTHON=$INSTALL_DIR/bin/python
 
 # Python options and regression test program that should always be run.
-REGRTEST_ARGS="-E $INSTALL_DIR/lib/python3.0/test/regrtest.py"
+REGRTEST_ARGS="-E -tt $INSTALL_DIR/lib/python3.0/test/regrtest.py"
 
 REFLOG="build/reflog.txt.out"
 # These tests are not stable and falsely report leaks sometimes.

Modified: python/branches/py3k/Misc/cheatsheet
==============================================================================
--- python/branches/py3k/Misc/cheatsheet	(original)
+++ python/branches/py3k/Misc/cheatsheet	Wed Jun  4 15:01:30 2008
@@ -46,6 +46,7 @@
 -OO     remove doc-strings in addition to the -O optimizations
 -Q arg  division options: -Qold (default), -Qwarn, -Qwarnall, -Qnew
 -S      Don't perform 'import site' on initialization
+-t      Issue warnings about inconsistent tab usage (-tt: issue errors)
 -u      Unbuffered binary stdout and stderr (also PYTHONUNBUFFERED=x).
 -v      Verbose (trace import statements) (also PYTHONVERBOSE=x)
 -W arg : warning control (arg is action:message:category:module:lineno)

Modified: python/branches/py3k/Misc/python.man
==============================================================================
--- python/branches/py3k/Misc/python.man	(original)
+++ python/branches/py3k/Misc/python.man	Wed Jun  4 15:01:30 2008
@@ -35,6 +35,9 @@
 .B \-S
 ]
 [
+.B \-t
+]
+[
 .B \-u
 ]
 .br
@@ -141,6 +144,11 @@
 .I sys.path
 that it entails.
 .TP
+.B \-t
+Issue a warning when a source file mixes tabs and spaces for
+indentation in a way that makes it depend on the worth of a tab
+expressed in spaces.  Issue an error when the option is given twice.
+.TP
 .B \-u
 Force stdin, stdout and stderr to be totally unbuffered.  On systems
 where it matters, also put stdin, stdout and stderr in binary mode.

Modified: python/branches/py3k/Misc/valgrind-python.supp
==============================================================================
--- python/branches/py3k/Misc/valgrind-python.supp	(original)
+++ python/branches/py3k/Misc/valgrind-python.supp	Wed Jun  4 15:01:30 2008
@@ -5,7 +5,7 @@
 #
 #	cd python/dist/src
 #	valgrind --tool=memcheck --suppressions=Misc/valgrind-python.supp \
-#		./python -E ./Lib/test/regrtest.py -u bsddb,network
+#		./python -E -tt ./Lib/test/regrtest.py -u bsddb,network
 #
 # You must edit Objects/obmalloc.c and uncomment Py_USING_MEMORY_DEBUGGER
 # to use the preferred suppressions with Py_ADDRESS_IN_RANGE.

Modified: python/branches/py3k/Modules/main.c
==============================================================================
--- python/branches/py3k/Modules/main.c	(original)
+++ python/branches/py3k/Modules/main.c	Wed Jun  4 15:01:30 2008
@@ -72,6 +72,7 @@
 -OO    : remove doc-strings in addition to the -O optimizations\n\
 -s     : don't add user site directory to sys.path; also PYTHONNOUSERSITE\n\
 -S     : don't imply 'import site' on initialization\n\
+-t     : issue warnings about inconsistent tab usage (-tt: issue errors)\n\
 ";
 static char *usage_3 = "\
 -u     : unbuffered binary stdout and stderr; also PYTHONUNBUFFERED=x\n\
@@ -369,7 +370,7 @@
 			break;
 
 		case 't':
-			/* ignored for backwards compatibility */
+			Py_TabcheckFlag++;
 			break;
 
 		case 'u':

Modified: python/branches/py3k/Objects/unicodectype.c
==============================================================================
--- python/branches/py3k/Objects/unicodectype.c	(original)
+++ python/branches/py3k/Objects/unicodectype.c	Wed Jun  4 15:01:30 2008
@@ -21,7 +21,6 @@
 #define UPPER_MASK 0x80
 #define XID_START_MASK 0x100
 #define XID_CONTINUE_MASK 0x200
-#define NONPRINTABLE_MASK 0x400
 
 typedef struct {
     const Py_UNICODE upper;
@@ -676,26 +675,6 @@
     return _PyUnicode_ToNumeric(ch) != -1.0;
 }
 
-/* Returns 1 for Unicode characters to be hex-escaped when repr()ed,
-   0 otherwise.
-   Characters defined in the Unicode character database as following
-   categories are not considered printable.
-      * Cc (Other, Control)
-      * Cf (Other, Format)
-      * Cs (Other, Surrogate)
-      * Co (Other, Private Use)
-      * Cn (Other, Not Assigned)
-      * Zl Separator, Line ('\u2028', LINE SEPARATOR)
-      * Zp Separator, Paragraph ('\u2029', PARAGRAPH SEPARATOR)
-      * Zs (Separator, Space) other than ASCII space('\x20').
-*/
-int _PyUnicode_IsPrintable(Py_UNICODE ch)
-{
-    const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
-
-    return (ctype->flags & NONPRINTABLE_MASK) == 0;
-}
-
 #ifndef WANT_WCTYPE_FUNCTIONS
 
 /* Returns 1 for Unicode characters having the bidirectional type

Modified: python/branches/py3k/Objects/unicodeobject.c
==============================================================================
--- python/branches/py3k/Objects/unicodeobject.c	(original)
+++ python/branches/py3k/Objects/unicodeobject.c	Wed Jun  4 15:01:30 2008
@@ -7149,36 +7149,6 @@
     return PyBool_FromLong(PyUnicode_IsIdentifier(self));
 }
 
-PyDoc_STRVAR(isprintable__doc__,
-"S.isprintable() -> bool\n\
-\n\
-Return True if all characters in S are considered\n\
-printable in repr() and there is at least one character\n\
-in S, False otherwise.");
-
-static PyObject*
-unicode_isprintable(PyObject *self)
-{
-    register const Py_UNICODE *p = PyUnicode_AS_UNICODE(self);
-    register const Py_UNICODE *e;
-
-    /* Shortcut for single character strings */
-    if (PyUnicode_GET_SIZE(self) == 1 &&
-	Py_UNICODE_ISPRINTABLE(*p))
-	return PyBool_FromLong(1);
-
-    /* Special case for empty strings */
-    if (PyUnicode_GET_SIZE(self) == 0)
-	return PyBool_FromLong(0);
-
-    e = p + PyUnicode_GET_SIZE(self);
-    for (; p < e; p++) {
-	if (!Py_UNICODE_ISPRINTABLE(*p))
-	    return PyBool_FromLong(0);
-    }
-    return PyBool_FromLong(1);
-}
-
 PyDoc_STRVAR(join__doc__,
 "S.join(sequence) -> str\n\
 \n\
@@ -7556,8 +7526,61 @@
             continue;
         }
 
-	/* Map special whitespace to '\t', \n', '\r' */
-        if (ch == '\t') {
+#ifdef Py_UNICODE_WIDE
+        /* Map 21-bit characters to '\U00xxxxxx' */
+        else if (ch >= 0x10000) {
+            *p++ = '\\';
+            *p++ = 'U';
+            *p++ = hexdigits[(ch >> 28) & 0x0000000F];
+            *p++ = hexdigits[(ch >> 24) & 0x0000000F];
+            *p++ = hexdigits[(ch >> 20) & 0x0000000F];
+            *p++ = hexdigits[(ch >> 16) & 0x0000000F];
+            *p++ = hexdigits[(ch >> 12) & 0x0000000F];
+            *p++ = hexdigits[(ch >> 8) & 0x0000000F];
+            *p++ = hexdigits[(ch >> 4) & 0x0000000F];
+            *p++ = hexdigits[ch & 0x0000000F];
+	    continue;
+        }
+#else
+	/* Map UTF-16 surrogate pairs to '\U00xxxxxx' */
+	else if (ch >= 0xD800 && ch < 0xDC00) {
+	    Py_UNICODE ch2;
+	    Py_UCS4 ucs;
+
+	    ch2 = *s++;
+	    size--;
+	    if (ch2 >= 0xDC00 && ch2 <= 0xDFFF) {
+		ucs = (((ch & 0x03FF) << 10) | (ch2 & 0x03FF)) + 0x00010000;
+		*p++ = '\\';
+		*p++ = 'U';
+		*p++ = hexdigits[(ucs >> 28) & 0x0000000F];
+		*p++ = hexdigits[(ucs >> 24) & 0x0000000F];
+		*p++ = hexdigits[(ucs >> 20) & 0x0000000F];
+		*p++ = hexdigits[(ucs >> 16) & 0x0000000F];
+		*p++ = hexdigits[(ucs >> 12) & 0x0000000F];
+		*p++ = hexdigits[(ucs >> 8) & 0x0000000F];
+		*p++ = hexdigits[(ucs >> 4) & 0x0000000F];
+		*p++ = hexdigits[ucs & 0x0000000F];
+		continue;
+	    }
+	    /* Fall through: isolated surrogates are copied as-is */
+	    s--;
+	    size++;
+	}
+#endif
+
+        /* Map 16-bit characters to '\uxxxx' */
+        if (ch >= 256) {
+            *p++ = '\\';
+            *p++ = 'u';
+            *p++ = hexdigits[(ch >> 12) & 0x000F];
+            *p++ = hexdigits[(ch >> 8) & 0x000F];
+            *p++ = hexdigits[(ch >> 4) & 0x000F];
+            *p++ = hexdigits[ch & 0x000F];
+        }
+
+        /* Map special whitespace to '\t', \n', '\r' */
+        else if (ch == '\t') {
             *p++ = '\\';
             *p++ = 't';
         }
@@ -7571,79 +7594,16 @@
         }
 
         /* Map non-printable US ASCII to '\xhh' */
-        else if (ch < ' ' || ch == 0x7F) {
+        else if (ch < ' ' || ch >= 0x7F) {
             *p++ = '\\';
             *p++ = 'x';
             *p++ = hexdigits[(ch >> 4) & 0x000F];
             *p++ = hexdigits[ch & 0x000F];
         }
 
-        /* Copy ASCII characters as-is */
-        else if (ch < 0x7F) {
-            *p++ = ch;
-        }
-
-	/* Non-ASCII characters */
-        else {
-            Py_UCS4 ucs = ch;
-
-#ifndef Py_UNICODE_WIDE
-            Py_UNICODE ch2 = 0;
-            /* Get code point from surrogate pair */
-            if (size > 0) {
-                ch2 = *s;
-                if (ch >= 0xD800 && ch < 0xDC00 && ch2 >= 0xDC00
-                            && ch2 <= 0xDFFF) {
-                    ucs = (((ch & 0x03FF) << 10) | (ch2 & 0x03FF)) 
-                            + 0x00010000;
-                    s++; 
-                    size--;
-                }
-            }
-#endif
-            /* Map Unicode whitespace and control characters 
-               (categories Z* and C* except ASCII space)
-            */
-            if (!Py_UNICODE_ISPRINTABLE(ucs)) {
-                /* Map 8-bit characters to '\xhh' */
-                if (ucs <= 0xff) {
-                    *p++ = '\\';
-                    *p++ = 'x';
-                    *p++ = hexdigits[(ch >> 4) & 0x000F];
-                    *p++ = hexdigits[ch & 0x000F];
-                }
-                /* Map 21-bit characters to '\U00xxxxxx' */
-                else if (ucs >= 0x10000) {
-                    *p++ = '\\';
-                    *p++ = 'U';
-                    *p++ = hexdigits[(ucs >> 28) & 0x0000000F];
-                    *p++ = hexdigits[(ucs >> 24) & 0x0000000F];
-                    *p++ = hexdigits[(ucs >> 20) & 0x0000000F];
-                    *p++ = hexdigits[(ucs >> 16) & 0x0000000F];
-                    *p++ = hexdigits[(ucs >> 12) & 0x0000000F];
-                    *p++ = hexdigits[(ucs >> 8) & 0x0000000F];
-                    *p++ = hexdigits[(ucs >> 4) & 0x0000000F];
-                    *p++ = hexdigits[ucs & 0x0000000F];
-                }
-                /* Map 16-bit characters to '\uxxxx' */
-                else {
-                    *p++ = '\\';
-                    *p++ = 'u';
-                    *p++ = hexdigits[(ucs >> 12) & 0x000F];
-                    *p++ = hexdigits[(ucs >> 8) & 0x000F];
-                    *p++ = hexdigits[(ucs >> 4) & 0x000F];
-                    *p++ = hexdigits[ucs & 0x000F];
-                }
-            }
-            /* Copy characters as-is */
-            else {
-                *p++ = ch;
-#ifndef Py_UNICODE_WIDE
-                if (ucs >= 0x10000)
-                    *p++ = ch2;
-#endif
-            }
-        }
+        /* Copy everything else as-is */
+        else
+            *p++ = (char) ch;
     }
     /* Add quote */
     *p++ = PyUnicode_AS_UNICODE(repr)[0];
@@ -8308,7 +8268,6 @@
     {"isalpha", (PyCFunction) unicode_isalpha, METH_NOARGS, isalpha__doc__},
     {"isalnum", (PyCFunction) unicode_isalnum, METH_NOARGS, isalnum__doc__},
     {"isidentifier", (PyCFunction) unicode_isidentifier, METH_NOARGS, isidentifier__doc__},
-    {"isprintable", (PyCFunction) unicode_isprintable, METH_NOARGS, isprintable__doc__},
     {"zfill", (PyCFunction) unicode_zfill, METH_VARARGS, zfill__doc__},
     {"format", (PyCFunction) do_string_format, METH_VARARGS | METH_KEYWORDS, format__doc__},
     {"__format__", (PyCFunction) unicode__format__, METH_VARARGS, p_format__doc__},
@@ -8894,7 +8853,6 @@
 
 	    case 's':
 	    case 'r':
-	    case 'a':
 		if (PyUnicode_Check(v) && c == 's') {
 		    temp = v;
 		    Py_INCREF(temp);
@@ -8914,22 +8872,6 @@
 					"%s argument has non-string str()");
 			goto onError;
 		    }
-		    if (c == 'a') {
-		        PyObject *ascii = PyUnicode_EncodeASCII(
-				PyUnicode_AS_UNICODE(temp),
-				PyUnicode_GET_SIZE(temp),
-				"backslashreplace");
-
-			Py_DECREF(temp);
-			if (ascii == NULL) 
-			    goto onError;
-
-			temp = PyUnicode_FromEncodedObject(ascii, 
-				    "ASCII", NULL);
-			Py_DECREF(ascii);
-			if (temp == NULL)
-			    goto onError;
-		    }
 		}
 		pbuf = PyUnicode_AS_UNICODE(temp);
 		len = PyUnicode_GET_SIZE(temp);

Modified: python/branches/py3k/Objects/unicodetype_db.h
==============================================================================
--- python/branches/py3k/Objects/unicodetype_db.h	(original)
+++ python/branches/py3k/Objects/unicodetype_db.h	Wed Jun  4 15:01:30 2008
@@ -1,12 +1,11 @@
-/* this file was generated by Tools\unicode\makeunicodedata.py 2.5 */
+/* this file was generated by Tools/unicode/makeunicodedata.py 2.5 */
 
 /* a list of unique character type descriptors */
 const _PyUnicode_TypeRecord _PyUnicode_TypeRecords[] = {
     {0, 0, 0, 0, 0, 0},
-    {0, 0, 0, 0, 0, 1024},
-    {0, 0, 0, 0, 0, 1056},
-    {0, 0, 0, 0, 0, 1072},
     {0, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 32},
+    {0, 0, 0, 0, 0, 48},
     {0, 0, 0, 0, 0, 518},
     {0, 0, 0, 1, 1, 518},
     {0, 0, 0, 2, 2, 518},
@@ -163,10 +162,10 @@
     21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 46, 21, 21, 21, 21, 47, 8, 8, 
     48, 49, 8, 8, 8, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
     21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
-    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 50, 51, 51, 51, 51, 51, 51, 
-    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
-    51, 51, 51, 51, 51, 51, 51, 51, 51, 21, 52, 53, 54, 55, 56, 57, 58, 59, 
-    8, 60, 61, 8, 8, 8, 62, 8, 63, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 50, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 21, 51, 52, 53, 54, 55, 56, 57, 58, 
+    8, 59, 60, 8, 8, 8, 61, 8, 62, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
@@ -174,8 +173,8 @@
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 64, 65, 66, 67, 68, 69, 70, 
-    71, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 63, 64, 65, 66, 67, 68, 69, 
+    70, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 21, 21, 21, 21, 21, 
     21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
     21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
@@ -185,11 +184,11 @@
     21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
     21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
     21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
-    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 72, 
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 71, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 21, 21, 73, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 21, 21, 72, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
@@ -307,7 +306,7 @@
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 74, 75, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 73, 74, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
@@ -317,143 +316,144 @@
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 51, 51, 51, 51, 51, 
-    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
-    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
-    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
-    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
-    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
-    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
-    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
-    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
-    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
-    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
-    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
-    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
-    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
-    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 76, 51, 
-    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
-    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
-    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
-    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
-    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
-    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
-    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
-    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
-    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
-    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
-    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
-    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
-    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
-    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
-    51, 51, 76, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 75, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
+    32, 32, 75, 
 };
 
 static unsigned char index2[] = {
     1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 2, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 3, 3, 3, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 4, 4, 4, 4, 4, 4, 4, 15, 15, 15, 15, 
+    1, 1, 1, 1, 3, 3, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 1, 1, 1, 1, 1, 1, 14, 14, 14, 14, 
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
+    14, 14, 14, 14, 1, 1, 1, 1, 15, 1, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 17, 1, 1, 
+    1, 1, 1, 1, 1, 18, 19, 1, 20, 1, 15, 1, 21, 17, 1, 1, 1, 1, 1, 14, 14, 
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
+    14, 14, 14, 1, 14, 14, 14, 14, 14, 14, 14, 17, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 1, 
+    16, 16, 16, 16, 16, 16, 16, 22, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
+    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
+    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
+    23, 24, 25, 26, 23, 24, 23, 24, 23, 24, 17, 23, 24, 23, 24, 23, 24, 23, 
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 17, 23, 24, 23, 24, 23, 24, 23, 24, 
+    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
+    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
+    23, 24, 27, 23, 24, 23, 24, 23, 24, 28, 17, 29, 23, 24, 23, 24, 30, 23, 
+    24, 31, 31, 23, 24, 17, 32, 33, 34, 23, 24, 31, 35, 36, 37, 38, 23, 24, 
+    39, 17, 37, 40, 41, 42, 23, 24, 23, 24, 23, 24, 43, 23, 24, 43, 17, 17, 
+    23, 24, 43, 23, 24, 44, 44, 23, 24, 23, 24, 45, 23, 24, 17, 46, 23, 24, 
+    17, 47, 46, 46, 46, 46, 48, 49, 50, 48, 49, 50, 48, 49, 50, 23, 24, 23, 
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 51, 23, 24, 23, 24, 
+    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 17, 48, 49, 50, 
+    23, 24, 52, 53, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
+    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
+    23, 24, 23, 24, 23, 24, 23, 24, 54, 17, 23, 24, 23, 24, 23, 24, 23, 24, 
+    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 17, 17, 17, 17, 17, 17, 55, 23, 
+    24, 56, 55, 17, 17, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 
+    17, 58, 59, 17, 60, 60, 17, 61, 17, 62, 17, 17, 17, 17, 60, 17, 17, 63, 
+    17, 17, 17, 17, 64, 65, 17, 17, 17, 17, 17, 65, 17, 17, 66, 17, 17, 67, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 68, 17, 17, 68, 17, 17, 17, 17, 
+    68, 17, 69, 69, 17, 17, 17, 17, 17, 17, 70, 17, 71, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 1, 1, 1, 1, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 46, 46, 46, 46, 46, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 46, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
     15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
-    15, 15, 15, 15, 4, 4, 4, 4, 16, 4, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
-    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 4, 4, 
-    4, 4, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 18, 4, 4, 
-    1, 4, 4, 4, 4, 19, 20, 4, 21, 4, 16, 4, 22, 18, 4, 4, 4, 4, 4, 15, 15, 
     15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
-    15, 15, 15, 4, 15, 15, 15, 15, 15, 15, 15, 18, 17, 17, 17, 17, 17, 17, 
-    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 4, 
-    17, 17, 17, 17, 17, 17, 17, 23, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
-    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
-    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
-    24, 25, 26, 27, 24, 25, 24, 25, 24, 25, 18, 24, 25, 24, 25, 24, 25, 24, 
-    25, 24, 25, 24, 25, 24, 25, 24, 25, 18, 24, 25, 24, 25, 24, 25, 24, 25, 
-    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
-    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
-    24, 25, 28, 24, 25, 24, 25, 24, 25, 29, 18, 30, 24, 25, 24, 25, 31, 24, 
-    25, 32, 32, 24, 25, 18, 33, 34, 35, 24, 25, 32, 36, 37, 38, 39, 24, 25, 
-    40, 18, 38, 41, 42, 43, 24, 25, 24, 25, 24, 25, 44, 24, 25, 44, 18, 18, 
-    24, 25, 44, 24, 25, 45, 45, 24, 25, 24, 25, 46, 24, 25, 18, 47, 24, 25, 
-    18, 48, 47, 47, 47, 47, 49, 50, 51, 49, 50, 51, 49, 50, 51, 24, 25, 24, 
-    25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 52, 24, 25, 24, 25, 
-    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 18, 49, 50, 51, 
-    24, 25, 53, 54, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
-    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
-    24, 25, 24, 25, 24, 25, 24, 25, 55, 18, 24, 25, 24, 25, 24, 25, 24, 25, 
-    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 18, 18, 18, 18, 18, 18, 56, 24, 
-    25, 57, 56, 18, 18, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 18, 
-    18, 59, 60, 18, 61, 61, 18, 62, 18, 63, 18, 18, 18, 18, 61, 18, 18, 64, 
-    18, 18, 18, 18, 65, 66, 18, 18, 18, 18, 18, 66, 18, 18, 67, 18, 18, 68, 
-    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 69, 18, 18, 69, 18, 18, 18, 18, 
-    69, 18, 70, 70, 18, 18, 18, 18, 18, 18, 71, 18, 72, 18, 18, 18, 18, 18, 
-    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
-    18, 18, 18, 18, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 4, 4, 4, 4, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 47, 47, 47, 47, 47, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 47, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
-    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
-    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
-    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 73, 16, 
-    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 72, 15, 
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
+    15, 15, 15, 15, 15, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 73, 0, 0, 0, 1, 0, 0, 
+    0, 0, 0, 1, 1, 74, 1, 75, 75, 75, 0, 76, 0, 77, 77, 17, 14, 14, 14, 14, 
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 14, 14, 14, 14, 
+    14, 14, 14, 14, 14, 78, 79, 79, 79, 17, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 80, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 81, 82, 82, 0, 83, 84, 55, 55, 55, 85, 86, 17, 23, 24, 23, 24, 23, 
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
+    24, 87, 88, 89, 17, 90, 91, 1, 23, 24, 92, 23, 24, 17, 55, 55, 55, 93, 
+    93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 14, 14, 14, 
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 16, 16, 16, 16, 16, 16, 16, 
     16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
-    16, 16, 16, 16, 16, 0, 0, 0, 0, 4, 4, 0, 0, 0, 0, 74, 0, 0, 0, 4, 0, 0, 
-    0, 0, 0, 4, 4, 75, 4, 76, 76, 76, 0, 77, 0, 78, 78, 18, 15, 15, 15, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 
-    15, 15, 15, 15, 15, 79, 80, 80, 80, 18, 17, 17, 17, 17, 17, 17, 17, 17, 
-    17, 17, 17, 17, 17, 17, 17, 17, 17, 81, 17, 17, 17, 17, 17, 17, 17, 17, 
-    17, 82, 83, 83, 0, 84, 85, 56, 56, 56, 86, 87, 18, 24, 25, 24, 25, 24, 
-    25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 
-    25, 88, 89, 90, 18, 91, 92, 4, 24, 25, 93, 24, 25, 18, 56, 56, 56, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 15, 15, 15, 
+    16, 16, 16, 16, 16, 16, 16, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 
+    88, 88, 88, 88, 88, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
+    24, 23, 24, 1, 15, 15, 15, 15, 0, 1, 1, 23, 24, 23, 24, 23, 24, 23, 24, 
+    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
+    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
+    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 55, 23, 24, 23, 24, 23, 24, 23, 
+    24, 23, 24, 23, 24, 23, 24, 0, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
+    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
+    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 0, 0, 0, 0, 0, 0, 
+    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
+    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
+    94, 94, 94, 94, 94, 94, 0, 0, 46, 1, 1, 1, 1, 1, 1, 0, 95, 95, 95, 95, 
+    95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 
+    95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 17, 0, 1, 
+    1, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
     15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 17, 17, 17, 17, 17, 17, 17, 
-    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
-    17, 17, 17, 17, 17, 17, 17, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 
-    89, 89, 89, 89, 89, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 
-    25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 
-    25, 24, 25, 4, 16, 16, 16, 16, 0, 4, 4, 24, 25, 24, 25, 24, 25, 24, 25, 
-    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
-    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
-    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 56, 24, 25, 24, 25, 24, 25, 24, 
-    25, 24, 25, 24, 25, 24, 25, 0, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
-    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
-    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 0, 0, 0, 0, 0, 0, 
-    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 0, 0, 0, 
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 1, 15, 1, 15, 15, 
+    1, 15, 15, 1, 15, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 0, 0, 0, 0, 0, 46, 46, 46, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 
+    1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 15, 15, 15, 15, 15, 15, 0, 
+    0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 
+    0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 15, 15, 15, 15, 15, 15, 
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 4, 5, 6, 7, 8, 
+    9, 10, 11, 12, 13, 1, 1, 1, 1, 46, 46, 15, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 1, 46, 15, 15, 15, 15, 15, 15, 15, 1, 1, 15, 15, 15, 15, 15, 15, 
+    46, 46, 15, 15, 1, 15, 15, 15, 15, 46, 46, 4, 5, 6, 7, 8, 9, 10, 11, 12, 
+    13, 46, 46, 46, 1, 1, 46, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 
+    46, 15, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 15, 15, 15, 15, 
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
+    15, 15, 15, 15, 15, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 46, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 
-    95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 
-    95, 95, 95, 95, 95, 95, 0, 0, 47, 4, 4, 4, 4, 4, 4, 0, 96, 96, 96, 96, 
-    96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 
-    96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 18, 0, 4, 
-    4, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
-    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
-    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 16, 16, 16, 4, 16, 4, 16, 16, 
-    4, 16, 16, 4, 16, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 0, 0, 0, 0, 0, 47, 47, 47, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 
-    1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 16, 16, 16, 16, 16, 16, 0, 
-    0, 0, 0, 0, 4, 0, 0, 4, 4, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 
-    0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 16, 16, 16, 16, 16, 16, 
-    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 5, 6, 7, 8, 9, 
-    10, 11, 12, 13, 14, 4, 4, 4, 4, 47, 47, 16, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 4, 47, 16, 16, 16, 16, 16, 16, 16, 1, 4, 16, 16, 16, 16, 16, 16, 
-    47, 47, 16, 16, 4, 16, 16, 16, 16, 47, 47, 5, 6, 7, 8, 9, 10, 11, 12, 13, 
-    14, 47, 47, 47, 4, 4, 47, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 1, 
-    47, 16, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 16, 16, 16, 16, 
-    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
-    16, 16, 16, 16, 16, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 47, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
@@ -466,232 +466,232 @@
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 15, 46, 15, 
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 46, 15, 
+    15, 15, 15, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 15, 15, 1, 
+    1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 46, 0, 0, 0, 15, 15, 15, 0, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 46, 
+    46, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 0, 46, 0, 0, 0, 
+    46, 46, 46, 46, 0, 0, 15, 46, 15, 15, 15, 15, 15, 15, 15, 0, 0, 15, 15, 
+    0, 0, 15, 15, 15, 46, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 46, 46, 0, 
+    46, 46, 46, 15, 15, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 46, 46, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 15, 15, 15, 0, 46, 46, 46, 46, 46, 
+    46, 0, 0, 0, 0, 46, 46, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 46, 
+    46, 0, 46, 46, 0, 46, 46, 0, 46, 46, 0, 0, 15, 0, 15, 15, 15, 15, 15, 0, 
+    0, 0, 0, 15, 15, 0, 0, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 
+    46, 46, 46, 0, 46, 0, 0, 0, 0, 0, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 
+    15, 15, 46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 0, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 0, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 
+    46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 0, 46, 46, 46, 46, 46, 0, 0, 15, 
+    46, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 0, 15, 15, 15, 0, 0, 
+    46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 15, 15, 0, 0, 4, 
+    5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 15, 15, 15, 0, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 46, 46, 0, 
+    0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 0, 46, 46, 
+    46, 46, 46, 0, 0, 15, 46, 15, 15, 15, 15, 15, 15, 0, 0, 0, 15, 15, 0, 0, 
+    15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 46, 46, 0, 46, 
+    46, 46, 0, 0, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 46, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 46, 0, 46, 46, 46, 46, 46, 46, 0, 
+    0, 0, 46, 46, 46, 0, 46, 46, 46, 46, 0, 0, 0, 46, 46, 0, 46, 0, 46, 46, 
+    0, 0, 0, 46, 46, 0, 0, 0, 46, 46, 46, 0, 0, 0, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 15, 15, 15, 15, 15, 0, 0, 0, 15, 15, 
+    15, 0, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 15, 15, 15, 0, 46, 46, 46, 46, 46, 
+    46, 46, 46, 0, 46, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 0, 0, 0, 0, 15, 15, 15, 15, 
+    15, 15, 15, 0, 15, 15, 15, 0, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 15, 
+    15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 0, 0, 0, 0, 4, 5, 6, 7, 8, 9, 10, 
+    11, 12, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 
+    0, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 0, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 0, 0, 
+    15, 46, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 0, 15, 15, 15, 15, 0, 
+    0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 46, 0, 46, 46, 0, 0, 0, 0, 
+    4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 15, 15, 0, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 
+    0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 0, 0, 15, 15, 15, 
+    0, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 
+    46, 46, 0, 0, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 0, 0, 46, 46, 46, 
+    46, 46, 46, 46, 0, 0, 0, 15, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 0, 15, 
+    0, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 15, 15, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 15, 46, 96, 15, 15, 15, 15, 15, 15, 
+    15, 0, 0, 0, 0, 1, 46, 46, 46, 46, 46, 46, 46, 15, 15, 15, 15, 15, 15, 
+    15, 15, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 1, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 46, 46, 0, 46, 0, 0, 46, 46, 0, 46, 0, 0, 46, 0, 0, 0, 
+    0, 0, 0, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 0, 
+    46, 0, 46, 0, 0, 46, 46, 0, 46, 46, 46, 46, 15, 46, 96, 15, 15, 15, 15, 
+    15, 15, 0, 15, 15, 46, 0, 0, 46, 46, 46, 46, 46, 0, 46, 0, 15, 15, 15, 
+    15, 15, 15, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 46, 46, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 46, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 15, 15, 1, 1, 1, 1, 1, 1, 4, 5, 6, 7, 8, 9, 10, 
+    11, 12, 13, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 15, 1, 15, 1, 15, 1, 1, 1, 
+    1, 15, 15, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 1, 15, 15, 
+    46, 46, 46, 46, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 1, 1, 
+    1, 1, 1, 1, 1, 1, 15, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 16, 47, 16, 
-    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 0, 47, 16, 
-    16, 16, 16, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 16, 16, 4, 
-    4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 47, 0, 0, 0, 16, 16, 16, 0, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 47, 
-    47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 0, 0, 0, 
-    47, 47, 47, 47, 0, 0, 16, 47, 16, 16, 16, 16, 16, 16, 16, 0, 0, 16, 16, 
-    0, 0, 16, 16, 16, 47, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 47, 47, 0, 
-    47, 47, 47, 16, 16, 0, 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 47, 47, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 16, 16, 16, 0, 47, 47, 47, 47, 
-    47, 47, 0, 0, 0, 0, 47, 47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 
-    47, 47, 0, 47, 47, 0, 47, 47, 0, 47, 47, 0, 0, 16, 0, 16, 16, 16, 16, 16, 
-    0, 0, 0, 0, 16, 16, 0, 0, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    47, 47, 47, 47, 0, 47, 0, 0, 0, 0, 0, 0, 0, 5, 6, 7, 8, 9, 10, 11, 12, 
-    13, 14, 16, 16, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 
-    16, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 0, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 0, 47, 47, 47, 47, 47, 0, 
-    0, 16, 47, 16, 16, 16, 16, 16, 16, 16, 16, 0, 16, 16, 16, 0, 16, 16, 16, 
-    0, 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 16, 16, 0, 
-    0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 16, 16, 16, 0, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 47, 
-    47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 0, 47, 
-    47, 47, 47, 47, 0, 0, 16, 47, 16, 16, 16, 16, 16, 16, 0, 0, 0, 16, 16, 0, 
-    0, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 47, 47, 0, 47, 
-    47, 47, 0, 0, 0, 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 4, 47, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 47, 0, 47, 47, 47, 47, 47, 47, 0, 
-    0, 0, 47, 47, 47, 0, 47, 47, 47, 47, 0, 0, 0, 47, 47, 0, 47, 0, 47, 47, 
-    0, 0, 0, 47, 47, 0, 0, 0, 47, 47, 47, 0, 0, 0, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 16, 16, 16, 16, 16, 0, 0, 0, 16, 16, 
-    16, 0, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 16, 16, 16, 0, 47, 47, 47, 47, 47, 
-    47, 47, 47, 0, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 0, 0, 0, 0, 16, 16, 16, 16, 
-    16, 16, 16, 0, 16, 16, 16, 0, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 16, 
-    16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 0, 0, 0, 0, 5, 6, 7, 8, 9, 10, 11, 
-    12, 13, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 
-    0, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 0, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 0, 0, 
-    16, 47, 16, 16, 16, 16, 16, 16, 16, 0, 16, 16, 16, 0, 16, 16, 16, 16, 0, 
-    0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 47, 0, 47, 47, 0, 0, 0, 0, 
-    5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 16, 16, 0, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 
-    0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 0, 0, 16, 16, 16, 
-    0, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 
-    47, 47, 0, 0, 0, 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 0, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 0, 0, 47, 47, 47, 
-    47, 47, 47, 47, 0, 0, 0, 16, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 0, 16, 
-    0, 16, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 16, 16, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 16, 47, 97, 16, 16, 16, 16, 16, 16, 
-    16, 0, 0, 0, 0, 4, 47, 47, 47, 47, 47, 47, 47, 16, 16, 16, 16, 16, 16, 
-    16, 16, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 4, 4, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 47, 47, 0, 47, 0, 0, 47, 47, 0, 47, 0, 0, 47, 0, 0, 0, 
-    0, 0, 0, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 0, 
-    47, 0, 47, 0, 0, 47, 47, 0, 47, 47, 47, 47, 16, 47, 97, 16, 16, 16, 16, 
-    16, 16, 0, 16, 16, 47, 0, 0, 47, 47, 47, 47, 47, 0, 47, 0, 16, 16, 16, 
-    16, 16, 16, 0, 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, 0, 47, 47, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 47, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 16, 16, 4, 4, 4, 4, 4, 4, 5, 6, 7, 8, 9, 10, 11, 
-    12, 13, 14, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 16, 4, 16, 4, 16, 4, 4, 4, 
-    4, 16, 16, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 
-    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 4, 16, 16, 
-    47, 47, 47, 47, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 16, 16, 0, 16, 16, 
-    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
-    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 4, 4, 
-    4, 4, 4, 4, 4, 4, 16, 4, 4, 4, 4, 4, 4, 0, 0, 4, 4, 4, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 0, 46, 46, 
+    0, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 
+    4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 1, 1, 1, 1, 1, 46, 46, 46, 46, 46, 
+    46, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 
+    97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 
+    97, 97, 97, 97, 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 1, 46, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 0, 0, 46, 46, 46, 46, 46, 46, 
+    46, 0, 46, 0, 46, 46, 46, 46, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 
+    46, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 
+    46, 46, 46, 46, 0, 0, 46, 46, 46, 46, 46, 46, 46, 0, 46, 0, 46, 46, 46, 
+    46, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 0, 46, 46, 46, 46, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 0, 0, 0, 0, 15, 1, 1, 1, 1, 1, 1, 1, 1, 1, 98, 99, 100, 
+    101, 102, 103, 104, 105, 106, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 1, 1, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 2, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 1, 1, 0, 0, 0, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    1, 1, 1, 107, 107, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 15, 
+    15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 15, 15, 15, 1, 1, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 0, 15, 15, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 1, 1, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 1, 1, 
+    1, 46, 1, 1, 1, 1, 46, 15, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 
+    0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 15, 15, 15, 2, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 
+    0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 15, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 
+    0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 15, 15, 
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 4, 
+    5, 6, 7, 8, 9, 10, 11, 12, 13, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 0, 0, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
+    15, 15, 15, 15, 15, 15, 15, 15, 46, 46, 46, 46, 46, 46, 46, 15, 15, 0, 0, 
+    0, 0, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 0, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 15, 15, 15, 15, 15, 0, 0, 1, 1, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 0, 47, 47, 
-    0, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 
-    5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 4, 4, 4, 4, 4, 4, 47, 47, 47, 47, 47, 
-    47, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 
-    98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 
-    98, 98, 98, 98, 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 4, 47, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 0, 0, 47, 47, 47, 47, 47, 47, 
-    47, 0, 47, 0, 47, 47, 47, 47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 
-    47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 
-    47, 47, 47, 47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 0, 47, 47, 47, 
-    47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 0, 47, 47, 47, 47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 0, 0, 0, 0, 16, 4, 4, 4, 4, 4, 4, 4, 4, 4, 99, 100, 101, 
-    102, 103, 104, 105, 106, 107, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 4, 4, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 2, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 4, 4, 0, 0, 0, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    4, 4, 4, 108, 108, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 16, 
-    16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 16, 16, 16, 4, 4, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 0, 16, 16, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 1, 1, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
-    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 4, 4, 
-    4, 47, 4, 4, 4, 4, 47, 16, 0, 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, 0, 
-    0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 16, 16, 16, 2, 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 
-    0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 16, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 
-    0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 16, 16, 
-    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 4, 0, 0, 0, 4, 4, 5, 
-    6, 7, 8, 9, 10, 11, 12, 13, 14, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 0, 0, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
-    16, 16, 16, 16, 16, 16, 16, 16, 47, 47, 47, 47, 47, 47, 47, 16, 16, 0, 0, 
-    0, 0, 0, 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, 0, 0, 0, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 16, 16, 16, 16, 16, 0, 0, 4, 4, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
@@ -700,133 +700,132 @@
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 46, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 15, 15, 
+    15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
-    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
-    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 18, 18, 18, 18, 18, 18, 
-    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 47, 18, 
-    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
-    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 16, 16, 
-    16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 25, 24, 25, 24, 25, 24, 25, 
-    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
-    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
-    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
-    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
-    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
-    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
-    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
-    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 18, 18, 
-    18, 18, 18, 109, 0, 0, 0, 0, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 
-    25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 
-    25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 
-    25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 
-    25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 
-    25, 24, 25, 24, 25, 24, 25, 0, 0, 0, 0, 0, 0, 110, 110, 110, 110, 110, 
-    110, 110, 110, 111, 111, 111, 111, 111, 111, 111, 111, 110, 110, 110, 
-    110, 110, 110, 0, 0, 111, 111, 111, 111, 111, 111, 0, 0, 110, 110, 110, 
-    110, 110, 110, 110, 110, 111, 111, 111, 111, 111, 111, 111, 111, 110, 
-    110, 110, 110, 110, 110, 110, 110, 111, 111, 111, 111, 111, 111, 111, 
-    111, 110, 110, 110, 110, 110, 110, 0, 0, 111, 111, 111, 111, 111, 111, 0, 
-    0, 18, 110, 18, 110, 18, 110, 18, 110, 0, 111, 0, 111, 0, 111, 0, 111, 
-    110, 110, 110, 110, 110, 110, 110, 110, 111, 111, 111, 111, 111, 111, 
-    111, 111, 112, 112, 113, 113, 113, 113, 114, 114, 115, 115, 116, 116, 
-    117, 117, 0, 0, 110, 110, 110, 110, 110, 110, 110, 110, 118, 118, 118, 
-    118, 118, 118, 118, 118, 110, 110, 110, 110, 110, 110, 110, 110, 118, 
-    118, 118, 118, 118, 118, 118, 118, 110, 110, 110, 110, 110, 110, 110, 
-    110, 118, 118, 118, 118, 118, 118, 118, 118, 110, 110, 18, 119, 18, 0, 
-    18, 18, 111, 111, 120, 120, 121, 4, 122, 4, 4, 4, 18, 119, 18, 0, 18, 18, 
-    123, 123, 123, 123, 121, 4, 4, 4, 110, 110, 18, 18, 0, 0, 18, 18, 111, 
-    111, 124, 124, 0, 4, 4, 4, 110, 110, 18, 18, 18, 90, 18, 18, 111, 111, 
-    125, 125, 93, 4, 4, 4, 0, 0, 18, 119, 18, 0, 18, 18, 126, 126, 127, 127, 
-    121, 4, 4, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 1, 1, 
-    1, 1, 1, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 16, 16, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 16, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 128, 18, 0, 
-    0, 129, 130, 131, 132, 133, 134, 4, 4, 4, 4, 4, 18, 128, 22, 19, 20, 129, 
-    130, 131, 132, 133, 134, 4, 4, 4, 4, 4, 0, 47, 47, 47, 47, 47, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
-    16, 4, 4, 4, 4, 16, 4, 4, 4, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 56, 4, 4, 4, 4, 56, 4, 
-    4, 18, 56, 56, 56, 18, 18, 56, 56, 56, 18, 4, 56, 4, 4, 108, 56, 56, 56, 
-    56, 56, 4, 4, 4, 4, 4, 4, 56, 4, 135, 4, 56, 4, 136, 137, 56, 56, 108, 
-    18, 56, 56, 4, 56, 18, 47, 47, 47, 47, 18, 4, 4, 18, 18, 56, 56, 4, 4, 4, 
-    4, 4, 56, 18, 18, 18, 18, 4, 4, 4, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 
-    138, 138, 138, 138, 138, 139, 139, 139, 139, 139, 139, 139, 139, 139, 
-    139, 139, 139, 139, 139, 139, 139, 108, 108, 108, 108, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 22, 19, 20, 129, 130, 131, 132, 133, 134, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 22, 19, 20, 129, 130, 131, 132, 133, 134, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 22, 19, 20, 129, 130, 131, 132, 133, 134, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 140, 140, 140, 140, 140, 140, 140, 140, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 24, 23, 24, 23, 24, 23, 24, 
+    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
+    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
+    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
+    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
+    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
+    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
+    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
+    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 17, 17, 
+    17, 17, 17, 108, 0, 0, 0, 0, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
+    24, 23, 24, 23, 24, 23, 24, 0, 0, 0, 0, 0, 0, 109, 109, 109, 109, 109, 
+    109, 109, 109, 110, 110, 110, 110, 110, 110, 110, 110, 109, 109, 109, 
+    109, 109, 109, 0, 0, 110, 110, 110, 110, 110, 110, 0, 0, 109, 109, 109, 
+    109, 109, 109, 109, 109, 110, 110, 110, 110, 110, 110, 110, 110, 109, 
+    109, 109, 109, 109, 109, 109, 109, 110, 110, 110, 110, 110, 110, 110, 
+    110, 109, 109, 109, 109, 109, 109, 0, 0, 110, 110, 110, 110, 110, 110, 0, 
+    0, 17, 109, 17, 109, 17, 109, 17, 109, 0, 110, 0, 110, 0, 110, 0, 110, 
+    109, 109, 109, 109, 109, 109, 109, 109, 110, 110, 110, 110, 110, 110, 
+    110, 110, 111, 111, 112, 112, 112, 112, 113, 113, 114, 114, 115, 115, 
+    116, 116, 0, 0, 109, 109, 109, 109, 109, 109, 109, 109, 117, 117, 117, 
+    117, 117, 117, 117, 117, 109, 109, 109, 109, 109, 109, 109, 109, 117, 
+    117, 117, 117, 117, 117, 117, 117, 109, 109, 109, 109, 109, 109, 109, 
+    109, 117, 117, 117, 117, 117, 117, 117, 117, 109, 109, 17, 118, 17, 0, 
+    17, 17, 110, 110, 119, 119, 120, 1, 121, 1, 1, 1, 17, 118, 17, 0, 17, 17, 
+    122, 122, 122, 122, 120, 1, 1, 1, 109, 109, 17, 17, 0, 0, 17, 17, 110, 
+    110, 123, 123, 0, 1, 1, 1, 109, 109, 17, 17, 17, 89, 17, 17, 110, 110, 
+    124, 124, 92, 1, 1, 1, 0, 0, 17, 118, 17, 0, 17, 17, 125, 125, 126, 126, 
+    120, 1, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 
+    1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 15, 15, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 15, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 127, 17, 0, 
+    0, 128, 129, 130, 131, 132, 133, 1, 1, 1, 1, 1, 17, 127, 21, 18, 19, 128, 
+    129, 130, 131, 132, 133, 1, 1, 1, 1, 1, 0, 46, 46, 46, 46, 46, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
+    15, 1, 1, 1, 1, 15, 1, 1, 1, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 55, 1, 1, 1, 1, 55, 1, 
+    1, 17, 55, 55, 55, 17, 17, 55, 55, 55, 17, 1, 55, 1, 1, 107, 55, 55, 55, 
+    55, 55, 1, 1, 1, 1, 1, 1, 55, 1, 134, 1, 55, 1, 135, 136, 55, 55, 107, 
+    17, 55, 55, 1, 55, 17, 46, 46, 46, 46, 17, 1, 1, 17, 17, 55, 55, 1, 1, 1, 
+    1, 1, 55, 17, 17, 17, 17, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 
+    137, 137, 137, 137, 137, 138, 138, 138, 138, 138, 138, 138, 138, 138, 
+    138, 138, 138, 138, 138, 138, 138, 107, 107, 107, 107, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 21, 18, 19, 128, 129, 130, 131, 132, 133, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 21, 18, 19, 128, 129, 130, 131, 132, 133, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 21, 18, 19, 128, 129, 130, 131, 132, 133, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 139, 139, 139, 139, 139, 139, 139, 139, 
+    139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 
+    139, 139, 139, 139, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 
     140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 
-    140, 140, 140, 140, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 
-    141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 
-    141, 141, 128, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 22, 19, 20, 129, 130, 131, 
-    132, 133, 134, 4, 128, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 
+    140, 140, 127, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 21, 18, 19, 128, 129, 130, 
+    131, 132, 133, 1, 127, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    4, 4, 4, 4, 0, 4, 4, 4, 4, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 0, 4, 0, 4, 4, 4, 4, 0, 0, 0, 4, 0, 4, 4, 4, 4, 4, 4, 4, 0, 0, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 22, 19, 
-    20, 129, 130, 131, 132, 133, 134, 4, 22, 19, 20, 129, 130, 131, 132, 133, 
-    134, 4, 22, 19, 20, 129, 130, 131, 132, 133, 134, 4, 4, 0, 0, 0, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 21, 18, 
+    19, 128, 129, 130, 131, 132, 133, 1, 21, 18, 19, 128, 129, 130, 131, 132, 
+    133, 1, 21, 18, 19, 128, 129, 130, 131, 132, 133, 1, 1, 0, 0, 0, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
@@ -835,133 +834,133 @@
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 95, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 94, 94, 
+    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
+    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
+    94, 94, 94, 94, 94, 94, 94, 94, 94, 0, 95, 95, 95, 95, 95, 95, 95, 95, 
     95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 
     95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 
-    95, 95, 95, 95, 95, 95, 95, 95, 95, 0, 96, 96, 96, 96, 96, 96, 96, 96, 
-    96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 
-    96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 
-    96, 96, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 25, 24, 25, 24, 25, 24, 25, 
-    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
-    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
-    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
-    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
-    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
-    24, 25, 18, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    4, 4, 4, 4, 4, 4, 4, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 
-    142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 
-    142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 
-    47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 
-    47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 
-    0, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 4, 
-    4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 
-    0, 0, 0, 2, 4, 4, 4, 4, 47, 47, 108, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 16, 16, 16, 16, 16, 16, 4, 47, 47, 47, 47, 47, 4, 4, 108, 108, 
-    108, 47, 47, 4, 4, 4, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 0, 0, 16, 16, 4, 4, 47, 47, 47, 4, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 4, 47, 47, 47, 47, 0, 0, 0, 
-    0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 
-    0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    95, 95, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 24, 23, 24, 23, 24, 23, 24, 
+    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
+    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
+    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
+    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
+    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
+    23, 24, 17, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    1, 1, 1, 1, 1, 1, 1, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 
+    141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 
+    141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 0, 46, 
+    46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 
+    46, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 
+    0, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 
+    1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 
+    0, 0, 0, 2, 1, 1, 1, 1, 46, 46, 107, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 107, 107, 107, 107, 107, 107, 107, 
+    107, 107, 15, 15, 15, 15, 15, 15, 1, 46, 46, 46, 46, 46, 1, 1, 107, 107, 
+    107, 46, 46, 1, 1, 1, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 0, 0, 15, 15, 1, 1, 46, 46, 46, 1, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 1, 46, 46, 46, 46, 0, 0, 0, 
+    0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
@@ -971,9 +970,9 @@
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 47, 47, 16, 47, 47, 47, 16, 47, 47, 47, 47, 16, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 16, 16, 16, 16, 16, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 46, 46, 15, 46, 46, 46, 15, 46, 46, 46, 46, 15, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 15, 15, 15, 15, 15, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
@@ -982,301 +981,290 @@
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 
-    0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 47, 
-    16, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 4, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 0, 47, 0, 47, 47, 0, 
-    47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 74, 74, 74, 74, 74, 74, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 4, 4, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 74, 74, 4, 4, 0, 0, 16, 16, 16, 16, 16, 16, 16, 16, 
-    16, 16, 16, 16, 16, 16, 16, 16, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 
-    0, 0, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 16, 
-    16, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 16, 16, 16, 4, 4, 4, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 0, 4, 4, 4, 4, 0, 0, 0, 0, 74, 47, 74, 47, 74, 0, 74, 47, 74, 
-    47, 74, 47, 74, 47, 74, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 0, 0, 1, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 4, 4, 4, 4, 4, 4, 4, 15, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
-    15, 15, 15, 15, 15, 15, 4, 4, 4, 4, 16, 4, 17, 17, 17, 17, 17, 17, 17, 
-    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
-    17, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 97, 97, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 47, 47, 47, 47, 47, 47, 0, 0, 
-    47, 47, 47, 47, 47, 47, 0, 0, 47, 47, 47, 47, 47, 47, 0, 0, 47, 47, 47, 
-    0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 0, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 1, 1, 1, 4, 4, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 0, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 4, 
-    4, 4, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 
+    17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 
+    17, 17, 0, 0, 0, 0, 0, 46, 15, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 1, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 
+    46, 0, 46, 0, 46, 46, 0, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 73, 73, 73, 73, 73, 73, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 73, 73, 1, 1, 0, 0, 15, 15, 
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 1, 1, 1, 15, 15, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 15, 15, 15, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 73, 46, 73, 
+    46, 73, 0, 73, 46, 73, 46, 73, 46, 73, 46, 73, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 1, 0, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 1, 
+    1, 1, 1, 1, 1, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 1, 1, 1, 1, 15, 1, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 96, 
+    96, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 46, 46, 
+    46, 46, 46, 46, 0, 0, 46, 46, 46, 46, 46, 46, 0, 0, 46, 46, 46, 46, 46, 
+    46, 0, 0, 46, 46, 46, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 
+    1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    0, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 107, 
+    107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 
+    107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 
+    107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 
+    107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 4, 
-    4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    0, 4, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 4, 108, 108, 108, 108, 
-    108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 143, 143, 143, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 0, 1, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 1, 107, 
+    107, 107, 107, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 
+    142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 
+    142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 143, 143, 
     143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 
     143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 
-    143, 143, 143, 143, 143, 143, 143, 143, 143, 144, 144, 144, 144, 144, 
-    144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 
-    144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 
-    144, 144, 144, 144, 144, 144, 144, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 5, 6, 
-    7, 8, 9, 10, 11, 12, 13, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 
-    47, 47, 47, 47, 47, 0, 0, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 
-    47, 0, 0, 0, 47, 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 46, 46, 46, 46, 46, 46, 0, 0, 46, 0, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 0, 46, 46, 0, 0, 0, 46, 0, 0, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 16, 16, 16, 0, 16, 16, 0, 0, 0, 0, 0, 16, 
-    16, 16, 16, 47, 47, 47, 47, 0, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 0, 0, 0, 0, 16, 16, 16, 0, 0, 0, 0, 16, 22, 19, 20, 129, 4, 4, 4, 
-    4, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 15, 15, 15, 0, 15, 15, 0, 0, 0, 
+    0, 0, 15, 15, 15, 15, 46, 46, 46, 46, 0, 46, 46, 46, 0, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 0, 0, 0, 0, 15, 15, 15, 0, 0, 0, 0, 15, 21, 18, 19, 
+    128, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 16, 16, 16, 16, 16, 4, 4, 4, 
-    16, 16, 16, 16, 16, 16, 1, 1, 1, 1, 1, 1, 1, 1, 16, 16, 16, 16, 16, 16, 
-    16, 16, 4, 4, 16, 16, 16, 16, 16, 16, 16, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 16, 16, 16, 
-    16, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 16, 16, 16, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 15, 15, 15, 15, 15, 
+    1, 1, 1, 15, 15, 15, 15, 15, 15, 1, 1, 1, 1, 1, 1, 1, 1, 15, 15, 15, 15, 
+    15, 15, 15, 15, 1, 1, 15, 15, 15, 15, 15, 15, 15, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 15, 15, 
+    15, 15, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 15, 15, 15, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
-    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 56, 56, 
-    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
-    56, 56, 56, 56, 56, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
-    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 56, 56, 56, 56, 56, 
-    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
-    56, 56, 56, 18, 18, 18, 18, 18, 18, 18, 0, 18, 18, 18, 18, 18, 18, 18, 
-    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 56, 56, 56, 56, 56, 56, 56, 
-    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
-    56, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
-    18, 18, 18, 18, 18, 18, 18, 18, 18, 56, 0, 56, 56, 0, 0, 56, 0, 0, 56, 
-    56, 0, 0, 56, 56, 56, 56, 0, 56, 56, 56, 56, 56, 56, 56, 56, 18, 18, 18, 
-    18, 0, 18, 0, 18, 18, 18, 18, 18, 18, 18, 0, 18, 18, 18, 18, 18, 18, 18, 
-    18, 18, 18, 18, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
-    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 18, 18, 18, 18, 18, 18, 
-    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
-    18, 18, 56, 56, 0, 56, 56, 56, 56, 0, 0, 56, 56, 56, 56, 56, 56, 56, 56, 
-    0, 56, 56, 56, 56, 56, 56, 56, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
-    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 56, 56, 
-    0, 56, 56, 56, 56, 0, 56, 56, 56, 56, 56, 0, 56, 0, 0, 0, 56, 56, 56, 56, 
-    56, 56, 56, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
-    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 56, 56, 56, 56, 56, 56, 
-    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
-    56, 56, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
-    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 56, 56, 56, 56, 56, 56, 56, 56, 
-    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
-    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
-    18, 18, 18, 18, 18, 18, 18, 18, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
-    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 18, 18, 
-    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
-    18, 18, 18, 18, 18, 18, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
-    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 18, 18, 18, 18, 
-    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
-    18, 18, 18, 18, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
-    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 18, 18, 18, 18, 18, 18, 
-    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
-    18, 18, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
-    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 18, 18, 18, 18, 18, 18, 18, 18, 
-    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
-    18, 18, 0, 0, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
-    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 4, 18, 18, 18, 18, 18, 18, 18, 
-    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
-    4, 18, 18, 18, 18, 18, 18, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
-    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 4, 18, 18, 18, 
-    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
-    18, 18, 18, 18, 4, 18, 18, 18, 18, 18, 18, 56, 56, 56, 56, 56, 56, 56, 
-    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
-    4, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
-    18, 18, 18, 18, 18, 18, 18, 18, 4, 18, 18, 18, 18, 18, 18, 56, 56, 56, 
-    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
-    56, 56, 56, 56, 4, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
-    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 4, 18, 18, 18, 18, 18, 
-    18, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
-    56, 56, 56, 56, 56, 56, 56, 56, 4, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
-    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 4, 18, 
-    18, 18, 18, 18, 18, 0, 0, 0, 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 5, 6, 
-    7, 8, 9, 10, 11, 12, 13, 14, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 5, 6, 7, 
-    8, 9, 10, 11, 12, 13, 14, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 
+    55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 
+    55, 55, 55, 55, 55, 55, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 55, 55, 55, 55, 
+    55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 
+    55, 55, 55, 55, 17, 17, 17, 17, 17, 17, 17, 0, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 55, 55, 55, 55, 55, 55, 
+    55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 
+    55, 55, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 55, 0, 55, 55, 0, 0, 55, 0, 0, 
+    55, 55, 0, 0, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 17, 17, 
+    17, 17, 0, 17, 0, 17, 17, 17, 17, 17, 17, 17, 0, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 
+    55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 55, 55, 0, 55, 55, 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, 
+    55, 0, 55, 55, 55, 55, 55, 55, 55, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 55, 
+    55, 0, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 0, 55, 0, 0, 0, 55, 55, 55, 
+    55, 55, 55, 55, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 55, 55, 55, 55, 55, 
+    55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 
+    55, 55, 55, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 55, 55, 55, 55, 55, 55, 55, 
+    55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 
+    55, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 55, 55, 55, 55, 55, 55, 55, 55, 55, 
+    55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 
+    55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 
+    55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 
+    55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 
+    55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 1, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 1, 17, 17, 17, 17, 17, 17, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 
+    55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 1, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 1, 17, 17, 17, 17, 17, 17, 55, 55, 55, 55, 55, 55, 
+    55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 
+    55, 1, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 1, 17, 17, 17, 17, 17, 17, 55, 55, 
+    55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 
+    55, 55, 55, 55, 55, 1, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 1, 17, 17, 17, 17, 
+    17, 17, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 
+    55, 55, 55, 55, 55, 55, 55, 55, 55, 1, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 1, 
+    17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 4, 
+    5, 6, 7, 8, 9, 10, 11, 12, 13, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 4, 5, 6, 
+    7, 8, 9, 10, 11, 12, 13, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
+    46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
@@ -1296,20 +1284,20 @@
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
-    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
-    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
-    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
-    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
-    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
-    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
-    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
-    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
-    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
-    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
-    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
-    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
-    16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 

Modified: python/branches/py3k/PC/VC6/rt.bat
==============================================================================
--- python/branches/py3k/PC/VC6/rt.bat	(original)
+++ python/branches/py3k/PC/VC6/rt.bat	Wed Jun  4 15:01:30 2008
@@ -31,11 +31,11 @@
 @if "%_qmode%"=="yes" goto Qmode
 @echo Deleting .pyc/.pyo files ...
 @%_exe% rmpyc.py
-%_exe% %_dashO% -E ../../lib/test/regrtest.py %1 %2 %3 %4 %5 %6 %7 %8 %9
+%_exe% %_dashO% -E -tt ../../lib/test/regrtest.py %1 %2 %3 %4 %5 %6 %7 %8 %9
 @echo About to run again without deleting .pyc/.pyo first:
 @pause
 :Qmode
-%_exe% %_dashO% -E ../../lib/test/regrtest.py %1 %2 %3 %4 %5 %6 %7 %8 %9
+%_exe% %_dashO% -E -tt ../../lib/test/regrtest.py %1 %2 %3 %4 %5 %6 %7 %8 %9
 @set _exe=
 @set _qmode=
 @set _dashO=

Modified: python/branches/py3k/PC/VS7.1/rt.bat
==============================================================================
--- python/branches/py3k/PC/VS7.1/rt.bat	(original)
+++ python/branches/py3k/PC/VS7.1/rt.bat	Wed Jun  4 15:01:30 2008
@@ -34,7 +34,7 @@
 if "%1"=="-q" (set qmode=yes)    & shift & goto CheckOpts
 if "%1"=="-d" (set exe=python_d) & shift & goto CheckOpts
 
-set cmd=%exe% %dashO% -E ../../lib/test/regrtest.py %1 %2 %3 %4 %5 %6 %7 %8 %9
+set cmd=%exe% %dashO% -E -tt ../../lib/test/regrtest.py %1 %2 %3 %4 %5 %6 %7 %8 %9
 if defined qmode goto Qmode
 
 echo Deleting .pyc/.pyo files ...

Modified: python/branches/py3k/PC/VS8.0/rt.bat
==============================================================================
--- python/branches/py3k/PC/VS8.0/rt.bat	(original)
+++ python/branches/py3k/PC/VS8.0/rt.bat	Wed Jun  4 15:01:30 2008
@@ -34,7 +34,7 @@
 if "%1"=="-q" (set qmode=yes)    & shift & goto CheckOpts
 if "%1"=="-d" (set exe=python_d) & shift & goto CheckOpts
 
-set cmd=%exe% %dashO% -E ../../lib/test/regrtest.py %1 %2 %3 %4 %5 %6 %7 %8 %9
+set cmd=%exe% %dashO% -E -tt ../../lib/test/regrtest.py %1 %2 %3 %4 %5 %6 %7 %8 %9
 if defined qmode goto Qmode
 
 echo Deleting .pyc/.pyo files ...

Modified: python/branches/py3k/PC/os2emx/Makefile
==============================================================================
--- python/branches/py3k/PC/os2emx/Makefile	(original)
+++ python/branches/py3k/PC/os2emx/Makefile	Wed Jun  4 15:01:30 2008
@@ -666,7 +666,7 @@
 # the test target
 test:
 	-find ../../Lib -name "*.py[co]" -exec rm {} ";"
-	-./python -E ../../lib/test/regrtest.py -l -u "network"
-	./python -E ../../lib/test/regrtest.py -l -u "network"
+	-./python -E -tt ../../lib/test/regrtest.py -l -u "network"
+	./python -E -tt ../../lib/test/regrtest.py -l -u "network"
 
 -include $(OUTBASE)python.dep

Modified: python/branches/py3k/PC/os2emx/python26.def
==============================================================================
--- python/branches/py3k/PC/os2emx/python26.def	(original)
+++ python/branches/py3k/PC/os2emx/python26.def	Wed Jun  4 15:01:30 2008
@@ -49,6 +49,7 @@
   "PyParser_Delete"
 
 ; From python26_s.lib(parsetok)
+  "Py_TabcheckFlag"
   "PyParser_ParseString"
   "PyParser_ParseStringFlagsFilename"
   "PyParser_ParseFile"

Modified: python/branches/py3k/PC/os2vacpp/python.def
==============================================================================
--- python/branches/py3k/PC/os2vacpp/python.def	(original)
+++ python/branches/py3k/PC/os2vacpp/python.def	Wed Jun  4 15:01:30 2008
@@ -61,6 +61,7 @@
                Py_InteractiveFlag
                Py_NoSiteFlag
                Py_OptimizeFlag
+               Py_TabcheckFlag
                Py_UseClassExceptionsFlag
                Py_VerboseFlag
                _PyImport_Filetab

Modified: python/branches/py3k/PCbuild/rt.bat
==============================================================================
--- python/branches/py3k/PCbuild/rt.bat	(original)
+++ python/branches/py3k/PCbuild/rt.bat	Wed Jun  4 15:01:30 2008
@@ -40,7 +40,7 @@
 
 PATH %PATH%;..\..\%tcltk%\bin
 set exe=%prefix%\python%suffix%
-set cmd=%exe% %dashO% -E ../lib/test/regrtest.py %1 %2 %3 %4 %5 %6 %7 %8 %9
+set cmd=%exe% %dashO% -E -tt ../lib/test/regrtest.py %1 %2 %3 %4 %5 %6 %7 %8 %9
 if defined qmode goto Qmode
 
 echo Deleting .pyc/.pyo files ...

Modified: python/branches/py3k/Parser/parsetok.c
==============================================================================
--- python/branches/py3k/Parser/parsetok.c	(original)
+++ python/branches/py3k/Parser/parsetok.c	Wed Jun  4 15:01:30 2008
@@ -10,6 +10,8 @@
 #include "errcode.h"
 #include "graminit.h"
 
+int Py_TabcheckFlag;
+
 
 /* Forward */
 static node *parsetok(struct tok_state *, grammar *, int, perrdetail *, int *);
@@ -55,6 +57,9 @@
 	}
 
         tok->filename = filename ? filename : "<string>";
+	if (Py_TabcheckFlag >= 3)
+		tok->alterror = 0;
+
 	return parsetok(tok, g, start, err_ret, flags);
 }
 
@@ -92,6 +97,9 @@
 		return NULL;
 	}
 	tok->filename = filename;
+	if (Py_TabcheckFlag >= 3)
+		tok->alterror = 0;
+
 	return parsetok(tok, g, start, err_ret, flags);
 }
 

Modified: python/branches/py3k/Python/bltinmodule.c
==============================================================================
--- python/branches/py3k/Python/bltinmodule.c	(original)
+++ python/branches/py3k/Python/bltinmodule.c	Wed Jun  4 15:01:30 2008
@@ -265,38 +265,6 @@
 \n\
 Return True if bool(x) is True for any x in the iterable.");
 
-static PyObject *
-builtin_ascii(PyObject *self, PyObject *v)
-{
-	PyObject *repr, *bytes, *ascii;
-	repr = PyObject_Repr(v);
-	if (!repr)
-	    return NULL;
-
-        bytes = PyUnicode_EncodeASCII(
-		PyUnicode_AS_UNICODE(repr),
-		PyUnicode_GET_SIZE(repr),
-		"backslashreplace");
-
-	Py_DECREF(repr);
-	if (bytes == NULL) 
-	    return NULL;
-
-	ascii = PyUnicode_FromEncodedObject(bytes, 
-		    "ASCII", NULL);
-	Py_DECREF(bytes);
-	if (ascii == NULL)
-	    return NULL;
-
-	return ascii;
-}
-
-PyDoc_STRVAR(ascii_doc,
-"ascii(object) -> string\n\
-\n\
-Return the canonical string representation of the object as repr(),\n\
-but non-ASCII characters in the string are hex-escaped");
-
 
 static PyObject *
 builtin_bin(PyObject *self, PyObject *v)
@@ -2220,7 +2188,6 @@
  	{"abs",		builtin_abs,        METH_O, abs_doc},
  	{"all",		builtin_all,        METH_O, all_doc},
  	{"any",		builtin_any,        METH_O, any_doc},
- 	{"ascii",	builtin_ascii,      METH_O, ascii_doc},
 	{"bin",		builtin_bin,	    METH_O, bin_doc},
  	{"chr",		builtin_chr,        METH_VARARGS, chr_doc},
  	{"cmp",		builtin_cmp,        METH_VARARGS, cmp_doc},

Modified: python/branches/py3k/Python/sysmodule.c
==============================================================================
--- python/branches/py3k/Python/sysmodule.c	(original)
+++ python/branches/py3k/Python/sysmodule.c	Wed Jun  4 15:01:30 2008
@@ -1100,6 +1100,7 @@
 	{"no_user_site",	"-s"},
 	{"no_site",		"-S"},
 	{"ignore_environment",	"-E"},
+	{"tabcheck",		"-t or -tt"},
 	{"verbose",		"-v"},
 #ifdef RISCOS
 	{"riscos_wimp",		"???"},
@@ -1115,9 +1116,9 @@
 	flags__doc__,	/* doc */
 	flags_fields,	/* fields */
 #ifdef RISCOS
-	11
+	12
 #else
-	10
+	11
 #endif
 };
 
@@ -1143,6 +1144,7 @@
 	SetFlag(Py_NoUserSiteDirectory);
 	SetFlag(Py_NoSiteFlag);
 	SetFlag(Py_IgnoreEnvironmentFlag);
+	SetFlag(Py_TabcheckFlag);
 	SetFlag(Py_VerboseFlag);
 #ifdef RISCOS
 	SetFlag(Py_RISCOSWimpFlag);

Modified: python/branches/py3k/Tools/unicode/makeunicodedata.py
==============================================================================
--- python/branches/py3k/Tools/unicode/makeunicodedata.py	(original)
+++ python/branches/py3k/Tools/unicode/makeunicodedata.py	Wed Jun  4 15:01:30 2008
@@ -60,7 +60,6 @@
 UPPER_MASK = 0x80
 XID_START_MASK = 0x100
 XID_CONTINUE_MASK = 0x200
-NONPRINTABLE_MASK = 0x400
 
 def maketables(trace=0):
 
@@ -72,7 +71,7 @@
                           EASTASIAN_WIDTH % version,
                           DERIVED_CORE_PROPERTIES % version)
 
-    print(len(list(filter(None, unicode.table))), "characters")
+    print(len(filter(None, unicode.table)), "characters")
 
     for version in old_versions:
         print("--- Reading", UNICODE_DATA % ("-"+version), "...")
@@ -80,7 +79,7 @@
                                   COMPOSITION_EXCLUSIONS % ("-"+version),
                                   EASTASIAN_WIDTH % ("-"+version),
                                   DERIVED_CORE_PROPERTIES % ("-"+version))
-        print(len(list(filter(None, old_unicode.table))), "characters")
+        print(len(filter(None, old_unicode.table)), "characters")
         merge_old_version(version, unicode, old_unicode)
 
     makeunicodename(unicode, trace)
@@ -372,10 +371,6 @@
                 flags |= TITLE_MASK
             if category == "Lu":
                 flags |= UPPER_MASK
-            if category[0] == "C":
-                flags |= NONPRINTABLE_MASK
-            if category[0] == "Z" and char != " ":
-                flags |= NONPRINTABLE_MASK
             if "XID_Start" in properties:
                 flags |= XID_START_MASK
             if "XID_Continue" in properties:
@@ -470,7 +465,7 @@
             if name and name[0] != "<":
                 names[char] = name + chr(0)
 
-    print(len(list(n for n in names if n is not None)), "distinct names")
+    print(len(n for n in names if n is not None), "distinct names")
 
     # collect unique words from names (note that we differ between
     # words inside a sentence, and words ending a sentence.  the

From python-3000-checkins at python.org  Wed Jun  4 15:06:58 2008
From: python-3000-checkins at python.org (georg.brandl)
Date: Wed,  4 Jun 2008 15:06:58 +0200 (CEST)
Subject: [Python-3000-checkins] r63936 - in python/branches/py3k:
	Doc/library/sys.rst Doc/using/cmdline.rst Include/pydebug.h
	Lib/test/test_exceptions.py
	Mac/BuildScript/scripts/postflight.framework Mac/Makefile.in
	Makefile.pre.in Misc/NEWS Misc/build.sh Misc/cheatsheet
	Misc/python.man Misc/valgrind-python.supp Modules/main.c
	PC/VC6/rt.bat PC/VS7.1/rt.bat PC/VS8.0/rt.bat
	PC/os2emx/Makefile PC/os2emx/python26.def
	PC/os2vacpp/python.def PCbuild/rt.bat Parser/parsetok.c
	Python/sysmodule.c
Message-ID: <20080604130658.EF8681E4002@bag.python.org>

Author: georg.brandl
Date: Wed Jun  4 15:06:58 2008
New Revision: 63936

Log:
Remove meaning of -ttt, but still accept -t option on cmdline for compatibility.


Modified:
   python/branches/py3k/Doc/library/sys.rst
   python/branches/py3k/Doc/using/cmdline.rst
   python/branches/py3k/Include/pydebug.h
   python/branches/py3k/Lib/test/test_exceptions.py
   python/branches/py3k/Mac/BuildScript/scripts/postflight.framework
   python/branches/py3k/Mac/Makefile.in
   python/branches/py3k/Makefile.pre.in
   python/branches/py3k/Misc/NEWS
   python/branches/py3k/Misc/build.sh
   python/branches/py3k/Misc/cheatsheet
   python/branches/py3k/Misc/python.man
   python/branches/py3k/Misc/valgrind-python.supp
   python/branches/py3k/Modules/main.c
   python/branches/py3k/PC/VC6/rt.bat
   python/branches/py3k/PC/VS7.1/rt.bat
   python/branches/py3k/PC/VS8.0/rt.bat
   python/branches/py3k/PC/os2emx/Makefile
   python/branches/py3k/PC/os2emx/python26.def
   python/branches/py3k/PC/os2vacpp/python.def
   python/branches/py3k/PCbuild/rt.bat
   python/branches/py3k/Parser/parsetok.c
   python/branches/py3k/Python/sysmodule.c

Modified: python/branches/py3k/Doc/library/sys.rst
==============================================================================
--- python/branches/py3k/Doc/library/sys.rst	(original)
+++ python/branches/py3k/Doc/library/sys.rst	Wed Jun  4 15:06:58 2008
@@ -231,8 +231,6 @@
    +------------------------------+------------------------------------------+
    | :const:`ignore_environment`  | -E                                       |
    +------------------------------+------------------------------------------+
-   | :const:`tabcheck`            | -t or -tt                                |
-   +------------------------------+------------------------------------------+
    | :const:`verbose`             | -v                                       |
    +------------------------------+------------------------------------------+
    | :const:`unicode`             | -U                                       |

Modified: python/branches/py3k/Doc/using/cmdline.rst
==============================================================================
--- python/branches/py3k/Doc/using/cmdline.rst	(original)
+++ python/branches/py3k/Doc/using/cmdline.rst	Wed Jun  4 15:06:58 2008
@@ -222,13 +222,6 @@
    manipulations of :data:`sys.path` that it entails.
 
 
-.. cmdoption:: -t
-
-   Issue a warning when a source file mixes tabs and spaces for indentation in a
-   way that makes it depend on the worth of a tab expressed in spaces.  Issue an
-   error when the option is given twice (:option:`-tt`).
-
-
 .. cmdoption:: -u
    
    Force stdin, stdout and stderr to be totally unbuffered.  On systems where it

Modified: python/branches/py3k/Include/pydebug.h
==============================================================================
--- python/branches/py3k/Include/pydebug.h	(original)
+++ python/branches/py3k/Include/pydebug.h	Wed Jun  4 15:06:58 2008
@@ -14,7 +14,6 @@
 PyAPI_DATA(int) Py_BytesWarningFlag;
 PyAPI_DATA(int) Py_UseClassExceptionsFlag;
 PyAPI_DATA(int) Py_FrozenFlag;
-PyAPI_DATA(int) Py_TabcheckFlag;
 PyAPI_DATA(int) Py_IgnoreEnvironmentFlag;
 PyAPI_DATA(int) Py_DivisionWarningFlag;
 PyAPI_DATA(int) Py_DontWriteBytecodeFlag;

Modified: python/branches/py3k/Lib/test/test_exceptions.py
==============================================================================
--- python/branches/py3k/Lib/test/test_exceptions.py	(original)
+++ python/branches/py3k/Lib/test/test_exceptions.py	Wed Jun  4 15:06:58 2008
@@ -80,10 +80,10 @@
         self.raise_catch(IndentationError, "IndentationError")
 
         self.raise_catch(TabError, "TabError")
-        # can only be tested under -tt, and is the only test for -tt
-        #try: compile("try:\n\t1/0\n    \t1/0\nfinally:\n pass\n", '<string>', 'exec')
-        #except TabError: pass
-        #else: self.fail("TabError not raised")
+        try: compile("try:\n\t1/0\n    \t1/0\nfinally:\n pass\n",
+                     '<string>', 'exec')
+        except TabError: pass
+        else: self.fail("TabError not raised")
 
         self.raise_catch(SystemError, "SystemError")
 

Modified: python/branches/py3k/Mac/BuildScript/scripts/postflight.framework
==============================================================================
--- python/branches/py3k/Mac/BuildScript/scripts/postflight.framework	(original)
+++ python/branches/py3k/Mac/BuildScript/scripts/postflight.framework	Wed Jun  4 15:06:58 2008
@@ -6,22 +6,22 @@
 PYVER="@PYVER@"
 FWK="/Library/Frameworks/Python.framework/Versions/@PYVER@"
 
-"${FWK}/bin/python" -Wi -tt \
+"${FWK}/bin/python" -Wi \
     "${FWK}/lib/python${PYVER}/compileall.py" \
     -x badsyntax -x site-packages \
     "${FWK}/lib/python${PYVER}"
 
-"${FWK}/bin/python" -Wi -tt -O \
+"${FWK}/bin/python" -Wi -O \
     "${FWK}/lib/python${PYVER}/compileall.py" \
     -x badsyntax -x site-packages \
     "${FWK}/lib/python${PYVER}"
 
-"${FWK}/bin/python" -Wi -tt \
+"${FWK}/bin/python" -Wi \
     "${FWK}/lib/python${PYVER}/compileall.py" \
     -x badsyntax -x site-packages \
     "${FWK}/Mac/Tools"
 
-"${FWK}/bin/python" -Wi -tt -O \
+"${FWK}/bin/python" -Wi -O \
     "${FWK}/lib/python${PYVER}/compileall.py" \
     -x badsyntax -x site-packages \
     "${FWK}/Mac/Tools"

Modified: python/branches/py3k/Mac/Makefile.in
==============================================================================
--- python/branches/py3k/Mac/Makefile.in	(original)
+++ python/branches/py3k/Mac/Makefile.in	Wed Jun  4 15:06:58 2008
@@ -226,8 +226,8 @@
 
 
 	$(RUNSHARED) $(BUILDPYTHON) $(CACHERSRC) -v $(DESTDIR)$(MACLIBDEST) $(DESTDIR)$(MACTOOLSDEST)
-	$(RUNSHARED) $(BUILDPYTHON) -Wi -tt $(compileall) -d $(MACTOOLSDEST) -x badsyntax $(DESTDIR)$(MACTOOLSDEST)
-	$(RUNSHARED) $(BUILDPYTHON) -O -Wi -tt $(compileall) -d $(MACTOOLSDEST) -x badsyntax $(DESTDIR)$(MACTOOLSDEST)
+	$(RUNSHARED) $(BUILDPYTHON) -Wi $(compileall) -d $(MACTOOLSDEST) -x badsyntax $(DESTDIR)$(MACTOOLSDEST)
+	$(RUNSHARED) $(BUILDPYTHON) -O -Wi $(compileall) -d $(MACTOOLSDEST) -x badsyntax $(DESTDIR)$(MACTOOLSDEST)
 
 $(INSTALLED_PYTHONAPP): install_Python
 

Modified: python/branches/py3k/Makefile.pre.in
==============================================================================
--- python/branches/py3k/Makefile.pre.in	(original)
+++ python/branches/py3k/Makefile.pre.in	Wed Jun  4 15:06:58 2008
@@ -664,7 +664,7 @@
 
 TESTOPTS=	-l $(EXTRATESTOPTS)
 TESTPROG=	$(srcdir)/Lib/test/regrtest.py
-TESTPYTHON=	$(RUNSHARED) ./$(BUILDPYTHON) -E -tt -bb
+TESTPYTHON=	$(RUNSHARED) ./$(BUILDPYTHON) -E -bb
 test:		all platform
 		-find $(srcdir)/Lib -name '*.py[co]' -print | xargs rm -f
 		-$(TESTPYTHON) $(TESTPROG) $(TESTOPTS)
@@ -687,7 +687,7 @@
 		-find $(srcdir)/Lib -name '*.py[co]' -print | xargs rm -f
 		-$(TESTPYTHON) $(TESTPROG) $(TESTOPTS) -uall
 		$(TESTPYTHON) $(TESTPROG) $(TESTOPTS) -uall
-		$(RUNSHARED) /usr/libexec/oah/translate ./$(BUILDPYTHON) -E -tt $(TESTPROG) $(TESTOPTS) -uall
+		$(RUNSHARED) /usr/libexec/oah/translate ./$(BUILDPYTHON) -E $(TESTPROG) $(TESTOPTS) -uall
 
 
 # Like testall, but with a single pass only
@@ -872,23 +872,23 @@
 	done
 	$(INSTALL_DATA) $(srcdir)/LICENSE $(DESTDIR)$(LIBDEST)/LICENSE.txt
 	-PYTHONPATH=$(DESTDIR)$(LIBDEST)  $(RUNSHARED) \
-		./$(BUILDPYTHON) -Wi -tt $(DESTDIR)$(LIBDEST)/compileall.py \
+		./$(BUILDPYTHON) -Wi $(DESTDIR)$(LIBDEST)/compileall.py \
 		-d $(LIBDEST) -f \
 		-x 'bad_coding|badsyntax|site-packages' $(DESTDIR)$(LIBDEST)
 	-PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
-		./$(BUILDPYTHON) -Wi -tt -O $(DESTDIR)$(LIBDEST)/compileall.py \
+		./$(BUILDPYTHON) -Wi -O $(DESTDIR)$(LIBDEST)/compileall.py \
 		-d $(LIBDEST) -f \
 		-x 'bad_coding|badsyntax|site-packages' $(DESTDIR)$(LIBDEST)
 	-PYTHONPATH=$(DESTDIR)$(LIBDEST)  $(RUNSHARED) \
-		./$(BUILDPYTHON) -Wi -t $(DESTDIR)$(LIBDEST)/compileall.py \
+		./$(BUILDPYTHON) -Wi $(DESTDIR)$(LIBDEST)/compileall.py \
 		-d $(LIBDEST)/site-packages -f \
 		-x badsyntax $(DESTDIR)$(LIBDEST)/site-packages
 	-PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
-		./$(BUILDPYTHON) -Wi -t -O $(DESTDIR)$(LIBDEST)/compileall.py \
+		./$(BUILDPYTHON) -Wi -O $(DESTDIR)$(LIBDEST)/compileall.py \
 		-d $(LIBDEST)/site-packages -f \
 		-x badsyntax $(DESTDIR)$(LIBDEST)/site-packages
 	-PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
-		./$(BUILDPYTHON) -Wi -t -c "import lib2to3.pygram"
+		./$(BUILDPYTHON) -Wi -c "import lib2to3.pygram"
 
 # Create the PLATDIR source directory, if one wasn't distributed..
 $(srcdir)/Lib/$(PLATDIR):

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Wed Jun  4 15:06:58 2008
@@ -12,6 +12,8 @@
 Core and Builtins
 -----------------
 
+- Removed the already-defunct ``-t`` option.
+
 - Issue #2957: Corrected a ValueError "recursion limit exceeded", when
   unmarshalling many code objects, which happens when importing a
   large .pyc file (~1000 functions).

Modified: python/branches/py3k/Misc/build.sh
==============================================================================
--- python/branches/py3k/Misc/build.sh	(original)
+++ python/branches/py3k/Misc/build.sh	Wed Jun  4 15:06:58 2008
@@ -59,7 +59,7 @@
 PYTHON=$INSTALL_DIR/bin/python
 
 # Python options and regression test program that should always be run.
-REGRTEST_ARGS="-E -tt $INSTALL_DIR/lib/python3.0/test/regrtest.py"
+REGRTEST_ARGS="-E $INSTALL_DIR/lib/python3.0/test/regrtest.py"
 
 REFLOG="build/reflog.txt.out"
 # These tests are not stable and falsely report leaks sometimes.

Modified: python/branches/py3k/Misc/cheatsheet
==============================================================================
--- python/branches/py3k/Misc/cheatsheet	(original)
+++ python/branches/py3k/Misc/cheatsheet	Wed Jun  4 15:06:58 2008
@@ -46,7 +46,6 @@
 -OO     remove doc-strings in addition to the -O optimizations
 -Q arg  division options: -Qold (default), -Qwarn, -Qwarnall, -Qnew
 -S      Don't perform 'import site' on initialization
--t      Issue warnings about inconsistent tab usage (-tt: issue errors)
 -u      Unbuffered binary stdout and stderr (also PYTHONUNBUFFERED=x).
 -v      Verbose (trace import statements) (also PYTHONVERBOSE=x)
 -W arg : warning control (arg is action:message:category:module:lineno)

Modified: python/branches/py3k/Misc/python.man
==============================================================================
--- python/branches/py3k/Misc/python.man	(original)
+++ python/branches/py3k/Misc/python.man	Wed Jun  4 15:06:58 2008
@@ -35,9 +35,6 @@
 .B \-S
 ]
 [
-.B \-t
-]
-[
 .B \-u
 ]
 .br
@@ -144,11 +141,6 @@
 .I sys.path
 that it entails.
 .TP
-.B \-t
-Issue a warning when a source file mixes tabs and spaces for
-indentation in a way that makes it depend on the worth of a tab
-expressed in spaces.  Issue an error when the option is given twice.
-.TP
 .B \-u
 Force stdin, stdout and stderr to be totally unbuffered.  On systems
 where it matters, also put stdin, stdout and stderr in binary mode.

Modified: python/branches/py3k/Misc/valgrind-python.supp
==============================================================================
--- python/branches/py3k/Misc/valgrind-python.supp	(original)
+++ python/branches/py3k/Misc/valgrind-python.supp	Wed Jun  4 15:06:58 2008
@@ -5,7 +5,7 @@
 #
 #	cd python/dist/src
 #	valgrind --tool=memcheck --suppressions=Misc/valgrind-python.supp \
-#		./python -E -tt ./Lib/test/regrtest.py -u bsddb,network
+#		./python -E ./Lib/test/regrtest.py -u bsddb,network
 #
 # You must edit Objects/obmalloc.c and uncomment Py_USING_MEMORY_DEBUGGER
 # to use the preferred suppressions with Py_ADDRESS_IN_RANGE.

Modified: python/branches/py3k/Modules/main.c
==============================================================================
--- python/branches/py3k/Modules/main.c	(original)
+++ python/branches/py3k/Modules/main.c	Wed Jun  4 15:06:58 2008
@@ -72,7 +72,6 @@
 -OO    : remove doc-strings in addition to the -O optimizations\n\
 -s     : don't add user site directory to sys.path; also PYTHONNOUSERSITE\n\
 -S     : don't imply 'import site' on initialization\n\
--t     : issue warnings about inconsistent tab usage (-tt: issue errors)\n\
 ";
 static char *usage_3 = "\
 -u     : unbuffered binary stdout and stderr; also PYTHONUNBUFFERED=x\n\
@@ -370,7 +369,7 @@
 			break;
 
 		case 't':
-			Py_TabcheckFlag++;
+			/* ignored for backwards compatibility */
 			break;
 
 		case 'u':

Modified: python/branches/py3k/PC/VC6/rt.bat
==============================================================================
--- python/branches/py3k/PC/VC6/rt.bat	(original)
+++ python/branches/py3k/PC/VC6/rt.bat	Wed Jun  4 15:06:58 2008
@@ -31,11 +31,11 @@
 @if "%_qmode%"=="yes" goto Qmode
 @echo Deleting .pyc/.pyo files ...
 @%_exe% rmpyc.py
-%_exe% %_dashO% -E -tt ../../lib/test/regrtest.py %1 %2 %3 %4 %5 %6 %7 %8 %9
+%_exe% %_dashO% -E ../../lib/test/regrtest.py %1 %2 %3 %4 %5 %6 %7 %8 %9
 @echo About to run again without deleting .pyc/.pyo first:
 @pause
 :Qmode
-%_exe% %_dashO% -E -tt ../../lib/test/regrtest.py %1 %2 %3 %4 %5 %6 %7 %8 %9
+%_exe% %_dashO% -E ../../lib/test/regrtest.py %1 %2 %3 %4 %5 %6 %7 %8 %9
 @set _exe=
 @set _qmode=
 @set _dashO=

Modified: python/branches/py3k/PC/VS7.1/rt.bat
==============================================================================
--- python/branches/py3k/PC/VS7.1/rt.bat	(original)
+++ python/branches/py3k/PC/VS7.1/rt.bat	Wed Jun  4 15:06:58 2008
@@ -34,7 +34,7 @@
 if "%1"=="-q" (set qmode=yes)    & shift & goto CheckOpts
 if "%1"=="-d" (set exe=python_d) & shift & goto CheckOpts
 
-set cmd=%exe% %dashO% -E -tt ../../lib/test/regrtest.py %1 %2 %3 %4 %5 %6 %7 %8 %9
+set cmd=%exe% %dashO% -E ../../lib/test/regrtest.py %1 %2 %3 %4 %5 %6 %7 %8 %9
 if defined qmode goto Qmode
 
 echo Deleting .pyc/.pyo files ...

Modified: python/branches/py3k/PC/VS8.0/rt.bat
==============================================================================
--- python/branches/py3k/PC/VS8.0/rt.bat	(original)
+++ python/branches/py3k/PC/VS8.0/rt.bat	Wed Jun  4 15:06:58 2008
@@ -34,7 +34,7 @@
 if "%1"=="-q" (set qmode=yes)    & shift & goto CheckOpts
 if "%1"=="-d" (set exe=python_d) & shift & goto CheckOpts
 
-set cmd=%exe% %dashO% -E -tt ../../lib/test/regrtest.py %1 %2 %3 %4 %5 %6 %7 %8 %9
+set cmd=%exe% %dashO% -E ../../lib/test/regrtest.py %1 %2 %3 %4 %5 %6 %7 %8 %9
 if defined qmode goto Qmode
 
 echo Deleting .pyc/.pyo files ...

Modified: python/branches/py3k/PC/os2emx/Makefile
==============================================================================
--- python/branches/py3k/PC/os2emx/Makefile	(original)
+++ python/branches/py3k/PC/os2emx/Makefile	Wed Jun  4 15:06:58 2008
@@ -666,7 +666,7 @@
 # the test target
 test:
 	-find ../../Lib -name "*.py[co]" -exec rm {} ";"
-	-./python -E -tt ../../lib/test/regrtest.py -l -u "network"
-	./python -E -tt ../../lib/test/regrtest.py -l -u "network"
+	-./python -E ../../lib/test/regrtest.py -l -u "network"
+	./python -E ../../lib/test/regrtest.py -l -u "network"
 
 -include $(OUTBASE)python.dep

Modified: python/branches/py3k/PC/os2emx/python26.def
==============================================================================
--- python/branches/py3k/PC/os2emx/python26.def	(original)
+++ python/branches/py3k/PC/os2emx/python26.def	Wed Jun  4 15:06:58 2008
@@ -49,7 +49,6 @@
   "PyParser_Delete"
 
 ; From python26_s.lib(parsetok)
-  "Py_TabcheckFlag"
   "PyParser_ParseString"
   "PyParser_ParseStringFlagsFilename"
   "PyParser_ParseFile"

Modified: python/branches/py3k/PC/os2vacpp/python.def
==============================================================================
--- python/branches/py3k/PC/os2vacpp/python.def	(original)
+++ python/branches/py3k/PC/os2vacpp/python.def	Wed Jun  4 15:06:58 2008
@@ -61,7 +61,6 @@
                Py_InteractiveFlag
                Py_NoSiteFlag
                Py_OptimizeFlag
-               Py_TabcheckFlag
                Py_UseClassExceptionsFlag
                Py_VerboseFlag
                _PyImport_Filetab

Modified: python/branches/py3k/PCbuild/rt.bat
==============================================================================
--- python/branches/py3k/PCbuild/rt.bat	(original)
+++ python/branches/py3k/PCbuild/rt.bat	Wed Jun  4 15:06:58 2008
@@ -40,7 +40,7 @@
 
 PATH %PATH%;..\..\%tcltk%\bin
 set exe=%prefix%\python%suffix%
-set cmd=%exe% %dashO% -E -tt ../lib/test/regrtest.py %1 %2 %3 %4 %5 %6 %7 %8 %9
+set cmd=%exe% %dashO% -E ../lib/test/regrtest.py %1 %2 %3 %4 %5 %6 %7 %8 %9
 if defined qmode goto Qmode
 
 echo Deleting .pyc/.pyo files ...

Modified: python/branches/py3k/Parser/parsetok.c
==============================================================================
--- python/branches/py3k/Parser/parsetok.c	(original)
+++ python/branches/py3k/Parser/parsetok.c	Wed Jun  4 15:06:58 2008
@@ -10,8 +10,6 @@
 #include "errcode.h"
 #include "graminit.h"
 
-int Py_TabcheckFlag;
-
 
 /* Forward */
 static node *parsetok(struct tok_state *, grammar *, int, perrdetail *, int *);
@@ -57,9 +55,6 @@
 	}
 
         tok->filename = filename ? filename : "<string>";
-	if (Py_TabcheckFlag >= 3)
-		tok->alterror = 0;
-
 	return parsetok(tok, g, start, err_ret, flags);
 }
 
@@ -97,9 +92,6 @@
 		return NULL;
 	}
 	tok->filename = filename;
-	if (Py_TabcheckFlag >= 3)
-		tok->alterror = 0;
-
 	return parsetok(tok, g, start, err_ret, flags);
 }
 

Modified: python/branches/py3k/Python/sysmodule.c
==============================================================================
--- python/branches/py3k/Python/sysmodule.c	(original)
+++ python/branches/py3k/Python/sysmodule.c	Wed Jun  4 15:06:58 2008
@@ -1100,7 +1100,6 @@
 	{"no_user_site",	"-s"},
 	{"no_site",		"-S"},
 	{"ignore_environment",	"-E"},
-	{"tabcheck",		"-t or -tt"},
 	{"verbose",		"-v"},
 #ifdef RISCOS
 	{"riscos_wimp",		"???"},
@@ -1116,9 +1115,9 @@
 	flags__doc__,	/* doc */
 	flags_fields,	/* fields */
 #ifdef RISCOS
-	12
-#else
 	11
+#else
+	10
 #endif
 };
 
@@ -1144,7 +1143,6 @@
 	SetFlag(Py_NoUserSiteDirectory);
 	SetFlag(Py_NoSiteFlag);
 	SetFlag(Py_IgnoreEnvironmentFlag);
-	SetFlag(Py_TabcheckFlag);
 	SetFlag(Py_VerboseFlag);
 #ifdef RISCOS
 	SetFlag(Py_RISCOSWimpFlag);

From python-3000-checkins at python.org  Wed Jun  4 16:03:56 2008
From: python-3000-checkins at python.org (georg.brandl)
Date: Wed,  4 Jun 2008 16:03:56 +0200 (CEST)
Subject: [Python-3000-checkins] r63937 -
	python/branches/py3k/Lib/test/test_sys.py
Message-ID: <20080604140356.46B6B1E4004@bag.python.org>

Author: georg.brandl
Date: Wed Jun  4 16:03:46 2008
New Revision: 63937

Log:
Remove tabcheck from the expected flags in sys.flags.


Modified:
   python/branches/py3k/Lib/test/test_sys.py

Modified: python/branches/py3k/Lib/test/test_sys.py
==============================================================================
--- python/branches/py3k/Lib/test/test_sys.py	(original)
+++ python/branches/py3k/Lib/test/test_sys.py	Wed Jun  4 16:03:46 2008
@@ -324,7 +324,7 @@
         self.failUnless(sys.flags)
         attrs = ("debug", "division_warning",
                  "inspect", "interactive", "optimize", "dont_write_bytecode",
-                 "no_site", "ignore_environment", "tabcheck", "verbose",
+                 "no_site", "ignore_environment", "verbose",
                  "bytes_warning")
         for attr in attrs:
             self.assert_(hasattr(sys.flags, attr), attr)

From python-3000-checkins at python.org  Wed Jun  4 16:18:44 2008
From: python-3000-checkins at python.org (martin.v.loewis)
Date: Wed,  4 Jun 2008 16:18:44 +0200 (CEST)
Subject: [Python-3000-checkins] r63940 - in python/branches/py3k:
	Doc/library/sys.rst Lib/test/test_descrtut.py
	Lib/test/test_sys.py Objects/bytesobject.c
	Objects/dictobject.c Objects/listobject.c
	Objects/longobject.c Objects/typeobject.c Python/sysmodule.c
Message-ID: <20080604141844.42CC11E4015@bag.python.org>

Author: martin.v.loewis
Date: Wed Jun  4 16:18:43 2008
New Revision: 63940

Log:
Merged revisions 63856-63857,63859-63860 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/trunk

........
  r63856 | robert.schuppenies | 2008-06-01 18:16:17 +0200 (So, 01 Jun 2008) | 2 lines
  
  Issue #2898: Added sys.getsizeof() to retrieve size of objects in bytes.
........
  r63859 | georg.brandl | 2008-06-01 18:42:16 +0200 (So, 01 Jun 2008) | 2 lines
  
  Some style nits. Also clarify in the docstrings what __sizeof__ does.
........
  r63860 | georg.brandl | 2008-06-01 19:05:56 +0200 (So, 01 Jun 2008) | 2 lines
  
  Fix test_descrtut.
........


Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Doc/library/sys.rst
   python/branches/py3k/Lib/test/test_descrtut.py
   python/branches/py3k/Lib/test/test_sys.py
   python/branches/py3k/Objects/bytesobject.c
   python/branches/py3k/Objects/dictobject.c
   python/branches/py3k/Objects/listobject.c
   python/branches/py3k/Objects/longobject.c
   python/branches/py3k/Objects/typeobject.c
   python/branches/py3k/Python/sysmodule.c

Modified: python/branches/py3k/Doc/library/sys.rst
==============================================================================
--- python/branches/py3k/Doc/library/sys.rst	(original)
+++ python/branches/py3k/Doc/library/sys.rst	Wed Jun  4 16:18:43 2008
@@ -331,6 +331,16 @@
    :func:`setrecursionlimit`.
 
 
+.. function:: getsizeof(object)
+
+   Return the size of an object in bytes. The object can be any type of
+   object. All built-in objects will return correct results, but this
+   does not have to hold true for third-party extensions as it is implementation 
+   specific.
+
+   .. versionadded:: 2.6
+
+
 .. function:: _getframe([depth])
 
    Return a frame object from the call stack.  If optional integer *depth* is

Modified: python/branches/py3k/Lib/test/test_descrtut.py
==============================================================================
--- python/branches/py3k/Lib/test/test_descrtut.py	(original)
+++ python/branches/py3k/Lib/test/test_descrtut.py	Wed Jun  4 16:18:43 2008
@@ -195,6 +195,7 @@
      '__rmul__',
      '__setattr__',
      '__setitem__',
+     '__sizeof__',
      '__str__',
      '__subclasshook__',
      'append',

Modified: python/branches/py3k/Lib/test/test_sys.py
==============================================================================
--- python/branches/py3k/Lib/test/test_sys.py	(original)
+++ python/branches/py3k/Lib/test/test_sys.py	Wed Jun  4 16:18:43 2008
@@ -1,6 +1,6 @@
 # -*- coding: iso-8859-1 -*-
 import unittest, test.support
-import sys, io
+import sys, io, os
 
 class SysModuleTest(unittest.TestCase):
 
@@ -369,8 +369,141 @@
         self.assertEqual(out, b'?')
 
 
+class SizeofTest(unittest.TestCase):
+
+    def setUp(self):
+        import struct
+        self.i = len(struct.pack('i', 0))
+        self.l = len(struct.pack('l', 0))
+        self.p = len(struct.pack('P', 0))
+        self.headersize = self.l + self.p
+        if hasattr(sys, "gettotalrefcount"):
+            self.headersize += 2 * self.p
+        self.file = open(test.support.TESTFN, 'wb')
+
+    def tearDown(self):
+        self.file.close()
+        test.support.unlink(test.support.TESTFN)
+
+    def check_sizeof(self, o, size):
+        result = sys.getsizeof(o)
+        msg = 'wrong size for %s: got %d, expected %d' \
+            % (type(o), result, size)
+        self.assertEqual(result, size, msg)
+
+    def align(self, value):
+        mod = value % self.p
+        if mod != 0:
+            return value - mod + self.p
+        else:
+            return value
+
+    def test_align(self):
+        self.assertEqual(self.align(0) % self.p, 0)
+        self.assertEqual(self.align(1) % self.p, 0)
+        self.assertEqual(self.align(3) % self.p, 0)
+        self.assertEqual(self.align(4) % self.p, 0)
+        self.assertEqual(self.align(7) % self.p, 0)
+        self.assertEqual(self.align(8) % self.p, 0)
+        self.assertEqual(self.align(9) % self.p, 0)
+
+    def test_standardtypes(self):
+        i = self.i
+        l = self.l
+        p = self.p
+        h = self.headersize
+        # bool
+        self.check_sizeof(True, h + 2*l)
+        # bytearray
+        self.check_sizeof(bytes(), h + self.align(i) + l + p)
+        # cell
+        def get_cell():
+            x = 42
+            def inner():
+                return x
+            return inner
+        self.check_sizeof(get_cell().__closure__[0], h + p)
+        # code XXX wrong size
+        # self.check_sizeof(get_cell().__code__, h + self.align(4*i) + 8*p +\
+        #                    self.align(i) + 2*p)
+        # complex
+        self.check_sizeof(complex(0,1), h + 2*8)
+        # enumerate
+        self.check_sizeof(enumerate([]), h + l + 3*p)
+        # reverse
+        self.check_sizeof(reversed(''), h + l + p )
+        # file XXX wrong size
+        #self.check_sizeof(self.file, h + 4*p + self.align(2*i) + 4*p +\
+        #                    self.align(3*i) + 3*p + self.align(i))
+        # float
+        self.check_sizeof(float(0), h + 8)
+        # function
+        def func(): pass
+        self.check_sizeof(func, h + 11 * p)
+        class c():
+            @staticmethod
+            def foo():
+                pass
+            @classmethod
+            def bar(cls):
+                pass
+            # staticmethod
+            self.check_sizeof(foo, h + l)
+            # classmethod
+            self.check_sizeof(bar, h + l)
+        # generator
+        def get_gen(): yield 1
+        self.check_sizeof(get_gen(), h + p + self.align(i) + 2*p)
+        # builtin_function_or_method
+        self.check_sizeof(abs, h + 3*p)
+        # module
+        self.check_sizeof(unittest, h + p)
+        # range
+        self.check_sizeof(range(1), h + 3*p)
+        # slice
+        self.check_sizeof(slice(0), h + 3*p)
+
+        h += l
+        # new-style class
+        class class_newstyle(object):
+            def method():
+                pass
+        # type (PyTypeObject + PyNumberMethods +  PyMappingMethods +
+        #       PySequenceMethods +  PyBufferProcs)
+        # XXX wrong size
+        # len_typeobject = p + 2*l + 15*p + l + 4*p + l + 9*p + l + 11*p
+        # self.check_sizeof(class_newstyle,
+        #                  h + len_typeobject + 42*p + 10*p + 3*p + 6*p)
+
+
+    def test_specialtypes(self):
+        i = self.i
+        l = self.l
+        p = self.p
+        h = self.headersize
+        # dict
+        self.check_sizeof({}, h + 3*l + 3*p + 8*(l + 2*p))
+        longdict = {1:1, 2:2, 3:3, 4:4, 5:5, 6:6, 7:7, 8:8}
+        self.check_sizeof(longdict, h + 3*l + 3*p + 8*(l + 2*p) + 16*(l + 2*p))
+        # list
+        self.check_sizeof([], h + l + p + l)
+        self.check_sizeof([1, 2, 3], h + l + p + l + 3*l)
+
+        h += l
+        # long
+        self.check_sizeof(0, h + self.align(2))
+        self.check_sizeof(1, h + self.align(2))
+        self.check_sizeof(-1, h + self.align(2))
+        self.check_sizeof(32768, h + self.align(2) + 2)
+        self.check_sizeof(32768*32768-1, h + self.align(2) + 2)
+        self.check_sizeof(32768*32768, h + self.align(2) + 4)
+        # XXX add Unicode support
+        # self.check_sizeof('', h + l + self.align(i + 1))
+        # self.check_sizeof('abc', h + l + self.align(i + 1) + 3)
+
+
 def test_main():
-    test.support.run_unittest(SysModuleTest)
+    test.support.run_unittest(SysModuleTest, SizeofTest)
 
 if __name__ == "__main__":
     test_main()

Modified: python/branches/py3k/Objects/bytesobject.c
==============================================================================
--- python/branches/py3k/Objects/bytesobject.c	(original)
+++ python/branches/py3k/Objects/bytesobject.c	Wed Jun  4 16:18:43 2008
@@ -2784,6 +2784,17 @@
 	return NULL;
 }
 
+PyDoc_STRVAR(sizeof__doc__,
+"S.__sizeof__() -> size of S in memory, in bytes");
+
+static PyObject *
+string_sizeof(PyBytesObject *v)
+{
+	Py_ssize_t res;
+	res = sizeof(PyBytesObject) + Py_SIZE(v) * Py_TYPE(v)->tp_itemsize;
+	return PyLong_FromSsize_t(res);
+}
+
 
 static PyObject *
 string_getnewargs(PyBytesObject *v)
@@ -2848,6 +2859,8 @@
 	 translate__doc__},
 	{"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__},
 	{"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__},
+	{"__sizeof__", (PyCFunction)string_sizeof, METH_NOARGS,
+	 sizeof__doc__},
 	{NULL,     NULL}		     /* sentinel */
 };
 

Modified: python/branches/py3k/Objects/dictobject.c
==============================================================================
--- python/branches/py3k/Objects/dictobject.c	(original)
+++ python/branches/py3k/Objects/dictobject.c	Wed Jun  4 16:18:43 2008
@@ -1840,11 +1840,28 @@
 
 static PyObject *dictiter_new(PyDictObject *, PyTypeObject *);
 
+static PyObject *
+dict_sizeof(PyDictObject *mp)
+{
+	Py_ssize_t res;
+
+	res = sizeof(PyDictObject) + sizeof(mp->ma_table);
+	if (mp->ma_table != mp->ma_smalltable)
+		res = res + (mp->ma_mask + 1) * sizeof(PyDictEntry);
+	return PyLong_FromSsize_t(res);
+}
+
+PyDoc_STRVAR(has_key__doc__,
+"D.has_key(k) -> True if D has a key k, else False");
+
 PyDoc_STRVAR(contains__doc__,
 "D.__contains__(k) -> True if D has a key k, else False");
 
 PyDoc_STRVAR(getitem__doc__, "x.__getitem__(y) <==> x[y]");
 
+PyDoc_STRVAR(sizeof__doc__,
+"D.__sizeof__() -> size of D in memory, in bytes");
+
 PyDoc_STRVAR(get__doc__,
 "D.get(k[,d]) -> D[k] if k in D, else d.  d defaults to None.");
 
@@ -1890,6 +1907,8 @@
 	 contains__doc__},
 	{"__getitem__", (PyCFunction)dict_subscript,	METH_O | METH_COEXIST,
 	 getitem__doc__},
+	{"__sizeof__",	(PyCFunction)dict_sizeof,	METH_NOARGS,
+	 sizeof__doc__},
 	{"get",         (PyCFunction)dict_get,          METH_VARARGS,
 	 get__doc__},
 	{"setdefault",  (PyCFunction)dict_setdefault,   METH_VARARGS,

Modified: python/branches/py3k/Objects/listobject.c
==============================================================================
--- python/branches/py3k/Objects/listobject.c	(original)
+++ python/branches/py3k/Objects/listobject.c	Wed Jun  4 16:18:43 2008
@@ -2247,6 +2247,15 @@
 	return 0;
 }
 
+static PyObject *
+list_sizeof(PyListObject *self)
+{
+	Py_ssize_t res;
+
+	res = sizeof(PyListObject) + self->allocated * sizeof(void*);
+	return PyLong_FromSsize_t(res);
+}
+
 static PyObject *list_iter(PyObject *seq);
 static PyObject *list_reversed(PyListObject* seq, PyObject* unused);
 
@@ -2254,6 +2263,8 @@
 "x.__getitem__(y) <==> x[y]");
 PyDoc_STRVAR(reversed_doc,
 "L.__reversed__() -- return a reverse iterator over the list");
+PyDoc_STRVAR(sizeof_doc,
+"L.__sizeof__() -- size of L in memory, in bytes");
 PyDoc_STRVAR(append_doc,
 "L.append(object) -- append object to end");
 PyDoc_STRVAR(extend_doc,
@@ -2279,6 +2290,7 @@
 static PyMethodDef list_methods[] = {
 	{"__getitem__", (PyCFunction)list_subscript, METH_O|METH_COEXIST, getitem_doc},
 	{"__reversed__",(PyCFunction)list_reversed, METH_NOARGS, reversed_doc},
+	{"__sizeof__",  (PyCFunction)list_sizeof, METH_NOARGS, sizeof_doc},
 	{"append",	(PyCFunction)listappend,  METH_O, append_doc},
 	{"insert",	(PyCFunction)listinsert,  METH_VARARGS, insert_doc},
 	{"extend",      (PyCFunction)listextend,  METH_O, extend_doc},

Modified: python/branches/py3k/Objects/longobject.c
==============================================================================
--- python/branches/py3k/Objects/longobject.c	(original)
+++ python/branches/py3k/Objects/longobject.c	Wed Jun  4 16:18:43 2008
@@ -3625,6 +3625,17 @@
 #undef UNDEF_NDIGITS
 }
 
+static PyObject *
+long_sizeof(PyLongObject *v)
+{
+	Py_ssize_t res;
+
+	res = sizeof(PyLongObject) + abs(Py_SIZE(v)) * sizeof(digit);
+        if (Py_SIZE(v) != 0)
+		res -=  sizeof(digit);
+	return PyLong_FromSsize_t(res);
+}
+
 #if 0
 static PyObject *
 long_is_finite(PyObject *v)
@@ -3651,6 +3662,8 @@
 	 "Rounding with an ndigits arguments defers to float.__round__."},
 	{"__getnewargs__",	(PyCFunction)long_getnewargs,	METH_NOARGS},
         {"__format__", (PyCFunction)long__format__, METH_VARARGS},
+	{"__sizeof__",	(PyCFunction)long_sizeof, METH_NOARGS,
+	 "Returns size in memory, in bytes"},
 	{NULL,		NULL}		/* sentinel */
 };
 

Modified: python/branches/py3k/Objects/typeobject.c
==============================================================================
--- python/branches/py3k/Objects/typeobject.c	(original)
+++ python/branches/py3k/Objects/typeobject.c	Wed Jun  4 16:18:43 2008
@@ -3275,6 +3275,20 @@
         return result;
 }
 
+static PyObject *
+object_sizeof(PyObject *self, PyObject *args)
+{
+	Py_ssize_t res, isize;
+
+	res = 0;
+	isize = self->ob_type->tp_itemsize;
+	if (isize > 0)
+		res = Py_SIZE(self->ob_type) * isize;
+	res += self->ob_type->tp_basicsize;
+
+	return PyLong_FromSsize_t(res);	 
+}
+
 static PyMethodDef object_methods[] = {
 	{"__reduce_ex__", object_reduce_ex, METH_VARARGS,
 	 PyDoc_STR("helper for pickle")},
@@ -3284,6 +3298,8 @@
 	 object_subclasshook_doc},
         {"__format__", object_format, METH_VARARGS,
          PyDoc_STR("default object formatter")},
+        {"__sizeof__", object_sizeof, METH_NOARGS,
+         PyDoc_STR("__sizeof__() -> size of object in memory, in bytes")},
 	{0}
 };
 

Modified: python/branches/py3k/Python/sysmodule.c
==============================================================================
--- python/branches/py3k/Python/sysmodule.c	(original)
+++ python/branches/py3k/Python/sysmodule.c	Wed Jun  4 16:18:43 2008
@@ -610,6 +610,39 @@
 #endif /* USE_MALLOPT */
 
 static PyObject *
+sys_getsizeof(PyObject *self, PyObject *args)
+{
+	static PyObject * str__sizeof__ = NULL;
+
+	/* Initialize static variable needed by _PyType_Lookup */
+	if (str__sizeof__ == NULL) {
+		str__sizeof__ = PyUnicode_InternFromString("__sizeof__");
+		if (str__sizeof__ == NULL)
+			return NULL;
+	}
+
+	/* Type objects */
+	if (PyType_Check(args)){
+		PyObject *method = _PyType_Lookup(Py_TYPE(args),
+						  str__sizeof__);
+		if (method == NULL) {
+			PyErr_Format(PyExc_TypeError,
+				     "Type %.100s doesn't define __sizeof__",
+				     Py_TYPE(args)->tp_name);
+			return NULL;
+		}
+		return PyObject_CallFunctionObjArgs(method, args, NULL);
+	} 
+	else
+		return PyObject_CallMethod(args, "__sizeof__", NULL);
+}
+
+PyDoc_STRVAR(getsizeof_doc,
+"getsizeof(object) -> int\n\
+\n\
+Return the size of object in bytes.");
+
+static PyObject *
 sys_getrefcount(PyObject *self, PyObject *arg)
 {
 	return PyLong_FromSsize_t(arg->ob_refcnt);
@@ -812,6 +845,7 @@
 	{"getrefcount",	(PyCFunction)sys_getrefcount, METH_O, getrefcount_doc},
 	{"getrecursionlimit", (PyCFunction)sys_getrecursionlimit, METH_NOARGS,
 	 getrecursionlimit_doc},
+ 	{"getsizeof",	sys_getsizeof,  METH_O, getsizeof_doc},
 	{"_getframe", sys_getframe, METH_VARARGS, getframe_doc},
 #ifdef MS_WINDOWS
 	{"getwindowsversion", (PyCFunction)sys_getwindowsversion, METH_NOARGS,
@@ -983,6 +1017,7 @@
 getprofile() -- get the global profiling function\n\
 getrefcount() -- return the reference count for an object (plus one :-)\n\
 getrecursionlimit() -- return the max recursion depth for the interpreter\n\
+getsizeof() -- return the size of an object in bytes\n\
 gettrace() -- get the global debug tracing function\n\
 setcheckinterval() -- control how often the interpreter checks for events\n\
 setdlopenflags() -- set the flags to be used for dlopen() calls\n\

From python-3000-checkins at python.org  Wed Jun  4 22:26:54 2008
From: python-3000-checkins at python.org (alexandre.vassalotti)
Date: Wed,  4 Jun 2008 22:26:54 +0200 (CEST)
Subject: [Python-3000-checkins] r63947 - python/branches/py3k/Lib/dis.py
Message-ID: <20080604202654.824DE1E4004@bag.python.org>

Author: alexandre.vassalotti
Date: Wed Jun  4 22:26:54 2008
New Revision: 63947

Log:
Fixed isinstance() check in dis.dis().


Modified:
   python/branches/py3k/Lib/dis.py

Modified: python/branches/py3k/Lib/dis.py
==============================================================================
--- python/branches/py3k/Lib/dis.py	(original)
+++ python/branches/py3k/Lib/dis.py	Wed Jun  4 22:26:54 2008
@@ -35,7 +35,7 @@
                 print()
     elif hasattr(x, 'co_code'):
         disassemble(x)
-    elif isinstance(x, str):
+    elif isinstance(x, (bytes, bytearray)):
         disassemble_string(x)
     else:
         raise TypeError("don't know how to disassemble %s objects" %

From python-3000-checkins at python.org  Wed Jun  4 23:39:16 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Wed,  4 Jun 2008 23:39:16 +0200 (CEST)
Subject: [Python-3000-checkins] r63950 -
	python/branches/py3k/Objects/dictobject.c
Message-ID: <20080604213916.264301E4003@bag.python.org>

Author: benjamin.peterson
Date: Wed Jun  4 23:39:15 2008
New Revision: 63950

Log:
remove unused docstring


Modified:
   python/branches/py3k/Objects/dictobject.c

Modified: python/branches/py3k/Objects/dictobject.c
==============================================================================
--- python/branches/py3k/Objects/dictobject.c	(original)
+++ python/branches/py3k/Objects/dictobject.c	Wed Jun  4 23:39:15 2008
@@ -1851,9 +1851,6 @@
 	return PyLong_FromSsize_t(res);
 }
 
-PyDoc_STRVAR(has_key__doc__,
-"D.has_key(k) -> True if D has a key k, else False");
-
 PyDoc_STRVAR(contains__doc__,
 "D.__contains__(k) -> True if D has a key k, else False");
 

From python-3000-checkins at python.org  Thu Jun  5 19:57:21 2008
From: python-3000-checkins at python.org (thomas.heller)
Date: Thu,  5 Jun 2008 19:57:21 +0200 (CEST)
Subject: [Python-3000-checkins] r63964 - python/branches/py3k
Message-ID: <20080605175721.105761E4004@bag.python.org>

Author: thomas.heller
Date: Thu Jun  5 19:57:20 2008
New Revision: 63964

Log:
Blocked revisions 63961-63963 via svnmerge

........
  r63961 | thomas.heller | 2008-06-05 19:29:38 +0200 (Do, 05 Jun 2008) | 1 line
  
  Fix preprocessor statement.
........
  r63962 | thomas.heller | 2008-06-05 19:51:15 +0200 (Do, 05 Jun 2008) | 3 lines
  
  Backport from py3k: Implement the new buffer interface from pep3118
  for ctypes instances.  Closes issue #2404.
........
  r63963 | thomas.heller | 2008-06-05 19:52:59 +0200 (Do, 05 Jun 2008) | 3 lines
  
  Backport from py3k: Implement the new buffer interface from pep3118
  for ctypes instances.  Closes issue #2404.
........


Modified:
   python/branches/py3k/   (props changed)

From python-3000-checkins at python.org  Fri Jun  6 00:53:41 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Fri,  6 Jun 2008 00:53:41 +0200 (CEST)
Subject: [Python-3000-checkins] r63966 -
	python/branches/py3k/Demo/imputil/importers.py
Message-ID: <20080605225341.33EC01E4004@bag.python.org>

Author: benjamin.peterson
Date: Fri Jun  6 00:53:40 2008
New Revision: 63966

Log:
remove imputil demo


Removed:
   python/branches/py3k/Demo/imputil/importers.py

Deleted: python/branches/py3k/Demo/imputil/importers.py
==============================================================================
--- python/branches/py3k/Demo/imputil/importers.py	Fri Jun  6 00:53:40 2008
+++ (empty file)
@@ -1,248 +0,0 @@
-#
-# importers.py
-#
-# Demonstration subclasses of imputil.Importer
-#
-
-# There should be consideration for the imports below if it is desirable
-# to have "all" modules be imported through the imputil system.
-
-# these are C extensions
-import sys
-import imp
-import struct
-import marshal
-
-# these are .py modules
-import imputil
-import os
-
-######################################################################
-
-_TupleType = type(())
-_StringType = type('')
-
-######################################################################
-
-# byte-compiled file suffic character
-_suffix_char = __debug__ and 'c' or 'o'
-
-# byte-compiled file suffix
-_suffix = '.py' + _suffix_char
-
-# the C_EXTENSION suffixes
-_c_suffixes = [x for x in imp.get_suffixes() if x[2] == imp.C_EXTENSION]
-
-def _timestamp(pathname):
-    "Return the file modification time as a Long."
-    try:
-        s = os.stat(pathname)
-    except OSError:
-        return None
-    return int(s[8])
-
-def _fs_import(dir, modname, fqname):
-    "Fetch a module from the filesystem."
-
-    pathname = os.path.join(dir, modname)
-    if os.path.isdir(pathname):
-        values = { '__pkgdir__' : pathname, '__path__' : [ pathname ] }
-        ispkg = 1
-        pathname = os.path.join(pathname, '__init__')
-    else:
-        values = { }
-        ispkg = 0
-
-        # look for dynload modules
-        for desc in _c_suffixes:
-            file = pathname + desc[0]
-            try:
-                fp = open(file, desc[1])
-            except IOError:
-                pass
-            else:
-                module = imp.load_module(fqname, fp, file, desc)
-                values['__file__'] = file
-                return 0, module, values
-
-    t_py = _timestamp(pathname + '.py')
-    t_pyc = _timestamp(pathname + _suffix)
-    if t_py is None and t_pyc is None:
-        return None
-    code = None
-    if t_py is None or (t_pyc is not None and t_pyc >= t_py):
-        file = pathname + _suffix
-        f = open(file, 'rb')
-        if f.read(4) == imp.get_magic():
-            t = struct.unpack('<I', f.read(4))[0]
-            if t == t_py:
-                code = marshal.load(f)
-        f.close()
-    if code is None:
-        file = pathname + '.py'
-        code = _compile(file, t_py)
-
-    values['__file__'] = file
-    return ispkg, code, values
-
-######################################################################
-#
-# Simple function-based importer
-#
-class FuncImporter(imputil.Importer):
-    "Importer subclass to delegate to a function rather than method overrides."
-    def __init__(self, func):
-        self.func = func
-    def get_code(self, parent, modname, fqname):
-        return self.func(parent, modname, fqname)
-
-def install_with(func):
-    FuncImporter(func).install()
-
-
-######################################################################
-#
-# Base class for archive-based importing
-#
-class PackageArchiveImporter(imputil.Importer):
-    """Importer subclass to import from (file) archives.
-
-    This Importer handles imports of the style <archive>.<subfile>, where
-    <archive> can be located using a subclass-specific mechanism and the
-    <subfile> is found in the archive using a subclass-specific mechanism.
-
-    This class defines two hooks for subclasses: one to locate an archive
-    (and possibly return some context for future subfile lookups), and one
-    to locate subfiles.
-    """
-
-    def get_code(self, parent, modname, fqname):
-        if parent:
-            # the Importer._finish_import logic ensures that we handle imports
-            # under the top level module (package / archive).
-            assert parent.__importer__ == self
-
-            # if a parent "package" is provided, then we are importing a
-            # sub-file from the archive.
-            result = self.get_subfile(parent.__archive__, modname)
-            if result is None:
-                return None
-            if isinstance(result, _TupleType):
-                assert len(result) == 2
-                return (0,) + result
-            return 0, result, {}
-
-        # no parent was provided, so the archive should exist somewhere on the
-        # default "path".
-        archive = self.get_archive(modname)
-        if archive is None:
-            return None
-        return 1, "", {'__archive__':archive}
-
-    def get_archive(self, modname):
-        """Get an archive of modules.
-
-        This method should locate an archive and return a value which can be
-        used by get_subfile to load modules from it. The value may be a simple
-        pathname, an open file, or a complex object that caches information
-        for future imports.
-
-        Return None if the archive was not found.
-        """
-        raise RuntimeError("get_archive not implemented")
-
-    def get_subfile(self, archive, modname):
-        """Get code from a subfile in the specified archive.
-
-        Given the specified archive (as returned by get_archive()), locate
-        and return a code object for the specified module name.
-
-        A 2-tuple may be returned, consisting of a code object and a dict
-        of name/values to place into the target module.
-
-        Return None if the subfile was not found.
-        """
-        raise RuntimeError("get_subfile not implemented")
-
-
-class PackageArchive(PackageArchiveImporter):
-    "PackageArchiveImporter subclass that refers to a specific archive."
-
-    def __init__(self, modname, archive_pathname):
-        self.__modname = modname
-        self.__path = archive_pathname
-
-    def get_archive(self, modname):
-        if modname == self.__modname:
-            return self.__path
-        return None
-
-    # get_subfile is passed the full pathname of the archive
-
-
-######################################################################
-#
-# Emulate the standard directory-based import mechanism
-#
-class DirectoryImporter(imputil.Importer):
-    "Importer subclass to emulate the standard importer."
-
-    def __init__(self, dir):
-        self.dir = dir
-
-    def get_code(self, parent, modname, fqname):
-        if parent:
-            dir = parent.__pkgdir__
-        else:
-            dir = self.dir
-
-        # Return the module (and other info) if found in the specified
-        # directory. Otherwise, return None.
-        return _fs_import(dir, modname, fqname)
-
-    def __repr__(self):
-        return '<%s.%s for "%s" at 0x%x>' % (self.__class__.__module__,
-                                             self.__class__.__name__,
-                                             self.dir,
-                                             id(self))
-
-
-######################################################################
-#
-# Emulate the standard path-style import mechanism
-#
-class PathImporter(imputil.Importer):
-    def __init__(self, path=sys.path):
-        self.path = path
-
-    def get_code(self, parent, modname, fqname):
-        if parent:
-            # we are looking for a module inside of a specific package
-            return _fs_import(parent.__pkgdir__, modname, fqname)
-
-        # scan sys.path, looking for the requested module
-        for dir in self.path:
-            if isinstance(dir, _StringType):
-                result = _fs_import(dir, modname, fqname)
-                if result:
-                    return result
-
-        # not found
-        return None
-
-######################################################################
-
-def _test_dir():
-    "Debug/test function to create DirectoryImporters from sys.path."
-    imputil.ImportManager().install()
-    path = sys.path[:]
-    path.reverse()
-    for d in path:
-        sys.path.insert(0, DirectoryImporter(d))
-    sys.path.insert(0, imputil.BuiltinImporter())
-
-def _test_revamp():
-    "Debug/test function for the revamped import system."
-    imputil.ImportManager().install()
-    sys.path.insert(0, PathImporter())
-    sys.path.insert(0, imputil.BuiltinImporter())

From python-3000-checkins at python.org  Fri Jun  6 01:07:42 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Fri,  6 Jun 2008 01:07:42 +0200 (CEST)
Subject: [Python-3000-checkins] r63968 - python/branches/py3k/Lib/tokenize.py
Message-ID: <20080605230742.933F81E4012@bag.python.org>

Author: benjamin.peterson
Date: Fri Jun  6 01:07:42 2008
New Revision: 63968

Log:
use the more idomatic (and Py3k faster) while True


Modified:
   python/branches/py3k/Lib/tokenize.py

Modified: python/branches/py3k/Lib/tokenize.py
==============================================================================
--- python/branches/py3k/Lib/tokenize.py	(original)
+++ python/branches/py3k/Lib/tokenize.py	Fri Jun  6 01:07:42 2008
@@ -337,7 +337,7 @@
 
     if encoding is not None:
         yield (ENCODING, encoding, (0, 0), (0, 0), '')
-    while 1:                                   # loop over lines in stream
+    while True:             # loop over lines in stream
         try:
             line = readline()
         except StopIteration:

From python-3000-checkins at python.org  Fri Jun  6 01:57:55 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Fri,  6 Jun 2008 01:57:55 +0200 (CEST)
Subject: [Python-3000-checkins] r63973 - python/branches/py3k
Message-ID: <20080605235755.3004F1E4004@bag.python.org>

Author: benjamin.peterson
Date: Fri Jun  6 01:57:54 2008
New Revision: 63973

Log:
Blocked revisions 63965,63967 via svnmerge

........
  r63965 | benjamin.peterson | 2008-06-05 17:39:34 -0500 (Thu, 05 Jun 2008) | 2 lines
  
  use the more idomatic while True
........
  r63967 | benjamin.peterson | 2008-06-05 18:02:33 -0500 (Thu, 05 Jun 2008) | 2 lines
  
  revert 63965 for preformance reasons
........


Modified:
   python/branches/py3k/   (props changed)

From python-3000-checkins at python.org  Fri Jun  6 11:02:07 2008
From: python-3000-checkins at python.org (georg.brandl)
Date: Fri,  6 Jun 2008 11:02:07 +0200 (CEST)
Subject: [Python-3000-checkins] r63978 - in python/branches/py3k:
	Lib/test/test_sys.py Python/sysmodule.c
Message-ID: <20080606090207.DA9561E4008@bag.python.org>

Author: georg.brandl
Date: Fri Jun  6 11:02:07 2008
New Revision: 63978

Log:
Fix sys.flags sequence behavior and add a test case.


Modified:
   python/branches/py3k/Lib/test/test_sys.py
   python/branches/py3k/Python/sysmodule.c

Modified: python/branches/py3k/Lib/test/test_sys.py
==============================================================================
--- python/branches/py3k/Lib/test/test_sys.py	(original)
+++ python/branches/py3k/Lib/test/test_sys.py	Fri Jun  6 11:02:07 2008
@@ -324,12 +324,13 @@
         self.failUnless(sys.flags)
         attrs = ("debug", "division_warning",
                  "inspect", "interactive", "optimize", "dont_write_bytecode",
-                 "no_site", "ignore_environment", "verbose",
+                 "no_user_site", "no_site", "ignore_environment", "verbose",
                  "bytes_warning")
         for attr in attrs:
             self.assert_(hasattr(sys.flags, attr), attr)
             self.assertEqual(type(getattr(sys.flags, attr)), int, attr)
         self.assert_(repr(sys.flags))
+        self.assertEqual(len(sys.flags), len(attrs))
 
     def test_clear_type_cache(self):
         sys._clear_type_cache()

Modified: python/branches/py3k/Python/sysmodule.c
==============================================================================
--- python/branches/py3k/Python/sysmodule.c	(original)
+++ python/branches/py3k/Python/sysmodule.c	Fri Jun  6 11:02:07 2008
@@ -1150,9 +1150,9 @@
 	flags__doc__,	/* doc */
 	flags_fields,	/* fields */
 #ifdef RISCOS
-	11
+	12
 #else
-	10
+	11
 #endif
 };
 

From python-3000-checkins at python.org  Fri Jun  6 11:11:46 2008
From: python-3000-checkins at python.org (thomas.heller)
Date: Fri,  6 Jun 2008 11:11:46 +0200 (CEST)
Subject: [Python-3000-checkins] r63979 - in python/branches/py3k:
	Lib/ctypes/test/__init__.py
	Modules/_ctypes/libffi/fficonfig.py.in setup.py
Message-ID: <20080606091146.6DAC11E4004@bag.python.org>

Author: thomas.heller
Date: Fri Jun  6 11:11:46 2008
New Revision: 63979

Log:
Merged revisions 63897-63898 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/trunk

........
  r63897 | thomas.heller | 2008-06-02 20:41:30 +0200 (Mon, 02 Jun 2008) | 1 line
  
  Fix misspelled sys.platform name and misspelled filename.
........
  r63898 | thomas.heller | 2008-06-02 22:07:46 +0200 (Mon, 02 Jun 2008) | 1 line
  
  Fix the -x flag so that is does work.
........


Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Lib/ctypes/test/__init__.py
   python/branches/py3k/Modules/_ctypes/libffi/fficonfig.py.in
   python/branches/py3k/setup.py

Modified: python/branches/py3k/Lib/ctypes/test/__init__.py
==============================================================================
--- python/branches/py3k/Lib/ctypes/test/__init__.py	(original)
+++ python/branches/py3k/Lib/ctypes/test/__init__.py	Fri Jun  6 11:11:46 2008
@@ -178,7 +178,7 @@
         elif flag == "-u":
             use_resources.extend(value.split(","))
         elif flag == "-x":
-            exclude.append(value.split(","))
+            exclude.extend(value.split(","))
 
     mask = "test_*.py"
     if args:

Modified: python/branches/py3k/Modules/_ctypes/libffi/fficonfig.py.in
==============================================================================
--- python/branches/py3k/Modules/_ctypes/libffi/fficonfig.py.in	(original)
+++ python/branches/py3k/Modules/_ctypes/libffi/fficonfig.py.in	Fri Jun  6 11:11:46 2008
@@ -25,7 +25,7 @@
     'SH64': ['src/sh64/sysv.S', 'src/sh64/ffi.c'],
     'PA': ['src/pa/linux.S', 'src/pa/ffi.c'],
     'PA_LINUX': ['src/pa/linux.S', 'src/pa/ffi.c'],
-    'PA_HPUX': ['src/pa/hpux32.s', 'src/pa/ffi.c'],
+    'PA_HPUX': ['src/pa/hpux32.S', 'src/pa/ffi.c'],
 }
 
 ffi_srcdir = '@srcdir@'

Modified: python/branches/py3k/setup.py
==============================================================================
--- python/branches/py3k/setup.py	(original)
+++ python/branches/py3k/setup.py	Fri Jun  6 11:11:46 2008
@@ -1416,7 +1416,7 @@
             # finding some -z option for the Sun compiler.
             extra_link_args.append('-mimpure-text')
 
-        elif sys.platform.startswith('hpux'):
+        elif sys.platform.startswith('hp-ux'):
             extra_link_args.append('-fPIC')
 
         ext = Extension('_ctypes',

From python-3000-checkins at python.org  Fri Jun  6 11:13:04 2008
From: python-3000-checkins at python.org (thomas.heller)
Date: Fri,  6 Jun 2008 11:13:04 +0200 (CEST)
Subject: [Python-3000-checkins] r63980 - python/branches/py3k
Message-ID: <20080606091304.A2E491E4004@bag.python.org>

Author: thomas.heller
Date: Fri Jun  6 11:13:04 2008
New Revision: 63980

Log:
Blocked revisions 63942-63943,63945 via svnmerge

........
  r63942 | thomas.heller | 2008-06-04 20:59:03 +0200 (Wed, 04 Jun 2008) | 42 lines
  
  Issue #1798: Add ctypes calling convention that allows safe access to
  errno (and LastError, on Windows).
  
  ctypes maintains a module-global, but thread-local, variable that
  contains an error number; called 'ctypes_errno' for this discussion.
  This variable is a private copy of the systems 'errno' value; the copy
  is swapped with the 'errno' variable on several occasions.
  
  Foreign functions created with CDLL(..., use_errno=True), when called,
  swap the values just before the actual function call, and swapped
  again immediately afterwards.  The 'use_errno' parameter defaults to
  False, in this case 'ctypes_errno' is not touched.
  
  The values are also swapped immeditately before and after ctypes
  callback functions are called, if the callbacks are constructed using
  the new optional use_errno parameter set to True: CFUNCTYPE(..., use_errno=TRUE)
  or WINFUNCTYPE(..., use_errno=True).
  
  Two new ctypes functions are provided to access the 'ctypes_errno'
  value from Python:
  
  - ctypes.set_errno(value) sets ctypes_errno to 'value', the previous
    ctypes_errno value is returned.
  
  - ctypes.get_errno() returns the current ctypes_errno value.
  
  ---
  
  On Windows, the same scheme is implemented for the error value which
  is managed by the GetLastError() and SetLastError() windows api calls.
  
  The ctypes functions are 'ctypes.set_last_error(value)' and
  'ctypes.get_last_error()', the CDLL and WinDLL optional parameter is
  named 'use_last_error', defaults to False.
  
  ---
  
  On Windows, TlsSetValue and TlsGetValue calls are used to provide
  thread local storage for the variables; ctypes compiled with __GNUC__
  uses __thread variables.
........
  r63943 | thomas.heller | 2008-06-04 21:19:00 +0200 (Wed, 04 Jun 2008) | 1 line
  
  Fix ctypes.set_errno for gcc.
........
  r63945 | thomas.heller | 2008-06-04 22:22:05 +0200 (Wed, 04 Jun 2008) | 7 lines
  
  Revert revisions 63943 and 63942 (Issue #1798: Add ctypes calling
  convention that allows safe access to errno)
  
  This code does not yet work on OS X (__thread storage specifier not
  available), so i needs a configure check plus a more portable
  solution.
........


Modified:
   python/branches/py3k/   (props changed)

From python-3000-checkins at python.org  Fri Jun  6 11:31:41 2008
From: python-3000-checkins at python.org (thomas.heller)
Date: Fri,  6 Jun 2008 11:31:41 +0200 (CEST)
Subject: [Python-3000-checkins] r63981 - in python/branches/py3k:
	Lib/ctypes/__init__.py Lib/ctypes/test/test_errno.py
	Modules/_ctypes/_ctypes.c Modules/_ctypes/callbacks.c
	Modules/_ctypes/callproc.c Modules/_ctypes/ctypes.h
Message-ID: <20080606093141.4690A1E4023@bag.python.org>

Author: thomas.heller
Date: Fri Jun  6 11:31:40 2008
New Revision: 63981

Log:
Merged revisions 63977 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/trunk

........
  r63977 | thomas.heller | 2008-06-06 10:33:46 +0200 (Fri, 06 Jun 2008) | 31 lines
  
  Issue #1798: Add ctypes calling convention that allows safe access of errno.
  
  ctypes maintains thread-local storage that has space for two error
  numbers: private copies of the system 'errno' value and, on Windows,
  the system error code accessed by the GetLastError() and
  SetLastError() api functions.
    
  Foreign functions created with CDLL(..., use_errno=True), when called,
  swap the system 'errno' value with the private copy just before the
  actual function call, and swapped again immediately afterwards.  The
  'use_errno' parameter defaults to False, in this case 'ctypes_errno'
  is not touched.
  
  On Windows, foreign functions created with CDLL(...,
  use_last_error=True) or WinDLL(..., use_last_error=True) swap the
  system LastError value with the ctypes private copy.
  
  The values are also swapped immeditately before and after ctypes
  callback functions are called, if the callbacks are constructed using
  the new optional use_errno parameter set to True: CFUNCTYPE(...,
  use_errno=TRUE) or WINFUNCTYPE(..., use_errno=True).
  
  New ctypes functions are provided to access the ctypes private copies
  from Python:
  
  - ctypes.set_errno(value) and ctypes.set_last_error(value) store
    'value' in the private copy and returns the previous value.
  
  - ctypes.get_errno() and ctypes.get_last_error() returns the current
    ctypes private copies value.
........


Added:
   python/branches/py3k/Lib/ctypes/test/test_errno.py
      - copied unchanged from r63977, /python/trunk/Lib/ctypes/test/test_errno.py
Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Lib/ctypes/__init__.py
   python/branches/py3k/Modules/_ctypes/_ctypes.c
   python/branches/py3k/Modules/_ctypes/callbacks.c
   python/branches/py3k/Modules/_ctypes/callproc.c
   python/branches/py3k/Modules/_ctypes/ctypes.h

Modified: python/branches/py3k/Lib/ctypes/__init__.py
==============================================================================
--- python/branches/py3k/Lib/ctypes/__init__.py	(original)
+++ python/branches/py3k/Lib/ctypes/__init__.py	Fri Jun  6 11:31:40 2008
@@ -30,7 +30,9 @@
         DEFAULT_MODE = RTLD_GLOBAL
 
 from _ctypes import FUNCFLAG_CDECL as _FUNCFLAG_CDECL, \
-     FUNCFLAG_PYTHONAPI as _FUNCFLAG_PYTHONAPI
+     FUNCFLAG_PYTHONAPI as _FUNCFLAG_PYTHONAPI, \
+     FUNCFLAG_USE_ERRNO as _FUNCFLAG_USE_ERRNO, \
+     FUNCFLAG_USE_LASTERROR as _FUNCFLAG_USE_LASTERROR
 
 """
 WINOLEAPI -> HRESULT
@@ -70,8 +72,9 @@
     return create_string_buffer(init, size)
 
 _c_functype_cache = {}
-def CFUNCTYPE(restype, *argtypes):
-    """CFUNCTYPE(restype, *argtypes) -> function prototype.
+def CFUNCTYPE(restype, *argtypes, **kw):
+    """CFUNCTYPE(restype, *argtypes,
+                 use_errno=False, use_last_error=False) -> function prototype.
 
     restype: the result type
     argtypes: a sequence specifying the argument types
@@ -85,14 +88,21 @@
     prototype((ordinal number, dll object)[, paramflags]) -> foreign function exported by ordinal
     prototype((function name, dll object)[, paramflags]) -> foreign function exported by name
     """
+    flags = _FUNCFLAG_CDECL
+    if kw.pop("use_errno", False):
+        flags |= _FUNCFLAG_USE_ERRNO
+    if kw.pop("use_last_error", False):
+        flags |= _FUNCFLAG_USE_LASTERROR
+    if kw:
+        raise ValueError("unexpected keyword argument(s) %s" % kw.keys())
     try:
-        return _c_functype_cache[(restype, argtypes)]
+        return _c_functype_cache[(restype, argtypes, flags)]
     except KeyError:
         class CFunctionType(_CFuncPtr):
             _argtypes_ = argtypes
             _restype_ = restype
-            _flags_ = _FUNCFLAG_CDECL
-        _c_functype_cache[(restype, argtypes)] = CFunctionType
+            _flags_ = flags
+        _c_functype_cache[(restype, argtypes, flags)] = CFunctionType
         return CFunctionType
 
 if _os.name in ("nt", "ce"):
@@ -103,16 +113,23 @@
         _FUNCFLAG_STDCALL = _FUNCFLAG_CDECL
 
     _win_functype_cache = {}
-    def WINFUNCTYPE(restype, *argtypes):
+    def WINFUNCTYPE(restype, *argtypes, **kw):
         # docstring set later (very similar to CFUNCTYPE.__doc__)
+        flags = _FUNCFLAG_STDCALL
+        if kw.pop("use_errno", False):
+            flags |= _FUNCFLAG_USE_ERRNO
+        if kw.pop("use_last_error", False):
+            flags |= _FUNCFLAG_USE_LASTERROR
+        if kw:
+            raise ValueError("unexpected keyword argument(s) %s" % kw.keys())
         try:
-            return _win_functype_cache[(restype, argtypes)]
+            return _win_functype_cache[(restype, argtypes, flags)]
         except KeyError:
             class WinFunctionType(_CFuncPtr):
                 _argtypes_ = argtypes
                 _restype_ = restype
-                _flags_ = _FUNCFLAG_STDCALL
-            _win_functype_cache[(restype, argtypes)] = WinFunctionType
+                _flags_ = flags
+            _win_functype_cache[(restype, argtypes, flags)] = WinFunctionType
             return WinFunctionType
     if WINFUNCTYPE.__doc__:
         WINFUNCTYPE.__doc__ = CFUNCTYPE.__doc__.replace("CFUNCTYPE", "WINFUNCTYPE")
@@ -121,6 +138,7 @@
     from _ctypes import dlopen as _dlopen
 
 from _ctypes import sizeof, byref, addressof, alignment, resize
+from _ctypes import get_errno, set_errno
 from _ctypes import _SimpleCData
 
 def _check_size(typ, typecode=None):
@@ -310,12 +328,24 @@
     Calling the functions releases the Python GIL during the call and
     reacquires it afterwards.
     """
-    class _FuncPtr(_CFuncPtr):
-        _flags_ = _FUNCFLAG_CDECL
-        _restype_ = c_int # default, can be overridden in instances
+    _func_flags_ = _FUNCFLAG_CDECL
+    _func_restype_ = c_int
 
-    def __init__(self, name, mode=DEFAULT_MODE, handle=None):
+    def __init__(self, name, mode=DEFAULT_MODE, handle=None,
+                 use_errno=False,
+                 use_last_error=False):
         self._name = name
+        flags = self._func_flags_
+        if use_errno:
+            flags |= _FUNCFLAG_USE_ERRNO
+        if use_last_error:
+            flags |= _FUNCFLAG_USE_LASTERROR
+
+        class _FuncPtr(_CFuncPtr):
+            _flags_ = flags
+            _restype_ = self._func_restype_
+        self._FuncPtr = _FuncPtr
+
         if handle is None:
             self._handle = _dlopen(self._name, mode)
         else:
@@ -345,9 +375,7 @@
     access Python API functions.  The GIL is not released, and
     Python exceptions are handled correctly.
     """
-    class _FuncPtr(_CFuncPtr):
-        _flags_ = _FUNCFLAG_CDECL | _FUNCFLAG_PYTHONAPI
-        _restype_ = c_int # default, can be overridden in instances
+    _func_flags_ = _FUNCFLAG_CDECL | _FUNCFLAG_PYTHONAPI
 
 if _os.name in ("nt", "ce"):
 
@@ -355,9 +383,7 @@
         """This class represents a dll exporting functions using the
         Windows stdcall calling convention.
         """
-        class _FuncPtr(_CFuncPtr):
-            _flags_ = _FUNCFLAG_STDCALL
-            _restype_ = c_int # default, can be overridden in instances
+        _func_flags_ = _FUNCFLAG_STDCALL
 
     # XXX Hm, what about HRESULT as normal parameter?
     # Mustn't it derive from c_long then?
@@ -381,9 +407,8 @@
         HRESULT error values are automatically raised as WindowsError
         exceptions.
         """
-        class _FuncPtr(_CFuncPtr):
-            _flags_ = _FUNCFLAG_STDCALL
-            _restype_ = HRESULT
+        _func_flags_ = _FUNCFLAG_STDCALL
+        _func_restype_ = HRESULT
 
 class LibraryLoader(object):
     def __init__(self, dlltype):
@@ -421,6 +446,7 @@
         GetLastError = windll.kernel32.GetLastError
     else:
         GetLastError = windll.coredll.GetLastError
+    from _ctypes import get_last_error, set_last_error
 
     def WinError(code=None, descr=None):
         if code is None:

Modified: python/branches/py3k/Modules/_ctypes/_ctypes.c
==============================================================================
--- python/branches/py3k/Modules/_ctypes/_ctypes.c	(original)
+++ python/branches/py3k/Modules/_ctypes/_ctypes.c	Fri Jun  6 11:31:40 2008
@@ -3340,7 +3340,7 @@
 	thunk = AllocFunctionCallback(callable,
 				      dict->argtypes,
 				      dict->restype,
-				      dict->flags & FUNCFLAG_CDECL);
+				      dict->flags);
 	if (!thunk)
 		return NULL;
 
@@ -5333,6 +5333,8 @@
 	PyModule_AddObject(m, "FUNCFLAG_STDCALL", PyLong_FromLong(FUNCFLAG_STDCALL));
 #endif
 	PyModule_AddObject(m, "FUNCFLAG_CDECL", PyLong_FromLong(FUNCFLAG_CDECL));
+	PyModule_AddObject(m, "FUNCFLAG_USE_ERRNO", PyLong_FromLong(FUNCFLAG_USE_ERRNO));
+	PyModule_AddObject(m, "FUNCFLAG_USE_LASTERROR", PyLong_FromLong(FUNCFLAG_USE_LASTERROR));
 	PyModule_AddObject(m, "FUNCFLAG_PYTHONAPI", PyLong_FromLong(FUNCFLAG_PYTHONAPI));
 	PyModule_AddStringConstant(m, "__version__", "1.1.0");
 

Modified: python/branches/py3k/Modules/_ctypes/callbacks.c
==============================================================================
--- python/branches/py3k/Modules/_ctypes/callbacks.c	(original)
+++ python/branches/py3k/Modules/_ctypes/callbacks.c	Fri Jun  6 11:31:40 2008
@@ -185,12 +185,15 @@
 			      SETFUNC setfunc,
 			      PyObject *callable,
 			      PyObject *converters,
+			      int flags,
 			      void **pArgs)
 {
 	Py_ssize_t i;
 	PyObject *result;
 	PyObject *arglist = NULL;
 	Py_ssize_t nArgs;
+	PyObject *error_object = NULL;
+	int *space;
 #ifdef WITH_THREAD
 	PyGILState_STATE state = PyGILState_Ensure();
 #endif
@@ -267,8 +270,41 @@
 #define CHECK(what, x) \
 if (x == NULL) _AddTraceback(what, "_ctypes/callbacks.c", __LINE__ - 1), PyErr_Print()
 
+	if (flags & (FUNCFLAG_USE_ERRNO | FUNCFLAG_USE_LASTERROR)) {
+		error_object = get_error_object(&space);
+		if (error_object == NULL)
+			goto Done;
+		if (flags & FUNCFLAG_USE_ERRNO) {
+			int temp = space[0];
+			space[0] = errno;
+			errno = temp;
+		}
+#ifdef MS_WIN32
+		if (flags & FUNCFLAG_USE_LASTERROR) {
+			int temp = space[1];
+			space[1] = GetLastError();
+			SetLastError(temp);
+		}
+#endif
+	}
+
 	result = PyObject_CallObject(callable, arglist);
 	CHECK("'calling callback function'", result);
+
+#ifdef MS_WIN32
+	if (flags & FUNCFLAG_USE_LASTERROR) {
+		int temp = space[1];
+		space[1] = GetLastError();
+		SetLastError(temp);
+	}
+#endif
+	if (flags & FUNCFLAG_USE_ERRNO) {
+		int temp = space[0];
+		space[0] = errno;
+		errno = temp;
+	}
+	Py_XDECREF(error_object);
+
 	if ((restype != &ffi_type_void) && result) {
 		PyObject *keep;
 		assert(setfunc);
@@ -319,6 +355,7 @@
 			  p->setfunc,
 			  p->callable,
 			  p->converters,
+			  p->flags,
 			  args);
 }
 
@@ -348,7 +385,7 @@
 CThunkObject *AllocFunctionCallback(PyObject *callable,
 				    PyObject *converters,
 				    PyObject *restype,
-				    int is_cdecl)
+				    int flags)
 {
 	int result;
 	CThunkObject *p;
@@ -368,6 +405,7 @@
 		goto error;
 	}
 
+	p->flags = flags;
 	for (i = 0; i < nArgs; ++i) {
 		PyObject *cnv = PySequence_GetItem(converters, i);
 		if (cnv == NULL)
@@ -395,7 +433,7 @@
 
 	cc = FFI_DEFAULT_ABI;
 #if defined(MS_WIN32) && !defined(_WIN32_WCE) && !defined(MS_WIN64)
-	if (is_cdecl == 0)
+	if ((flags & FUNCFLAG_CDECL) == 0)
 		cc = FFI_STDCALL;
 #endif
 	result = ffi_prep_cif(&p->cif, cc,

Modified: python/branches/py3k/Modules/_ctypes/callproc.c
==============================================================================
--- python/branches/py3k/Modules/_ctypes/callproc.c	(original)
+++ python/branches/py3k/Modules/_ctypes/callproc.c	Fri Jun  6 11:31:40 2008
@@ -78,7 +78,129 @@
 #define DONT_USE_SEH
 #endif
 
+/*
+  ctypes maintains thread-local storage that has space for two error numbers:
+  private copies of the system 'errno' value and, on Windows, the system error code
+  accessed by the GetLastError() and SetLastError() api functions.
+  
+  Foreign functions created with CDLL(..., use_errno=True), when called, swap
+  the system 'errno' value with the private copy just before the actual
+  function call, and swapped again immediately afterwards.  The 'use_errno'
+  parameter defaults to False, in this case 'ctypes_errno' is not touched.
+
+  On Windows, foreign functions created with CDLL(..., use_last_error=True) or
+  WinDLL(..., use_last_error=True) swap the system LastError value with the
+  ctypes private copy.
+
+  The values are also swapped immeditately before and after ctypes callback
+  functions are called, if the callbacks are constructed using the new
+  optional use_errno parameter set to True: CFUNCTYPE(..., use_errno=TRUE) or
+  WINFUNCTYPE(..., use_errno=True).
+
+  New ctypes functions are provided to access the ctypes private copies from
+  Python:
+
+  - ctypes.set_errno(value) and ctypes.set_last_error(value) store 'value' in
+    the private copy and returns the previous value.
+
+  - ctypes.get_errno() and ctypes.get_last_error() returns the current ctypes
+    private copies value.
+*/
+
+/*
+  This function creates and returns a thread-local Python object that has
+  space to store two integer error numbers; once created the Python object is
+  kept alive in the thread state dictionary as long as the thread itself.
+*/
+PyObject *
+get_error_object(int **pspace)
+{
+	PyObject *dict = PyThreadState_GetDict();
+	PyObject *errobj;
+	if (dict == 0) {
+		PyErr_SetString(PyExc_RuntimeError,
+				"cannot get thread state");
+		return NULL;
+	}
+	errobj = PyDict_GetItemString(dict, "ctypes.error_object");
+	if (errobj)
+		Py_INCREF(errobj);
+	else {
+		void *space = PyMem_Malloc(sizeof(int) * 2);
+		if (space == NULL)
+			return NULL;
+		memset(space, 0, sizeof(int) * 2);
+		errobj = PyCObject_FromVoidPtr(space, PyMem_Free);
+		if (errobj == NULL)
+			return NULL;
+		if (-1 == PyDict_SetItemString(dict, "ctypes.error_object",
+					       errobj)) {
+			Py_DECREF(errobj);
+			return NULL;
+		}
+	}
+	*pspace = (int *)PyCObject_AsVoidPtr(errobj);
+	return errobj;
+}
+
+static PyObject *
+get_error_internal(PyObject *self, PyObject *args, int index)
+{
+	int *space;
+	PyObject *errobj = get_error_object(&space);
+	PyObject *result;
+
+	if (errobj == NULL)
+		return NULL;
+	result = PyLong_FromLong(space[index]);
+	Py_DECREF(errobj);
+	return result;
+}
+
+static PyObject *
+set_error_internal(PyObject *self, PyObject *args, int index)
+{
+	int new_errno, old_errno;
+	PyObject *errobj;
+	int *space;
+
+	if (!PyArg_ParseTuple(args, "i", &new_errno))
+		return NULL;
+	errobj = get_error_object(&space);
+	if (errobj == NULL)
+		return NULL;
+	old_errno = space[index];
+	space[index] = new_errno;
+	Py_DECREF(errobj);
+	return PyLong_FromLong(old_errno);
+}
+
+static PyObject *
+get_errno(PyObject *self, PyObject *args)
+{
+	return get_error_internal(self, args, 0);
+}
+
+static PyObject *
+set_errno(PyObject *self, PyObject *args)
+{
+	return set_error_internal(self, args, 0);
+}
+
 #ifdef MS_WIN32
+
+static PyObject *
+get_last_error(PyObject *self, PyObject *args)
+{
+	return get_error_internal(self, args, 1);
+}
+
+static PyObject *
+set_last_error(PyObject *self, PyObject *args)
+{
+	return set_error_internal(self, args, 1);
+}
+
 PyObject *ComError;
 
 static TCHAR *FormatError(DWORD code)
@@ -614,6 +736,8 @@
 #ifdef WITH_THREAD
 	PyThreadState *_save = NULL; /* For Py_BLOCK_THREADS and Py_UNBLOCK_THREADS */
 #endif
+	PyObject *error_object = NULL;
+	int *space;
 	ffi_cif cif;
 	int cc;
 #ifdef MS_WIN32
@@ -645,11 +769,26 @@
 		return -1;
 	}
 
+	if (flags & (FUNCFLAG_USE_ERRNO | FUNCFLAG_USE_LASTERROR)) {
+		error_object = get_error_object(&space);
+		if (error_object == NULL)
+			return -1;
+	}
 #ifdef WITH_THREAD
 	if ((flags & FUNCFLAG_PYTHONAPI) == 0)
 		Py_UNBLOCK_THREADS
 #endif
+	if (flags & FUNCFLAG_USE_ERRNO) {
+		int temp = space[0];
+		space[0] = errno;
+		errno = temp;
+	}
 #ifdef MS_WIN32
+	if (flags & FUNCFLAG_USE_LASTERROR) {
+		int temp = space[1];
+		space[1] = GetLastError();
+		SetLastError(temp);
+	}
 #ifndef DONT_USE_SEH
 	__try {
 #endif
@@ -664,7 +803,18 @@
 		;
 	}
 #endif
+	if (flags & FUNCFLAG_USE_LASTERROR) {
+		int temp = space[1];
+		space[1] = GetLastError();
+		SetLastError(temp);
+	}
 #endif
+	if (flags & FUNCFLAG_USE_ERRNO) {
+		int temp = space[0];
+		space[0] = errno;
+		errno = temp;
+	}
+	Py_XDECREF(error_object);
 #ifdef WITH_THREAD
 	if ((flags & FUNCFLAG_PYTHONAPI) == 0)
 		Py_BLOCK_THREADS
@@ -1658,6 +1808,8 @@
 }
 
 PyMethodDef module_methods[] = {
+	{"get_errno", get_errno, METH_NOARGS},
+	{"set_errno", set_errno, METH_VARARGS},
 	{"POINTER", POINTER, METH_O },
 	{"pointer", pointer, METH_O },
 	{"_unpickle", unpickle, METH_VARARGS },
@@ -1667,6 +1819,8 @@
 	{"set_conversion_mode", set_conversion_mode, METH_VARARGS, set_conversion_mode_doc},
 #endif
 #ifdef MS_WIN32
+	{"get_last_error", get_last_error, METH_NOARGS},
+	{"set_last_error", set_last_error, METH_VARARGS},
 	{"CopyComPointer", copy_com_pointer, METH_VARARGS, copy_com_pointer_doc},
 	{"FormatError", format_error, METH_VARARGS, format_error_doc},
 	{"LoadLibrary", load_library, METH_VARARGS, load_library_doc},

Modified: python/branches/py3k/Modules/_ctypes/ctypes.h
==============================================================================
--- python/branches/py3k/Modules/_ctypes/ctypes.h	(original)
+++ python/branches/py3k/Modules/_ctypes/ctypes.h	Fri Jun  6 11:31:40 2008
@@ -56,6 +56,7 @@
 	PyObject_VAR_HEAD
 	ffi_closure *pcl; /* the C callable */
 	ffi_cif cif;
+	int flags;
 	PyObject *converters;
 	PyObject *callable;
 	PyObject *restype;
@@ -154,7 +155,7 @@
 extern CThunkObject *AllocFunctionCallback(PyObject *callable,
 					   PyObject *converters,
 					   PyObject *restype,
-					   int stdcall);
+					   int flags);
 /* a table entry describing a predefined ctypes type */
 struct fielddesc {
 	char code;
@@ -280,6 +281,8 @@
 #define FUNCFLAG_CDECL   0x1
 #define FUNCFLAG_HRESULT 0x2
 #define FUNCFLAG_PYTHONAPI 0x4
+#define FUNCFLAG_USE_ERRNO 0x8
+#define FUNCFLAG_USE_LASTERROR 0x10
 
 #define TYPEFLAG_ISPOINTER 0x100
 #define TYPEFLAG_HASPOINTER 0x200
@@ -356,6 +359,7 @@
 extern int IsSimpleSubType(PyObject *obj);
 
 extern PyObject *_pointer_type_cache;
+PyObject *get_error_object(int **pspace);
 
 #ifdef MS_WIN32
 extern PyObject *ComError;

From python-3000-checkins at python.org  Fri Jun  6 12:45:06 2008
From: python-3000-checkins at python.org (georg.brandl)
Date: Fri,  6 Jun 2008 12:45:06 +0200 (CEST)
Subject: [Python-3000-checkins] r63983 - python/branches/py3k
Message-ID: <20080606104506.C15061E4004@bag.python.org>

Author: georg.brandl
Date: Fri Jun  6 12:45:06 2008
New Revision: 63983

Log:
Blocked revisions 63982 via svnmerge

........
  r63982 | georg.brandl | 2008-06-06 10:43:43 +0000 (Fri, 06 Jun 2008) | 2 lines
  
  Fix brackets.
........


Modified:
   python/branches/py3k/   (props changed)

From python-3000-checkins at python.org  Fri Jun  6 13:49:52 2008
From: python-3000-checkins at python.org (robert.schuppenies)
Date: Fri,  6 Jun 2008 13:49:52 +0200 (CEST)
Subject: [Python-3000-checkins] r63985 -
	python/branches/py3k/Lib/test/test_sys.py
Message-ID: <20080606114952.3BA121E4004@bag.python.org>

Author: robert.schuppenies
Date: Fri Jun  6 13:49:51 2008
New Revision: 63985

Log:
Issue 3049: Some 3k sizeof tests fail.


Modified:
   python/branches/py3k/Lib/test/test_sys.py

Modified: python/branches/py3k/Lib/test/test_sys.py
==============================================================================
--- python/branches/py3k/Lib/test/test_sys.py	(original)
+++ python/branches/py3k/Lib/test/test_sys.py	Fri Jun  6 13:49:51 2008
@@ -424,18 +424,15 @@
                 return x
             return inner
         self.check_sizeof(get_cell().__closure__[0], h + p)
-        # code XXX wrong size
-        # self.check_sizeof(get_cell().__code__, h + self.align(4*i) + 8*p +\
-        #                    self.align(i) + 2*p)
+        # code
+        self.check_sizeof(get_cell().__code__, h + self.align(5*i) + 8*p +\
+                           self.align(i) + 2*p)
         # complex
         self.check_sizeof(complex(0,1), h + 2*8)
         # enumerate
         self.check_sizeof(enumerate([]), h + l + 3*p)
         # reverse
         self.check_sizeof(reversed(''), h + l + p )
-        # file XXX wrong size
-        #self.check_sizeof(self.file, h + 4*p + self.align(2*i) + 4*p +\
-        #                    self.align(3*i) + 3*p + self.align(i))
         # float
         self.check_sizeof(float(0), h + 8)
         # function
@@ -469,13 +466,13 @@
         class class_newstyle(object):
             def method():
                 pass
-        # type (PyTypeObject + PyNumberMethods +  PyMappingMethods +
-        #       PySequenceMethods +  PyBufferProcs)
-        # XXX wrong size
-        # len_typeobject = p + 2*l + 15*p + l + 4*p + l + 9*p + l + 11*p
-        # self.check_sizeof(class_newstyle,
-        #                  h + len_typeobject + 42*p + 10*p + 3*p + 6*p)
-
+        # type (PyTypeObject + PyNumberMethods + PyMappingMethods +
+        #       PySequenceMethods + PyBufferProcs)
+        self.check_sizeof(class_newstyle, h +\
+                          p + 2*l + 15*p + l + 4*p + l + 9*p + l + 11*p +\
+                              self.align(4) +\
+                          16*p + self.align(i) + 20*p +\
+                          10*p + 3*p + 2*p + 2*p);
 
     def test_specialtypes(self):
         i = self.i

From python-3000-checkins at python.org  Fri Jun  6 14:18:18 2008
From: python-3000-checkins at python.org (marc-andre.lemburg)
Date: Fri,  6 Jun 2008 14:18:18 +0200 (CEST)
Subject: [Python-3000-checkins] r63986 - in python/branches/py3k:
	Include/codecs.h Include/unicodeobject.h
	Lib/encodings/punycode.py Objects/bytearrayobject.c
	Objects/bytesobject.c Objects/unicodeobject.c Python/codecs.c
	Python/pythonrun.c
Message-ID: <20080606121818.8E3C71E4005@bag.python.org>

Author: marc-andre.lemburg
Date: Fri Jun  6 14:18:17 2008
New Revision: 63986

Log:
Move the codec decode type checks to bytes/bytearray.decode().

Use faster PyUnicode_FromEncodedObject() for bytes/bytearray.decode().

Add new PyCodec_KnownEncoding() API.

Add new PyUnicode_AsDecodedUnicode() and PyUnicode_AsEncodedUnicode() APIs.

Add missing PyUnicode_AsDecodedObject() to unicodeobject.h

Fix punicode codec to also work on memoryviews.



Modified:
   python/branches/py3k/Include/codecs.h
   python/branches/py3k/Include/unicodeobject.h
   python/branches/py3k/Lib/encodings/punycode.py
   python/branches/py3k/Objects/bytearrayobject.c
   python/branches/py3k/Objects/bytesobject.c
   python/branches/py3k/Objects/unicodeobject.c
   python/branches/py3k/Python/codecs.c
   python/branches/py3k/Python/pythonrun.c

Modified: python/branches/py3k/Include/codecs.h
==============================================================================
--- python/branches/py3k/Include/codecs.h	(original)
+++ python/branches/py3k/Include/codecs.h	Fri Jun  6 14:18:17 2008
@@ -27,7 +27,7 @@
        PyObject *search_function
        );
 
-/* Codec register lookup API.
+/* Codec registry lookup API.
 
    Looks up the given encoding and returns a CodecInfo object with
    function attributes which implement the different aspects of
@@ -49,6 +49,17 @@
        const char *encoding
        );
 
+/* Codec registry encoding check API.
+
+   Returns 1/0 depending on whether there is a registered codec for
+   the given encoding.
+
+*/
+
+PyAPI_FUNC(int) PyCodec_KnownEncoding(
+       const char *encoding
+       );
+
 /* Generic codec based encoding API.
 
    object is passed through the encoder function found for the given

Modified: python/branches/py3k/Include/unicodeobject.h
==============================================================================
--- python/branches/py3k/Include/unicodeobject.h	(original)
+++ python/branches/py3k/Include/unicodeobject.h	Fri Jun  6 14:18:17 2008
@@ -139,8 +139,11 @@
 
 # define PyUnicode_AsASCIIString PyUnicodeUCS2_AsASCIIString
 # define PyUnicode_AsCharmapString PyUnicodeUCS2_AsCharmapString
+# define PyUnicode_AsDecodedObject PyUnicodeUCS2_AsDecodedObject
+# define PyUnicode_AsDecodedUnicode PyUnicodeUCS2_AsDecodedUnicode
 # define PyUnicode_AsEncodedObject PyUnicodeUCS2_AsEncodedObject
 # define PyUnicode_AsEncodedString PyUnicodeUCS2_AsEncodedString
+# define PyUnicode_AsEncodedUnicode PyUnicodeUCS2_AsEncodedUnicode
 # define PyUnicode_AsLatin1String PyUnicodeUCS2_AsLatin1String
 # define PyUnicode_AsRawUnicodeEscapeString PyUnicodeUCS2_AsRawUnicodeEscapeString
 # define PyUnicode_AsUTF32String PyUnicodeUCS2_AsUTF32String
@@ -233,8 +236,11 @@
 
 # define PyUnicode_AsASCIIString PyUnicodeUCS4_AsASCIIString
 # define PyUnicode_AsCharmapString PyUnicodeUCS4_AsCharmapString
+# define PyUnicode_AsDecodedObject PyUnicodeUCS4_AsDecodedObject
+# define PyUnicode_AsDecodedUnicode PyUnicodeUCS4_AsDecodedUnicode
 # define PyUnicode_AsEncodedObject PyUnicodeUCS4_AsEncodedObject
 # define PyUnicode_AsEncodedString PyUnicodeUCS4_AsEncodedString
+# define PyUnicode_AsEncodedUnicode PyUnicodeUCS4_AsEncodedUnicode
 # define PyUnicode_AsLatin1String PyUnicodeUCS4_AsLatin1String
 # define PyUnicode_AsRawUnicodeEscapeString PyUnicodeUCS4_AsRawUnicodeEscapeString
 # define PyUnicode_AsUTF32String PyUnicodeUCS4_AsUTF32String
@@ -744,6 +750,24 @@
     const char *errors          /* error handling */
     );
 
+/* Decode a Unicode object unicode and return the result as Python
+   object. */
+
+PyAPI_FUNC(PyObject*) PyUnicode_AsDecodedObject(
+    PyObject *unicode,	 	/* Unicode object */
+    const char *encoding,	/* encoding */
+    const char *errors		/* error handling */
+    );
+
+/* Decode a Unicode object unicode and return the result as Unicode
+   object. */
+
+PyAPI_FUNC(PyObject*) PyUnicode_AsDecodedUnicode(
+    PyObject *unicode,	 	/* Unicode object */
+    const char *encoding,	/* encoding */
+    const char *errors		/* error handling */
+    );
+
 /* Encodes a Py_UNICODE buffer of the given size and returns a 
    Python string object. */
 
@@ -772,11 +796,21 @@
     const char *errors		/* error handling */
     );
 
+/* Encodes a Unicode object and returns the result as Unicode
+   object. */
+
+PyAPI_FUNC(PyObject*) PyUnicode_AsEncodedUnicode(
+    PyObject *unicode,	 	/* Unicode object */
+    const char *encoding,	/* encoding */
+    const char *errors		/* error handling */
+    );
+
+/* Build an encoding map. */
+
 PyAPI_FUNC(PyObject*) PyUnicode_BuildEncodingMap(
     PyObject* string            /* 256 character map */
    );
 
-
 /* --- UTF-7 Codecs ------------------------------------------------------- */
 
 PyAPI_FUNC(PyObject*) PyUnicode_DecodeUTF7(

Modified: python/branches/py3k/Lib/encodings/punycode.py
==============================================================================
--- python/branches/py3k/Lib/encodings/punycode.py	(original)
+++ python/branches/py3k/Lib/encodings/punycode.py	Fri Jun  6 14:18:17 2008
@@ -183,6 +183,8 @@
 def punycode_decode(text, errors):
     if isinstance(text, str):
         text = text.encode("ascii")
+    if isinstance(text, memoryview):
+        text = bytes(text)
     pos = text.rfind(b"-")
     if pos == -1:
         base = ""

Modified: python/branches/py3k/Objects/bytearrayobject.c
==============================================================================
--- python/branches/py3k/Objects/bytearrayobject.c	(original)
+++ python/branches/py3k/Objects/bytearrayobject.c	Fri Jun  6 14:18:17 2008
@@ -725,7 +725,7 @@
                             "string argument without an encoding");
             return -1;
         }
-        encoded = PyCodec_Encode(arg, encoding, errors);
+        encoded = PyUnicode_AsEncodedString(arg, encoding, errors);
         if (encoded == NULL)
             return -1;
         assert(PyBytes_Check(encoded));
@@ -2854,7 +2854,7 @@
         return NULL;
     if (encoding == NULL)
         encoding = PyUnicode_GetDefaultEncoding();
-    return PyCodec_Decode(self, encoding, errors);
+    return PyUnicode_FromEncodedObject(self, encoding, errors);
 }
 
 PyDoc_STRVAR(alloc_doc,

Modified: python/branches/py3k/Objects/bytesobject.c
==============================================================================
--- python/branches/py3k/Objects/bytesobject.c	(original)
+++ python/branches/py3k/Objects/bytesobject.c	Fri Jun  6 14:18:17 2008
@@ -2713,7 +2713,7 @@
 		return NULL;
 	if (encoding == NULL)
 		encoding = PyUnicode_GetDefaultEncoding();
-	return PyCodec_Decode(self, encoding, errors);
+	return PyUnicode_FromEncodedObject(self, encoding, errors);
 }
 
 
@@ -2899,7 +2899,7 @@
 					"string argument without an encoding");
 			return NULL;
 		}
-		new = PyCodec_Encode(x, encoding, errors);
+		new = PyUnicode_AsEncodedString(x, encoding, errors);
 		if (new == NULL)
 			return NULL;
 		assert(PyBytes_Check(new));

Modified: python/branches/py3k/Objects/unicodeobject.c
==============================================================================
--- python/branches/py3k/Objects/unicodeobject.c	(original)
+++ python/branches/py3k/Objects/unicodeobject.c	Fri Jun  6 14:18:17 2008
@@ -1099,14 +1099,18 @@
 
     /* Coerce object */
     if (PyBytes_Check(obj)) {
-	    s = PyBytes_AS_STRING(obj);
-	    len = PyBytes_GET_SIZE(obj);
-	    }
+        s = PyBytes_AS_STRING(obj);
+        len = PyBytes_GET_SIZE(obj);
+    }
+    else if (PyByteArray_Check(obj)) {
+        s = PyByteArray_AS_STRING(obj);
+        len = PyByteArray_GET_SIZE(obj);
+    }
     else if (PyObject_AsCharBuffer(obj, &s, &len)) {
 	/* Overwrite the error message with something more useful in
 	   case of a TypeError. */
 	if (PyErr_ExceptionMatches(PyExc_TypeError))
-	PyErr_Format(PyExc_TypeError,
+            PyErr_Format(PyExc_TypeError,
 			 "coercing to Unicode: need string or buffer, "
 			 "%.80s found",
 		     Py_TYPE(obj)->tp_name);
@@ -1188,7 +1192,7 @@
         goto onError;
     if (!PyUnicode_Check(unicode)) {
         PyErr_Format(PyExc_TypeError,
-                     "decoder did not return an unicode object (type=%.400s)",
+                     "decoder did not return a unicode object (type=%.400s)",
                      Py_TYPE(unicode)->tp_name);
         Py_DECREF(unicode);
         goto onError;
@@ -1225,6 +1229,37 @@
     return NULL;
 }
 
+PyObject *PyUnicode_AsDecodedUnicode(PyObject *unicode,
+                                     const char *encoding,
+                                     const char *errors)
+{
+    PyObject *v;
+
+    if (!PyUnicode_Check(unicode)) {
+        PyErr_BadArgument();
+        goto onError;
+    }
+
+    if (encoding == NULL)
+	encoding = PyUnicode_GetDefaultEncoding();
+
+    /* Decode via the codec registry */
+    v = PyCodec_Decode(unicode, encoding, errors);
+    if (v == NULL)
+        goto onError;
+    if (!PyUnicode_Check(v)) {
+        PyErr_Format(PyExc_TypeError,
+                     "decoder did not return a unicode object (type=%.400s)",
+                     Py_TYPE(v)->tp_name);
+        Py_DECREF(v);
+        goto onError;
+    }
+    return v;
+
+ onError:
+    return NULL;
+}
+
 PyObject *PyUnicode_Encode(const Py_UNICODE *s,
 			   Py_ssize_t size,
 			   const char *encoding,
@@ -1296,7 +1331,54 @@
     v = PyCodec_Encode(unicode, encoding, errors);
     if (v == NULL)
         goto onError;
-    assert(PyBytes_Check(v));
+    if (PyByteArray_Check(v)) {
+        char msg[100];
+        PyOS_snprintf(msg, sizeof(msg),
+                      "encoder %s returned buffer instead of bytes",
+                      encoding);
+        if (PyErr_WarnEx(PyExc_RuntimeWarning, msg, 1) < 0) {
+            v = NULL;
+            goto onError;
+        }
+        v = PyBytes_FromStringAndSize(PyByteArray_AS_STRING(v), Py_SIZE(v));
+    }
+    else if (!PyBytes_Check(v)) {
+        PyErr_Format(PyExc_TypeError,
+                     "encoder did not return a bytes object (type=%.400s)",
+                     Py_TYPE(v)->tp_name);
+        v = NULL;
+    }
+    return v;
+
+ onError:
+    return NULL;
+}
+
+PyObject *PyUnicode_AsEncodedUnicode(PyObject *unicode,
+                                     const char *encoding,
+                                     const char *errors)
+{
+    PyObject *v;
+
+    if (!PyUnicode_Check(unicode)) {
+        PyErr_BadArgument();
+        goto onError;
+    }
+
+    if (encoding == NULL)
+	encoding = PyUnicode_GetDefaultEncoding();
+
+    /* Encode via the codec registry */
+    v = PyCodec_Encode(unicode, encoding, errors);
+    if (v == NULL)
+        goto onError;
+    if (!PyUnicode_Check(v)) {
+        PyErr_Format(PyExc_TypeError,
+                     "encoder did not return an unicode object (type=%.400s)",
+                     Py_TYPE(v)->tp_name);
+        Py_DECREF(v);
+        goto onError;
+    }
     return v;
 
  onError:
@@ -6617,7 +6699,7 @@
 
     if (!PyArg_ParseTuple(args, "|ss:encode", &encoding, &errors))
         return NULL;
-    v = PyUnicode_AsEncodedObject((PyObject *)self, encoding, errors);
+    v = PyUnicode_AsEncodedString((PyObject *)self, encoding, errors);
     if (v == NULL)
         goto onError;
     if (!PyBytes_Check(v)) {

Modified: python/branches/py3k/Python/codecs.c
==============================================================================
--- python/branches/py3k/Python/codecs.c	(original)
+++ python/branches/py3k/Python/codecs.c	Fri Jun  6 14:18:17 2008
@@ -183,6 +183,23 @@
     return NULL;
 }
 
+/* Codec registry encoding check API. */
+
+int PyCodec_KnownEncoding(const char *encoding)
+{
+    PyObject *codecs;
+    
+    codecs = _PyCodec_Lookup(encoding);
+    if (!codecs) {
+	PyErr_Clear();
+	return 0;
+    }
+    else {
+	Py_DECREF(codecs);
+	return 1;
+    }
+}
+
 static
 PyObject *args_tuple(PyObject *object,
 		     const char *errors)
@@ -344,32 +361,20 @@
 			"encoder must return a tuple (object, integer)");
 	goto onError;
     }
-    v = PyTuple_GET_ITEM(result, 0);
-    if (PyByteArray_Check(v)) {
-        char msg[100];
-        PyOS_snprintf(msg, sizeof(msg),
-                      "encoder %s returned buffer instead of bytes",
-                      encoding);
-        if (PyErr_WarnEx(PyExc_RuntimeWarning, msg, 1) < 0) {
-            v = NULL;
-            goto onError;
-        }
-        v = PyBytes_FromStringAndSize(PyByteArray_AS_STRING(v), Py_SIZE(v));
-    }
-    else if (PyBytes_Check(v))
-        Py_INCREF(v);
-    else {
-        PyErr_SetString(PyExc_TypeError,
-                        "encoding must return a tuple(bytes, integer)");
-        v = NULL;
-    }
+    v = PyTuple_GET_ITEM(result,0);
+    Py_INCREF(v);
     /* We don't check or use the second (integer) entry. */
 
+    Py_DECREF(args);
+    Py_DECREF(encoder);
+    Py_DECREF(result);
+    return v;
+	
  onError:
     Py_XDECREF(result);
     Py_XDECREF(args);
     Py_XDECREF(encoder);
-    return v;
+    return NULL;
 }
 
 /* Decode an object (usually a Python string) using the given encoding

Modified: python/branches/py3k/Python/pythonrun.c
==============================================================================
--- python/branches/py3k/Python/pythonrun.c	(original)
+++ python/branches/py3k/Python/pythonrun.c	Fri Jun  6 14:18:17 2008
@@ -261,14 +261,10 @@
 
 	codeset = nl_langinfo(CODESET);
 	if (codeset && *codeset) {
-		PyObject *enc = PyCodec_Encoder(codeset);
-		if (enc) {
-			codeset = strdup(codeset);
-			Py_DECREF(enc);
-		} else {
-			codeset = NULL;
-			PyErr_Clear();
-		}
+	    if (PyCodec_KnownEncoding(codeset))
+		codeset = strdup(codeset);
+	    else
+		codeset = NULL;
 	} else
 		codeset = NULL;
 

From python-3000-checkins at python.org  Fri Jun  6 22:52:39 2008
From: python-3000-checkins at python.org (travis.oliphant)
Date: Fri,  6 Jun 2008 22:52:39 +0200 (CEST)
Subject: [Python-3000-checkins] r63994 - in python/branches/py3k:
	Include/object.h Modules/_bsddb.c Modules/_ctypes/_ctypes.c
	Modules/arraymodule.c Objects/abstract.c Objects/memoryobject.c
Message-ID: <20080606205239.17C7A1E4004@bag.python.org>

Author: travis.oliphant
Date: Fri Jun  6 22:52:38 2008
New Revision: 63994

Log:
Remove locking from buffer protocol as-per discussion.

Modified:
   python/branches/py3k/Include/object.h
   python/branches/py3k/Modules/_bsddb.c
   python/branches/py3k/Modules/_ctypes/_ctypes.c
   python/branches/py3k/Modules/arraymodule.c
   python/branches/py3k/Objects/abstract.c
   python/branches/py3k/Objects/memoryobject.c

Modified: python/branches/py3k/Include/object.h
==============================================================================
--- python/branches/py3k/Include/object.h	(original)
+++ python/branches/py3k/Include/object.h	Fri Jun  6 22:52:38 2008
@@ -163,7 +163,6 @@
 #define PyBUF_WRITABLE 0x0001
 /*  we used to include an E, backwards compatible alias  */
 #define PyBUF_WRITEABLE PyBUF_WRITABLE
-#define PyBUF_LOCK 0x0002
 #define PyBUF_FORMAT 0x0004
 #define PyBUF_ND 0x0008
 #define PyBUF_STRIDES (0x0010 | PyBUF_ND)
@@ -174,25 +173,15 @@
 
 #define PyBUF_CONTIG (PyBUF_ND | PyBUF_WRITABLE)
 #define PyBUF_CONTIG_RO (PyBUF_ND)
-#define PyBUF_CONTIG_LCK (PyBUF_ND | PyBUF_LOCK)
-#define PyBUF_CONTIG_XLCK (PyBUF_ND | PyBUF_LOCK | PyBUF_WRITABLE)
 
 #define PyBUF_STRIDED (PyBUF_STRIDES | PyBUF_WRITABLE)
 #define PyBUF_STRIDED_RO (PyBUF_STRIDES)
-#define PyBUF_STRIDED_LCK (PyBUF_STRIDES | PyBUF_LOCK)
-#define PyBUF_STRIDED_XLCK (PyBUF_STRIDES | PyBUF_LOCK | PyBUF_WRITABLE)
 
 #define PyBUF_RECORDS (PyBUF_STRIDES | PyBUF_WRITABLE | PyBUF_FORMAT)
 #define PyBUF_RECORDS_RO (PyBUF_STRIDES | PyBUF_FORMAT)
-#define PyBUF_RECORDS_LCK (PyBUF_STRIDES | PyBUF_LOCK | PyBUF_FORMAT)
-#define PyBUF_RECORDS_XLCK (PyBUF_STRIDES | PyBUF_LOCK | PyBUF_WRITABLE \
-			    | PyBUF_FORMAT)
 
 #define PyBUF_FULL (PyBUF_INDIRECT | PyBUF_WRITABLE | PyBUF_FORMAT)
 #define PyBUF_FULL_RO (PyBUF_INDIRECT | PyBUF_FORMAT)
-#define PyBUF_FULL_LCK (PyBUF_INDIRECT | PyBUF_LOCK | PyBUF_FORMAT)
-#define PyBUF_FULL_XLCK (PyBUF_INDIRECT | PyBUF_LOCK | PyBUF_WRITABLE \
-			 | PyBUF_FORMAT)
 
 
 #define PyBUF_READ  0x100

Modified: python/branches/py3k/Modules/_bsddb.c
==============================================================================
--- python/branches/py3k/Modules/_bsddb.c	(original)
+++ python/branches/py3k/Modules/_bsddb.c	Fri Jun  6 22:52:38 2008
@@ -312,12 +312,6 @@
                         "Py_buffer malloc failed");
         return NULL;
     }
-    /* We use PyBUF_LOCK to prevent other threads from trashing the data
-       buffer while we release the GIL.  http://bugs.python.org/issue1035 */
-    if (PyObject_GetBuffer(obj, view, PyBUF_LOCK) == -1) {
-        PyMem_Free(view);
-        return NULL;
-    }
     if (view->ndim > 1) {
         PyErr_SetString(PyExc_BufferError,
                         "buffers must be single dimension");

Modified: python/branches/py3k/Modules/_ctypes/_ctypes.c
==============================================================================
--- python/branches/py3k/Modules/_ctypes/_ctypes.c	(original)
+++ python/branches/py3k/Modules/_ctypes/_ctypes.c	Fri Jun  6 22:52:38 2008
@@ -2449,11 +2449,6 @@
 	Py_ssize_t i;
 
 	if (view == NULL) return 0;
-	if (((flags & PyBUF_LOCK) == PyBUF_LOCK)) {
-		PyErr_SetString(PyExc_BufferError,
-				"Cannot lock this object.");
-		return -1;
-	}
 
 	view->buf = self->b_ptr;
 	view->len = self->b_size;

Modified: python/branches/py3k/Modules/arraymodule.c
==============================================================================
--- python/branches/py3k/Modules/arraymodule.c	(original)
+++ python/branches/py3k/Modules/arraymodule.c	Fri Jun  6 22:52:38 2008
@@ -1779,11 +1779,6 @@
 static int
 array_buffer_getbuf(arrayobject *self, Py_buffer *view, int flags)
 {
-        if ((flags & PyBUF_LOCK)) {
-                PyErr_SetString(PyExc_BufferError,
-                                "Cannot lock data");
-                return -1;
-        }
         if (view==NULL) goto finish;
 
         view->buf = (void *)self->ob_item;

Modified: python/branches/py3k/Objects/abstract.c
==============================================================================
--- python/branches/py3k/Objects/abstract.c	(original)
+++ python/branches/py3k/Objects/abstract.c	Fri Jun  6 22:52:38 2008
@@ -672,12 +672,6 @@
 	      int readonly, int flags)
 {
 	if (view == NULL) return 0;
-	if (((flags & PyBUF_LOCK) == PyBUF_LOCK) &&
-	    readonly != 0) {
-		PyErr_SetString(PyExc_BufferError,
-				"Cannot lock this object.");
-		return -1;
-	}
 	if (((flags & PyBUF_WRITABLE) == PyBUF_WRITABLE) &&
 	    (readonly == 1)) {
 		PyErr_SetString(PyExc_BufferError,

Modified: python/branches/py3k/Objects/memoryobject.c
==============================================================================
--- python/branches/py3k/Objects/memoryobject.c	(original)
+++ python/branches/py3k/Objects/memoryobject.c	Fri Jun  6 22:52:38 2008
@@ -230,9 +230,6 @@
         case PyBUF_WRITE:
                 flags = PyBUF_FULL;
                 break;
-        case PyBUF_SHADOW:
-                flags = PyBUF_FULL_XLCK;
-                break;
         }
 
         if (PyObject_GetBuffer(obj, view, flags) != 0) {

From python-3000-checkins at python.org  Sat Jun  7 19:56:06 2008
From: python-3000-checkins at python.org (georg.brandl)
Date: Sat,  7 Jun 2008 19:56:06 +0200 (CEST)
Subject: [Python-3000-checkins] r64020 - python/branches/py3k
Message-ID: <20080607175606.1082D1E4004@bag.python.org>

Author: georg.brandl
Date: Sat Jun  7 19:56:05 2008
New Revision: 64020

Log:
Blocked revisions 64016,64018-64019 via svnmerge

........
  r64016 | georg.brandl | 2008-06-07 16:16:12 +0000 (Sat, 07 Jun 2008) | 2 lines
  
  Register IterableUserDict as a MutableMapping.
........
  r64018 | georg.brandl | 2008-06-07 17:03:28 +0000 (Sat, 07 Jun 2008) | 2 lines
  
  #3057: Fix the MutableMapping ABC to use the 2.6 dict interface.
........
  r64019 | georg.brandl | 2008-06-07 17:11:00 +0000 (Sat, 07 Jun 2008) | 2 lines
  
  Backport docs for abc module to 2.6.
........


Modified:
   python/branches/py3k/   (props changed)

From python-3000-checkins at python.org  Sat Jun  7 21:01:03 2008
From: python-3000-checkins at python.org (georg.brandl)
Date: Sat,  7 Jun 2008 21:01:03 +0200 (CEST)
Subject: [Python-3000-checkins] r64023 - python/branches/py3k/Lib/aifc.py
Message-ID: <20080607190103.A629D1E4004@bag.python.org>

Author: georg.brandl
Date: Sat Jun  7 21:01:03 2008
New Revision: 64023

Log:
Remove cl usage from aifc and use bytes throughout.

This module needs a test suite!


Modified:
   python/branches/py3k/Lib/aifc.py

Modified: python/branches/py3k/Lib/aifc.py
==============================================================================
--- python/branches/py3k/Lib/aifc.py	(original)
+++ python/branches/py3k/Lib/aifc.py	Sat Jun  7 21:01:03 2008
@@ -137,15 +137,15 @@
 import struct
 import builtins
 
-__all__ = ["Error","open","openfp"]
+__all__ = ["Error", "open", "openfp"]
 
 class Error(Exception):
     pass
 
 _AIFC_version = 0xA2805140     # Version 1 of AIFF-C
 
-_skiplist = 'COMT', 'INST', 'MIDI', 'AESD', \
-      'APPL', 'NAME', 'AUTH', '(c) ', 'ANNO'
+_skiplist = b'COMT', b'INST', b'MIDI', b'AESD', \
+      b'APPL', b'NAME', b'AUTH', b'(c) ', b'ANNO'
 
 def _read_long(file):
     try:
@@ -168,7 +168,7 @@
 def _read_string(file):
     length = ord(file.read(1))
     if length == 0:
-        data = ''
+        data = b''
     else:
         data = file.read(length)
     if length & 1 == 0:
@@ -203,10 +203,10 @@
 def _write_string(f, s):
     if len(s) > 255:
         raise ValueError("string exceeds maximum pstring length")
-    f.write(chr(len(s)))
+    f.write(struct.pack('b', len(s)))
     f.write(s)
     if len(s) & 1 == 0:
-        f.write(chr(0))
+        f.write(b'\x00')
 
 def _write_float(f, x):
     import math
@@ -281,17 +281,16 @@
 
     def initfp(self, file):
         self._version = 0
-        self._decomp = None
         self._convert = None
         self._markers = []
         self._soundpos = 0
         self._file = Chunk(file)
-        if self._file.getname() != 'FORM':
+        if self._file.getname() != b'FORM':
             raise Error('file does not start with FORM id')
         formdata = self._file.read(4)
-        if formdata == 'AIFF':
+        if formdata == b'AIFF':
             self._aifc = 0
-        elif formdata == 'AIFC':
+        elif formdata == b'AIFC':
             self._aifc = 1
         else:
             raise Error('not an AIFF or AIFF-C file')
@@ -303,39 +302,28 @@
             except EOFError:
                 break
             chunkname = chunk.getname()
-            if chunkname == 'COMM':
+            if chunkname == b'COMM':
                 self._read_comm_chunk(chunk)
                 self._comm_chunk_read = 1
-            elif chunkname == 'SSND':
+            elif chunkname == b'SSND':
                 self._ssnd_chunk = chunk
                 dummy = chunk.read(8)
                 self._ssnd_seek_needed = 0
-            elif chunkname == 'FVER':
+            elif chunkname == b'FVER':
                 self._version = _read_ulong(chunk)
-            elif chunkname == 'MARK':
+            elif chunkname == b'MARK':
                 self._readmark(chunk)
             elif chunkname in _skiplist:
                 pass
             else:
-                raise Error('unrecognized chunk type '+chunk.chunkname)
+                raise Error('unrecognized chunk type ' +
+                            chunkname.decode('latin1'))
             chunk.skip()
         if not self._comm_chunk_read or not self._ssnd_chunk:
             raise Error('COMM chunk and/or SSND chunk missing')
-        if self._aifc and self._decomp:
-            import cl
-            params = [cl.ORIGINAL_FORMAT, 0,
-                  cl.BITS_PER_COMPONENT, self._sampwidth * 8,
-                  cl.FRAME_RATE, self._framerate]
-            if self._nchannels == 1:
-                params[1] = cl.MONO
-            elif self._nchannels == 2:
-                params[1] = cl.STEREO_INTERLEAVED
-            else:
-                raise Error('cannot compress more than 2 channels')
-            self._decomp.SetParams(params)
 
     def __init__(self, f):
-        if type(f) == type(''):
+        if isinstance(f, str):
             f = builtins.open(f, 'rb')
         # else, assume it is an open file object already
         self.initfp(f)
@@ -351,9 +339,6 @@
         self._soundpos = 0
 
     def close(self):
-        if self._decomp:
-            self._decomp.CloseDecompressor()
-            self._decomp = None
         self._file = None
 
     def tell(self):
@@ -394,7 +379,7 @@
         for marker in self._markers:
             if id == marker[0]:
                 return marker
-        raise Error('marker %r does not exist' % (id,))
+        raise Error('marker {0!r} does not exist'.format(id))
 
     def setpos(self, pos):
         if pos < 0 or pos > self._nframes:
@@ -411,23 +396,21 @@
                 self._ssnd_chunk.seek(pos + 8)
             self._ssnd_seek_needed = 0
         if nframes == 0:
-            return ''
+            return b''
         data = self._ssnd_chunk.read(nframes * self._framesize)
         if self._convert and data:
             data = self._convert(data)
-        self._soundpos = self._soundpos + len(data) / (self._nchannels * self._sampwidth)
+        self._soundpos = self._soundpos + len(data) // (self._nchannels
+                                                        * self._sampwidth)
         return data
 
     #
     # Internal methods.
     #
 
-    def _decomp_data(self, data):
-        import cl
-        dummy = self._decomp.SetParam(cl.FRAME_BUFFER_SIZE,
-                          len(data) * 2)
-        return self._decomp.Decompress(len(data) / self._nchannels,
-                           data)
+    def _alaw2lin(self, data):
+        import audioop
+        return audioop.alaw2lin(data, 2)
 
     def _ulaw2lin(self, data):
         import audioop
@@ -438,14 +421,13 @@
         if not hasattr(self, '_adpcmstate'):
             # first time
             self._adpcmstate = None
-        data, self._adpcmstate = audioop.adpcm2lin(data, 2,
-                               self._adpcmstate)
+        data, self._adpcmstate = audioop.adpcm2lin(data, 2, self._adpcmstate)
         return data
 
     def _read_comm_chunk(self, chunk):
         self._nchannels = _read_short(chunk)
         self._nframes = _read_long(chunk)
-        self._sampwidth = (_read_short(chunk) + 7) / 8
+        self._sampwidth = (_read_short(chunk) + 7) // 8
         self._framerate = int(_read_float(chunk))
         self._framesize = self._nchannels * self._sampwidth
         if self._aifc:
@@ -466,42 +448,21 @@
                 chunk.file.seek(-1, 1)
             #DEBUG end
             self._compname = _read_string(chunk)
-            if self._comptype != 'NONE':
-                if self._comptype == 'G722':
-                    try:
-                        import audioop
-                    except ImportError:
-                        pass
-                    else:
-                        self._convert = self._adpcm2lin
-                        self._framesize = self._framesize / 4
-                        return
-                # for ULAW and ALAW try Compression Library
-                try:
-                    import cl
-                except ImportError:
-                    if self._comptype == 'ULAW':
-                        try:
-                            import audioop
-                            self._convert = self._ulaw2lin
-                            self._framesize = self._framesize / 2
-                            return
-                        except ImportError:
-                            pass
-                    raise Error('cannot read compressed AIFF-C files')
-                if self._comptype == 'ULAW':
-                    scheme = cl.G711_ULAW
-                    self._framesize = self._framesize / 2
-                elif self._comptype == 'ALAW':
-                    scheme = cl.G711_ALAW
-                    self._framesize = self._framesize / 2
+            if self._comptype != b'NONE':
+                if self._comptype == b'G722':
+                    self._convert = self._adpcm2lin
+                    self._framesize = self._framesize // 4
+                elif self._comptype in (b'ulaw', b'ULAW'):
+                    self._convert = self._ulaw2lin
+                    self._framesize = self._framesize // 2
+                elif self._comptype in (b'alaw', b'ALAW'):
+                    self._convert = self._alaw2lin
+                    self._framesize = self._framesize // 2
                 else:
                     raise Error('unsupported compression type')
-                self._decomp = cl.OpenDecompressor(scheme)
-                self._convert = self._decomp_data
         else:
-            self._comptype = 'NONE'
-            self._compname = 'not compressed'
+            self._comptype = b'NONE'
+            self._compname = b'not compressed'
 
     def _readmark(self, chunk):
         nmarkers = _read_short(chunk)
@@ -555,7 +516,7 @@
     # _datawritten -- the size of the audio samples actually written
 
     def __init__(self, f):
-        if type(f) == type(''):
+        if isinstance(f, str):
             filename = f
             f = builtins.open(f, 'wb')
         else:
@@ -570,9 +531,8 @@
     def initfp(self, file):
         self._file = file
         self._version = _AIFC_version
-        self._comptype = 'NONE'
-        self._compname = 'not compressed'
-        self._comp = None
+        self._comptype = b'NONE'
+        self._compname = b'not compressed'
         self._convert = None
         self._nchannels = 0
         self._sampwidth = 0
@@ -649,7 +609,8 @@
     def setcomptype(self, comptype, compname):
         if self._nframeswritten:
             raise Error('cannot change parameters after starting to write')
-        if comptype not in ('NONE', 'ULAW', 'ALAW', 'G722'):
+        if comptype not in (b'NONE', b'ulaw', b'ULAW',
+                            b'alaw', b'ALAW', b'G722'):
             raise Error('unsupported compression type')
         self._comptype = comptype
         self._compname = compname
@@ -669,7 +630,8 @@
         nchannels, sampwidth, framerate, nframes, comptype, compname = params
         if self._nframeswritten:
             raise Error('cannot change parameters after starting to write')
-        if comptype not in ('NONE', 'ULAW', 'ALAW', 'G722'):
+        if comptype not in (b'NONE', b'ulaw', b'ULAW',
+                            b'alaw', b'ALAW', b'G722'):
             raise Error('unsupported compression type')
         self.setnchannels(nchannels)
         self.setsampwidth(sampwidth)
@@ -688,7 +650,7 @@
             raise Error('marker ID must be > 0')
         if pos < 0:
             raise Error('marker position must be >= 0')
-        if type(name) != type(''):
+        if not isinstance(name, str):
             raise Error('marker name must be a string')
         for i in range(len(self._markers)):
             if id == self._markers[i][0]:
@@ -700,7 +662,7 @@
         for marker in self._markers:
             if id == marker[0]:
                 return marker
-        raise Error('marker %r does not exist' % (id,))
+        raise Error('marker {0!r} does not exist'.format(id))
 
     def getmarkers(self):
         if len(self._markers) == 0:
@@ -712,7 +674,7 @@
 
     def writeframesraw(self, data):
         self._ensure_header_written(len(data))
-        nframes = len(data) / (self._sampwidth * self._nchannels)
+        nframes = len(data) // (self._sampwidth * self._nchannels)
         if self._convert:
             data = self._convert(data)
         self._file.write(data)
@@ -729,16 +691,13 @@
         self._ensure_header_written(0)
         if self._datawritten & 1:
             # quick pad to even size
-            self._file.write(chr(0))
+            self._file.write(b'\x00')
             self._datawritten = self._datawritten + 1
         self._writemarkers()
         if self._nframeswritten != self._nframes or \
               self._datalength != self._datawritten or \
               self._marklength:
             self._patchheader()
-        if self._comp:
-            self._comp.CloseCompressor()
-            self._comp = None
         self._file.flush()
         self._file = None
 
@@ -746,11 +705,9 @@
     # Internal methods.
     #
 
-    def _comp_data(self, data):
-        import cl
-        dummy = self._comp.SetParam(cl.FRAME_BUFFER_SIZE, len(data))
-        dummy = self._comp.SetParam(cl.COMPRESSED_BUFFER_SIZE, len(data))
-        return self._comp.Compress(self._nframes, data)
+    def _lin2alaw(self, data):
+        import audioop
+        return audioop.lin2alaw(data, 2)
 
     def _lin2ulaw(self, data):
         import audioop
@@ -760,22 +717,23 @@
         import audioop
         if not hasattr(self, '_adpcmstate'):
             self._adpcmstate = None
-        data, self._adpcmstate = audioop.lin2adpcm(data, 2,
-                               self._adpcmstate)
+        data, self._adpcmstate = audioop.lin2adpcm(data, 2, self._adpcmstate)
         return data
 
     def _ensure_header_written(self, datasize):
         if not self._nframeswritten:
-            if self._comptype in ('ULAW', 'ALAW'):
+            if self._comptype in (b'ULAW', b'ALAW'):
                 if not self._sampwidth:
                     self._sampwidth = 2
                 if self._sampwidth != 2:
-                    raise Error('sample width must be 2 when compressing with ULAW or ALAW')
-            if self._comptype == 'G722':
+                    raise Error('sample width must be 2 when compressing '
+                                'with ulaw/ULAW or alaw/ALAW')
+            if self._comptype == b'G722':
                 if not self._sampwidth:
                     self._sampwidth = 2
                 if self._sampwidth != 2:
-                    raise Error('sample width must be 2 when compressing with G7.22 (ADPCM)')
+                    raise Error('sample width must be 2 when compressing '
+                                'with G7.22 (ADPCM)')
             if not self._nchannels:
                 raise Error('# channels not specified')
             if not self._sampwidth:
@@ -785,71 +743,43 @@
             self._write_header(datasize)
 
     def _init_compression(self):
-        if self._comptype == 'G722':
+        if self._comptype == b'G722':
             self._convert = self._lin2adpcm
-            return
-        try:
-            import cl
-        except ImportError:
-            if self._comptype == 'ULAW':
-                try:
-                    import audioop
-                    self._convert = self._lin2ulaw
-                    return
-                except ImportError:
-                    pass
-            raise Error('cannot write compressed AIFF-C files')
-        if self._comptype == 'ULAW':
-            scheme = cl.G711_ULAW
-        elif self._comptype == 'ALAW':
-            scheme = cl.G711_ALAW
+        elif self._comptype in (b'ulaw', b'ULAW'):
+            self._convert = self._lin2ulaw
+        elif self._comptype in (b'alaw', b'ALAW'):
+            self._convert = self._lin2alaw
         else:
             raise Error('unsupported compression type')
-        self._comp = cl.OpenCompressor(scheme)
-        params = [cl.ORIGINAL_FORMAT, 0,
-              cl.BITS_PER_COMPONENT, self._sampwidth * 8,
-              cl.FRAME_RATE, self._framerate,
-              cl.FRAME_BUFFER_SIZE, 100,
-              cl.COMPRESSED_BUFFER_SIZE, 100]
-        if self._nchannels == 1:
-            params[1] = cl.MONO
-        elif self._nchannels == 2:
-            params[1] = cl.STEREO_INTERLEAVED
-        else:
-            raise Error('cannot compress more than 2 channels')
-        self._comp.SetParams(params)
-        # the compressor produces a header which we ignore
-        dummy = self._comp.Compress(0, '')
-        self._convert = self._comp_data
 
     def _write_header(self, initlength):
-        if self._aifc and self._comptype != 'NONE':
+        if self._aifc and self._comptype != b'NONE':
             self._init_compression()
-        self._file.write('FORM')
+        self._file.write(b'FORM')
         if not self._nframes:
-            self._nframes = initlength / (self._nchannels * self._sampwidth)
+            self._nframes = initlength // (self._nchannels * self._sampwidth)
         self._datalength = self._nframes * self._nchannels * self._sampwidth
         if self._datalength & 1:
             self._datalength = self._datalength + 1
         if self._aifc:
-            if self._comptype in ('ULAW', 'ALAW'):
-                self._datalength = self._datalength / 2
+            if self._comptype in (b'ulaw', b'ULAW', b'alaw', b'ALAW'):
+                self._datalength = self._datalength // 2
                 if self._datalength & 1:
                     self._datalength = self._datalength + 1
-            elif self._comptype == 'G722':
-                self._datalength = (self._datalength + 3) / 4
+            elif self._comptype == b'G722':
+                self._datalength = (self._datalength + 3) // 4
                 if self._datalength & 1:
                     self._datalength = self._datalength + 1
         self._form_length_pos = self._file.tell()
         commlength = self._write_form_length(self._datalength)
         if self._aifc:
-            self._file.write('AIFC')
-            self._file.write('FVER')
+            self._file.write(b'AIFC')
+            self._file.write(b'FVER')
             _write_long(self._file, 4)
             _write_long(self._file, self._version)
         else:
-            self._file.write('AIFF')
-        self._file.write('COMM')
+            self._file.write(b'AIFF')
+        self._file.write(b'COMM')
         _write_long(self._file, commlength)
         _write_short(self._file, self._nchannels)
         self._nframes_pos = self._file.tell()
@@ -859,7 +789,7 @@
         if self._aifc:
             self._file.write(self._comptype)
             _write_string(self._file, self._compname)
-        self._file.write('SSND')
+        self._file.write(b'SSND')
         self._ssnd_length_pos = self._file.tell()
         _write_long(self._file, self._datalength + 8)
         _write_long(self._file, 0)
@@ -882,7 +812,7 @@
         curpos = self._file.tell()
         if self._datawritten & 1:
             datalength = self._datawritten + 1
-            self._file.write(chr(0))
+            self._file.write(b'\x00')
         else:
             datalength = self._datawritten
         if datalength == self._datalength and \
@@ -903,7 +833,7 @@
     def _writemarkers(self):
         if len(self._markers) == 0:
             return
-        self._file.write('MARK')
+        self._file.write(b'MARK')
         length = 2
         for marker in self._markers:
             id, pos, name = marker

From python-3000-checkins at python.org  Sun Jun  8 04:26:05 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Sun,  8 Jun 2008 04:26:05 +0200 (CEST)
Subject: [Python-3000-checkins] r64032 - python/branches/py3k
Message-ID: <20080608022605.55E431E4004@bag.python.org>

Author: benjamin.peterson
Date: Sun Jun  8 04:26:05 2008
New Revision: 64032

Log:
Blocked revisions 64031 via svnmerge

........
  r64031 | benjamin.peterson | 2008-06-07 21:05:33 -0500 (Sat, 07 Jun 2008) | 2 lines
  
  change Py3k backquote warning to a SyntaxWarning and add a test
........


Modified:
   python/branches/py3k/   (props changed)

From python-3000-checkins at python.org  Sun Jun  8 10:40:06 2008
From: python-3000-checkins at python.org (georg.brandl)
Date: Sun,  8 Jun 2008 10:40:06 +0200 (CEST)
Subject: [Python-3000-checkins] r64033 - python/branches/py3k/Lib/calendar.py
Message-ID: <20080608084006.14F371E4004@bag.python.org>

Author: georg.brandl
Date: Sun Jun  8 10:40:05 2008
New Revision: 64033

Log:
#3059: Stop decoding Unicode in calendar module.
The strftime routines must know how to decode
localized month/day names themselves.


Modified:
   python/branches/py3k/Lib/calendar.py

Modified: python/branches/py3k/Lib/calendar.py
==============================================================================
--- python/branches/py3k/Lib/calendar.py	(original)
+++ python/branches/py3k/Lib/calendar.py	Sun Jun  8 10:40:05 2008
@@ -481,13 +481,13 @@
         return ''.join(v).encode(encoding, "xmlcharrefreplace")
 
 
-class TimeEncoding:
+class different_locale:
     def __init__(self, locale):
         self.locale = locale
 
     def __enter__(self):
         self.oldlocale = _locale.setlocale(_locale.LC_TIME, self.locale)
-        return _locale.getlocale(_locale.LC_TIME)[1]
+        #return _locale.getlocale(_locale.LC_TIME)[1]
 
     def __exit__(self, *args):
         _locale.setlocale(_locale.LC_TIME, self.oldlocale)
@@ -508,21 +508,17 @@
         self.locale = locale
 
     def formatweekday(self, day, width):
-        with TimeEncoding(self.locale) as encoding:
+        with different_locale(self.locale):
             if width >= 9:
                 names = day_name
             else:
                 names = day_abbr
             name = names[day]
-            if encoding is not None:
-                name = name.decode(encoding)
             return name[:width].center(width)
 
     def formatmonthname(self, theyear, themonth, width, withyear=True):
-        with TimeEncoding(self.locale) as encoding:
+        with different_locale(self.locale):
             s = month_name[themonth]
-            if encoding is not None:
-                s = s.decode(encoding)
             if withyear:
                 s = "%s %r" % (s, theyear)
             return s.center(width)
@@ -542,17 +538,13 @@
         self.locale = locale
 
     def formatweekday(self, day):
-        with TimeEncoding(self.locale) as encoding:
+        with different_locale(self.locale):
             s = day_abbr[day]
-            if encoding is not None:
-                s = s.decode(encoding)
             return '<th class="%s">%s</th>' % (self.cssclasses[day], s)
 
     def formatmonthname(self, theyear, themonth, withyear=True):
-        with TimeEncoding(self.locale) as encoding:
+        with different_locale(self.locale):
             s = month_name[themonth]
-            if encoding is not None:
-                s = s.decode(encoding)
             if withyear:
                 s = '%s %s' % (s, theyear)
             return '<tr><th colspan="7" class="month">%s</th></tr>' % s

From python-3000-checkins at python.org  Sun Jun  8 17:54:35 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Sun,  8 Jun 2008 17:54:35 +0200 (CEST)
Subject: [Python-3000-checkins] r64041 - python/branches/py3k
Message-ID: <20080608155435.B59D31E4004@bag.python.org>

Author: benjamin.peterson
Date: Sun Jun  8 17:54:35 2008
New Revision: 64041

Log:
Blocked revisions 64040 via svnmerge

........
  r64040 | benjamin.peterson | 2008-06-08 10:45:23 -0500 (Sun, 08 Jun 2008) | 2 lines
  
  add an ast_warn helper function to make adding those Py3k warnings easier
........


Modified:
   python/branches/py3k/   (props changed)

From python-3000-checkins at python.org  Mon Jun  9 01:04:41 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Mon,  9 Jun 2008 01:04:41 +0200 (CEST)
Subject: [Python-3000-checkins] r64046 - python/branches/py3k
Message-ID: <20080608230441.182FA1E4004@bag.python.org>

Author: benjamin.peterson
Date: Mon Jun  9 01:04:40 2008
New Revision: 64046

Log:
Blocked revisions 64044-64045 via svnmerge

........
  r64044 | benjamin.peterson | 2008-06-08 17:52:37 -0500 (Sun, 08 Jun 2008) | 2 lines
  
  Warn about assigning to Py3k keywords (True and False)
........
  r64045 | benjamin.peterson | 2008-06-08 18:00:00 -0500 (Sun, 08 Jun 2008) | 2 lines
  
  warn about parameter tuple unpacking
........


Modified:
   python/branches/py3k/   (props changed)

From python-3000-checkins at python.org  Mon Jun  9 07:13:42 2008
From: python-3000-checkins at python.org (gregory.p.smith)
Date: Mon,  9 Jun 2008 07:13:42 +0200 (CEST)
Subject: [Python-3000-checkins] r64049 - python/branches/py3k
Message-ID: <20080609051342.7447A1E4004@bag.python.org>

Author: gregory.p.smith
Date: Mon Jun  9 07:13:42 2008
New Revision: 64049

Log:
block r64048

Modified:
   python/branches/py3k/   (props changed)

From python-3000-checkins at python.org  Tue Jun 10 06:03:04 2008
From: python-3000-checkins at python.org (alexandre.vassalotti)
Date: Tue, 10 Jun 2008 06:03:04 +0200 (CEST)
Subject: [Python-3000-checkins] r64059 - in python/branches/py3k:
	Lib/test/test_range.py Objects/rangeobject.c
Message-ID: <20080610040304.99EC41E4002@bag.python.org>

Author: alexandre.vassalotti
Date: Tue Jun 10 06:03:04 2008
New Revision: 64059

Log:
Issue 2582: Fix pickling of range objects.


Modified:
   python/branches/py3k/Lib/test/test_range.py
   python/branches/py3k/Objects/rangeobject.c

Modified: python/branches/py3k/Lib/test/test_range.py
==============================================================================
--- python/branches/py3k/Lib/test/test_range.py	(original)
+++ python/branches/py3k/Lib/test/test_range.py	Tue Jun 10 06:03:04 2008
@@ -2,6 +2,7 @@
 
 import test.support, unittest
 import sys
+import pickle
 
 import warnings
 warnings.filterwarnings("ignore", "integer argument expected",
@@ -61,6 +62,15 @@
         self.assertEqual(repr(range(1, 2)), 'range(1, 2)')
         self.assertEqual(repr(range(1, 2, 3)), 'range(1, 2, 3)')
 
+    def test_pickling(self):
+        testcases = [(13,), (0, 11), (-22, 10), (20, 3, -1),
+                     (13, 21, 3), (-2, 2, 2)]
+        for proto in range(pickle.HIGHEST_PROTOCOL):
+            for t in testcases:
+                r = range(*t)
+                self.assertEquals(list(pickle.loads(pickle.dumps(r, proto))),
+                                  list(r))
+
 def test_main():
     test.support.run_unittest(RangeTest)
 

Modified: python/branches/py3k/Objects/rangeobject.c
==============================================================================
--- python/branches/py3k/Objects/rangeobject.c	(original)
+++ python/branches/py3k/Objects/rangeobject.c	Tue Jun 10 06:03:04 2008
@@ -252,6 +252,14 @@
                                     r->start, r->stop, r->step);
 }
 
+/* Pickling support */
+static PyObject *
+range_reduce(rangeobject *r, PyObject *args)
+{
+	return Py_BuildValue("(O(OOO))", Py_TYPE(r),
+                         r->start, r->stop, r->step);
+}
+
 static PySequenceMethods range_as_sequence = {
     (lenfunc)range_length,	/* sq_length */
     0,			/* sq_concat */
@@ -269,6 +277,7 @@
 static PyMethodDef range_methods[] = {
     {"__reversed__",	(PyCFunction)range_reverse, METH_NOARGS,
 	reverse_doc},
+    {"__reduce__",	(PyCFunction)range_reduce, METH_VARARGS},
     {NULL,		NULL}		/* sentinel */
 };
 

From python-3000-checkins at python.org  Tue Jun 10 06:04:02 2008
From: python-3000-checkins at python.org (alexandre.vassalotti)
Date: Tue, 10 Jun 2008 06:04:02 +0200 (CEST)
Subject: [Python-3000-checkins] r64060 - python/branches/py3k
Message-ID: <20080610040402.B12D61E4002@bag.python.org>

Author: alexandre.vassalotti
Date: Tue Jun 10 06:04:02 2008
New Revision: 64060

Log:
Blocked revisions 64057-64058 via svnmerge

........
  r64057 | alexandre.vassalotti | 2008-06-09 23:34:53 -0400 (Mon, 09 Jun 2008) | 2 lines
  
  Issue 2582: Fix pickling of xrange objects.
........
  r64058 | alexandre.vassalotti | 2008-06-10 00:01:23 -0400 (Tue, 10 Jun 2008) | 3 lines
  
  Added better pickling support to xrange objects.
  Cleaned up the unit test.
........


Modified:
   python/branches/py3k/   (props changed)

From python-3000-checkins at python.org  Tue Jun 10 06:44:09 2008
From: python-3000-checkins at python.org (martin.v.loewis)
Date: Tue, 10 Jun 2008 06:44:09 +0200 (CEST)
Subject: [Python-3000-checkins] r64061 - in python/branches/py3k:
	Demo/turtle Demo/turtle/about_turtle.txt
	Demo/turtle/about_turtledemo.txt Demo/turtle/demohelp.txt
	Demo/turtle/tdemo_I_dontlike_tiltdemo.py
	Demo/turtle/tdemo_bytedesign.py Demo/turtle/tdemo_chaos.py
	Demo/turtle/tdemo_clock.py Demo/turtle/tdemo_colormixer.py
	Demo/turtle/tdemo_forest.py Demo/turtle/tdemo_fractalcurves.py
	Demo/turtle/tdemo_lindenmayer_indian.py
	Demo/turtle/tdemo_minimal_hanoi.py Demo/turtle/tdemo_paint.py
	Demo/turtle/tdemo_peace.py Demo/turtle/tdemo_penrose.py
	Demo/turtle/tdemo_planet_and_moon.py
	Demo/turtle/tdemo_tree.py Demo/turtle/tdemo_wikipedia.py
	Demo/turtle/tdemo_yinyang.py Demo/turtle/turtleDemo.py
	Demo/turtle/turtledemo_two_canvases.py
	Doc/library/tkinter.turtle.rst Lib/tkinter/turtle.py Misc/ACKS
Message-ID: <20080610044409.6D9D41E4002@bag.python.org>

Author: martin.v.loewis
Date: Tue Jun 10 06:44:07 2008
New Revision: 64061

Log:
Patch #3064: Port new turtle module and demos to 3.0.


Added:
   python/branches/py3k/Demo/turtle/
      - copied from r63929, /python/trunk/Demo/turtle/
   python/branches/py3k/Demo/turtle/tdemo_forest.py   (contents, props changed)
Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Demo/turtle/about_turtle.txt
   python/branches/py3k/Demo/turtle/about_turtledemo.txt
   python/branches/py3k/Demo/turtle/demohelp.txt
   python/branches/py3k/Demo/turtle/tdemo_I_dontlike_tiltdemo.py
   python/branches/py3k/Demo/turtle/tdemo_bytedesign.py
   python/branches/py3k/Demo/turtle/tdemo_chaos.py
   python/branches/py3k/Demo/turtle/tdemo_clock.py
   python/branches/py3k/Demo/turtle/tdemo_colormixer.py
   python/branches/py3k/Demo/turtle/tdemo_fractalcurves.py
   python/branches/py3k/Demo/turtle/tdemo_lindenmayer_indian.py
   python/branches/py3k/Demo/turtle/tdemo_minimal_hanoi.py
   python/branches/py3k/Demo/turtle/tdemo_paint.py
   python/branches/py3k/Demo/turtle/tdemo_peace.py
   python/branches/py3k/Demo/turtle/tdemo_penrose.py
   python/branches/py3k/Demo/turtle/tdemo_planet_and_moon.py
   python/branches/py3k/Demo/turtle/tdemo_tree.py
   python/branches/py3k/Demo/turtle/tdemo_wikipedia.py
   python/branches/py3k/Demo/turtle/tdemo_yinyang.py
   python/branches/py3k/Demo/turtle/turtleDemo.py
   python/branches/py3k/Demo/turtle/turtledemo_two_canvases.py
   python/branches/py3k/Doc/library/tkinter.turtle.rst
   python/branches/py3k/Lib/tkinter/turtle.py
   python/branches/py3k/Misc/ACKS

Modified: python/branches/py3k/Demo/turtle/about_turtle.txt
==============================================================================
--- /python/trunk/Demo/turtle/about_turtle.txt	(original)
+++ python/branches/py3k/Demo/turtle/about_turtle.txt	Tue Jun 10 06:44:07 2008
@@ -1,6 +1,6 @@
 
 ========================================================
-                       A new turtle module for Python
+    A new turtle module for Python
 ========================================================
 
 Turtle graphics is a popular way for introducing programming to
@@ -29,49 +29,48 @@
 Roughly it has the following features added:
 
 - Better animation of the turtle movements, especially of turning the
-  turtle. So the turtles can more easily be used as a visual feedback
-  instrument by the (beginning) programmer.
+    turtle. So the turtles can more easily be used as a visual feedback
+    instrument by the (beginning) programmer.
 
 - Different turtle shapes, gif-images as turtle shapes, user defined
-  and user controllable turtle shapes, among them compound
-  (multicolored) shapes. Turtle shapes can be stgretched and tilted, which
-  makes turtles zu very versatile geometrical objects.
+    and user controllable turtle shapes, among them compound
+    (multicolored) shapes. Turtle shapes can be stgretched and tilted, which
+    makes turtles zu very versatile geometrical objects.
 
 - Fine control over turtle movement and screen updates via delay(),
-  and enhanced tracer() and speed() methods.
+    and enhanced tracer() and speed() methods.
 
 - Aliases for the most commonly used commands, like fd for forward etc.,
-  following the early Logo traditions. This reduces the boring work of
-  typing long sequences of commands, which often occur in a natural way
-  when kids try to program fancy pictures on their first encounter with
-  turtle graphcis.
+    following the early Logo traditions. This reduces the boring work of
+    typing long sequences of commands, which often occur in a natural way
+    when kids try to program fancy pictures on their first encounter with
+    turtle graphcis.
 
 - Turtles now have an undo()-method with configurable undo-buffer.
 
 - Some simple commands/methods for creating event driven programs
-  (mouse-, key-, timer-events). Especially useful for programming games.
-  
+    (mouse-, key-, timer-events). Especially useful for programming games.
+
 - A scrollable Canvas class. The default scrollable Canvas can be
-  extended interactively as needed while playing around with the turtle(s).
+    extended interactively as needed while playing around with the turtle(s).
 
 - A TurtleScreen class with methods controlling background color or
-  background image, window and canvas size and other properties of the
-  TurtleScreen.
+    background image, window and canvas size and other properties of the
+    TurtleScreen.
 
 - There is a method, setworldcoordinates(), to install a user defined
-  coordinate-system for the TurtleScreen. 
+    coordinate-system for the TurtleScreen.
 
 - The implementation uses a 2-vector class named Vec2D, derived from tuple.
-  This class is public, so it can be imported by the application programmer,
-  which makes certain types of computations very natural and compact.
+    This class is public, so it can be imported by the application programmer,
+    which makes certain types of computations very natural and compact.
 
 - Appearance of the TurtleScreen and the Turtles at startup/import can be
-  configured by means of a turtle.cfg configuration file.
-  The default configuration mimics the appearance of the old turtle module.
+    configured by means of a turtle.cfg configuration file.
+    The default configuration mimics the appearance of the old turtle module.
 
 - If configured appropriately the module reads in docstrings from a docstring
-  dictionary in some different language, supplied separately  and replaces
-  the english ones by those read in. There is a utility function
-  write_docstringdict() to write a dictionary with the original (english)
-  docstrings to disc, so it can serve as a template for translations.
-
+    dictionary in some different language, supplied separately  and replaces
+    the english ones by those read in. There is a utility function
+    write_docstringdict() to write a dictionary with the original (english)
+    docstrings to disc, so it can serve as a template for translations.

Modified: python/branches/py3k/Demo/turtle/about_turtledemo.txt
==============================================================================
--- /python/trunk/Demo/turtle/about_turtledemo.txt	(original)
+++ python/branches/py3k/Demo/turtle/about_turtledemo.txt	Tue Jun 10 06:44:07 2008
@@ -1,14 +1,13 @@
 
-  --------------------------------------
-     About xturtleDemo.py  
-  --------------------------------------
+    --------------------------------------
+        About turtleDemo.py
+    --------------------------------------
 
-  Tiny demo Viewer to view turtle graphics example scripts.
+    Tiny demo Viewer to view turtle graphics example scripts.
 
-  Quickly and dirtyly assembled by Gregor Lingl.
-  June, 2006
+    Quickly and dirtyly assembled by Gregor Lingl.
+    June, 2006
 
-  For more information see: xturtleDemo - Help 
+    For more information see: turtleDemo - Help
 
-  Have fun!
-    
+    Have fun!

Modified: python/branches/py3k/Demo/turtle/demohelp.txt
==============================================================================
--- /python/trunk/Demo/turtle/demohelp.txt	(original)
+++ python/branches/py3k/Demo/turtle/demohelp.txt	Tue Jun 10 06:44:07 2008
@@ -2,7 +2,7 @@
 
   ----------------------------------------------
 
-      xturtleDemo - Help
+      turtleDemo - Help
 
   ----------------------------------------------
 
@@ -56,7 +56,7 @@
    - scriptname: must begin with tdemo_ ,
      so it must have the form tdemo_<your-script-name>.py
 
-   - place: same directory as xturtleDemo.py or some
+   - place: same directory as turtleDemo.py or some
      subdirectory, the name of which must also begin with
      tdemo_.....
 

Modified: python/branches/py3k/Demo/turtle/tdemo_I_dontlike_tiltdemo.py
==============================================================================
--- /python/trunk/Demo/turtle/tdemo_I_dontlike_tiltdemo.py	(original)
+++ python/branches/py3k/Demo/turtle/tdemo_I_dontlike_tiltdemo.py	Tue Jun 10 06:44:07 2008
@@ -12,7 +12,7 @@
       Without using reset() ;-)
  ---------------------------------------
 """
-from turtle import *
+from tkinter.turtle import *
 import time
 
 def main():
@@ -54,5 +54,5 @@
 
 if __name__=="__main__":
     msg = main()
-    print msg
-    mainloop()
+    print(msg)
+#    mainloop()

Modified: python/branches/py3k/Demo/turtle/tdemo_bytedesign.py
==============================================================================
--- /python/trunk/Demo/turtle/tdemo_bytedesign.py	(original)
+++ python/branches/py3k/Demo/turtle/tdemo_bytedesign.py	Tue Jun 10 06:44:07 2008
@@ -23,7 +23,7 @@
 """
 
 import math
-from turtle import Turtle, mainloop
+from tkinter.turtle import Turtle, mainloop
 from time import clock
 
 # wrapper for any additional drawing routines
@@ -46,7 +46,7 @@
         self.right(198)
         self.down()
         self.centerpiece(46 * scale, 143.4, scale)
-        self.tracer(True)
+        self.getscreen().tracer(True)
 
     def wheel(self, initpos, scale):
         self.right(54)
@@ -150,7 +150,7 @@
     t.speed(0)
     t.hideturtle()
     t.getscreen().delay(0)
-    t.tracer(0)
+    t.getscreen().tracer(0)
     at = clock()
     t.design(t.position(), 2)
     et = clock()
@@ -158,5 +158,5 @@
 
 if __name__ == '__main__':
     msg = main()
-    print msg
+    print(msg)
     mainloop()

Modified: python/branches/py3k/Demo/turtle/tdemo_chaos.py
==============================================================================
--- /python/trunk/Demo/turtle/tdemo_chaos.py	(original)
+++ python/branches/py3k/Demo/turtle/tdemo_chaos.py	Tue Jun 10 06:44:07 2008
@@ -4,7 +4,7 @@
 
 # Ein einfaches Programm zur Demonstration von "chaotischem Verhalten".
 
-from turtle import *
+from tkinter.turtle import *
 
 def f(x):
     return 3.9*x*(1-x)

Modified: python/branches/py3k/Demo/turtle/tdemo_clock.py
==============================================================================
--- /python/trunk/Demo/turtle/tdemo_clock.py	(original)
+++ python/branches/py3k/Demo/turtle/tdemo_clock.py	Tue Jun 10 06:44:07 2008
@@ -10,7 +10,7 @@
    Press STOP to exit the program!
   ------------------------------------
 """
-from turtle import *
+from tkinter.turtle import *
 from datetime import datetime
 
 mode("logo")
@@ -128,5 +128,5 @@
 
 if __name__ == "__main__":
     msg = main()
-    print msg
+    print(msg)
     mainloop()

Modified: python/branches/py3k/Demo/turtle/tdemo_colormixer.py
==============================================================================
--- /python/trunk/Demo/turtle/tdemo_colormixer.py	(original)
+++ python/branches/py3k/Demo/turtle/tdemo_colormixer.py	Tue Jun 10 06:44:07 2008
@@ -1,6 +1,8 @@
 # colormixer
 
-from turtle import Screen, Turtle, mainloop
+from tkinter.turtle import Screen, Turtle, mainloop
+import sys
+sys.setrecursionlimit(20000)   # overcomes, for now, an instability of Python 3.0
 
 class ColorTurtle(Turtle):
 
@@ -54,5 +56,5 @@
 
 if __name__ == "__main__":
     msg = main()
-    print msg
+    print(msg)
     mainloop()

Added: python/branches/py3k/Demo/turtle/tdemo_forest.py
==============================================================================
--- (empty file)
+++ python/branches/py3k/Demo/turtle/tdemo_forest.py	Tue Jun 10 06:44:07 2008
@@ -0,0 +1,109 @@
+#!/usr/bin/python
+"""     turtlegraphics-example-suite:
+
+             tdemo_forest.py
+
+Displays a 'forest' of 3 'breadth-first-trees'
+similar to the one from example tree.
+For further remarks see xtx_tree.py
+
+This example is a 'breadth-first'-rewrite of
+a Logo program written by Erich Neuwirth. See:
+http://homepage.univie.ac.at/erich.neuwirth/
+"""
+from tkinter.turtle import Turtle, colormode, tracer, mainloop
+from random import randrange
+from time import clock
+
+def symRandom(n):
+    return randrange(-n,n+1)
+
+def randomize( branchlist, angledist, sizedist ):
+    return [ (angle+symRandom(angledist),
+              sizefactor*1.01**symRandom(sizedist))
+                     for angle, sizefactor in branchlist ]
+
+def randomfd( t, distance, parts, angledist ):
+    for i in range(parts):
+        t.left(symRandom(angledist))
+        t.forward( (1.0 * distance)/parts )
+
+def tree(tlist, size, level, widthfactor, branchlists, angledist=10, sizedist=5):
+    # benutzt Liste von turtles und Liste von Zweiglisten,
+    # fuer jede turtle eine!
+    if level > 0:
+        lst = []
+        brs = []
+        for t, branchlist in list(zip(tlist,branchlists)):
+            t.pensize( size * widthfactor )
+            t.pencolor( 255 - (180 - 11 * level + symRandom(15)),
+                        180 - 11 * level + symRandom(15),
+                        0 )
+            t.pendown()
+            randomfd(t, size, level, angledist )
+            yield 1
+            for angle, sizefactor in branchlist:
+                t.left(angle)
+                lst.append(t.clone())
+                brs.append(randomize(branchlist, angledist, sizedist))
+                t.right(angle)
+        for x in tree(lst, size*sizefactor, level-1, widthfactor, brs,
+                      angledist, sizedist):
+            yield None
+
+
+def start(t,x,y):
+    colormode(255)
+    t.reset()
+    t.speed(0)
+    t.hideturtle()
+    t.left(90)
+    t.penup()
+    t.setpos(x,y)
+    t.pendown()
+
+def doit1(level, pen):
+    pen.hideturtle()
+    start(pen, 20, -208)
+    t = tree( [pen], 80, level, 0.1, [[ (45,0.69), (0,0.65), (-45,0.71) ]] )
+    return t
+
+def doit2(level, pen):
+    pen.hideturtle()
+    start(pen, -135, -130)
+    t = tree( [pen], 120, level, 0.1, [[ (45,0.69), (-45,0.71) ]] )
+    return t
+
+def doit3(level, pen):
+    pen.hideturtle()
+    start(pen, 190, -90)
+    t = tree( [pen], 100, level, 0.1, [[ (45,0.7), (0,0.72), (-45,0.65) ]] )
+    return t
+
+# Hier 3 Baumgeneratoren:
+def main():
+    p = Turtle()
+    p.ht()
+    tracer(75,0)
+    u = doit1(6, Turtle(undobuffersize=1))
+    s = doit2(7, Turtle(undobuffersize=1))
+    t = doit3(5, Turtle(undobuffersize=1))
+    a = clock()
+    while True:
+        done = 0
+        for b in u,s,t:
+            try:
+                b.__next__()
+            except:
+                done += 1
+        if done == 3:
+            break
+
+    tracer(1,10)
+    b = clock()
+    return "runtime: %.2f sec." % (b-a)
+
+if __name__ == '__main__':
+    msg = main()
+    print(msg)
+    mainloop()

Modified: python/branches/py3k/Demo/turtle/tdemo_fractalcurves.py
==============================================================================
--- /python/trunk/Demo/turtle/tdemo_fractalcurves.py	(original)
+++ python/branches/py3k/Demo/turtle/tdemo_fractalcurves.py	Tue Jun 10 06:44:07 2008
@@ -11,7 +11,7 @@
 methods are taken from the PythonCard example
 scripts for turtle-graphics.
 """
-from turtle import *
+from tkinter.turtle import *
 from time import sleep, clock
 
 class CurvesTurtle(Pen):
@@ -81,7 +81,7 @@
     ft.reset()
     ft.speed(0)
     ft.ht()
-    ft.tracer(1,0)
+    ft.getscreen().tracer(1,0)
     ft.pu()
 
     size = 6
@@ -90,7 +90,7 @@
 
     ta=clock()
     ft.fillcolor("red")
-    ft.fill(True)
+    ft.begin_fill()
     ft.fd(size)
 
     ft.hilbert(size, 6, 1)
@@ -108,7 +108,7 @@
     for i in range(4):
         ft.fd(size*(66+i%2))
         ft.rt(90)
-    ft.fill(False)
+    ft.end_fill()
     tb=clock()
     res =  "Hilbert: %.2fsec. " % (tb-ta)
 
@@ -117,21 +117,22 @@
     ft.reset()
     ft.speed(0)
     ft.ht()
-    ft.tracer(1,0)
+    ft.getscreen().tracer(1,0)
 
     ta=clock()
     ft.color("black", "blue")
-    ft.fill(True)
+    ft.begin_fill()
     ft.fractalgon(3, 250, 4, 1)
-    ft.fill(True)
+    ft.end_fill()
+    ft.begin_fill()
     ft.color("red")
     ft.fractalgon(3, 200, 4, -1)
-    ft.fill(False)
+    ft.end_fill()
     tb=clock()
     res +=  "Koch: %.2fsec." % (tb-ta)
     return res
 
 if __name__  == '__main__':
     msg = main()
-    print msg
+    print(msg)
     mainloop()

Modified: python/branches/py3k/Demo/turtle/tdemo_lindenmayer_indian.py
==============================================================================
--- /python/trunk/Demo/turtle/tdemo_lindenmayer_indian.py	(original)
+++ python/branches/py3k/Demo/turtle/tdemo_lindenmayer_indian.py	Tue Jun 10 06:44:07 2008
@@ -25,7 +25,7 @@
 # Mini Lindenmayer tool
 ###############################
 
-from turtle import *
+from tkinter.turtle import *
 
 def replace( seq, replacementRules, n ):
     for i in range(n):
@@ -115,5 +115,5 @@
 
 if __name__=='__main__':
     msg = main()
-    print msg
+    print(msg)
     mainloop()

Modified: python/branches/py3k/Demo/turtle/tdemo_minimal_hanoi.py
==============================================================================
--- /python/trunk/Demo/turtle/tdemo_minimal_hanoi.py	(original)
+++ python/branches/py3k/Demo/turtle/tdemo_minimal_hanoi.py	Tue Jun 10 06:44:07 2008
@@ -17,7 +17,7 @@
        To exit press STOP button
  ---------------------------------------
 """
-from turtle import *
+from tkinter.turtle import *
 
 class Disc(Turtle):
     def __init__(self, n):
@@ -72,5 +72,5 @@
 
 if __name__=="__main__":
     msg = main()
-    print msg
+    print(msg)
     mainloop()

Modified: python/branches/py3k/Demo/turtle/tdemo_paint.py
==============================================================================
--- /python/trunk/Demo/turtle/tdemo_paint.py	(original)
+++ python/branches/py3k/Demo/turtle/tdemo_paint.py	Tue Jun 10 06:44:07 2008
@@ -15,7 +15,7 @@
           To exit press STOP button
  -------------------------------------------
 """
-from turtle import *
+from tkinter.turtle import *
 
 def switchupdown(x=0, y=0):
     if pen()["pendown"]:
@@ -46,5 +46,5 @@
 
 if __name__ == "__main__":
     msg = main()
-    print msg
+    print(msg)
     mainloop()

Modified: python/branches/py3k/Demo/turtle/tdemo_peace.py
==============================================================================
--- /python/trunk/Demo/turtle/tdemo_peace.py	(original)
+++ python/branches/py3k/Demo/turtle/tdemo_peace.py	Tue Jun 10 06:44:07 2008
@@ -13,7 +13,7 @@
 colorloop:
 """
 
-from turtle import *
+from tkinter.turtle import *
 
 def main():
     peacecolors = ("red3",  "orange", "yellow",

Modified: python/branches/py3k/Demo/turtle/tdemo_penrose.py
==============================================================================
--- /python/trunk/Demo/turtle/tdemo_penrose.py	(original)
+++ python/branches/py3k/Demo/turtle/tdemo_penrose.py	Tue Jun 10 06:44:07 2008
@@ -15,7 +15,7 @@
  http://en.wikipedia.org/wiki/Penrose_tiling
  -------------------------------------------
 """
-from turtle import *
+from tkinter.turtle import *
 from math import cos, pi
 from time import clock, sleep
 
@@ -144,12 +144,12 @@
     draw(l, n, th)
     tracer(1)
     c = clock()
-    print "Calculation:   %7.4f s" % (b - a)
-    print "Drawing:  %7.4f s" % (c - b)
-    print "Together: %7.4f s" % (c - a)
+    print("Calculation:   %7.4f s" % (b - a))
+    print("Drawing:  %7.4f s" % (c - b))
+    print("Together: %7.4f s" % (c - a))
     nk = len([x for x in tiledict if tiledict[x]])
     nd = len([x for x in tiledict if not tiledict[x]])
-    print "%d kites and %d darts = %d pieces." % (nk, nd, nk+nd)
+    print("%d kites and %d darts = %d pieces." % (nk, nd, nk+nd))
 
 def demo(fun=sun):
     start()

Modified: python/branches/py3k/Demo/turtle/tdemo_planet_and_moon.py
==============================================================================
--- /python/trunk/Demo/turtle/tdemo_planet_and_moon.py	(original)
+++ python/branches/py3k/Demo/turtle/tdemo_planet_and_moon.py	Tue Jun 10 06:44:07 2008
@@ -17,7 +17,7 @@
 scrollbar of the canvas.
 
 """
-from turtle import Shape, Turtle, mainloop, Vec2D as Vec
+from tkinter.turtle import Shape, Turtle, mainloop, Vec2D as Vec
 from time import sleep
 
 G = 8
@@ -71,7 +71,7 @@
 def main():
     s = Turtle()
     s.reset()
-    s.tracer(0,0)
+    s.getscreen().tracer(0,0)
     s.ht()
     s.pu()
     s.fd(6)
@@ -89,7 +89,7 @@
     planetshape.addcomponent(m1,"orange")
     planetshape.addcomponent(m2,"blue")
     s.getscreen().register_shape("planet", planetshape)
-    s.tracer(1,0)
+    s.getscreen().tracer(1,0)
 
     ## setup gravitational system
     gs = GravSys()
@@ -109,5 +109,5 @@
 
 if __name__ == '__main__':
     msg = main()
-    print msg
-    mainloop()
+    print(msg)
+    #mainloop()

Modified: python/branches/py3k/Demo/turtle/tdemo_tree.py
==============================================================================
--- /python/trunk/Demo/turtle/tdemo_tree.py	(original)
+++ python/branches/py3k/Demo/turtle/tdemo_tree.py	Tue Jun 10 06:44:07 2008
@@ -15,7 +15,7 @@
 current pen is cloned. So in the end there
 are 1024 turtles.
 """
-from turtle import Turtle, mainloop
+from tkinter.turtle import Turtle, mainloop
 from time import clock
 
 def tree(plist, l, a, f):
@@ -41,7 +41,7 @@
     p.setundobuffer(None)
     p.hideturtle()
     p.speed(0)
-    p.tracer(30,0)
+    p.getscreen().tracer(30,0)
     p.left(90)
     p.penup()
     p.forward(-210)
@@ -49,7 +49,7 @@
     t = tree([p], 200, 65, 0.6375)
     for x in t:
         pass
-    print len(p.getscreen().turtles())
+    print(len(p.getscreen().turtles()))
 
 def main():
     a=clock()
@@ -59,5 +59,5 @@
 
 if __name__ == "__main__":
     msg = main()
-    print msg
+    print(msg)
     mainloop()

Modified: python/branches/py3k/Demo/turtle/tdemo_wikipedia.py
==============================================================================
--- /python/trunk/Demo/turtle/tdemo_wikipedia.py	(original)
+++ python/branches/py3k/Demo/turtle/tdemo_wikipedia.py	Tue Jun 10 06:44:07 2008
@@ -13,7 +13,7 @@
 
 Followed by a complete undo().
 """
-from turtle import Screen, Turtle, mainloop
+from tkinter.turtle import Screen, Turtle, mainloop
 from time import clock, sleep
 
 def mn_eck(p, ne,sz):
@@ -61,5 +61,5 @@
 
 if __name__ == '__main__':
     msg = main()
-    print msg
+    print(msg)
     mainloop()

Modified: python/branches/py3k/Demo/turtle/tdemo_yinyang.py
==============================================================================
--- /python/trunk/Demo/turtle/tdemo_yinyang.py	(original)
+++ python/branches/py3k/Demo/turtle/tdemo_yinyang.py	Tue Jun 10 06:44:07 2008
@@ -11,36 +11,36 @@
 
 """
 
-from turtle import *
+from tkinter.turtle import *
 
 def yin(radius, color1, color2):
     width(3)
-    color("black")
-    fill(True)
+    color("black", color1)
+    begin_fill()
     circle(radius/2., 180)
     circle(radius, 180)
     left(180)
     circle(-radius/2., 180)
-    color(color1)
-    fill(True)
-    color(color2)
+    end_fill()
     left(90)
     up()
-    forward(radius*0.375)
+    forward(radius*0.35)
     right(90)
     down()
-    circle(radius*0.125)
+    color(color1, color2)
+    begin_fill()
+    circle(radius*0.15)
+    end_fill()
     left(90)
-    fill(False)
     up()
-    backward(radius*0.375)
+    backward(radius*0.35)
     down()
     left(90)
 
 def main():
     reset()
-    yin(200, "white", "black")
     yin(200, "black", "white")
+    yin(200, "white", "black")
     ht()
     return "Done!"
 

Modified: python/branches/py3k/Demo/turtle/turtleDemo.py
==============================================================================
--- /python/trunk/Demo/turtle/turtleDemo.py	(original)
+++ python/branches/py3k/Demo/turtle/turtleDemo.py	Tue Jun 10 06:44:07 2008
@@ -2,12 +2,13 @@
 import sys
 import os
 
-from Tkinter import *
+from tkinter import *
 from idlelib.Percolator import Percolator
 from idlelib.ColorDelegator import ColorDelegator
-from idlelib.textView import TextViewer
+from idlelib.textView import view_file # TextViewer
+from imp import reload
 
-import turtle
+from tkinter import turtle
 import time
 
 STARTUP = 1
@@ -22,9 +23,10 @@
 
 def getExampleEntries():
     cwd = os.getcwd()
+    #print(cwd, os.listdir(cwd))
     if "turtleDemo.py" not in os.listdir(cwd):
-        print "Directory of turtleDemo must be current working directory!"
-        print "But in your case this is", cwd
+        print("Directory of turtleDemo must be current working directory!")
+        print("But in your case this is", cwd)
         sys.exit()
     entries1 = [entry for entry in os.listdir(cwd) if
                      entry.startswith("tdemo_") and
@@ -44,13 +46,13 @@
     return entries2
 
 def showDemoHelp():
-    TextViewer(demo.root, "Help on turtleDemo", "demohelp.txt")
+    view_file(demo.root, "Help on turtleDemo", "demohelp.txt")
 
 def showAboutDemo():
-    TextViewer(demo.root, "About turtleDemo", "about_turtledemo.txt")
+    view_file(demo.root, "About turtleDemo", "about_turtledemo.txt")
 
 def showAboutTurtle():
-    TextViewer(demo.root, "About the new turtle module", "about_turtle.txt")
+    view_file(demo.root, "About the new turtle module.", "about_turtle.txt")
 
 class DemoWindow(object):
 
@@ -98,6 +100,9 @@
         turtle.Screen._canvas = turtle.ScrolledCanvas(g_frame, 800, 600, 1000, 800)
         #xturtle.Screen._canvas.pack(expand=1, fill="both")
         self.screen = _s_ = turtle.Screen()
+#####
+        turtle.TurtleScreen.__init__(_s_, _s_._canvas)
+#####
         self.scanvas = _s_._canvas
         #xturtle.RawTurtle.canvases = [self.scanvas]
         turtle.RawTurtle.screens = [_s_]
@@ -211,7 +216,7 @@
             self.text.delete("1.0", "end")
             self.text.insert("1.0",chars)
             direc, fname = os.path.split(filename)
-            self.root.title(fname[6:-3]+" - an xturtle example")
+            self.root.title(fname[6:-3]+" - a Python turtle graphics example")
             self.module = __import__(fname[:-3])
             reload(self.module)
             self.configGUI(NORMAL, NORMAL, DISABLED, DISABLED,
@@ -247,6 +252,7 @@
 
     def clearCanvas(self):
         self.refreshCanvas()
+        self.screen._delete("all")
         self.scanvas.config(cursor="")
         self.configGUI(NORMAL, NORMAL, DISABLED, DISABLED)
 
@@ -267,13 +273,19 @@
     RUN = True
     while RUN:
         try:
-            print "ENTERING mainloop"
+            #print("ENTERING mainloop")
             demo.root.mainloop()
         except AttributeError:
-            print "CRASH!!!- WAIT A MOMENT!"
+            #print("AttributeError!- WAIT A MOMENT!")
             time.sleep(0.3)
-            print "GOING ON .."
-            demo.refreshCanvas()
-##            time.sleep(1)
+            print("GOING ON ..")
+            demo.ckearCanvas()
+        except TypeError:
+            demo.screen._delete("all")
+            #print("CRASH!!!- WAIT A MOMENT!")
+            time.sleep(0.3)
+            #print("GOING ON ..")
+            demo.clearCanvas()
         except:
-            RUN = FALSE
+            print("BYE!")
+            RUN = False

Modified: python/branches/py3k/Demo/turtle/turtledemo_two_canvases.py
==============================================================================
--- /python/trunk/Demo/turtle/turtledemo_two_canvases.py	(original)
+++ python/branches/py3k/Demo/turtle/turtledemo_two_canvases.py	Tue Jun 10 06:44:07 2008
@@ -3,7 +3,7 @@
 """turtle example: Using TurtleScreen and RawTurtle
 for drawing on two distinct canvases.
 """
-from turtle import TurtleScreen, RawTurtle, TK
+from tkinter.turtle import TurtleScreen, RawTurtle, TK
 
 root = TK.Tk()
 cv1 = TK.Canvas(root, width=300, height=200, bg="#ddffff")
@@ -19,9 +19,9 @@
 p = RawTurtle(s1)
 q = RawTurtle(s2)
 
-p.color("red", "white")
+p.color("red", (1, 0.85, 0.85))
 p.width(3)
-q.color("blue", "black")
+q.color("blue", (0.85, 0.85, 1))
 q.width(3)
 
 for t in p,q:
@@ -30,20 +30,23 @@
 
 q.lt(180)
 
+for t in p, q:
+    t.begin_fill()
 for i in range(5):
     for t in p, q:
         t.fd(50)
         t.lt(72)
 for t in p,q:
+    t.end_fill()
     t.lt(54)
     t.pu()
     t.bk(50)
 
 ## Want to get some info?
 
-print s1, s2
-print p, q
-print s1.turtles()
-print s2.turtles()
+print(s1, s2)
+print(p, q)
+print(s1.turtles())
+print(s2.turtles())
 
 TK.mainloop()

Modified: python/branches/py3k/Doc/library/tkinter.turtle.rst
==============================================================================
--- python/branches/py3k/Doc/library/tkinter.turtle.rst	(original)
+++ python/branches/py3k/Doc/library/tkinter.turtle.rst	Tue Jun 10 06:44:07 2008
@@ -1,288 +1,1887 @@
-:mod:`tkinter.turtle` --- Turtle graphics for Tk
-================================================
+========================================
+:mod:`turtle` --- Turtle graphics for Tk
+========================================
+
+Introduction
+============
+
+Turtle graphics is a popular way for introducing programming to kids.  It was
+part of the original Logo programming language developed by Wally Feurzig and
+Seymour Papert in 1966.
+
+Imagine a robotic turtle starting at (0, 0) in the x-y plane.  Give it the
+command ``turtle.forward(15)``, and it moves (on-screen!) 15 pixels in the
+direction it is facing, drawing a line as it moves.  Give it the command
+``turtle.left(25)``, and it rotates in-place 25 degrees clockwise.
+
+By combining together these and similar commands, intricate shapes and pictures
+can easily be drawn.
+
+The :mod:`turtle` module is an extended reimplementation of the same-named
+module from the Python standard distribution up to version Python 2.5.
+
+It tries to keep the merits of the old turtle module and to be (nearly) 100%
+compatible with it.  This means in the first place to enable the learning
+programmer to use all the commands, classes and methods interactively when using
+the module from within IDLE run with the ``-n`` switch.
+
+The turtle module provides turtle graphics primitives, in both object-oriented
+and procedure-oriented ways.  Because it uses :mod:`Tkinter` for the underlying
+graphics, it needs a version of python installed with Tk support.
+
+The object-oriented interface uses essentially two+two classes:
+
+1. The :class:`TurtleScreen` class defines graphics windows as a playground for
+   the drawing turtles.  Its constructor needs a :class:`Tkinter.Canvas` or a
+   :class:`ScrolledCanvas` as argument.  It should be used when :mod:`turtle` is
+   used as part of some application.
+
+   Derived from :class:`TurtleScreen` is the subclass :class:`Screen`.  Screen
+   is implemented as sort of singleton, so there can exist only one instance of
+   Screen at a time.  It should be used when :mod:`turtle` is used as a
+   standalone tool for doing graphics.
+
+   All methods of TurtleScreen/Screen also exist as functions, i.e. as part of
+   the procedure-oriented interface.
+
+2. :class:`RawTurtle` (alias: :class:`RawPen`) defines Turtle objects which draw
+   on a :class:`TurtleScreen`.  Its constructor needs a Canvas, ScrolledCanvas
+   or TurtleScreen as argument, so the RawTurtle objects know where to draw.
+
+   Derived from RawTurtle is the subclass :class:`Turtle` (alias: :class:`Pen`),
+   which draws on "the" :class:`Screen` - instance which is automatically
+   created, if not already present.
+
+   All methods of RawTurtle/Turtle also exist as functions, i.e. part of the
+   procedure-oriented interface.
+
+The procedural interface provides functions which are derived from the methods
+of the classes :class:`Screen` and :class:`Turtle`.  They have the same names as
+the corresponding methods.  A screen object is automativally created whenever a
+function derived from a Screen method is called.  An (unnamed) turtle object is
+automatically created whenever any of the functions derived from a Turtle method
+is called.
+
+To use multiple turtles an a screen one has to use the object-oriented interface.
+
+.. note::
+   In the following documentation the argument list for functions is given.
+   Methods, of course, have the additional first argument *self* which is
+   omitted here.
+
+
+Overview over available Turtle and Screen methods
+=================================================
+
+Turtle methods
+--------------
+
+Turtle motion
+   Move and draw
+      | :func:`forward` | :func:`fd`
+      | :func:`backward` | :func:`bk` | :func:`back`
+      | :func:`right` | :func:`rt`
+      | :func:`left` | :func:`lt`
+      | :func:`goto` | :func:`setpos` | :func:`setposition`
+      | :func:`setx`
+      | :func:`sety`
+      | :func:`setheading` | :func:`seth`
+      | :func:`home`
+      | :func:`circle`
+      | :func:`dot`
+      | :func:`stamp`
+      | :func:`clearstamp`
+      | :func:`clearstamps`
+      | :func:`undo`
+      | :func:`speed`
+
+   Tell Turtle's state
+      | :func:`position` | :func:`pos`
+      | :func:`towards`
+      | :func:`xcor`
+      | :func:`ycor`
+      | :func:`heading`
+      | :func:`distance`
+
+   Setting and measurement
+      | :func:`degrees`
+      | :func:`radians`
+
+Pen control
+   Drawing state
+      | :func:`pendown` | :func:`pd` | :func:`down`
+      | :func:`penup` | :func:`pu` | :func:`up`
+      | :func:`pensize` | :func:`width`
+      | :func:`pen`
+      | :func:`isdown`
+
+   Color control
+      | :func:`color`
+      | :func:`pencolor`
+      | :func:`fillcolor`
+
+   Filling
+      | :func:`filling`
+      | :func:`begin_fill`
+      | :func:`end_fill`
+
+   More drawing control
+      | :func:`reset`
+      | :func:`clear`
+      | :func:`write`
+
+Turtle state
+   Visibility
+      | :func:`showturtle` | :func:`st`
+      | :func:`hideturtle` | :func:`ht`
+      | :func:`isvisible`
+
+   Appearance
+      | :func:`shape`
+      | :func:`resizemode`
+      | :func:`shapesize` | :func:`turtlesize`
+      | :func:`settiltangle`
+      | :func:`tiltangle`
+      | :func:`tilt`
+
+Using events
+   | :func:`onclick`
+   | :func:`onrelease`
+   | :func:`ondrag`
+
+Special Turtle methods
+   | :func:`begin_poly`
+   | :func:`end_poly`
+   | :func:`get_poly`
+   | :func:`clone`
+   | :func:`getturtle` | :func:`getpen`
+   | :func:`getscreen`
+   | :func:`setundobuffer`
+   | :func:`undobufferentries`
 
-.. module:: tkinter.turtle
-   :platform: Tk
-   :synopsis: An environment for turtle graphics.
-.. moduleauthor:: Guido van Rossum <guido at python.org>
 
+Methods of TurtleScreen/Screen
+------------------------------
+
+Window control
+   | :func:`bgcolor`
+   | :func:`bgpic`
+   | :func:`clear` | :func:`clearscreen`
+   | :func:`reset` | :func:`resetscreen`
+   | :func:`screensize`
+   | :func:`setworldcoordinates`
+
+Animation control
+   | :func:`delay`
+   | :func:`tracer`
+   | :func:`update`
+
+Using screen events
+   | :func:`listen`
+   | :func:`onkey`
+   | :func:`onclick` | :func:`onscreenclick`
+   | :func:`ontimer`
+
+Settings and special methods
+   | :func:`mode`
+   | :func:`colormode`
+   | :func:`getcanvas`
+   | :func:`getshapes`
+   | :func:`register_shape` | :func:`addshape`
+   | :func:`turtles`
+   | :func:`window_height`
+   | :func:`window_width`
+
+Methods specific to Screen
+   | :func:`bye`
+   | :func:`exitonclick`
+   | :func:`setup`
+   | :func:`title`
+
+
+Methods of RawTurtle/Turtle and corresponding functions
+=======================================================
+
+Most of the examples in this section refer to a Turtle instance called
+``turtle``.
+
+Turtle motion
+-------------
+
+.. function:: forward(distance)
+              fd(distance)
+
+   :param distance: a number (integer or float)
+
+   Move the turtle forward by the specified *distance*, in the direction the
+   turtle is headed.
+
+   >>> turtle.position()
+   (0.00, 0.00)
+   >>> turtle.forward(25)
+   >>> turtle.position()
+   (25.00,0.00)
+   >>> turtle.forward(-75)
+   >>> turtle.position()
+   (-50.00,0.00)
+
+
+.. function:: back(distance)
+              bk(distance)
+              backward(distance)
+
+   :param distance: a number
+
+   Move the turtle backward by *distance*, opposite to the direction the
+   turtle is headed.  Do not change the turtle's heading.
+
+   >>> turtle.position()
+   (0.00, 0.00)
+   >>> turtle.backward(30)
+   >>> turtle.position()
+   (-30.00, 0.00)
+
+
+.. function:: right(angle)
+              rt(angle)
+
+   :param angle: a number (integer or float)
+
+   Turn turtle right by *angle* units.  (Units are by default degrees, but
+   can be set via the :func:`degrees` and :func:`radians` functions.)  Angle
+   orientation depends on the turtle mode, see :func:`mode`.
+
+   >>> turtle.heading()
+   22.0
+   >>> turtle.right(45)
+   >>> turtle.heading()
+   337.0
+
+
+.. function:: left(angle)
+              lt(angle)
+
+   :param angle: a number (integer or float)
+
+   Turn turtle left by *angle* units.  (Units are by default degrees, but
+   can be set via the :func:`degrees` and :func:`radians` functions.)  Angle
+   orientation depends on the turtle mode, see :func:`mode`.
+
+   >>> turtle.heading()
+   22.0
+   >>> turtle.left(45)
+   >>> turtle.heading()
+   67.0
+
+.. function:: goto(x, y=None)
+              setpos(x, y=None)
+              setposition(x, y=None)
+
+    :param x: a number or a pair/vector of numbers
+    :param y: a number or ``None``
+
+    If *y* is ``None``, *x* must be a pair of coordinates or a :class:`Vec2D`
+    (e.g. as returned by :func:`pos`).
+
+    Move turtle to an absolute position.  If the pen is down, draw line.  Do
+    not change the turtle's orientation.
+
+    >>> tp = turtle.pos()
+    >>> tp
+    (0.00, 0.00)
+    >>> turtle.setpos(60,30)
+    >>> turtle.pos()
+    (60.00,30.00)
+    >>> turtle.setpos((20,80))
+    >>> turtle.pos()
+    (20.00,80.00)
+    >>> turtle.setpos(tp)
+    >>> turtle.pos()
+    (0.00,0.00)
+
+
+.. function:: setx(x)
+
+   :param x: a number (integer or float)
+
+   Set the turtle's first coordinate to *x*, leave second coordinate
+   unchanged.
+
+   >>> turtle.position()
+   (0.00, 240.00)
+   >>> turtle.setx(10)
+   >>> turtle.position()
+   (10.00, 240.00)
+
+
+.. function:: sety(y)
+
+   :param y: a number (integer or float)
+
+   Set the turtle's first coordinate to *y*, leave second coordinate
+   unchanged.
+
+   >>> turtle.position()
+   (0.00, 40.00)
+   >>> turtle.sety(-10)
+   >>> turtle.position()
+   (0.00, -10.00)
+
+
+.. function:: setheading(to_angle)
+              seth(to_angle)
+
+   :param to_angle: a number (integer or float)
+
+   Set the orientation of the turtle to *to_angle*.  Here are some common
+   directions in degrees:
+
+   =================== ====================
+    standard mode           logo mode
+   =================== ====================
+      0 - east                0 - north
+     90 - north              90 - east
+    180 - west              180 - south
+    270 - south             270 - west
+   =================== ====================
 
-.. sectionauthor:: Moshe Zadka <moshez at zadka.site.co.il>
+   >>> turtle.setheading(90)
+   >>> turtle.heading()
+   90
 
 
-The :mod:`tkinter.turtle` module provides turtle graphics primitives, in both an
-object-oriented and procedure-oriented ways. Because it uses :mod:`tkinter` for
-the underlying graphics, it needs a version of python installed with Tk support.
+.. function:: home()
 
-The procedural interface uses a pen and a canvas which are automagically created
-when any of the functions are called.
+   Move turtle to the origin -- coordinates (0,0) -- and set its heading to
+   its start-orientation (which depends on the mode, see :func:`mode`).
+
+
+.. function:: circle(radius, extent=None, steps=None)
+
+   :param radius: a number
+   :param extent: a number (or ``None``)
+   :param steps: an integer (or ``None``)
+
+   Draw a circle with given *radius*.  The center is *radius* units left of
+   the turtle; *extent* -- an angle -- determines which part of the circle
+   is drawn.  If *extent* is not given, draw the entire circle.  If *extent*
+   is not a full circle, one endpoint of the arc is the current pen
+   position.  Draw the arc in counterclockwise direction if *radius* is
+   positive, otherwise in clockwise direction.  Finally the direction of the
+   turtle is changed by the amount of *extent*.
+
+   As the circle is approximated by an inscribed regular polygon, *steps*
+   determines the number of steps to use.  If not given, it will be
+   calculated automatically.  May be used to draw regular polygons.
+
+   >>> turtle.circle(50)
+   >>> turtle.circle(120, 180)  # draw a semicircle
+
+
+.. function:: dot(size=None, *color)
+
+   :param size: an integer >= 1 (if given)
+   :param color: a colorstring or a numeric color tuple
+
+   Draw a circular dot with diameter *size*, using *color*.  If *size* is
+   not given, the maximum of pensize+4 and 2*pensize is used.
+
+   >>> turtle.dot()
+   >>> turtle.fd(50); turtle.dot(20, "blue"); turtle.fd(50)
+
+
+.. function:: stamp()
+
+   Stamp a copy of the turtle shape onto the canvas at the current turtle
+   position.  Return a stamp_id for that stamp, which can be used to delete
+   it by calling ``clearstamp(stamp_id)``.
+
+   >>> turtle.color("blue")
+   >>> turtle.stamp()
+   13
+   >>> turtle.fd(50)
+
+
+.. function:: clearstamp(stampid)
+
+   :param stampid: an integer, must be return value of previous
+                   :func:`stamp` call
+
+   Delete stamp with given *stampid*.
+
+   >>> turtle.color("blue")
+   >>> astamp = turtle.stamp()
+   >>> turtle.fd(50)
+   >>> turtle.clearstamp(astamp)
+
+
+.. function:: clearstamps(n=None)
+
+   :param n: an integer (or ``None``)
+
+   Delete all or first/last *n* of turtle's stamps.  If *n* is None, delete
+   all stamps, if *n* > 0 delete first *n* stamps, else if *n* < 0 delete
+   last *n* stamps.
+
+   >>> for i in range(8):
+   ...     turtle.stamp(); turtle.fd(30)
+   >>> turtle.clearstamps(2)
+   >>> turtle.clearstamps(-2)
+   >>> turtle.clearstamps()
+
+
+.. function:: undo()
+
+   Undo (repeatedly) the last turtle action(s).  Number of available
+   undo actions is determined by the size of the undobuffer.
+
+   >>> for i in range(4):
+   ...     turtle.fd(50); turtle.lt(80)
+   ...
+   >>> for i in range(8):
+   ...     turtle.undo()
+
+
+.. function:: speed(speed=None)
+
+   :param speed: an integer in the range 0..10 or a speedstring (see below)
+
+   Set the turtle's speed to an integer value in the range 0..10.  If no
+   argument is given, return current speed.
+
+   If input is a number greater than 10 or smaller than 0.5, speed is set
+   to 0.  Speedstrings are mapped to speedvalues as follows:
+
+   * "fastest":  0
+   * "fast":  10
+   * "normal":  6
+   * "slow":  3
+   * "slowest":  1
+
+   Speeds from 1 to 10 enforce increasingly faster animation of line drawing
+   and turtle turning.
+
+   Attention: *speed* = 0 means that *no* animation takes
+   place. forward/back makes turtle jump and likewise left/right make the
+   turtle turn instantly.
+
+   >>> turtle.speed(3)
+
+
+Tell Turtle's state
+-------------------
+
+.. function:: position()
+              pos()
 
-The :mod:`tkinter.turtle` module defines the following functions:
+   Return the turtle's current location (x,y) (as a :class:`Vec2D` vector).
 
+   >>> turtle.pos()
+   (0.00, 240.00)
 
-.. function:: degrees()
 
-   Set angle measurement units to degrees.
+.. function:: towards(x, y=None)
+
+   :param x: a number or a pair/vector of numbers or a turtle instance
+   :param y: a number if *x* is a number, else ``None``
+
+   Return the angle between the line from turtle position to position specified
+   by (x,y), the vector or the other turtle.  This depends on the turtle's start
+   orientation which depends on the mode - "standard"/"world" or "logo").
+
+   >>> turtle.pos()
+   (10.00, 10.00)
+   >>> turtle.towards(0,0)
+   225.0
+
+
+.. function:: xcor()
+
+   Return the turtle's x coordinate.
+
+   >>> reset()
+   >>> turtle.left(60)
+   >>> turtle.forward(100)
+   >>> print turtle.xcor()
+   50.0
+
+
+.. function:: ycor()
+
+   Return the turtle's y coordinate.
+
+   >>> reset()
+   >>> turtle.left(60)
+   >>> turtle.forward(100)
+   >>> print turtle.ycor()
+   86.6025403784
+
+
+.. function:: heading()
+
+   Return the turtle's current heading (value depends on the turtle mode, see
+   :func:`mode`).
+
+   >>> turtle.left(67)
+   >>> turtle.heading()
+   67.0
+
+
+.. function:: distance(x, y=None)
+
+   :param x: a number or a pair/vector of numbers or a turtle instance
+   :param y: a number if *x* is a number, else ``None``
+
+   Return the distance from the turtle to (x,y), the given vector, or the given
+   other turtle, in turtle step units.
+
+   >>> turtle.pos()
+   (0.00, 0.00)
+   >>> turtle.distance(30,40)
+   50.0
+   >>> joe = Turtle()
+   >>> joe.forward(77)
+   >>> turtle.distance(joe)
+   77.0
+
+
+Settings for measurement
+------------------------
+
+.. function:: degrees(fullcircle=360.0)
+
+   :param fullcircle: a number
+
+   Set angle measurement units, i.e. set number of "degrees" for a full circle.
+   Default value is 360 degrees.
+
+   >>> turtle.left(90)
+   >>> turtle.heading()
+   90
+   >>> turtle.degrees(400.0)  # angle measurement in gon
+   >>> turtle.heading()
+   100
 
 
 .. function:: radians()
 
-   Set angle measurement units to radians.
+   Set the angle measurement units to radians.  Equivalent to
+   ``degrees(2*math.pi)``.
 
+   >>> turtle.heading()
+   90
+   >>> turtle.radians()
+   >>> turtle.heading()
+   1.5707963267948966
 
-.. function:: setup(**kwargs)
 
-   Sets the size and position of the main window.  Keywords are:
+Pen control
+-----------
 
-   * ``width``: either a size in pixels or a fraction of the screen. The default is
-     50% of the screen.
+Drawing state
+~~~~~~~~~~~~~
 
-   * ``height``: either a size in pixels or a fraction of the screen. The default
-     is 50% of the screen.
+.. function:: pendown()
+              pd()
+              down()
 
-   * ``startx``: starting position in pixels from the left edge of the screen.
-     ``None`` is the default value and  centers the window horizontally on screen.
+   Pull the pen down -- drawing when moving.
 
-   * ``starty``: starting position in pixels from the top edge of the screen.
-     ``None`` is the default value and  centers the window vertically on screen.
 
-   Examples::
+.. function:: penup()
+              pu()
+              up()
 
-      # Uses default geometry: 50% x 50% of screen, centered.
-      setup()  
+   Pull the pen up -- no drawing when moving.
 
-      # Sets window to 200x200 pixels, in upper left of screen
-      setup (width=200, height=200, startx=0, starty=0)
 
-      # Sets window to 75% of screen by 50% of screen, and centers it.
-      setup(width=.75, height=0.5, startx=None, starty=None)
+.. function:: pensize(width=None)
+              width(width=None)
 
+   :param width: a positive number
 
-.. function:: title(title_str)
+   Set the line thickness to *width* or return it.  If resizemode is set to
+   "auto" and turtleshape is a polygon, that polygon is drawn with the same line
+   thickness.  If no argument is given, the current pensize is returned.
 
-   Set the window's title to *title*.
+   >>> turtle.pensize()
+   1
+   >>> turtle.pensize(10)   # from here on lines of width 10 are drawn
 
 
-.. function:: done()
+.. function:: pen(pen=None, **pendict)
 
-   Enters the Tk main loop.  The window will continue to  be displayed until the
-   user closes it or the process is killed.
+   :param pen: a dictionary with some or all of the below listed keys
+   :param pendict: one or more keyword-arguments with the below listed keys as keywords
 
+   Return or set the pen's attributes in a "pen-dictionary" with the following
+   key/value pairs:
 
-.. function:: reset()
+   * "shown": True/False
+   * "pendown": True/False
+   * "pencolor": color-string or color-tuple
+   * "fillcolor": color-string or color-tuple
+   * "pensize": positive number
+   * "speed": number in range 0..10
+   * "resizemode": "auto" or "user" or "noresize"
+   * "stretchfactor": (positive number, positive number)
+   * "outline": positive number
+   * "tilt": number
 
-   Clear the screen, re-center the pen, and set variables to the default values.
+   This dicionary can be used as argument for a subsequent call to :func:`pen`
+   to restore the former pen-state.  Moreover one or more of these attributes
+   can be provided as keyword-arguments.  This can be used to set several pen
+   attributes in one statement.
 
+   >>> turtle.pen(fillcolor="black", pencolor="red", pensize=10)
+   >>> turtle.pen()
+   {'pensize': 10, 'shown': True, 'resizemode': 'auto', 'outline': 1,
+   'pencolor': 'red', 'pendown': True, 'fillcolor': 'black',
+   'stretchfactor': (1,1), 'speed': 3}
+   >>> penstate=turtle.pen()
+   >>> turtle.color("yellow","")
+   >>> turtle.penup()
+   >>> turtle.pen()
+   {'pensize': 10, 'shown': True, 'resizemode': 'auto', 'outline': 1,
+   'pencolor': 'yellow', 'pendown': False, 'fillcolor': '',
+   'stretchfactor': (1,1), 'speed': 3}
+   >>> p.pen(penstate, fillcolor="green")
+   >>> p.pen()
+   {'pensize': 10, 'shown': True, 'resizemode': 'auto', 'outline': 1,
+   'pencolor': 'red', 'pendown': True, 'fillcolor': 'green',
+   'stretchfactor': (1,1), 'speed': 3}
 
-.. function:: clear()
 
-   Clear the screen.
+.. function:: isdown()
 
+   Return ``True`` if pen is down, ``False`` if it's up.
 
-.. function:: tracer(flag)
+   >>> turtle.penup()
+   >>> turtle.isdown()
+   False
+   >>> turtle.pendown()
+   >>> turtle.isdown()
+   True
 
-   Set tracing on/off (according to whether flag is true or not). Tracing means
-   line are drawn more slowly, with an animation of an arrow along the  line.
 
+Color control
+~~~~~~~~~~~~~
 
-.. function:: speed(speed)
+.. function:: pencolor(*args)
 
-   Set the speed of the turtle. Valid values for the parameter *speed* are
-   ``'fastest'`` (no delay), ``'fast'``, (delay 5ms), ``'normal'`` (delay 10ms),
-   ``'slow'`` (delay 15ms), and ``'slowest'`` (delay 20ms).
+   Return or set the pencolor.
 
+   Four input formats are allowed:
 
-.. function:: delay(delay)
+   ``pencolor()``
+      Return the current pencolor as color specification string, possibly in
+      hex-number format (see example).  May be used as input to another
+      color/pencolor/fillcolor call.
 
-   Set the speed of the turtle to *delay*, which is given in ms.
+   ``pencolor(colorstring)``
+      Set pencolor to *colorstring*, which is a Tk color specification string,
+      such as ``"red"``, ``"yellow"``, or ``"#33cc8c"``.
 
+   ``pencolor((r, g, b))``
+      Set pencolor to the RGB color represented by the tuple of *r*, *g*, and
+      *b*.  Each of *r*, *g*, and *b* must be in the range 0..colormode, where
+      colormode is either 1.0 or 255 (see :func:`colormode`).
 
-.. function:: forward(distance)
+   ``pencolor(r, g, b)``
+      Set pencolor to the RGB color represented by *r*, *g*, and *b*.  Each of
+      *r*, *g*, and *b* must be in the range 0..colormode.
 
-   Go forward *distance* steps.
+    If turtleshape is a polygon, the outline of that polygon is drawn with the
+    newly set pencolor.
 
+    >>> turtle.pencolor("brown")
+    >>> tup = (0.2, 0.8, 0.55)
+    >>> turtle.pencolor(tup)
+    >>> turtle.pencolor()
+    "#33cc8c"
 
-.. function:: backward(distance)
 
-   Go backward *distance* steps.
+.. function:: fillcolor(*args)
 
+   Return or set the fillcolor.
 
-.. function:: left(angle)
+   Four input formats are allowed:
 
-   Turn left *angle* units. Units are by default degrees, but can be set via the
-   :func:`degrees` and :func:`radians` functions.
+   ``fillcolor()``
+      Return the current fillcolor as color specification string, possibly in
+      hex-number format (see example).  May be used as input to another
+      color/pencolor/fillcolor call.
 
+   ``fillcolor(colorstring)``
+      Set fillcolor to *colorstring*, which is a Tk color specification string,
+      such as ``"red"``, ``"yellow"``, or ``"#33cc8c"``.
 
-.. function:: right(angle)
+   ``fillcolor((r, g, b))``
+      Set fillcolor to the RGB color represented by the tuple of *r*, *g*, and
+      *b*.  Each of *r*, *g*, and *b* must be in the range 0..colormode, where
+      colormode is either 1.0 or 255 (see :func:`colormode`).
 
-   Turn right *angle* units. Units are by default degrees, but can be set via the
-   :func:`degrees` and :func:`radians` functions.
+   ``fillcolor(r, g, b)``
+      Set fillcolor to the RGB color represented by *r*, *g*, and *b*.  Each of
+      *r*, *g*, and *b* must be in the range 0..colormode.
 
+    If turtleshape is a polygon, the interior of that polygon is drawn
+    with the newly set fillcolor.
 
-.. function:: up()
+    >>> turtle.fillcolor("violet")
+    >>> col = turtle.pencolor()
+    >>> turtle.fillcolor(col)
+    >>> turtle.fillcolor(0, .5, 0)
 
-   Move the pen up --- stop drawing.
 
+.. function:: color(*args)
 
-.. function:: down()
+   Return or set pencolor and fillcolor.
 
-   Move the pen down --- draw when moving.
+   Several input formats are allowed.  They use 0 to 3 arguments as
+   follows:
 
+   ``color()``
+      Return the current pencolor and the current fillcolor as a pair of color
+      specification strings as returned by :func:`pencolor` and
+      :func:`fillcolor`.
 
-.. function:: width(width)
+   ``color(colorstring)``, ``color((r,g,b))``, ``color(r,g,b)``
+      Inputs as in :func:`pencolor`, set both, fillcolor and pencolor, to the
+      given value.
 
-   Set the line width to *width*.
+   ``color(colorstring1, colorstring2)``, ``color((r1,g1,b1), (r2,g2,b2))``
+      Equivalent to ``pencolor(colorstring1)`` and ``fillcolor(colorstring2)``
+      and analogously if the other input format is used.
 
+    If turtleshape is a polygon, outline and interior of that polygon is drawn
+    with the newly set colors.
 
-.. function:: color(s)
-              color((r, g, b))
-              color(r, g, b)
+    >>> turtle.color("red", "green")
+    >>> turtle.color()
+    ("red", "green")
+    >>> colormode(255)
+    >>> color((40, 80, 120), (160, 200, 240))
+    >>> color()
+    ("#285078", "#a0c8f0")
 
-   Set the pen color.  In the first form, the color is specified as a Tk color
-   specification as a string.  The second form specifies the color as a tuple of
-   the RGB values, each in the range [0..1].  For the third form, the color is
-   specified giving the RGB values as three separate parameters (each in the range
-   [0..1]).
 
+See also: Screen method :func:`colormode`.
 
-.. function:: write(text[, move])
 
-   Write *text* at the current pen position. If *move* is true, the pen is moved to
-   the bottom-right corner of the text. By default, *move* is false.
+Filling
+~~~~~~~
 
+.. function:: filling()
 
-.. function:: fill(flag)
+   Return fillstate (``True`` if filling, ``False`` else).
 
-   The complete specifications are rather complex, but the recommended  usage is:
-   call ``fill(1)`` before drawing a path you want to fill, and call ``fill(0)``
-   when you finish to draw the path.
+   >>> turtle.begin_fill()
+   >>> if turtle.filling():
+   ...    turtle.pensize(5)
+   else:
+   ...    turtle.pensize(3)
 
 
 .. function:: begin_fill()
 
-   Switch turtle into filling mode;  Must eventually be followed by a corresponding
-   end_fill() call. Otherwise it will be ignored.
+   To be called just before drawing a shape to be filled.
+
+   >>> turtle.color("black", "red")
+   >>> turtle.begin_fill()
+   >>> turtle.circle(60)
+   >>> turtle.end_fill()
 
 
 .. function:: end_fill()
 
-   End filling mode, and fill the shape; equivalent to ``fill(0)``.
+   Fill the shape drawn after the last call to :func:`begin_fill`.
 
 
-.. function:: circle(radius[, extent])
+More drawing control
+~~~~~~~~~~~~~~~~~~~~
 
-   Draw a circle with radius *radius* whose center-point is *radius* units left of
-   the turtle. *extent* determines which part of a circle is drawn: if not given it
-   defaults to a full circle.
+.. function:: reset()
 
-   If *extent* is not a full circle, one endpoint of the arc is the current pen
-   position. The arc is drawn in a counter clockwise direction if *radius* is
-   positive, otherwise in a clockwise direction.  In the process, the direction of
-   the turtle is changed by the amount of the *extent*.
+   Delete the turtle's drawings from the screen, re-center the turtle and set
+   variables to the default values.
 
+   >>> turtle.position()
+   (0.00,-22.00)
+   >>> turtle.heading()
+   100.0
+   >>> turtle.reset()
+   >>> turtle.position()
+   (0.00,0.00)
+   >>> turtle.heading()
+   0.0
 
-.. function:: goto(x, y)
-              goto((x, y))
 
-   Go to co-ordinates *x*, *y*.  The co-ordinates may be specified either as two
-   separate arguments or as a 2-tuple.
+.. function:: clear()
 
+   Delete the turtle's drawings from the screen.  Do not move turtle.  State and
+   position of the turtle as well as drawings of other turtles are not affected.
 
-.. function:: towards(x, y)
 
-   Return the angle of the line from the turtle's position to the point *x*, *y*.
-   The co-ordinates may be specified either as two separate arguments, as a
-   2-tuple, or as another pen object.
+.. function:: write(arg, move=False, align="left", font=("Arial", 8, "normal"))
 
+   :param arg: object to be written to the TurtleScreen
+   :param move: True/False
+   :param align: one of the strings "left", "center" or right"
+   :param font: a triple (fontname, fontsize, fonttype)
 
-.. function:: heading()
+   Write text - the string representation of *arg* - at the current turtle
+   position according to *align* ("left", "center" or right") and with the given
+   font.  If *move* is True, the pen is moved to the bottom-right corner of the
+   text.  By default, *move* is False.
 
-   Return the current orientation of the turtle.
+   >>> turtle.write("Home = ", True, align="center")
+   >>> turtle.write((0,0), True)
 
 
-.. function:: setheading(angle)
+Turtle state
+------------
 
-   Set the orientation of the turtle to *angle*.
+Visibility
+~~~~~~~~~~
 
+.. function:: showturtle()
+              st()
 
-.. function:: position()
+   Make the turtle visible.
 
-   Return the current location of the turtle as an ``(x,y)`` pair.
+   >>> turtle.hideturtle()
+   >>> turtle.showturtle()
 
 
-.. function:: setx(x)
+.. function:: hideturtle()
+              ht()
 
-   Set the x coordinate of the turtle to *x*.
+   Make the turtle invisible.  It's a good idea to do this while you're in the
+   middle of doing some complex drawing, because hiding the turtle speeds up the
+   drawing observably.
 
+   >>> turtle.hideturtle()
 
-.. function:: sety(y)
 
-   Set the y coordinate of the turtle to *y*.
+.. function:: isvisible()
 
+   Return True if the Turtle is shown, False if it's hidden.
+
+   >>> turtle.hideturtle()
+   >>> print turtle.isvisible():
+   False
+
+
+Appearance
+~~~~~~~~~~
+
+.. function:: shape(name=None)
+
+   :param name: a string which is a valid shapename
+
+   Set turtle shape to shape with given *name* or, if name is not given, return
+   name of current shape.  Shape with *name* must exist in the TurtleScreen's
+   shape dictionary.  Initially there are the following polygon shapes: "arrow",
+   "turtle", "circle", "square", "triangle", "classic".  To learn about how to
+   deal with shapes see Screen method :func:`register_shape`.
+
+   >>> turtle.shape()
+   "arrow"
+   >>> turtle.shape("turtle")
+   >>> turtle.shape()
+   "turtle"
+
+
+.. function:: resizemode(rmode=None)
+
+   :param rmode: one of the strings "auto", "user", "noresize"
+
+   Set resizemode to one of the values: "auto", "user", "noresize".  If *rmode*
+   is not given, return current resizemode.  Different resizemodes have the
+   following effects:
+
+   - "auto": adapts the appearance of the turtle corresponding to the value of pensize.
+   - "user": adapts the appearance of the turtle according to the values of
+     stretchfactor and outlinewidth (outline), which are set by
+     :func:`shapesize`.
+   - "noresize": no adaption of the turtle's appearance takes place.
+
+   resizemode("user") is called by :func:`shapesize` when used with arguments.
+
+   >>> turtle.resizemode("noresize")
+   >>> turtle.resizemode()
+   "noresize"
+
+
+.. function:: shapesize(stretch_wid=None, stretch_len=None, outline=None)
+
+   :param stretch_wid: positive number
+   :param stretch_len: positive number
+   :param outline: positive number
+
+   Return or set the pen's attributes x/y-stretchfactors and/or outline.  Set
+   resizemode to "user".  If and only if resizemode is set to "user", the turtle
+   will be displayed stretched according to its stretchfactors: *stretch_wid* is
+   stretchfactor perpendicular to its orientation, *stretch_len* is
+   stretchfactor in direction of its orientation, *outline* determines the width
+   of the shapes's outline.
+
+   >>> turtle.resizemode("user")
+   >>> turtle.shapesize(5, 5, 12)
+   >>> turtle.shapesize(outline=8)
+
+
+.. function:: tilt(angle)
+
+   :param angle: a number
+
+   Rotate the turtleshape by *angle* from its current tilt-angle, but do *not*
+   change the turtle's heading (direction of movement).
+
+   >>> turtle.shape("circle")
+   >>> turtle.shapesize(5,2)
+   >>> turtle.tilt(30)
+   >>> turtle.fd(50)
+   >>> turtle.tilt(30)
+   >>> turtle.fd(50)
+
+
+.. function:: settiltangle(angle)
+
+   :param angle: a number
+
+   Rotate the turtleshape to point in the direction specified by *angle*,
+   regardless of its current tilt-angle.  *Do not* change the turtle's heading
+   (direction of movement).
+
+   >>> turtle.shape("circle")
+   >>> turtle.shapesize(5,2)
+   >>> turtle.settiltangle(45)
+   >>> stamp()
+   >>> turtle.fd(50)
+   >>> turtle.settiltangle(-45)
+   >>> stamp()
+   >>> turtle.fd(50)
+
+
+.. function:: tiltangle()
+
+   Return the current tilt-angle, i.e. the angle between the orientation of the
+   turtleshape and the heading of the turtle (its direction of movement).
+
+   >>> turtle.shape("circle")
+   >>> turtle.shapesize(5,2)
+   >>> turtle.tilt(45)
+   >>> turtle.tiltangle()
+   45
+
+
+Using events
+------------
+
+.. function:: onclick(fun, btn=1, add=None)
+
+   :param fun: a function with two arguments which will be called with the
+               coordinates of the clicked point on the canvas
+   :param num: number of the mouse-button, defaults to 1 (left mouse button)
+   :param add: ``True`` or ``False`` -- if ``True``, a new binding will be
+               added, otherwise it will replace a former binding
+
+   Bind *fun* to mouse-click events on this turtle.  If *fun* is ``None``,
+   existing bindings are removed.  Example for the anonymous turtle, i.e. the
+   procedural way:
+
+   >>> def turn(x, y):
+   ...     left(180)
+   ...
+   >>> onclick(turn)  # Now clicking into the turtle will turn it.
+   >>> onclick(None)  # event-binding will be removed
+
+
+.. function:: onrelease(fun, btn=1, add=None)
+
+   :param fun: a function with two arguments which will be called with the
+               coordinates of the clicked point on the canvas
+   :param num: number of the mouse-button, defaults to 1 (left mouse button)
+   :param add: ``True`` or ``False`` -- if ``True``, a new binding will be
+               added, otherwise it will replace a former binding
+
+   Bind *fun* to mouse-button-release events on this turtle.  If *fun* is
+   ``None``, existing bindings are removed.
+
+   >>> class MyTurtle(Turtle):
+   ...     def glow(self,x,y):
+   ...         self.fillcolor("red")
+   ...     def unglow(self,x,y):
+   ...         self.fillcolor("")
+   ...
+   >>> turtle = MyTurtle()
+   >>> turtle.onclick(turtle.glow)     # clicking on turtle turns fillcolor red,
+   >>> turtle.onrelease(turtle.unglow) # releasing turns it to transparent.
 
-.. function:: window_width()
 
-   Return the width of the canvas window.
+.. function:: ondrag(fun, btn=1, add=None)
+
+   :param fun: a function with two arguments which will be called with the
+               coordinates of the clicked point on the canvas
+   :param num: number of the mouse-button, defaults to 1 (left mouse button)
+   :param add: ``True`` or ``False`` -- if ``True``, a new binding will be
+               added, otherwise it will replace a former binding
+
+   Bind *fun* to mouse-move events on this turtle.  If *fun* is ``None``,
+   existing bindings are removed.
+
+   Remark: Every sequence of mouse-move-events on a turtle is preceded by a
+   mouse-click event on that turtle.
+
+   >>> turtle.ondrag(turtle.goto)
+   # Subsequently, clicking and dragging the Turtle will move it across
+   # the screen thereby producing handdrawings (if pen is down).
+
+
+Special Turtle methods
+----------------------
+
+.. function:: begin_poly()
+
+   Start recording the vertices of a polygon.  Current turtle position is first
+   vertex of polygon.
+
+
+.. function:: end_poly()
+
+   Stop recording the vertices of a polygon.  Current turtle position is last
+   vertex of polygon.  This will be connected with the first vertex.
+
+
+.. function:: get_poly()
+
+   Return the last recorded polygon.
+
+   >>> p = turtle.get_poly()
+   >>> turtle.register_shape("myFavouriteShape", p)
+
+
+.. function:: clone()
+
+   Create and return a clone of the turtle with same position, heading and
+   turtle properties.
+
+   >>> mick = Turtle()
+   >>> joe = mick.clone()
+
+
+.. function:: getturtle()
+
+   Return the Turtle object itself.  Only reasonable use: as a function to
+   return the "anonymous turtle":
+
+   >>> pet = getturtle()
+   >>> pet.fd(50)
+   >>> pet
+   <turtle.Turtle object at 0x01417350>
+   >>> turtles()
+   [<turtle.Turtle object at 0x01417350>]
+
+
+.. function:: getscreen()
+
+   Return the :class:`TurtleScreen` object the turtle is drawing on.
+   TurtleScreen methods can then be called for that object.
+
+   >>> ts = turtle.getscreen()
+   >>> ts
+   <turtle.Screen object at 0x01417710>
+   >>> ts.bgcolor("pink")
+
+
+.. function:: setundobuffer(size)
+
+   :param size: an integer or ``None``
+
+   Set or disable undobuffer.  If *size* is an integer an empty undobuffer of
+   given size is installed.  *size* gives the maximum number of turtle actions
+   that can be undone by the :func:`undo` method/function.  If *size* is
+   ``None``, the undobuffer is disabled.
+
+   >>> turtle.setundobuffer(42)
+
+
+.. function:: undobufferentries()
+
+   Return number of entries in the undobuffer.
+
+   >>> while undobufferentries():
+   ...     undo()
+
+
+.. _compoundshapes:
+
+Excursus about the use of compound shapes
+-----------------------------------------
+
+To use compound turtle shapes, which consist of several polygons of different
+color, you must use the helper class :class:`Shape` explicitly as described
+below:
+
+1. Create an empty Shape object of type "compound".
+2. Add as many components to this object as desired, using the
+   :meth:`addcomponent` method.
+
+   For example:
+
+   >>> s = Shape("compound")
+   >>> poly1 = ((0,0),(10,-5),(0,10),(-10,-5))
+   >>> s.addcomponent(poly1, "red", "blue")
+   >>> poly2 = ((0,0),(10,-5),(-10,-5))
+   >>> s.addcomponent(poly2, "blue", "red")
+
+3. Now add the Shape to the Screen's shapelist and use it:
+
+   >>> register_shape("myshape", s)
+   >>> shape("myshape")
+
+
+.. note::
+
+   The :class:`Shape` class is used internally by the :func:`register_shape`
+   method in different ways.  The application programmer has to deal with the
+   Shape class *only* when using compound shapes like shown above!
+
+
+Methods of TurtleScreen/Screen and corresponding functions
+==========================================================
+
+Most of the examples in this section refer to a TurtleScreen instance called
+``screen``.
+
+
+Window control
+--------------
+
+.. function:: bgcolor(*args)
+
+   :param args: a color string or three numbers in the range 0..colormode or a
+                3-tuple of such numbers
+
+   Set or return background color of the TurtleScreen.
+
+   >>> screen.bgcolor("orange")
+   >>> screen.bgcolor()
+   "orange"
+   >>> screen.bgcolor(0.5,0,0.5)
+   >>> screen.bgcolor()
+   "#800080"
+
+
+.. function:: bgpic(picname=None)
+
+   :param picname: a string, name of a gif-file or ``"nopic"``, or ``None``
+
+   Set background image or return name of current backgroundimage.  If *picname*
+   is a filename, set the corresponding image as background.  If *picname* is
+   ``"nopic"``, delete background image, if present.  If *picname* is ``None``,
+   return the filename of the current backgroundimage.
+
+   >>> screen.bgpic()
+   "nopic"
+   >>> screen.bgpic("landscape.gif")
+   >>> screen.bgpic()
+   "landscape.gif"
+
+
+.. function:: clear()
+              clearscreen()
+
+   Delete all drawings and all turtles from the TurtleScreen.  Reset the now
+   empty TurtleScreen to its initial state: white background, no background
+   image, no event bindings and tracing on.
+
+   .. note::
+      This TurtleScreen method is available as a global function only under the
+      name ``clearscreen``.  The global function ``clear`` is another one
+      derived from the Turtle method ``clear``.
+
+
+.. function:: reset()
+              resetscreen()
+
+   Reset all Turtles on the Screen to their initial state.
+
+   .. note::
+      This TurtleScreen method is available as a global function only under the
+      name ``resetscreen``.  The global function ``reset`` is another one
+      derived from the Turtle method ``reset``.
+
+
+.. function:: screensize(canvwidth=None, canvheight=None, bg=None)
+
+   :param canvwidth: positive integer, new width of canvas in pixels
+   :param canvheight: positive integer, new height of canvas in pixels
+   :param bg: colorstring or color-tupel, new background color
+
+   If no arguments are given, return current (canvaswidth, canvasheight).  Else
+   resize the canvas the turtles are drawing on.  Do not alter the drawing
+   window.  To observe hidden parts of the canvas, use the scrollbars. With this
+   method, one can make visible those parts of a drawing which were outside the
+   canvas before.
+
+      >>> turtle.screensize(2000,1500)
+      # e.g. to search for an erroneously escaped turtle ;-)
+
+
+.. function:: setworldcoordinates(llx, lly, urx, ury)
+
+   :param llx: a number, x-coordinate of lower left corner of canvas
+   :param lly: a number, y-coordinate of lower left corner of canvas
+   :param urx: a number, x-coordinate of upper right corner of canvas
+   :param ury: a number, y-coordinate of upper right corner of canvas
+
+   Set up user-defined coordinate system and switch to mode "world" if
+   necessary.  This performs a ``screen.reset()``.  If mode "world" is already
+   active, all drawings are redrawn according to the new coordinates.
+
+   **ATTENTION**: in user-defined coordinate systems angles may appear
+   distorted.
+
+   >>> screen.reset()
+   >>> screen.setworldcoordinates(-50,-7.5,50,7.5)
+   >>> for _ in range(72):
+   ...     left(10)
+   ...
+   >>> for _ in range(8):
+   ...     left(45); fd(2)   # a regular octogon
+
+
+Animation control
+-----------------
+
+.. function:: delay(delay=None)
+
+   :param delay: positive integer
+
+   Set or return the drawing *delay* in milliseconds.  (This is approximately
+   the time interval between two consecutived canvas updates.)  The longer the
+   drawing delay, the slower the animation.
+
+   Optional argument:
+
+   >>> screen.delay(15)
+   >>> screen.delay()
+   15
+
+
+.. function:: tracer(n=None, delay=None)
+
+   :param n: nonnegative integer
+   :param delay: nonnegative integer
+
+   Turn turtle animation on/off and set delay for update drawings.  If *n* is
+   given, only each n-th regular screen update is really performed.  (Can be
+   used to accelerate the drawing of complex graphics.)  Second argument sets
+   delay value (see :func:`delay`).
+
+   >>> screen.tracer(8, 25)
+   >>> dist = 2
+   >>> for i in range(200):
+   ...     fd(dist)
+   ...     rt(90)
+   ...     dist += 2
+
+
+.. function:: update()
+
+   Perform a TurtleScreen update. To be used when tracer is turned off.
+
+See also the RawTurtle/Turtle method :func:`speed`.
+
+
+Using screen events
+-------------------
+
+.. function:: listen(xdummy=None, ydummy=None)
+
+   Set focus on TurtleScreen (in order to collect key-events).  Dummy arguments
+   are provided in order to be able to pass :func:`listen` to the onclick method.
+
+
+.. function:: onkey(fun, key)
+
+   :param fun: a function with no arguments or ``None``
+   :param key: a string: key (e.g. "a") or key-symbol (e.g. "space")
+
+   Bind *fun* to key-release event of key.  If *fun* is ``None``, event bindings
+   are removed. Remark: in order to be able to register key-events, TurtleScreen
+   must have the focus. (See method :func:`listen`.)
+
+   >>> def f():
+   ...     fd(50)
+   ...     lt(60)
+   ...
+   >>> screen.onkey(f, "Up")
+   >>> screen.listen()
+
+
+.. function:: onclick(fun, btn=1, add=None)
+              onscreenclick(fun, btn=1, add=None)
+
+   :param fun: a function with two arguments which will be called with the
+               coordinates of the clicked point on the canvas
+   :param num: number of the mouse-button, defaults to 1 (left mouse button)
+   :param add: ``True`` or ``False`` -- if ``True``, a new binding will be
+               added, otherwise it will replace a former binding
+
+   Bind *fun* to mouse-click events on this screen.  If *fun* is ``None``,
+   existing bindings are removed.
+
+   Example for a TurtleScreen instance named ``screen`` and a Turtle instance
+   named turtle:
+
+   >>> screen.onclick(turtle.goto)
+   # Subsequently clicking into the TurtleScreen will
+   # make the turtle move to the clicked point.
+   >>> screen.onclick(None)  # remove event binding again
+
+   .. note::
+      This TurtleScreen method is available as a global function only under the
+      name ``onscreenclick``.  The global function ``onclick`` is another one
+      derived from the Turtle method ``onclick``.
+
+
+.. function:: ontimer(fun, t=0)
+
+   :param fun: a function with no arguments
+   :param t: a number >= 0
+
+   Install a timer that calls *fun* after *t* milliseconds.
+
+   >>> running = True
+   >>> def f():
+           if running:
+               fd(50)
+               lt(60)
+               screen.ontimer(f, 250)
+   >>> f()   ### makes the turtle marching around
+   >>> running = False
+
+
+Settings and special methods
+----------------------------
+
+.. function:: mode(mode=None)
+
+   :param mode: one of the strings "standard", "logo" or "world"
+
+   Set turtle mode ("standard", "logo" or "world") and perform reset.  If mode
+   is not given, current mode is returned.
+
+   Mode "standard" is compatible with old :mod:`turtle`.  Mode "logo" is
+   compatible with most Logo turtle graphics.  Mode "world" uses user-defined
+   "world coordinates". **Attention**: in this mode angles appear distorted if
+   ``x/y`` unit-ratio doesn't equal 1.
+
+   ============ ========================= ===================
+       Mode      Initial turtle heading     positive angles
+   ============ ========================= ===================
+    "standard"    to the right (east)       counterclockwise
+      "logo"        upward    (north)         clockwise
+   ============ ========================= ===================
+
+   >>> mode("logo")   # resets turtle heading to north
+   >>> mode()
+   "logo"
+
+
+.. function:: colormode(cmode=None)
+
+   :param cmode: one of the values 1.0 or 255
+
+   Return the colormode or set it to 1.0 or 255.  Subsequently *r*, *g*, *b*
+   values of color triples have to be in the range 0..\ *cmode*.
+
+   >>> screen.colormode()
+   1.0
+   >>> screen.colormode(255)
+   >>> turtle.pencolor(240,160,80)
+
+
+.. function:: getcanvas()
+
+   Return the Canvas of this TurtleScreen.  Useful for insiders who know what to
+   do with a Tkinter Canvas.
+
+   >>> cv = screen.getcanvas()
+   >>> cv
+   <turtle.ScrolledCanvas instance at 0x010742D8>
+
+
+.. function:: getshapes()
+
+   Return a list of names of all currently available turtle shapes.
+
+   >>> screen.getshapes()
+   ["arrow", "blank", "circle", ..., "turtle"]
+
+
+.. function:: register_shape(name, shape=None)
+              addshape(name, shape=None)
+
+   There are three different ways to call this function:
+
+   (1) *name* is the name of a gif-file and *shape* is ``None``: Install the
+       corresponding image shape.
+
+       .. note::
+          Image shapes *do not* rotate when turning the turtle, so they do not
+          display the heading of the turtle!
+
+   (2) *name* is an arbitrary string and *shape* is a tuple of pairs of
+       coordinates: Install the corresponding polygon shape.
+
+   (3) *name* is an arbitrary string and shape is a (compound) :class:`Shape`
+       object: Install the corresponding compound shape.
+
+   Add a turtle shape to TurtleScreen's shapelist.  Only thusly registered
+   shapes can be used by issuing the command ``shape(shapename)``.
+
+   >>> screen.register_shape("turtle.gif")
+   >>> screen.register_shape("triangle", ((5,-3), (0,5), (-5,-3)))
+
+
+.. function:: turtles()
+
+   Return the list of turtles on the screen.
+
+   >>> for turtle in screen.turtles()
+   ...     turtle.color("red")
 
 
 .. function:: window_height()
 
-   Return the height of the canvas window.
+   Return the height of the turtle window.
 
+   >>> screen.window_height()
+   480
 
-This module also does ``from math import *``, so see the documentation for the
-:mod:`math` module for additional constants and functions useful for turtle
-graphics.
 
+.. function:: window_width()
 
-.. function:: demo()
+   Return the width of the turtle window.
 
-   Exercise the module a bit.
+   >>> screen.window_width()
+   640
 
 
-.. exception:: Error
+.. _screenspecific:
 
-   Exception raised on any error caught by this module.
+Methods specific to Screen, not inherited from TurtleScreen
+-----------------------------------------------------------
 
-For examples, see the code of the :func:`demo` function.
+.. function:: bye()
 
-This module defines the following classes:
+   Shut the turtlegraphics window.
 
 
-.. class:: Pen()
+.. function:: exitonclick()
 
-   Define a pen. All above functions can be called as a methods on the given pen.
-   The constructor automatically creates a canvas do be drawn on.
+   Bind bye() method to mouse clicks on the Screen.
 
 
-.. class:: Turtle()
+   If the value "using_IDLE" in the configuration dictionary is ``False``
+   (default value), also enter mainloop.  Remark: If IDLE with the ``-n`` switch
+   (no subprocess) is used, this value should be set to ``True`` in
+   :file:`turtle.cfg`.  In this case IDLE's own mainloop is active also for the
+   client script.
 
-   Define a pen. This is essentially a synonym for ``Pen()``; :class:`Turtle` is an
-   empty subclass of :class:`Pen`.
 
+.. function:: setup(width=_CFG["width"], height=_CFG["height"], startx=_CFG["leftright"], starty=_CFG["topbottom"])
 
-.. class:: RawPen(canvas)
+   Set the size and position of the main window.  Default values of arguments
+   are stored in the configuration dicionary and can be changed via a
+   :file:`turtle.cfg` file.
 
-   Define a pen which draws on a canvas *canvas*. This is useful if  you want to
-   use the module to create graphics in a "real" program.
+   :param width: if an integer, a size in pixels, if a float, a fraction of the
+                 screen; default is 50% of screen
+   :param height: if an integer, the height in pixels, if a float, a fraction of
+                  the screen; default is 75% of screen
+   :param startx: if positive, starting position in pixels from the left
+                  edge of the screen, if negative from the right edge, if None,
+                  center window horizontally
+   :param startx: if positive, starting position in pixels from the top
+                  edge of the screen, if negative from the bottom edge, if None,
+                  center window vertically
 
+   >>> screen.setup (width=200, height=200, startx=0, starty=0)
+   # sets window to 200x200 pixels, in upper left of screen
+   >>> screen.setup(width=.75, height=0.5, startx=None, starty=None)
+   # sets window to 75% of screen by 50% of screen and centers
 
-.. _pen-rawpen-objects:
 
-Turtle, Pen and RawPen Objects
-------------------------------
+.. function:: title(titlestring)
+
+   :param titlestring: a string that is shown in the titlebar of the turtle
+                       graphics window
+
+   Set title of turtle window to *titlestring*.
+
+   >>> screen.title("Welcome to the turtle zoo!")
+
+
+The public classes of the module :mod:`turtle`
+==============================================
+
+
+.. class:: RawTurtle(canvas)
+           RawPen(canvas)
+
+   :param canvas: a :class:`Tkinter.Canvas`, a :class:`ScrolledCanvas` or a
+                  :class:`TurtleScreen`
+
+    Create a turtle.  The turtle has all methods described above as "methods of
+    Turtle/RawTurtle".
+
+
+.. class:: Turtle()
 
-Most of the global functions available in the module are also available as
-methods of the :class:`Turtle`, :class:`Pen` and :class:`RawPen` classes,
-affecting only the state of the given pen.
+    Subclass of RawTurtle, has the same interface but draws on a default
+    :class:`Screen` object created automatically when needed for the first time.
 
-The only method which is more powerful as a method is :func:`degrees`, which
-takes an optional argument letting  you specify the number of units
-corresponding to a full circle:
 
+.. class:: TurtleScreen(cv)
 
-.. method:: Turtle.degrees([fullcircle])
+   :param cv: a :class:`Tkinter.Canvas`
 
-   *fullcircle* is by default 360. This can cause the pen to have any angular units
-   whatever: give *fullcircle* ``2*pi`` for radians, or 400 for gradians.
+   Provides screen oriented methods like :func:`setbg` etc. that are described
+   above.
+
+.. class:: Screen()
+
+   Subclass of TurtleScreen, with :ref:`four methods added <screenspecific>`.
+
+   
+.. class:: ScrolledCavas(master)
+
+   :param master: some Tkinter widget to contain the ScrolledCanvas, i.e.
+      a Tkinter-canvas with scrollbars added
+
+   Used by class Screen, which thus automatically provides a ScrolledCanvas as
+   playground for the turtles.
+
+.. class:: Shape(type_, data)
+
+   :param type\_: one of the strings "polygon", "image", "compound"
+
+   Data structure modeling shapes.  The pair ``(type_, data)`` must follow this
+   specification:
+
+
+   =========== ===========
+   *type_*     *data*
+   =========== ===========
+   "polygon"   a polygon-tuple, i.e. a tuple of pairs of coordinates
+   "image"     an image  (in this form only used internally!)
+   "compound"  ``None`` (a compund shape has to be constructed using the
+               :meth:`addcomponent` method)
+   =========== ===========
+                
+   .. method:: addcomponent(poly, fill, outline=None)
+
+      :param poly: a polygon, i.e. a tuple of pairs of numbers
+      :param fill: a color the *poly* will be filled with
+      :param outline: a color for the poly's outline (if given)
+     
+      Example:
+
+      >>> poly = ((0,0),(10,-5),(0,10),(-10,-5))
+      >>> s = Shape("compound")
+      >>> s.addcomponent(poly, "red", "blue")
+      # .. add more components and then use register_shape()
+
+      See :ref:`compoundshapes`.
+
+
+.. class:: Vec2D(x, y)
+
+   A two-dimensional vector class, used as a helper class for implementing
+   turtle graphics.  May be useful for turtle graphics programs too.  Derived
+   from tuple, so a vector is a tuple!
+
+   Provides (for *a*, *b* vectors, *k* number):
+
+   * ``a + b`` vector addition
+   * ``a - b`` vector subtraction
+   * ``a * b`` inner product
+   * ``k * a`` and ``a * k`` multiplication with scalar
+   * ``abs(a)`` absolute value of a
+   * ``a.rotate(angle)`` rotation
+
+
+Help and configuration
+======================
+
+How to use help
+---------------
+
+The public methods of the Screen and Turtle classes are documented extensively
+via docstrings.  So these can be used as online-help via the Python help
+facilities:
+
+- When using IDLE, tooltips show the signatures and first lines of the
+  docstrings of typed in function-/method calls.
+
+- Calling :func:`help` on methods or functions displays the docstrings::
+
+     >>> help(Screen.bgcolor)
+     Help on method bgcolor in module turtle:
+    
+     bgcolor(self, *args) unbound turtle.Screen method
+         Set or return backgroundcolor of the TurtleScreen.
+    
+         Arguments (if given): a color string or three numbers
+         in the range 0..colormode or a 3-tuple of such numbers.
+    
+    
+           >>> screen.bgcolor("orange")
+           >>> screen.bgcolor()
+           "orange"
+           >>> screen.bgcolor(0.5,0,0.5)
+           >>> screen.bgcolor()
+           "#800080"
+    
+     >>> help(Turtle.penup)
+     Help on method penup in module turtle:
+    
+     penup(self) unbound turtle.Turtle method
+         Pull the pen up -- no drawing when moving.
+    
+         Aliases: penup | pu | up
+    
+         No argument
+    
+         >>> turtle.penup()
+
+- The docstrings of the functions which are derived from methods have a modified
+  form::
+
+     >>> help(bgcolor)
+     Help on function bgcolor in module turtle:
+    
+     bgcolor(*args)
+         Set or return backgroundcolor of the TurtleScreen.
+    
+         Arguments (if given): a color string or three numbers
+         in the range 0..colormode or a 3-tuple of such numbers.
+    
+         Example::
+    
+           >>> bgcolor("orange")
+           >>> bgcolor()
+           "orange"
+           >>> bgcolor(0.5,0,0.5)
+           >>> bgcolor()
+           "#800080"
+    
+     >>> help(penup)
+     Help on function penup in module turtle:
+    
+     penup()
+         Pull the pen up -- no drawing when moving.
+    
+         Aliases: penup | pu | up
+    
+         No argument
+    
+         Example:
+         >>> penup()
+
+These modified docstrings are created automatically together with the function
+definitions that are derived from the methods at import time.
+
+
+Translation of docstrings into different languages
+--------------------------------------------------
+
+There is a utility to create a dictionary the keys of which are the method names
+and the values of which are the docstrings of the public methods of the classes
+Screen and Turtle.
+
+.. function:: write_docstringdict(filename="turtle_docstringdict")
+
+   :param filename: a string, used as filename
+
+   Create and write docstring-dictionary to a Python script with the given
+   filename.  This function has to be called explicitly (it is not used by the
+   turtle graphics classes).  The docstring dictionary will be written to the
+   Python script :file:`{filename}.py`.  It is intended to serve as a template
+   for translation of the docstrings into different languages.
+
+If you (or your students) want to use :mod:`turtle` with online help in your
+native language, you have to translate the docstrings and save the resulting
+file as e.g. :file:`turtle_docstringdict_german.py`.
+
+If you have an appropriate entry in your :file:`turtle.cfg` file this dictionary
+will be read in at import time and will replace the original English docstrings.
+
+At the time of this writing there are docstring dictionaries in German and in
+Italian.  (Requests please to glingl at aon.at.)
+
+
+
+How to configure Screen and Turtles
+-----------------------------------
+
+The built-in default configuration mimics the appearance and behaviour of the
+old turtle module in order to retain best possible compatibility with it.
+
+If you want to use a different configuration which better reflects the features
+of this module or which better fits to your needs, e.g. for use in a classroom,
+you can prepare a configuration file ``turtle.cfg`` which will be read at import
+time and modify the configuration according to its settings.
+
+The built in configuration would correspond to the following turtle.cfg::
+
+   width = 0.5
+   height = 0.75
+   leftright = None
+   topbottom = None
+   canvwidth = 400
+   canvheight = 300
+   mode = standard
+   colormode = 1.0
+   delay = 10
+   undobuffersize = 1000
+   shape = classic
+   pencolor = black
+   fillcolor = black
+   resizemode = noresize
+   visible = True
+   language = english
+   exampleturtle = turtle
+   examplescreen = screen
+   title = Python Turtle Graphics
+   using_IDLE = False
+
+Short explanation of selected entries:
+
+- The first four lines correspond to the arguments of the :meth:`Screen.setup`
+  method.
+- Line 5 and 6 correspond to the arguments of the method
+  :meth:`Screen.screensize`.
+- *shape* can be any of the built-in shapes, e.g: arrow, turtle, etc.  For more
+  info try ``help(shape)``.
+- If you want to use no fillcolor (i.e. make the turtle transparent), you have
+  to write ``fillcolor = ""`` (but all nonempty strings must not have quotes in
+  the cfg-file).
+- If you want to reflect the turtle its state, you have to use ``resizemode =
+  auto``.
+- If you set e.g. ``language = italian`` the docstringdict
+  :file:`turtle_docstringdict_italian.py` will be loaded at import time (if
+  present on the import path, e.g. in the same directory as :mod:`turtle`.
+- The entries *exampleturtle* and *examplescreen* define the names of these
+  objects as they occur in the docstrings.  The transformation of
+  method-docstrings to function-docstrings will delete these names from the
+  docstrings.
+- *using_IDLE*: Set this to ``True`` if you regularly work with IDLE and its -n
+  switch ("no subprocess").  This will prevent :func:`exitonclick` to enter the
+  mainloop.
+
+There can be a :file:`turtle.cfg` file in the directory where :mod:`turtle` is
+stored and an additional one in the current working directory.  The latter will
+override the settings of the first one.
+
+The :file:`Demo/turtle` directory contains a :file:`turtle.cfg` file.  You can
+study it as an example and see its effects when running the demos (preferably
+not from within the demo-viewer).
+
+
+Demo scripts
+============
+
+There is a set of demo scripts in the turtledemo directory located in the
+:file:`Demo/turtle` directory in the source distribution.
+
+It contains:
+
+- a set of 15 demo scripts demonstrating differet features of the new module
+  :mod:`turtle`
+- a demo viewer :file:`turtleDemo.py` which can be used to view the sourcecode
+  of the scripts and run them at the same time. 14 of the examples can be
+  accessed via the Examples menu; all of them can also be run standalone.
+- The example :file:`turtledemo_two_canvases.py` demonstrates the simultaneous
+  use of two canvases with the turtle module.  Therefore it only can be run
+  standalone.
+- There is a :file:`turtle.cfg` file in this directory, which also serves as an
+  example for how to write and use such files.
+
+The demoscripts are:
+
++----------------+------------------------------+-----------------------+
+| Name           | Description                  | Features              |
++----------------+------------------------------+-----------------------+
+| bytedesign     | complex classical            | :func:`tracer`, delay,|
+|                | turtlegraphics pattern       | :func:`update`        |
++----------------+------------------------------+-----------------------+
+| chaos          | graphs verhust dynamics,     | world coordinates     |
+|                | proves that you must not     |                       |
+|                | trust computers' computations|                       |
++----------------+------------------------------+-----------------------+
+| clock          | analog clock showing time    | turtles as clock's    |
+|                | of your computer             | hands, ontimer        |
++----------------+------------------------------+-----------------------+
+| colormixer     | experiment with r, g, b      | :func:`ondrag`        |
++----------------+------------------------------+-----------------------+
+| fractalcurves  | Hilbert & Koch curves        | recursion             |
++----------------+------------------------------+-----------------------+
+| lindenmayer    | ethnomathematics             | L-System              |
+|                | (indian kolams)              |                       |
++----------------+------------------------------+-----------------------+
+| minimal_hanoi  | Towers of Hanoi              | Rectangular Turtles   |
+|                |                              | as Hanoi discs        |
+|                |                              | (shape, shapesize)    |
++----------------+------------------------------+-----------------------+
+| paint          | super minimalistic           | :func:`onclick`       |
+|                | drawing program              |                       |
++----------------+------------------------------+-----------------------+
+| peace          | elementary                   | turtle: appearance    |
+|                |                              | and animation         |
++----------------+------------------------------+-----------------------+
+| penrose        | aperiodic tiling with        | :func:`stamp`         |
+|                | kites and darts              |                       |
++----------------+------------------------------+-----------------------+
+| planet_and_moon| simulation of                | compound shapes,      |
+|                | gravitational system         | :class:`Vec2D`        |
++----------------+------------------------------+-----------------------+
+| tree           | a (graphical) breadth        | :func:`clone`         |
+|                | first tree (using generators)|                       |
++----------------+------------------------------+-----------------------+
+| wikipedia      | a pattern from the wikipedia | :func:`clone`,        |
+|                | article on turtle graphics   | :func:`undo`          |
++----------------+------------------------------+-----------------------+
+| yingyang       | another elementary example   | :func:`circle`        |
++----------------+------------------------------+-----------------------+
+
+Have fun!
+
+
+Changes since Python 2.6
+========================
+
+- The methods :meth:`Turtle.tracer`, :meth:`Turtle.window_width` and 
+  :meth:`Turtle.window_height` have been eliminated. 
+  Methods with these names and functionality are now available only 
+  as methods of :class:`Screen`. The functions derived from these remain
+  available. (In fact already in Python 2.6 these methods were merely 
+  duplications of the corresponding 
+  :class:`TurtleScreen`/:class:`Screen`-methods.)
+
+- The method :meth:`Turtle.fill` has been eliminated. 
+  The behaviour of :meth:`begin_fill` and :meth:`end_fill` 
+  have changed slightly: now  every filling-process must be completed with an 
+  ``end_fill()`` call.
+  
+- A method :meth:`Turtle.filling` has been added. It returns a boolean
+  value: ``True`` if a filling process is under way, ``False`` otherwise.
+  This behaviour corresponds to a ``fill()`` call without arguments in
+  Python 2.6
 

Modified: python/branches/py3k/Lib/tkinter/turtle.py
==============================================================================
--- python/branches/py3k/Lib/tkinter/turtle.py	(original)
+++ python/branches/py3k/Lib/tkinter/turtle.py	Tue Jun 10 06:44:07 2008
@@ -1,9 +1,31 @@
-# LogoMation-like turtle graphics
+#
+# turtle.py: a Tkinter based turtle graphics module for Python
+# Version 1.0b1 - 31. 5. 2008
+#
+# Copyright (C) 2006 - 2008  Gregor Lingl
+# email: glingl at aon.at
+#
+# This software is provided 'as-is', without any express or implied
+# warranty.  In no event will the authors be held liable for any damages
+# arising from the use of this software.
+#
+# Permission is granted to anyone to use this software for any purpose,
+# including commercial applications, and to alter it and redistribute it
+# freely, subject to the following restrictions:
+#
+# 1. The origin of this software must not be misrepresented; you must not
+#    claim that you wrote the original software. If you use this software
+#    in a product, an acknowledgment in the product documentation would be
+#    appreciated but is not required.
+# 2. Altered source versions must be plainly marked as such, and must not be
+#    misrepresented as being the original software.
+# 3. This notice may not be removed or altered from any source distribution.
+
 
 """
 Turtle graphics is a popular way for introducing programming to
 kids. It was part of the original Logo programming language developed
-by Wally Feurzeig and Seymour Papert in 1966.
+by Wally Feurzig and Seymour Papert in 1966.
 
 Imagine a robotic turtle starting at (0, 0) in the x-y plane. Give it
 the command turtle.forward(15), and it moves (on-screen!) 15 pixels in
@@ -12,945 +34,4018 @@
 
 By combining together these and similar commands, intricate shapes and
 pictures can easily be drawn.
+
+----- turtle.py
+
+This module is an extended reimplementation of turtle.py from the
+Python standard distribution up to Python 2.5. (See: http:\\www.python.org)
+
+It tries to keep the merits of turtle.py and to be (nearly) 100%
+compatible with it. This means in the first place to enable the
+learning programmer to use all the commands, classes and methods
+interactively when using the module from within IDLE run with
+the -n switch.
+
+Roughly it has the following features added:
+
+- Better animation of the turtle movements, especially of turning the
+  turtle. So the turtles can more easily be used as a visual feedback
+  instrument by the (beginning) programmer.
+
+- Different turtle shapes, gif-images as turtle shapes, user defined
+  and user controllable turtle shapes, among them compound
+  (multicolored) shapes. Turtle shapes can be stgretched and tilted, which
+  makes turtles zu very versatile geometrical objects.
+
+- Fine control over turtle movement and screen updates via delay(),
+  and enhanced tracer() and speed() methods.
+
+- Aliases for the most commonly used commands, like fd for forward etc.,
+  following the early Logo traditions. This reduces the boring work of
+  typing long sequences of commands, which often occur in a natural way
+  when kids try to program fancy pictures on their first encounter with
+  turtle graphcis.
+
+- Turtles now have an undo()-method with configurable undo-buffer.
+
+- Some simple commands/methods for creating event driven programs
+  (mouse-, key-, timer-events). Especially useful for programming games.
+
+- A scrollable Canvas class. The default scrollable Canvas can be
+  extended interactively as needed while playing around with the turtle(s).
+
+- A TurtleScreen class with methods controlling background color or
+  background image, window and canvas size and other properties of the
+  TurtleScreen.
+
+- There is a method, setworldcoordinates(), to install a user defined
+  coordinate-system for the TurtleScreen.
+
+- The implementation uses a 2-vector class named Vec2D, derived from tuple.
+  This class is public, so it can be imported by the application programmer,
+  which makes certain types of computations very natural and compact.
+
+- Appearance of the TurtleScreen and the Turtles at startup/import can be
+  configured by means of a turtle.cfg configuration file.
+  The default configuration mimics the appearance of the old turtle module.
+
+- If configured appropriately the module reads in docstrings from a docstring
+  dictionary in some different language, supplied separately  and replaces
+  the english ones by those read in. There is a utility function
+  write_docstringdict() to write a dictionary with the original (english)
+  docstrings to disc, so it can serve as a template for translations.
+
+Behind the scenes there are some features included with possible
+extensionsin in mind. These will be commented and documented elsewhere.
+
 """
 
-from math import * # Also for export
-from time import sleep
-import tkinter
+_ver = "turtle 1.0b1- - for Python 3.0   -  9. 6. 2008, 01:15"
+
+# print(_ver)
+
+import tkinter as TK
+import types
+import math
+import time
+import os
+
+from os.path import isfile, split, join
+from copy import deepcopy
+
+#from math import *    ## for compatibility with old turtle module
+
+_tg_classes = ['ScrolledCanvas', 'TurtleScreen', 'Screen',
+               'RawTurtle', 'Turtle', 'RawPen', 'Pen', 'Shape', 'Vec2D']
+_tg_screen_functions = ['addshape', 'bgcolor', 'bgpic', 'bye',
+        'clearscreen', 'colormode', 'delay', 'exitonclick', 'getcanvas',
+        'getshapes', 'listen', 'mode', 'onkey', 'onscreenclick', 'ontimer',
+        'register_shape', 'resetscreen', 'screensize', 'setup',
+        'setworldcoordinates', 'title', 'tracer', 'turtles', 'update',
+        'window_height', 'window_width']
+_tg_turtle_functions = ['back', 'backward', 'begin_fill', 'begin_poly', 'bk',
+        'circle', 'clear', 'clearstamp', 'clearstamps', 'clone', 'color',
+        'degrees', 'distance', 'dot', 'down', 'end_fill', 'end_poly', 'fd',
+        #'fill',
+        'fillcolor', 'forward', 'get_poly', 'getpen', 'getscreen',
+        'getturtle', 'goto', 'heading', 'hideturtle', 'home', 'ht', 'isdown',
+        'isvisible', 'left', 'lt', 'onclick', 'ondrag', 'onrelease', 'pd',
+        'pen', 'pencolor', 'pendown', 'pensize', 'penup', 'pos', 'position',
+        'pu', 'radians', 'right', 'reset', 'resizemode', 'rt',
+        'seth', 'setheading', 'setpos', 'setposition', 'settiltangle',
+        'setundobuffer', 'setx', 'sety', 'shape', 'shapesize', 'showturtle',
+        'speed', 'st', 'stamp', 'tilt', 'tiltangle', 'towards', #'tracer',
+        'turtlesize', 'undo', 'undobufferentries', 'up', 'width',
+        #'window_height', 'window_width',
+        'write', 'xcor', 'ycor']
+_tg_utilities = ['write_docstringdict', 'done', 'mainloop']
+##_math_functions = ['acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'cosh',
+##        'e', 'exp', 'fabs', 'floor', 'fmod', 'frexp', 'hypot', 'ldexp', 'log',
+##        'log10', 'modf', 'pi', 'pow', 'sin', 'sinh', 'sqrt', 'tan', 'tanh']
+
+__all__ = (_tg_classes + _tg_screen_functions + _tg_turtle_functions +
+           _tg_utilities) # + _math_functions)
+
+_alias_list = ['addshape', 'backward', 'bk', 'fd', 'ht', 'lt', 'pd', 'pos',
+               'pu', 'rt', 'seth', 'setpos', 'setposition', 'st',
+               'turtlesize', 'up', 'width']
+
+_CFG = {"width" : 0.5,               # Screen
+        "height" : 0.75,
+        "canvwidth" : 400,
+        "canvheight": 300,
+        "leftright": None,
+        "topbottom": None,
+        "mode": "standard",          # TurtleScreen
+        "colormode": 1.0,
+        "delay": 10,
+        "undobuffersize": 1000,      # RawTurtle
+        "shape": "classic",
+        "pencolor" : "black",
+        "fillcolor" : "black",
+        "resizemode" : "noresize",
+        "visible" : True,
+        "language": "english",        # docstrings
+        "exampleturtle": "turtle",
+        "examplescreen": "screen",
+        "title": "Python Turtle Graphics",
+        "using_IDLE": False
+       }
+
+##print "cwd:", os.getcwd()
+##print "__file__:", __file__
+##
+##def show(dictionary):
+##    print "=========================="
+##    for key in sorted(dictionary.keys()):
+##        print key, ":", dictionary[key]
+##    print "=========================="
+##    print
+
+def config_dict(filename):
+    """Convert content of config-file into dictionary."""
+    f = open(filename, "r")
+    cfglines = f.readlines()
+    f.close()
+    cfgdict = {}
+    for line in cfglines:
+        line = line.strip()
+        if not line or line.startswith("#"):
+            continue
+        try:
+            key, value = line.split("=")
+        except:
+            print("Bad line in config-file %s:\n%s" % (filename,line))
+            continue
+        key = key.strip()
+        value = value.strip()
+        if value in ["True", "False", "None", "''", '""']:
+            value = eval(value)
+        else:
+            try:
+                if "." in value:
+                    value = float(value)
+                else:
+                    value = int(value)
+            except:
+                pass # value need not be converted
+        cfgdict[key] = value
+    return cfgdict
+
+def readconfig(cfgdict):
+    """Read config-files, change configuration-dict accordingly.
+
+    If there is a turtle.cfg file in the current working directory,
+    read it from there. If this contains an importconfig-value,
+    say 'myway', construct filename turtle_mayway.cfg else use
+    turtle.cfg and read it from the import-directory, where
+    turtle.py is located.
+    Update configuration dictionary first according to config-file,
+    in the import directory, then according to config-file in the
+    current working directory.
+    If no config-file is found, the default configuration is used.
+    """
+    default_cfg = "turtle.cfg"
+    cfgdict1 = {}
+    cfgdict2 = {}
+    if isfile(default_cfg):
+        cfgdict1 = config_dict(default_cfg)
+        #print "1. Loading config-file %s from: %s" % (default_cfg, os.getcwd())
+    if "importconfig" in cfgdict1:
+        default_cfg = "turtle_%s.cfg" % cfgdict1["importconfig"]
+    try:
+        head, tail = split(__file__)
+        cfg_file2 = join(head, default_cfg)
+    except:
+        cfg_file2 = ""
+    if isfile(cfg_file2):
+        #print "2. Loading config-file %s:" % cfg_file2
+        cfgdict2 = config_dict(cfg_file2)
+##    show(_CFG)
+##    show(cfgdict2)
+    _CFG.update(cfgdict2)
+##    show(_CFG)
+##    show(cfgdict1)
+    _CFG.update(cfgdict1)
+##    show(_CFG)
+
+try:
+    readconfig(_CFG)
+except:
+    print ("No configfile read, reason unknown")
+
+
+class Vec2D(tuple):
+    """A 2 dimensional vector class, used as a helper class
+    for implementing turtle graphics.
+    May be useful for turtle graphics programs also.
+    Derived from tuple, so a vector is a tuple!
+
+    Provides (for a, b vectors, k number):
+       a+b vector addition
+       a-b vector subtraction
+       a*b inner product
+       k*a and a*k multiplication with scalar
+       |a| absolute value of a
+       a.rotate(angle) rotation
+    """
+    def __new__(cls, x, y):
+        return tuple.__new__(cls, (x, y))
+    def __add__(self, other):
+        return Vec2D(self[0]+other[0], self[1]+other[1])
+    def __mul__(self, other):
+        if isinstance(other, Vec2D):
+            return self[0]*other[0]+self[1]*other[1]
+        return Vec2D(self[0]*other, self[1]*other)
+    def __rmul__(self, other):
+        if isinstance(other, int) or isinstance(other, float):
+            return Vec2D(self[0]*other, self[1]*other)
+    def __sub__(self, other):
+        return Vec2D(self[0]-other[0], self[1]-other[1])
+    def __neg__(self):
+        return Vec2D(-self[0], -self[1])
+    def __abs__(self):
+        return (self[0]**2 + self[1]**2)**0.5
+    def rotate(self, angle):
+        """rotate self counterclockwise by angle
+        """
+        perp = Vec2D(-self[1], self[0])
+        angle = angle * math.pi / 180.0
+        c, s = math.cos(angle), math.sin(angle)
+        return Vec2D(self[0]*c+perp[0]*s, self[1]*c+perp[1]*s)
+    def __getnewargs__(self):
+        return (self[0], self[1])
+    def __repr__(self):
+        return "(%.2f,%.2f)" % self
+
+
+##############################################################################
+### From here up to line    : Tkinter - Interface for turtle.py            ###
+### May be replaced by an interface to some different graphcis-toolkit     ###
+##############################################################################
+
+## helper functions for Scrolled Canvas, to forward Canvas-methods
+## to ScrolledCanvas class
+
+def __methodDict(cls, _dict):
+    """helper function for Scrolled Canvas"""
+    baseList = list(cls.__bases__)
+    baseList.reverse()
+    for _super in baseList:
+        __methodDict(_super, _dict)
+    for key, value in cls.__dict__.items():
+        if type(value) == types.FunctionType:
+            _dict[key] = value
+
+def __methods(cls):
+    """helper function for Scrolled Canvas"""
+    _dict = {}
+    __methodDict(cls, _dict)
+    return _dict.keys()
+
+__stringBody = (
+    'def %(method)s(self, *args, **kw): return ' +
+    'self.%(attribute)s.%(method)s(*args, **kw)')
+
+def __forwardmethods(fromClass, toClass, toPart, exclude = ()):
+    ### MANY CHANGES ###
+    _dict_1 = {}
+    __methodDict(toClass, _dict_1)
+    _dict = {}
+    mfc = __methods(fromClass)
+    for ex in _dict_1.keys():
+        if ex[:1] == '_' or ex[-1:] == '_' or ex in exclude or ex in mfc:
+            pass
+        else:
+            _dict[ex] = _dict_1[ex]
+
+    for method, func in _dict.items():
+        d = {'method': method, 'func': func}
+        if isinstance(toPart, str):
+            execString = \
+                __stringBody % {'method' : method, 'attribute' : toPart}
+        exec(execString, d)
+        setattr(fromClass, method, d[method])   ### NEWU!
+
+
+class ScrolledCanvas(TK.Frame):
+    """Modeled after the scrolled canvas class from Grayons's Tkinter book.
+
+    Used as the default canvas, which pops up automatically when
+    using turtle graphics functions or the Turtle class.
+    """
+    def __init__(self, master, width=500, height=350,
+                                          canvwidth=600, canvheight=500):
+        TK.Frame.__init__(self, master, width=width, height=height)
+        self._root = self.winfo_toplevel()
+        self.width, self.height = width, height
+        self.canvwidth, self.canvheight = canvwidth, canvheight
+        self.bg = "white"
+        self._canvas = TK.Canvas(master, width=width, height=height,
+                                 bg=self.bg, relief=TK.SUNKEN, borderwidth=2)
+        self.hscroll = TK.Scrollbar(master, command=self._canvas.xview,
+                                    orient=TK.HORIZONTAL)
+        self.vscroll = TK.Scrollbar(master, command=self._canvas.yview)
+        self._canvas.configure(xscrollcommand=self.hscroll.set,
+                               yscrollcommand=self.vscroll.set)
+        self.rowconfigure(0, weight=1, minsize=0)
+        self.columnconfigure(0, weight=1, minsize=0)
+        self._canvas.grid(padx=1, in_ = self, pady=1, row=0,
+                column=0, rowspan=1, columnspan=1, sticky='news')
+        self.vscroll.grid(padx=1, in_ = self, pady=1, row=0,
+                column=1, rowspan=1, columnspan=1, sticky='news')
+        self.hscroll.grid(padx=1, in_ = self, pady=1, row=1,
+                column=0, rowspan=1, columnspan=1, sticky='news')
+        self.reset()
+        self._root.bind('<Configure>', self.onResize)
+
+    def reset(self, canvwidth=None, canvheight=None, bg = None):
+        """Ajust canvas and scrollbars according to given canvas size."""
+        if canvwidth:
+            self.canvwidth = canvwidth
+        if canvheight:
+            self.canvheight = canvheight
+        if bg:
+            self.bg = bg
+        self._canvas.config(bg=bg,
+                        scrollregion=(-self.canvwidth//2, -self.canvheight//2,
+                                       self.canvwidth//2, self.canvheight//2))
+        self._canvas.xview_moveto(0.5*(self.canvwidth - self.width + 30) /
+                                                               self.canvwidth)
+        self._canvas.yview_moveto(0.5*(self.canvheight- self.height + 30) /
+                                                              self.canvheight)
+        self.adjustScrolls()
+
+
+    def adjustScrolls(self):
+        """ Adjust scrollbars according to window- and canvas-size.
+        """
+        cwidth = self._canvas.winfo_width()
+        cheight = self._canvas.winfo_height()
+        self._canvas.xview_moveto(0.5*(self.canvwidth-cwidth)/self.canvwidth)
+        self._canvas.yview_moveto(0.5*(self.canvheight-cheight)/self.canvheight)
+        if cwidth < self.canvwidth or cheight < self.canvheight:
+            self.hscroll.grid(padx=1, in_ = self, pady=1, row=1,
+                              column=0, rowspan=1, columnspan=1, sticky='news')
+            self.vscroll.grid(padx=1, in_ = self, pady=1, row=0,
+                              column=1, rowspan=1, columnspan=1, sticky='news')
+        else:
+            self.hscroll.grid_forget()
+            self.vscroll.grid_forget()
+
+    def onResize(self, event):
+        """self-explanatory"""
+        self.adjustScrolls()
+
+    def bbox(self, *args):
+        """ 'forward' method, which canvas itself has inherited...
+        """
+        return self._canvas.bbox(*args)
+
+    def cget(self, *args, **kwargs):
+        """ 'forward' method, which canvas itself has inherited...
+        """
+        return self._canvas.cget(*args, **kwargs)
+
+    def config(self, *args, **kwargs):
+        """ 'forward' method, which canvas itself has inherited...
+        """
+        self._canvas.config(*args, **kwargs)
+
+    def bind(self, *args, **kwargs):
+        """ 'forward' method, which canvas itself has inherited...
+        """
+        self._canvas.bind(*args, **kwargs)
+
+    def unbind(self, *args, **kwargs):
+        """ 'forward' method, which canvas itself has inherited...
+        """
+        self._canvas.unbind(*args, **kwargs)
+
+    def focus_force(self):
+        """ 'forward' method, which canvas itself has inherited...
+        """
+        self._canvas.focus_force()
+
+__forwardmethods(ScrolledCanvas, TK.Canvas, '_canvas')
+
+
+class _Root(TK.Tk):
+    """Root class for Screen based on Tkinter."""
+    def __init__(self):
+        TK.Tk.__init__(self)
+
+    def setupcanvas(self, width, height, cwidth, cheight):
+        self._canvas = ScrolledCanvas(self, width, height, cwidth, cheight)
+        self._canvas.pack(expand=1, fill="both")
+
+    def _getcanvas(self):
+        return self._canvas
+
+    def set_geometry(self, width, height, startx, starty):
+        self.geometry("%dx%d%+d%+d"%(width, height, startx, starty))
+
+    def ondestroy(self, destroy):
+        self.wm_protocol("WM_DELETE_WINDOW", destroy)
+
+    def win_width(self):
+        return self.winfo_screenwidth()
+
+    def win_height(self):
+        return self.winfo_screenheight()
+
+Canvas = TK.Canvas
+
+
+class TurtleScreenBase(object):
+    """Provide the basic graphics functionality.
+       Interface between Tkinter and turtle.py.
+
+       To port turtle.py to some different graphics toolkit
+       a corresponding TurtleScreenBase class has to be implemented.
+    """
+
+    @staticmethod
+    def _blankimage():
+        """return a blank image object
+        """
+        img = TK.PhotoImage(width=1, height=1)
+        img.blank()
+        return img
+
+    @staticmethod
+    def _image(filename):
+        """return an image object containing the
+        imagedata from a gif-file named filename.
+        """
+        return TK.PhotoImage(file=filename)
+
+    def __init__(self, cv):
+        self.cv = cv
+        if isinstance(cv, ScrolledCanvas):
+            w = self.cv.canvwidth
+            h = self.cv.canvheight
+        else:  # expected: ordinary TK.Canvas
+            w = int(self.cv.cget("width"))
+            h = int(self.cv.cget("height"))
+            self.cv.config(scrollregion = (-w//2, -h//2, w//2, h//2 ))
+        self.canvwidth = w
+        self.canvheight = h
+        self.xscale = self.yscale = 1.0
+
+    def _createpoly(self):
+        """Create an invisible polygon item on canvas self.cv)
+        """
+        return self.cv.create_polygon((0, 0, 0, 0, 0, 0), fill="", outline="")
+
+    def _drawpoly(self, polyitem, coordlist, fill=None,
+                  outline=None, width=None, top=False):
+        """Configure polygonitem polyitem according to provided
+        arguments:
+        coordlist is sequence of coordinates
+        fill is filling color
+        outline is outline color
+        top is a boolean value, which specifies if polyitem
+        will be put on top of the canvas' displaylist so it
+        will not be covered by other items.
+        """
+        cl = []
+        for x, y in coordlist:
+            cl.append(x * self.xscale)
+            cl.append(-y * self.yscale)
+        self.cv.coords(polyitem, *cl)
+        if fill is not None:
+            self.cv.itemconfigure(polyitem, fill=fill)
+        if outline is not None:
+            self.cv.itemconfigure(polyitem, outline=outline)
+        if width is not None:
+            self.cv.itemconfigure(polyitem, width=width)
+        if top:
+            self.cv.tag_raise(polyitem)
+
+    def _createline(self):
+        """Create an invisible line item on canvas self.cv)
+        """
+        return self.cv.create_line(0, 0, 0, 0, fill="", width=2,
+                                   capstyle = TK.ROUND)
+
+    def _drawline(self, lineitem, coordlist=None,
+                  fill=None, width=None, top=False):
+        """Configure lineitem according to provided arguments:
+        coordlist is sequence of coordinates
+        fill is drawing color
+        width is width of drawn line.
+        top is a boolean value, which specifies if polyitem
+        will be put on top of the canvas' displaylist so it
+        will not be covered by other items.
+        """
+        if coordlist is not None:
+            cl = []
+            for x, y in coordlist:
+                cl.append(x * self.xscale)
+                cl.append(-y * self.yscale)
+            self.cv.coords(lineitem, *cl)
+        if fill is not None:
+            self.cv.itemconfigure(lineitem, fill=fill)
+        if width is not None:
+            self.cv.itemconfigure(lineitem, width=width)
+        if top:
+            self.cv.tag_raise(lineitem)
+
+    def _delete(self, item):
+        """Delete graphics item from canvas.
+        If item is"all" delete all graphics items.
+        """
+        self.cv.delete(item)
+
+    def _update(self):
+        """Redraw graphics items on canvas
+        """
+        self.cv.update()
+
+    def _delay(self, delay):
+        """Delay subsequent canvas actions for delay ms."""
+        self.cv.after(delay)
+
+    def _iscolorstring(self, color):
+        """Check if the string color is a legal Tkinter color string.
+        """
+        try:
+            rgb = self.cv.winfo_rgb(color)
+            ok = True
+        except TK.TclError:
+            ok = False
+        return ok
+
+    def _bgcolor(self, color=None):
+        """Set canvas' backgroundcolor if color is not None,
+        else return backgroundcolor."""
+        if color is not None:
+            self.cv.config(bg = color)
+            self._update()
+        else:
+            return self.cv.cget("bg")
+
+    def _write(self, pos, txt, align, font, pencolor):
+        """Write txt at pos in canvas with specified font
+        and color.
+        Return text item and x-coord of right bottom corner
+        of text's bounding box."""
+        x, y = pos
+        x = x * self.xscale
+        y = y * self.yscale
+        anchor = {"left":"sw", "center":"s", "right":"se" }
+        item = self.cv.create_text(x-1, -y, text = txt, anchor = anchor[align],
+                                        fill = pencolor, font = font)
+        x0, y0, x1, y1 = self.cv.bbox(item)
+        self.cv.update()
+        return item, x1-1
+
+##    def _dot(self, pos, size, color):
+##        """may be implemented for some other graphics toolkit"""
+
+    def _onclick(self, item, fun, num=1, add=None):
+        """Bind fun to mouse-click event on turtle.
+        fun must be a function with two arguments, the coordinates
+        of the clicked point on the canvas.
+        num, the number of the mouse-button defaults to 1
+        """
+        if fun is None:
+            self.cv.tag_unbind(item, "<Button-%s>" % num)
+        else:
+            def eventfun(event):
+                x, y = (self.cv.canvasx(event.x)/self.xscale,
+                        -self.cv.canvasy(event.y)/self.yscale)
+                fun(x, y)
+            self.cv.tag_bind(item, "<Button-%s>" % num, eventfun, add)
+
+    def _onrelease(self, item, fun, num=1, add=None):
+        """Bind fun to mouse-button-release event on turtle.
+        fun must be a function with two arguments, the coordinates
+        of the point on the canvas where mouse button is released.
+        num, the number of the mouse-button defaults to 1
+
+        If a turtle is clicked, first _onclick-event will be performed,
+        then _onscreensclick-event.
+        """
+        if fun is None:
+            self.cv.tag_unbind(item, "<Button%s-ButtonRelease>" % num)
+        else:
+            def eventfun(event):
+                x, y = (self.cv.canvasx(event.x)/self.xscale,
+                        -self.cv.canvasy(event.y)/self.yscale)
+                fun(x, y)
+            self.cv.tag_bind(item, "<Button%s-ButtonRelease>" % num,
+                             eventfun, add)
+
+    def _ondrag(self, item, fun, num=1, add=None):
+        """Bind fun to mouse-move-event (with pressed mouse button) on turtle.
+        fun must be a function with two arguments, the coordinates of the
+        actual mouse position on the canvas.
+        num, the number of the mouse-button defaults to 1
+
+        Every sequence of mouse-move-events on a turtle is preceded by a
+        mouse-click event on that turtle.
+        """
+        if fun is None:
+            self.cv.tag_unbind(item, "<Button%s-Motion>" % num)
+        else:
+            def eventfun(event):
+                try:
+                    x, y = (self.cv.canvasx(event.x)/self.xscale,
+                           -self.cv.canvasy(event.y)/self.yscale)
+                    fun(x, y)
+                except:
+                    pass
+            self.cv.tag_bind(item, "<Button%s-Motion>" % num, eventfun, add)
+
+    def _onscreenclick(self, fun, num=1, add=None):
+        """Bind fun to mouse-click event on canvas.
+        fun must be a function with two arguments, the coordinates
+        of the clicked point on the canvas.
+        num, the number of the mouse-button defaults to 1
+
+        If a turtle is clicked, first _onclick-event will be performed,
+        then _onscreensclick-event.
+        """
+        if fun is None:
+            self.cv.unbind("<Button-%s>" % num)
+        else:
+            def eventfun(event):
+                x, y = (self.cv.canvasx(event.x)/self.xscale,
+                        -self.cv.canvasy(event.y)/self.yscale)
+                fun(x, y)
+            self.cv.bind("<Button-%s>" % num, eventfun, add)
+
+    def _onkey(self, fun, key):
+        """Bind fun to key-release event of key.
+        Canvas must have focus. See method listen
+        """
+        if fun is None:
+            self.cv.unbind("<KeyRelease-%s>" % key, None)
+        else:
+            def eventfun(event):
+                fun()
+            self.cv.bind("<KeyRelease-%s>" % key, eventfun)
+
+    def _listen(self):
+        """Set focus on canvas (in order to collect key-events)
+        """
+        self.cv.focus_force()
+
+    def _ontimer(self, fun, t):
+        """Install a timer, which calls fun after t milliseconds.
+        """
+        if t == 0:
+            self.cv.after_idle(fun)
+        else:
+            self.cv.after(t, fun)
+
+    def _createimage(self, image):
+        """Create and return image item on canvas.
+        """
+        return self.cv.create_image(0, 0, image=image)
+
+    def _drawimage(self, item, pos, image):
+        """Configure image item as to draw image object
+        at position (x,y) on canvas)
+        """
+        x, y = pos
+        self.cv.coords(item, (x * self.xscale, -y * self.yscale))
+        self.cv.itemconfig(item, image=image)
+
+    def _setbgpic(self, item, image):
+        """Configure image item as to draw image object
+        at center of canvas. Set item to the first item
+        in the displaylist, so it will be drawn below
+        any other item ."""
+        self.cv.itemconfig(item, image=image)
+        self.cv.tag_lower(item)
+
+    def _type(self, item):
+        """Return 'line' or 'polygon' or 'image' depending on
+        type of item.
+        """
+        return self.cv.type(item)
+
+    def _pointlist(self, item):
+        """returns list of coordinate-pairs of points of item
+        Example (for insiders):
+        >>> from turtle import *
+        >>> getscreen()._pointlist(getturtle().turtle._item)
+        [(0.0, 9.9999999999999982), (0.0, -9.9999999999999982),
+        (9.9999999999999982, 0.0)]
+        >>> """
+        cl = list(self.cv.coords(item))
+        pl = [(cl[i], -cl[i+1]) for i in range(0, len(cl), 2)]
+        return  pl
+
+    def _setscrollregion(self, srx1, sry1, srx2, sry2):
+        self.cv.config(scrollregion=(srx1, sry1, srx2, sry2))
+
+    def _rescale(self, xscalefactor, yscalefactor):
+        items = self.cv.find_all()
+        for item in items:
+            coordinates = list(self.cv.coords(item))
+            newcoordlist = []
+            while coordinates:
+                x, y = coordinates[:2]
+                newcoordlist.append(x * xscalefactor)
+                newcoordlist.append(y * yscalefactor)
+                coordinates = coordinates[2:]
+            self.cv.coords(item, *newcoordlist)
+
+    def _resize(self, canvwidth=None, canvheight=None, bg=None):
+        """Resize the canvas, the turtles are drawing on. Does
+        not alter the drawing window.
+        """
+        # needs amendment
+        if not isinstance(self.cv, ScrolledCanvas):
+            return self.canvwidth, self.canvheight
+        if canvwidth is None and canvheight is None and bg is None:
+            return self.cv.canvwidth, self.cv.canvheight
+        if canvwidth is not None:
+            self.canvwidth = canvwidth
+        if canvheight is not None:
+            self.canvheight = canvheight
+        self.cv.reset(canvwidth, canvheight, bg)
+
+    def _window_size(self):
+        """ Return the width and height of the turtle window.
+        """
+        width = self.cv.winfo_width()
+        if width <= 1:  # the window isn't managed by a geometry manager
+            width = self.cv['width']
+        height = self.cv.winfo_height()
+        if height <= 1: # the window isn't managed by a geometry manager
+            height = self.cv['height']
+        return width, height
+
+
+##############################################################################
+###                  End of Tkinter - interface                            ###
+##############################################################################
+
 
-speeds = ['fastest', 'fast', 'normal', 'slow', 'slowest']
+class Terminator (Exception):
+    """Will be raised in TurtleScreen.update, if _RUNNING becomes False.
 
-class Error(Exception):
+    Thus stops execution of turtle graphics script. Main purpose: use in
+    in the Demo-Viewer turtle.Demo.py.
+    """
     pass
 
-class RawPen:
 
-    def __init__(self, canvas):
-        self._canvas = canvas
-        self._items = []
+class TurtleGraphicsError(Exception):
+    """Some TurtleGraphics Error
+    """
+
+
+class Shape(object):
+    """Data structure modeling shapes.
+
+    attribute _type is one of "polygon", "image", "compound"
+    attribute _data is - depending on _type a poygon-tuple,
+    an image or a list constructed using the addcomponent method.
+    """
+    def __init__(self, type_, data=None):
+        self._type = type_
+        if type_ == "polygon":
+            if isinstance(data, list):
+                data = tuple(data)
+        elif type_ == "image":
+            if isinstance(data, str):
+                if data.lower().endswith(".gif") and isfile(data):
+                    data = TurtleScreen._image(data)
+                # else data assumed to be Photoimage
+        elif type_ == "compound":
+            data = []
+        else:
+            raise TurtleGraphicsError("There is no shape type %s" % type_)
+        self._data = data
+
+    def addcomponent(self, poly, fill, outline=None):
+        """Add component to a shape of type compound.
+
+        Arguments: poly is a polygon, i. e. a tuple of number pairs.
+        fill is the fillcolor of the component,
+        outline is the outline color of the component.
+
+        call (for a Shapeobject namend s):
+        --   s.addcomponent(((0,0), (10,10), (-10,10)), "red", "blue")
+
+        Example:
+        >>> poly = ((0,0),(10,-5),(0,10),(-10,-5))
+        >>> s = Shape("compound")
+        >>> s.addcomponent(poly, "red", "blue")
+        ### .. add more components and then use register_shape()
+        """
+        if self._type != "compound":
+            raise TurtleGraphicsError("Cannot add component to %s Shape"
+                                                                % self._type)
+        if outline is None:
+            outline = fill
+        self._data.append([poly, fill, outline])
+
+
+class Tbuffer(object):
+    """Ring buffer used as undobuffer for RawTurtle objects."""
+    def __init__(self, bufsize=10):
+        self.bufsize = bufsize
+        self.buffer = [[None]] * bufsize
+        self.ptr = -1
+        self.cumulate = False
+    def reset(self, bufsize=None):
+        if bufsize is None:
+            for i in range(self.bufsize):
+                self.buffer[i] = [None]
+        else:
+            self.bufsize = bufsize
+            self.buffer = [[None]] * bufsize
+        self.ptr = -1
+    def push(self, item):
+        if self.bufsize > 0:
+            if not self.cumulate:
+                self.ptr = (self.ptr + 1) % self.bufsize
+                self.buffer[self.ptr] = item
+            else:
+                self.buffer[self.ptr].append(item)
+    def pop(self):
+        if self.bufsize > 0:
+            item = self.buffer[self.ptr]
+            if item is None:
+                return None
+            else:
+                self.buffer[self.ptr] = [None]
+                self.ptr = (self.ptr - 1) % self.bufsize
+                return (item)
+    def nr_of_items(self):
+        return self.bufsize - self.buffer.count([None])
+    def __repr__(self):
+        return str(self.buffer) + " " + str(self.ptr)
+
+
+
+class TurtleScreen(TurtleScreenBase):
+    """Provides screen oriented methods like setbg etc.
+
+    Only relies upon the methods of TurtleScreenBase and NOT
+    upon components of the underlying graphics toolkit -
+    which is Tkinter in this case.
+    """
+#    _STANDARD_DELAY = 5
+    _RUNNING = True
+
+    def __init__(self, cv, mode=_CFG["mode"],
+                 colormode=_CFG["colormode"], delay=_CFG["delay"]):
+        self._shapes = {
+                   "arrow" : Shape("polygon", ((-10,0), (10,0), (0,10))),
+                  "turtle" : Shape("polygon", ((0,16), (-2,14), (-1,10), (-4,7),
+                              (-7,9), (-9,8), (-6,5), (-7,1), (-5,-3), (-8,-6),
+                              (-6,-8), (-4,-5), (0,-7), (4,-5), (6,-8), (8,-6),
+                              (5,-3), (7,1), (6,5), (9,8), (7,9), (4,7), (1,10),
+                              (2,14))),
+                  "circle" : Shape("polygon", ((10,0), (9.51,3.09), (8.09,5.88),
+                              (5.88,8.09), (3.09,9.51), (0,10), (-3.09,9.51),
+                              (-5.88,8.09), (-8.09,5.88), (-9.51,3.09), (-10,0),
+                              (-9.51,-3.09), (-8.09,-5.88), (-5.88,-8.09),
+                              (-3.09,-9.51), (-0.00,-10.00), (3.09,-9.51),
+                              (5.88,-8.09), (8.09,-5.88), (9.51,-3.09))),
+                  "square" : Shape("polygon", ((10,-10), (10,10), (-10,10),
+                              (-10,-10))),
+                "triangle" : Shape("polygon", ((10,-5.77), (0,11.55),
+                              (-10,-5.77))),
+                  "classic": Shape("polygon", ((0,0),(-5,-9),(0,-7),(5,-9))),
+                   "blank" : Shape("image", self._blankimage())
+                  }
+
+        self._bgpics = {"nopic" : ""}
+
+        TurtleScreenBase.__init__(self, cv)
+        self._mode = mode
+        self._delayvalue = delay
+        self._colormode = _CFG["colormode"]
+        self._keys = []
+        self.clear()
+
+    def clear(self):
+        """Delete all drawings and all turtles from the TurtleScreen.
+
+        Reset empty TurtleScreen to it's initial state: white background,
+        no backgroundimage, no eventbindings and tracing on.
+
+        No argument.
+
+        Example (for a TurtleScreen instance named screen):
+        screen.clear()
+
+        Note: this method is not available as function.
+        """
+        self._delayvalue = _CFG["delay"]
+        self._colormode = _CFG["colormode"]
+        self._delete("all")
+        self._bgpic = self._createimage("")
+        self._bgpicname = "nopic"
         self._tracing = 1
-        self._arrow = 0
-        self._delay = 10     # default delay for drawing
-        self._angle = 0.0
-        self.degrees()
+        self._updatecounter = 0
+        self._turtles = []
+        self.bgcolor("white")
+        for btn in 1, 2, 3:
+            self.onclick(None, btn)
+        for key in self._keys[:]:
+            self.onkey(None, key)
+        Turtle._pen = None
+
+    def mode(self, mode=None):
+        """Set turtle-mode ('standard', 'logo' or 'world') and perform reset.
+
+        Optional argument:
+        mode -- on of the strings 'standard', 'logo' or 'world'
+
+        Mode 'standard' is compatible with turtle.py.
+        Mode 'logo' is compatible with most Logo-Turtle-Graphics.
+        Mode 'world' uses userdefined 'worldcoordinates'. *Attention*: in
+        this mode angles appear distorted if x/y unit-ratio doesn't equal 1.
+        If mode is not given, return the current mode.
+
+             Mode      Initial turtle heading     positive angles
+         ------------|-------------------------|-------------------
+          'standard'    to the right (east)       counterclockwise
+            'logo'        upward    (north)         clockwise
+
+        Examples:
+        >>> mode('logo')   # resets turtle heading to north
+        >>> mode()
+        'logo'
+        """
+        if mode == None:
+            return self._mode
+        mode = mode.lower()
+        if mode not in ["standard", "logo", "world"]:
+            raise TurtleGraphicsError("No turtle-graphics-mode %s" % mode)
+        self._mode = mode
+        if mode in ["standard", "logo"]:
+            self._setscrollregion(-self.canvwidth//2, -self.canvheight//2,
+                                       self.canvwidth//2, self.canvheight//2)
+            self.xscale = self.yscale = 1.0
         self.reset()
 
-    def degrees(self, fullcircle=360.0):
-        """ Set angle measurement units to degrees.
+    def setworldcoordinates(self, llx, lly, urx, ury):
+        """Set up a user defined coordinate-system.
+
+        Arguments:
+        llx -- a number, x-coordinate of lower left corner of canvas
+        lly -- a number, y-coordinate of lower left corner of canvas
+        urx -- a number, x-coordinate of upper right corner of canvas
+        ury -- a number, y-coordinate of upper right corner of canvas
+
+        Set up user coodinat-system and switch to mode 'world' if necessary.
+        This performs a screen.reset. If mode 'world' is already active,
+        all drawings are redrawn according to the new coordinates.
+
+        But ATTENTION: in user-defined coordinatesystems angles may appear
+        distorted. (see Screen.mode())
+
+        Example (for a TurtleScreen instance named screen):
+        >>> screen.setworldcoordinates(-10,-0.5,50,1.5)
+        >>> for _ in range(36):
+                left(10)
+                forward(0.5)
+        """
+        if self.mode() != "world":
+            self.mode("world")
+        xspan = float(urx - llx)
+        yspan = float(ury - lly)
+        wx, wy = self._window_size()
+        self.screensize(wx-20, wy-20)
+        oldxscale, oldyscale = self.xscale, self.yscale
+        self.xscale = self.canvwidth / xspan
+        self.yscale = self.canvheight / yspan
+        srx1 = llx * self.xscale
+        sry1 = -ury * self.yscale
+        srx2 = self.canvwidth + srx1
+        sry2 = self.canvheight + sry1
+        self._setscrollregion(srx1, sry1, srx2, sry2)
+        self._rescale(self.xscale/oldxscale, self.yscale/oldyscale)
+        self.update()
+
+    def register_shape(self, name, shape=None):
+        """Adds a turtle shape to TurtleScreen's shapelist.
+
+        Arguments:
+        (1) name is the name of a gif-file and shape is None.
+            Installs the corresponding image shape.
+            !! Image-shapes DO NOT rotate when turning the turtle,
+            !! so they do not display the heading of the turtle!
+        (2) name is an arbitrary string and shape is a tuple
+            of pairs of coordinates. Installs the corresponding
+            polygon shape
+        (3) name is an arbitrary string and shape is a
+            (compound) Shape object. Installs the corresponding
+            compound shape.
+        To use a shape, you have to issue the command shape(shapename).
+
+        call: register_shape("turtle.gif")
+        --or: register_shape("tri", ((0,0), (10,10), (-10,10)))
+
+        Example (for a TurtleScreen instance named screen):
+        >>> screen.register_shape("triangle", ((5,-3),(0,5),(-5,-3)))
+
+        """
+        if shape is None:
+            # image
+            if name.lower().endswith(".gif"):
+                shape = Shape("image", self._image(name))
+            else:
+                raise TurtleGraphicsError("Bad arguments for register_shape.\n"
+                                          + "Use  help(register_shape)" )
+        elif isinstance(shape, tuple):
+            shape = Shape("polygon", shape)
+        ## else shape assumed to be Shape-instance
+        self._shapes[name] = shape
+        # print "shape added:" , self._shapes
+
+    def _colorstr(self, color):
+        """Return color string corresponding to args.
+
+        Argument may be a string or a tuple of three
+        numbers corresponding to actual colormode,
+        i.e. in the range 0<=n<=colormode.
+
+        If the argument doesn't represent a color,
+        an error is raised.
+        """
+        if len(color) == 1:
+            color = color[0]
+        if isinstance(color, str):
+            if self._iscolorstring(color) or color == "":
+                return color
+            else:
+                raise TurtleGraphicsError("bad color string: %s" % str(color))
+        try:
+            r, g, b = color
+        except:
+            raise TurtleGraphicsError("bad color arguments: %s" % str(color))
+        if self._colormode == 1.0:
+            r, g, b = [round(255.0*x) for x in (r, g, b)]
+        if not ((0 <= r <= 255) and (0 <= g <= 255) and (0 <= b <= 255)):
+            raise TurtleGraphicsError("bad color sequence: %s" % str(color))
+        return "#%02x%02x%02x" % (r, g, b)
+
+    def _color(self, cstr):
+        if not cstr.startswith("#"):
+            return cstr
+        if len(cstr) == 7:
+            cl = [int(cstr[i:i+2], 16) for i in (1, 3, 5)]
+        elif len(cstr) == 4:
+            cl = [16*int(cstr[h], 16) for h in cstr[1:]]
+        else:
+            raise TurtleGraphicsError("bad colorstring: %s" % cstr)
+        return tuple([c * self._colormode/255 for c in cl])
+
+    def colormode(self, cmode=None):
+        """Return the colormode or set it to 1.0 or 255.
+
+        Optional argument:
+        cmode -- one of the values 1.0 or 255
+
+        r, g, b values of colortriples have to be in range 0..cmode.
+
+        Example (for a TurtleScreen instance named screen):
+        >>> screen.colormode()
+        1.0
+        >>> screen.colormode(255)
+        >>> turtle.pencolor(240,160,80)
+        """
+        if cmode is None:
+            return self._colormode
+        if cmode == 1.0:
+            self._colormode = float(cmode)
+        elif cmode == 255:
+            self._colormode = int(cmode)
+
+    def reset(self):
+        """Reset all Turtles on the Screen to their initial state.
+
+        No argument.
+
+        Example (for a TurtleScreen instance named screen):
+        >>> screen.reset()
+        """
+        for turtle in self._turtles:
+            turtle._setmode(self._mode)
+            turtle.reset()
+
+    def turtles(self):
+        """Return the list of turtles on the screen.
+
+        Example (for a TurtleScreen instance named screen):
+        >>> screen.turtles()
+        [<turtle.Turtle object at 0x00E11FB0>]
+        """
+        return self._turtles
+
+    def bgcolor(self, *args):
+        """Set or return backgroundcolor of the TurtleScreen.
+
+        Arguments (if given): a color string or three numbers
+        in the range 0..colormode or a 3-tuple of such numbers.
+
+        Example (for a TurtleScreen instance named screen):
+        >>> screen.bgcolor("orange")
+        >>> screen.bgcolor()
+        'orange'
+        >>> screen.bgcolor(0.5,0,0.5)
+        >>> screen.bgcolor()
+        '#800080'
+        """
+        if args:
+            color = self._colorstr(args)
+        else:
+            color = None
+        color = self._bgcolor(color)
+        if color is not None:
+            color = self._color(color)
+        return color
+
+    def tracer(self, n=None, delay=None):
+        """Turns turtle animation on/off and set delay for update drawings.
+
+        Optional arguments:
+        n -- nonnegative  integer
+        delay -- nonnegative  integer
+
+        If n is given, only each n-th regular screen update is really performed.
+        (Can be used to accelerate the drawing of complex graphics.)
+        Second arguments sets delay value (see RawTurtle.delay())
+
+        Example (for a TurtleScreen instance named screen):
+        >>> screen.tracer(8, 25)
+        >>> dist = 2
+        >>> for i in range(200):
+                fd(dist)
+                rt(90)
+                dist += 2
+        """
+        if n is None:
+            return self._tracing
+        self._tracing = int(n)
+        self._updatecounter = 0
+        if delay is not None:
+            self._delayvalue = int(delay)
+        if self._tracing:
+            self.update()
+
+    def delay(self, delay=None):
+        """ Return or set the drawing delay in milliseconds.
+
+        Optional argument:
+        delay -- positive integer
+
+        Example (for a TurtleScreen instance named screen):
+        >>> screen.delay(15)
+        >>> screen.delay()
+        15
+        """
+        if delay is None:
+            return self._delayvalue
+        self._delayvalue = int(delay)
+
+    def _incrementudc(self):
+        "Increment upadate counter."""
+        if not TurtleScreen._RUNNING:
+            TurtleScreen._RUNNNING = True
+            raise Terminator
+        if self._tracing > 0:
+            self._updatecounter += 1
+            self._updatecounter %= self._tracing
+
+    def update(self):
+        """Perform a TurtleScreen update.
+        """
+        for t in self.turtles():
+            t._update_data()
+            t._drawturtle()
+        self._update()
+
+    def window_width(self):
+        """ Return the width of the turtle window.
+
+        Example (for a TurtleScreen instance named screen):
+        >>> screen.window_width()
+        640
+        """
+        return self._window_size()[0]
+
+    def window_height(self):
+        """ Return the height of the turtle window.
+
+        Example (for a TurtleScreen instance named screen):
+        >>> screen.window_height()
+        480
+        """
+        return self._window_size()[1]
+
+    def getcanvas(self):
+        """Return the Canvas of this TurtleScreen.
+
+        No argument.
+
+        Example (for a Screen instance named screen):
+        >>> cv = screen.getcanvas()
+        >>> cv
+        <turtle.ScrolledCanvas instance at 0x010742D8>
+        """
+        return self.cv
+
+    def getshapes(self):
+        """Return a list of names of all currently available turtle shapes.
+
+        No argument.
+
+        Example (for a TurtleScreen instance named screen):
+        >>> screen.getshapes()
+        ['arrow', 'blank', 'circle', ... , 'turtle']
+        """
+        return sorted(self._shapes.keys())
+
+    def onclick(self, fun, btn=1, add=None):
+        """Bind fun to mouse-click event on canvas.
+
+        Arguments:
+        fun -- a function with two arguments, the coordinates of the
+               clicked point on the canvas.
+        num -- the number of the mouse-button, defaults to 1
+
+        Example (for a TurtleScreen instance named screen
+        and a Turtle instance named turtle):
+
+        >>> screen.onclick(turtle.goto)
+
+        ### Subsequently clicking into the TurtleScreen will
+        ### make the turtle move to the clicked point.
+        >>> screen.onclick(None)
+
+        ### event-binding will be removed
+        """
+        self._onscreenclick(fun, btn, add)
+
+    def onkey(self, fun, key):
+        """Bind fun to key-release event of key.
+
+        Arguments:
+        fun -- a function with no arguments
+        key -- a string: key (e.g. "a") or key-symbol (e.g. "space")
+
+        In order ro be able to register key-events, TurtleScreen
+        must have focus. (See method listen.)
+
+        Example (for a TurtleScreen instance named screen
+        and a Turtle instance named turtle):
+
+        >>> def f():
+                fd(50)
+                lt(60)
+
+
+        >>> screen.onkey(f, "Up")
+        >>> screen.listen()
+
+        ### Subsequently the turtle can be moved by
+        ### repeatedly pressing the up-arrow key,
+        ### consequently drawing a hexagon
+        """
+        if fun == None:
+            self._keys.remove(key)
+        elif key not in self._keys:
+            self._keys.append(key)
+        self._onkey(fun, key)
+
+    def listen(self, xdummy=None, ydummy=None):
+        """Set focus on TurtleScreen (in order to collect key-events)
+
+        No arguments.
+        Dummy arguments are provided in order
+        to be able to pass listen to the onclick method.
+
+        Example (for a TurtleScreen instance named screen):
+        >>> screen.listen()
+        """
+        self._listen()
+
+    def ontimer(self, fun, t=0):
+        """Install a timer, which calls fun after t milliseconds.
+
+        Arguments:
+        fun -- a function with no arguments.
+        t -- a number >= 0
+
+        Example (for a TurtleScreen instance named screen):
+
+        >>> running = True
+        >>> def f():
+                if running:
+                        fd(50)
+                        lt(60)
+                        screen.ontimer(f, 250)
+
+        >>> f()   ### makes the turtle marching around
+        >>> running = False
+        """
+        self._ontimer(fun, t)
+
+    def bgpic(self, picname=None):
+        """Set background image or return name of current backgroundimage.
+
+        Optional argument:
+        picname -- a string, name of a gif-file or "nopic".
+
+        If picname is a filename, set the corresponing image as background.
+        If picname is "nopic", delete backgroundimage, if present.
+        If picname is None, return the filename of the current backgroundimage.
+
+        Example (for a TurtleScreen instance named screen):
+        >>> screen.bgpic()
+        'nopic'
+        >>> screen.bgpic("landscape.gif")
+        >>> screen.bgpic()
+        'landscape.gif'
+        """
+        if picname is None:
+            return self._bgpicname
+        if picname not in self._bgpics:
+            self._bgpics[picname] = self._image(picname)
+        self._setbgpic(self._bgpic, self._bgpics[picname])
+        self._bgpicname = picname
+
+    def screensize(self, canvwidth=None, canvheight=None, bg=None):
+        """Resize the canvas, the turtles are drawing on.
+
+        Optional arguments:
+        canvwidth -- positive integer, new width of canvas in pixels
+        canvheight --  positive integer, new height of canvas in pixels
+        bg -- colorstring or color-tupel, new backgroundcolor
+        If no arguments are given, return current (canvaswidth, canvasheight)
+
+        Do not alter the drawing window. To observe hidden parts of
+        the canvas use the scrollbars. (Can make visible those parts
+        of a drawing, which were outside the canvas before!)
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.screensize(2000,1500)
+            ### e. g. to search for an erroneously escaped turtle ;-)
+        """
+        return self._resize(canvwidth, canvheight, bg)
+
+    onscreenclick = onclick
+    resetscreen = reset
+    clearscreen = clear
+    addshape = register_shape
+
+class TNavigator(object):
+    """Navigation part of the RawTurtle.
+    Implements methods for turtle movement.
+    """
+    START_ORIENTATION = {
+        "standard": Vec2D(1.0, 0.0),
+        "world"   : Vec2D(1.0, 0.0),
+        "logo"    : Vec2D(0.0, 1.0)  }
+    DEFAULT_MODE = "standard"
+    DEFAULT_ANGLEOFFSET = 0
+    DEFAULT_ANGLEORIENT = 1
+
+    def __init__(self, mode=DEFAULT_MODE):
+        self._angleOffset = self.DEFAULT_ANGLEOFFSET
+        self._angleOrient = self.DEFAULT_ANGLEORIENT
+        self._mode = mode
+        self.undobuffer = None
+        self.degrees()
+        self._mode = None
+        self._setmode(mode)
+        TNavigator.reset(self)
+
+    def reset(self):
+        """reset turtle to its initial values
+
+        Will be overwritten by parent class
+        """
+        self._position = Vec2D(0.0, 0.0)
+        self._orient =  TNavigator.START_ORIENTATION[self._mode]
+
+    def _setmode(self, mode=None):
+        """Set turtle-mode to 'standard', 'world' or 'logo'.
+        """
+        if mode == None:
+            return self._mode
+        if mode not in ["standard", "logo", "world"]:
+            return
+        self._mode = mode
+        if mode in ["standard", "world"]:
+            self._angleOffset = 0
+            self._angleOrient = 1
+        else: # mode == "logo":
+            self._angleOffset = self._fullcircle/4.
+            self._angleOrient = -1
+
+    def _setDegreesPerAU(self, fullcircle):
+        """Helper function for degrees() and radians()"""
+        self._fullcircle = fullcircle
+        self._degreesPerAU = 360/fullcircle
+        if self._mode == "standard":
+            self._angleOffset = 0
+        else:
+            self._angleOffset = fullcircle/4.
+
+    def degrees(self, fullcircle=360.0):
+        """ Set angle measurement units to degrees.
+
+        Optional argument:
+        fullcircle -  a number
+
+        Set angle measurement units, i. e. set number
+        of 'degrees' for a full circle. Dafault value is
+        360 degrees.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.left(90)
+        >>> turtle.heading()
+        90
+        >>> turtle.degrees(400.0)  # angle measurement in gon
+        >>> turtle.heading()
+        100
+
+        """
+        self._setDegreesPerAU(fullcircle)
+
+    def radians(self):
+        """ Set the angle measurement units to radians.
+
+        No arguments.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.heading()
+        90
+        >>> turtle.radians()
+        >>> turtle.heading()
+        1.5707963267948966
+        """
+        self._setDegreesPerAU(2*math.pi)
+
+    def _go(self, distance):
+        """move turtle forward by specified distance"""
+        ende = self._position + self._orient * distance
+        self._goto(ende)
+
+    def _rotate(self, angle):
+        """Turn turtle counterclockwise by specified angle if angle > 0."""
+        angle *= self._degreesPerAU
+        self._orient = self._orient.rotate(angle)
+
+    def _goto(self, end):
+        """move turtle to position end."""
+        self._position = end
+
+    def forward(self, distance):
+        """Move the turtle forward by the specified distance.
+
+        Aliases: forward | fd
+
+        Argument:
+        distance -- a number (integer or float)
+
+        Move the turtle forward by the specified distance, in the direction
+        the turtle is headed.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.position()
+        (0.00, 0.00)
+        >>> turtle.forward(25)
+        >>> turtle.position()
+        (25.00,0.00)
+        >>> turtle.forward(-75)
+        >>> turtle.position()
+        (-50.00,0.00)
+        """
+        self._go(distance)
+
+    def back(self, distance):
+        """Move the turtle backward by distance.
+
+        Aliases: back | backward | bk
+
+        Argument:
+        distance -- a number
+
+        Move the turtle backward by distance ,opposite to the direction the
+        turtle is headed. Do not change the turtle's heading.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.position()
+        (0.00, 0.00)
+        >>> turtle.backward(30)
+        >>> turtle.position()
+        (-30.00, 0.00)
+        """
+        self._go(-distance)
+
+    def right(self, angle):
+        """Turn turtle right by angle units.
+
+        Aliases: right | rt
+
+        Argument:
+        angle -- a number (integer or float)
+
+        Turn turtle right by angle units. (Units are by default degrees,
+        but can be set via the degrees() and radians() functions.)
+        Angle orientation depends on mode. (See this.)
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.heading()
+        22.0
+        >>> turtle.right(45)
+        >>> turtle.heading()
+        337.0
+        """
+        self._rotate(-angle)
+
+    def left(self, angle):
+        """Turn turtle left by angle units.
+
+        Aliases: left | lt
+
+        Argument:
+        angle -- a number (integer or float)
+
+        Turn turtle left by angle units. (Units are by default degrees,
+        but can be set via the degrees() and radians() functions.)
+        Angle orientation depends on mode. (See this.)
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.heading()
+        22.0
+        >>> turtle.left(45)
+        >>> turtle.heading()
+        67.0
+        """
+        self._rotate(angle)
+
+    def pos(self):
+        """Return the turtle's current location (x,y), as a Vec2D-vector.
+
+        Aliases: pos | position
+
+        No arguments.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.pos()
+        (0.00, 240.00)
+        """
+        return self._position
+
+    def xcor(self):
+        """ Return the turtle's x coordinate.
+
+        No arguments.
+
+        Example (for a Turtle instance named turtle):
+        >>> reset()
+        >>> turtle.left(60)
+        >>> turtle.forward(100)
+        >>> print turtle.xcor()
+        50.0
+        """
+        return self._position[0]
+
+    def ycor(self):
+        """ Return the turtle's y coordinate
+        ---
+        No arguments.
+
+        Example (for a Turtle instance named turtle):
+        >>> reset()
+        >>> turtle.left(60)
+        >>> turtle.forward(100)
+        >>> print turtle.ycor()
+        86.6025403784
+        """
+        return self._position[1]
+
+
+    def goto(self, x, y=None):
+        """Move turtle to an absolute position.
+
+        Aliases: setpos | setposition | goto:
+
+        Arguments:
+        x -- a number      or     a pair/vector of numbers
+        y -- a number             None
+
+        call: goto(x, y)         # two coordinates
+        --or: goto((x, y))       # a pair (tuple) of coordinates
+        --or: goto(vec)          # e.g. as returned by pos()
+
+        Move turtle to an absolute position. If the pen is down,
+        a line will be drawn. The turtle's orientation does not change.
+
+        Example (for a Turtle instance named turtle):
+        >>> tp = turtle.pos()
+        >>> tp
+        (0.00, 0.00)
+        >>> turtle.setpos(60,30)
+        >>> turtle.pos()
+        (60.00,30.00)
+        >>> turtle.setpos((20,80))
+        >>> turtle.pos()
+        (20.00,80.00)
+        >>> turtle.setpos(tp)
+        >>> turtle.pos()
+        (0.00,0.00)
+        """
+        if y is None:
+            self._goto(Vec2D(*x))
+        else:
+            self._goto(Vec2D(x, y))
+
+    def home(self):
+        """Move turtle to the origin - coordinates (0,0).
+
+        No arguments.
+
+        Move turtle to the origin - coordinates (0,0) and set it's
+        heading to it's start-orientation (which depends on mode).
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.home()
+        """
+        self.goto(0, 0)
+        self.setheading(0)
+
+    def setx(self, x):
+        """Set the turtle's first coordinate to x
+
+        Argument:
+        x -- a number (integer or float)
+
+        Set the turtle's first coordinate to x, leave second coordinate
+        unchanged.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.position()
+        (0.00, 240.00)
+        >>> turtle.setx(10)
+        >>> turtle.position()
+        (10.00, 240.00)
+        """
+        self._goto(Vec2D(x, self._position[1]))
+
+    def sety(self, y):
+        """Set the turtle's second coordinate to y
+
+        Argument:
+        y -- a number (integer or float)
+
+        Set the turtle's first coordinate to x, second coordinate remains
+        unchanged.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.position()
+        (0.00, 40.00)
+        >>> turtle.sety(-10)
+        >>> turtle.position()
+        (0.00, -10.00)
+        """
+        self._goto(Vec2D(self._position[0], y))
+
+    def distance(self, x, y=None):
+        """Return the distance from the turtle to (x,y) in turtle step units.
+
+        Arguments:
+        x -- a number   or  a pair/vector of numbers   or   a turtle instance
+        y -- a number       None                            None
+
+        call: distance(x, y)         # two coordinates
+        --or: distance((x, y))       # a pair (tuple) of coordinates
+        --or: distance(vec)          # e.g. as returned by pos()
+        --or: distance(mypen)        # where mypen is another turtle
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.pos()
+        (0.00, 0.00)
+        >>> turtle.distance(30,40)
+        50.0
+        >>> pen = Turtle()
+        >>> pen.forward(77)
+        >>> turtle.distance(pen)
+        77.0
+        """
+        if y is not None:
+            pos = Vec2D(x, y)
+        if isinstance(x, Vec2D):
+            pos = x
+        elif isinstance(x, tuple):
+            pos = Vec2D(*x)
+        elif isinstance(x, TNavigator):
+            pos = x._position
+        return abs(pos - self._position)
+
+    def towards(self, x, y=None):
+        """Return the angle of the line from the turtle's position to (x, y).
+
+        Arguments:
+        x -- a number   or  a pair/vector of numbers   or   a turtle instance
+        y -- a number       None                            None
+
+        call: distance(x, y)         # two coordinates
+        --or: distance((x, y))       # a pair (tuple) of coordinates
+        --or: distance(vec)          # e.g. as returned by pos()
+        --or: distance(mypen)        # where mypen is another turtle
+
+        Return the angle, between the line from turtle-position to position
+        specified by x, y and the turtle's start orientation. (Depends on
+        modes - "standard" or "logo")
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.pos()
+        (10.00, 10.00)
+        >>> turtle.towards(0,0)
+        225.0
+        """
+        if y is not None:
+            pos = Vec2D(x, y)
+        if isinstance(x, Vec2D):
+            pos = x
+        elif isinstance(x, tuple):
+            pos = Vec2D(*x)
+        elif isinstance(x, TNavigator):
+            pos = x._position
+        x, y = pos - self._position
+        result = round(math.atan2(y, x)*180.0/math.pi, 10) % 360.0
+        result /= self._degreesPerAU
+        return (self._angleOffset + self._angleOrient*result) % self._fullcircle
+
+    def heading(self):
+        """ Return the turtle's current heading.
+
+        No arguments.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.left(67)
+        >>> turtle.heading()
+        67.0
+        """
+        x, y = self._orient
+        result = round(math.atan2(y, x)*180.0/math.pi, 10) % 360.0
+        result /= self._degreesPerAU
+        return (self._angleOffset + self._angleOrient*result) % self._fullcircle
+
+    def setheading(self, to_angle):
+        """Set the orientation of the turtle to to_angle.
+
+        Aliases:  setheading | seth
+
+        Argument:
+        to_angle -- a number (integer or float)
+
+        Set the orientation of the turtle to to_angle.
+        Here are some common directions in degrees:
+
+         standard - mode:          logo-mode:
+        -------------------|--------------------
+           0 - east                0 - north
+          90 - north              90 - east
+         180 - west              180 - south
+         270 - south             270 - west
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.setheading(90)
+        >>> turtle.heading()
+        90
+        """
+        angle = (to_angle - self.heading())*self._angleOrient
+        full = self._fullcircle
+        angle = (angle+full/2.)%full - full/2.
+        self._rotate(angle)
+
+    def circle(self, radius, extent = None, steps = None):
+        """ Draw a circle with given radius.
+
+        Arguments:
+        radius -- a number
+        extent (optional) -- a number
+        steps (optional) -- an integer
+
+        Draw a circle with given radius. The center is radius units left
+        of the turtle; extent - an angle - determines which part of the
+        circle is drawn. If extent is not given, draw the entire circle.
+        If extent is not a full circle, one endpoint of the arc is the
+        current pen position. Draw the arc in counterclockwise direction
+        if radius is positive, otherwise in clockwise direction. Finally
+        the direction of the turtle is changed by the amount of extent.
+
+        As the circle is approximated by an inscribed regular polygon,
+        steps determines the number of steps to use. If not given,
+        it will be calculated automatically. Maybe used to draw regular
+        polygons.
+
+        call: circle(radius)                  # full circle
+        --or: circle(radius, extent)          # arc
+        --or: circle(radius, extent, steps)
+        --or: circle(radius, steps=6)         # 6-sided polygon
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.circle(50)
+        >>> turtle.circle(120, 180)  # semicircle
+        """
+        if self.undobuffer:
+            self.undobuffer.push(["seq"])
+            self.undobuffer.cumulate = True
+        speed = self.speed()
+        if extent is None:
+            extent = self._fullcircle
+        if steps is None:
+            frac = abs(extent)/self._fullcircle
+            steps = 1+int(min(11+abs(radius)/6.0, 59.0)*frac)
+        w = 1.0 * extent / steps
+        w2 = 0.5 * w
+        l = 2.0 * radius * math.sin(w2*math.pi/180.0*self._degreesPerAU)
+        if radius < 0:
+            l, w, w2 = -l, -w, -w2
+        tr = self._tracer()
+        dl = self._delay()
+        if speed == 0:
+            self._tracer(0, 0)
+        else:
+            self.speed(0)
+        self._rotate(w2)
+        for i in range(steps):
+            self.speed(speed)
+            self._go(l)
+            self.speed(0)
+            self._rotate(w)
+        self._rotate(-w2)
+        if speed == 0:
+            self._tracer(tr, dl)
+        self.speed(speed)
+        if self.undobuffer:
+            self.undobuffer.cumulate = False
+
+## three dummy methods to be implemented by child class:
+
+    def speed(self, s=0):
+        """dummy method - to be overwritten by child class"""
+    def _tracer(self, a=None, b=None):
+        """dummy method - to be overwritten by child class"""
+    def _delay(self, n=None):
+        """dummy method - to be overwritten by child class"""
+
+    fd = forward
+    bk = back
+    backward = back
+    rt = right
+    lt = left
+    position = pos
+    setpos = goto
+    setposition = goto
+    seth = setheading
+
+
+class TPen(object):
+    """Drawing part of the RawTurtle.
+    Implements drawing properties.
+    """
+    def __init__(self, resizemode=_CFG["resizemode"]):
+        self._resizemode = resizemode # or "user" or "noresize"
+        self.undobuffer = None
+        TPen._reset(self)
+
+    def _reset(self, pencolor=_CFG["pencolor"],
+                     fillcolor=_CFG["fillcolor"]):
+        self._pensize = 1
+        self._shown = True
+        self._pencolor = pencolor
+        self._fillcolor = fillcolor
+        self._drawing = True
+        self._speed = 3
+        self._stretchfactor = (1, 1)
+        self._tilt = 0
+        self._outlinewidth = 1
+        ### self.screen = None  # to override by child class
+
+    def resizemode(self, rmode=None):
+        """Set resizemode to one of the values: "auto", "user", "noresize".
+
+        (Optional) Argument:
+        rmode -- one of the strings "auto", "user", "noresize"
+
+        Different resizemodes have the following effects:
+          - "auto" adapts the appearance of the turtle
+                   corresponding to the value of pensize.
+          - "user" adapts the appearance of the turtle according to the
+                   values of stretchfactor and outlinewidth (outline),
+                   which are set by shapesize()
+          - "noresize" no adaption of the turtle's appearance takes place.
+        If no argument is given, return current resizemode.
+        resizemode("user") is called by a call of shapesize with arguments.
+
+
+        Examples (for a Turtle instance named turtle):
+        >>> turtle.resizemode("noresize")
+        >>> turtle.resizemode()
+        'noresize'
+        """
+        if rmode is None:
+            return self._resizemode
+        rmode = rmode.lower()
+        if rmode in ["auto", "user", "noresize"]:
+            self.pen(resizemode=rmode)
+
+    def pensize(self, width=None):
+        """Set or return the line thickness.
+
+        Aliases:  pensize | width
+
+        Argument:
+        width -- positive number
+
+        Set the line thickness to width or return it. If resizemode is set
+        to "auto" and turtleshape is a polygon, that polygon is drawn with
+        the same line thickness. If no argument is given, current pensize
+        is returned.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.pensize()
+        1
+        turtle.pensize(10)   # from here on lines of width 10 are drawn
+        """
+        if width is None:
+            return self._pensize
+        self.pen(pensize=width)
+
+
+    def penup(self):
+        """Pull the pen up -- no drawing when moving.
+
+        Aliases: penup | pu | up
+
+        No argument
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.penup()
+        """
+        if not self._drawing:
+            return
+        self.pen(pendown=False)
+
+    def pendown(self):
+        """Pull the pen down -- drawing when moving.
+
+        Aliases: pendown | pd | down
+
+        No argument.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.pendown()
+        """
+        if self._drawing:
+            return
+        self.pen(pendown=True)
+
+    def isdown(self):
+        """Return True if pen is down, False if it's up.
+
+        No argument.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.penup()
+        >>> turtle.isdown()
+        False
+        >>> turtle.pendown()
+        >>> turtle.isdown()
+        True
+        """
+        return self._drawing
+
+    def speed(self, speed=None):
+        """ Return or set the turtle's speed.
+
+        Optional argument:
+        speed -- an integer in the range 0..10 or a speedstring (see below)
+
+        Set the turtle's speed to an integer value in the range 0 .. 10.
+        If no argument is given: return current speed.
+
+        If input is a number greater than 10 or smaller than 0.5,
+        speed is set to 0.
+        Speedstrings  are mapped to speedvalues in the following way:
+            'fastest' :  0
+            'fast'    :  10
+            'normal'  :  6
+            'slow'    :  3
+            'slowest' :  1
+        speeds from 1 to 10 enforce increasingly faster animation of
+        line drawing and turtle turning.
+
+        Attention:
+        speed = 0 : *no* animation takes place. forward/back makes turtle jump
+        and likewise left/right make the turtle turn instantly.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.speed(3)
+        """
+        speeds = {'fastest':0, 'fast':10, 'normal':6, 'slow':3, 'slowest':1 }
+        if speed is None:
+            return self._speed
+        if speed in speeds:
+            speed = speeds[speed]
+        elif 0.5 < speed < 10.5:
+            speed = int(round(speed))
+        else:
+            speed = 0
+        self.pen(speed=speed)
+
+    def color(self, *args):
+        """Return or set the pencolor and fillcolor.
+
+        Arguments:
+        Several input formats are allowed.
+        They use 0, 1, 2, or 3 arguments as follows:
+
+        color()
+            Return the current pencolor and the current fillcolor
+            as a pair of color specification strings as are returned
+            by pencolor and fillcolor.
+        color(colorstring), color((r,g,b)), color(r,g,b)
+            inputs as in pencolor, set both, fillcolor and pencolor,
+            to the given value.
+        color(colorstring1, colorstring2),
+        color((r1,g1,b1), (r2,g2,b2))
+            equivalent to pencolor(colorstring1) and fillcolor(colorstring2)
+            and analogously, if the other input format is used.
+
+        If turtleshape is a polygon, outline and interior of that polygon
+        is drawn with the newly set colors.
+        For mor info see: pencolor, fillcolor
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.color('red', 'green')
+        >>> turtle.color()
+        ('red', 'green')
+        >>> colormode(255)
+        >>> color((40, 80, 120), (160, 200, 240))
+        >>> color()
+        ('#285078', '#a0c8f0')
+        """
+        if args:
+            l = len(args)
+            if l == 1:
+                pcolor = fcolor = args[0]
+            elif l == 2:
+                pcolor, fcolor = args
+            elif l == 3:
+                pcolor = fcolor = args
+            pcolor = self._colorstr(pcolor)
+            fcolor = self._colorstr(fcolor)
+            self.pen(pencolor=pcolor, fillcolor=fcolor)
+        else:
+            return self._color(self._pencolor), self._color(self._fillcolor)
+
+    def pencolor(self, *args):
+        """ Return or set the pencolor.
+
+        Arguments:
+        Four input formats are allowed:
+          - pencolor()
+            Return the current pencolor as color specification string,
+            possibly in hex-number format (see example).
+            May be used as input to another color/pencolor/fillcolor call.
+          - pencolor(colorstring)
+            s is a Tk color specification string, such as "red" or "yellow"
+          - pencolor((r, g, b))
+            *a tuple* of r, g, and b, which represent, an RGB color,
+            and each of r, g, and b are in the range 0..colormode,
+            where colormode is either 1.0 or 255
+          - pencolor(r, g, b)
+            r, g, and b represent an RGB color, and each of r, g, and b
+            are in the range 0..colormode
+
+        If turtleshape is a polygon, the outline of that polygon is drawn
+        with the newly set pencolor.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.pencolor('brown')
+        >>> tup = (0.2, 0.8, 0.55)
+        >>> turtle.pencolor(tup)
+        >>> turtle.pencolor()
+        '#33cc8c'
+        """
+        if args:
+            color = self._colorstr(args)
+            if color == self._pencolor:
+                return
+            self.pen(pencolor=color)
+        else:
+            return self._color(self._pencolor)
+
+    def fillcolor(self, *args):
+        """ Return or set the fillcolor.
+
+        Arguments:
+        Four input formats are allowed:
+          - fillcolor()
+            Return the current fillcolor as color specification string,
+            possibly in hex-number format (see example).
+            May be used as input to another color/pencolor/fillcolor call.
+          - fillcolor(colorstring)
+            s is a Tk color specification string, such as "red" or "yellow"
+          - fillcolor((r, g, b))
+            *a tuple* of r, g, and b, which represent, an RGB color,
+            and each of r, g, and b are in the range 0..colormode,
+            where colormode is either 1.0 or 255
+          - fillcolor(r, g, b)
+            r, g, and b represent an RGB color, and each of r, g, and b
+            are in the range 0..colormode
+
+        If turtleshape is a polygon, the interior of that polygon is drawn
+        with the newly set fillcolor.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.fillcolor('violet')
+        >>> col = turtle.pencolor()
+        >>> turtle.fillcolor(col)
+        >>> turtle.fillcolor(0, .5, 0)
+        """
+        if args:
+            color = self._colorstr(args)
+            if color == self._fillcolor:
+                return
+            self.pen(fillcolor=color)
+        else:
+            return self._color(self._fillcolor)
+
+    def showturtle(self):
+        """Makes the turtle visible.
+
+        Aliases: showturtle | st
+
+        No argument.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.hideturtle()
+        >>> turtle.showturtle()
+        """
+        self.pen(shown=True)
+
+    def hideturtle(self):
+        """Makes the turtle invisible.
+
+        Aliases: hideturtle | ht
+
+        No argument.
+
+        It's a good idea to do this while you're in the
+        middle of a complicated drawing, because hiding
+        the turtle speeds up the drawing observably.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.hideturtle()
+        """
+        self.pen(shown=False)
+
+    def isvisible(self):
+        """Return True if the Turtle is shown, False if it's hidden.
+
+        No argument.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.hideturtle()
+        >>> print turtle.isvisible():
+        False
+        """
+        return self._shown
+
+    def pen(self, pen=None, **pendict):
+        """Return or set the pen's attributes.
+
+        Arguments:
+            pen -- a dictionary with some or all of the below listed keys.
+            **pendict -- one or more keyword-arguments with the below
+                         listed keys as keywords.
+
+        Return or set the pen's attributes in a 'pen-dictionary'
+        with the following key/value pairs:
+           "shown"      :   True/False
+           "pendown"    :   True/False
+           "pencolor"   :   color-string or color-tuple
+           "fillcolor"  :   color-string or color-tuple
+           "pensize"    :   positive number
+           "speed"      :   number in range 0..10
+           "resizemode" :   "auto" or "user" or "noresize"
+           "stretchfactor": (positive number, positive number)
+           "outline"    :   positive number
+           "tilt"       :   number
+
+        This dicionary can be used as argument for a subsequent
+        pen()-call to restore the former pen-state. Moreover one
+        or more of these attributes can be provided as keyword-arguments.
+        This can be used to set several pen attributes in one statement.
+
+
+        Examples (for a Turtle instance named turtle):
+        >>> turtle.pen(fillcolor="black", pencolor="red", pensize=10)
+        >>> turtle.pen()
+        {'pensize': 10, 'shown': True, 'resizemode': 'auto', 'outline': 1,
+        'pencolor': 'red', 'pendown': True, 'fillcolor': 'black',
+        'stretchfactor': (1,1), 'speed': 3}
+        >>> penstate=turtle.pen()
+        >>> turtle.color("yellow","")
+        >>> turtle.penup()
+        >>> turtle.pen()
+        {'pensize': 10, 'shown': True, 'resizemode': 'auto', 'outline': 1,
+        'pencolor': 'yellow', 'pendown': False, 'fillcolor': '',
+        'stretchfactor': (1,1), 'speed': 3}
+        >>> p.pen(penstate, fillcolor="green")
+        >>> p.pen()
+        {'pensize': 10, 'shown': True, 'resizemode': 'auto', 'outline': 1,
+        'pencolor': 'red', 'pendown': True, 'fillcolor': 'green',
+        'stretchfactor': (1,1), 'speed': 3}
+        """
+        _pd =  {"shown"         : self._shown,
+                "pendown"       : self._drawing,
+                "pencolor"      : self._pencolor,
+                "fillcolor"     : self._fillcolor,
+                "pensize"       : self._pensize,
+                "speed"         : self._speed,
+                "resizemode"    : self._resizemode,
+                "stretchfactor" : self._stretchfactor,
+                "outline"       : self._outlinewidth,
+                "tilt"          : self._tilt
+               }
+
+        if not (pen or pendict):
+            return _pd
+
+        if isinstance(pen, dict):
+            p = pen
+        else:
+            p = {}
+        p.update(pendict)
+
+        _p_buf = {}
+        for key in p:
+            _p_buf[key] = _pd[key]
+
+        if self.undobuffer:
+            self.undobuffer.push(("pen", _p_buf))
+
+        newLine = False
+        if "pendown" in p:
+            if self._drawing != p["pendown"]:
+                newLine = True
+        if "pencolor" in p:
+            if isinstance(p["pencolor"], tuple):
+                p["pencolor"] = self._colorstr((p["pencolor"],))
+            if self._pencolor != p["pencolor"]:
+                newLine = True
+        if "pensize" in p:
+            if self._pensize != p["pensize"]:
+                newLine = True
+        if newLine:
+            self._newLine()
+        if "pendown" in p:
+            self._drawing = p["pendown"]
+        if "pencolor" in p:
+            self._pencolor = p["pencolor"]
+        if "pensize" in p:
+            self._pensize = p["pensize"]
+        if "fillcolor" in p:
+            if isinstance(p["fillcolor"], tuple):
+                p["fillcolor"] = self._colorstr((p["fillcolor"],))
+            self._fillcolor = p["fillcolor"]
+        if "speed" in p:
+            self._speed = p["speed"]
+        if "resizemode" in p:
+            self._resizemode = p["resizemode"]
+        if "stretchfactor" in p:
+            sf = p["stretchfactor"]
+            if isinstance(sf, (int, float)):
+                sf = (sf, sf)
+            self._stretchfactor = sf
+        if "outline" in p:
+            self._outlinewidth = p["outline"]
+        if "shown" in p:
+            self._shown = p["shown"]
+        if "tilt" in p:
+            self._tilt = p["tilt"]
+        self._update()
+
+## three dummy methods to be implemented by child class:
+
+    def _newLine(self, usePos = True):
+        """dummy method - to be overwritten by child class"""
+    def _update(self, count=True, forced=False):
+        """dummy method - to be overwritten by child class"""
+    def _color(self, args):
+        """dummy method - to be overwritten by child class"""
+    def _colorstr(self, args):
+        """dummy method - to be overwritten by child class"""
+
+    width = pensize
+    up = penup
+    pu = penup
+    pd = pendown
+    down = pendown
+    st = showturtle
+    ht = hideturtle
+
+
+class _TurtleImage(object):
+    """Helper class: Datatype to store Turtle attributes
+    """
 
-        Example:
-        >>> turtle.degrees()
-        """
-        # Don't try to change _angle if it is 0, because
-        # _fullcircle might not be set, yet
-        if self._angle:
-            self._angle = (self._angle / self._fullcircle) * fullcircle
-        self._fullcircle = fullcircle
-        self._invradian = pi / (fullcircle * 0.5)
+    def __init__(self, screen, shapeIndex):
+        self.screen = screen
+        self._type = None
+        self._setshape(shapeIndex)
+
+    def _setshape(self, shapeIndex):
+        screen = self.screen # RawTurtle.screens[self.screenIndex]
+        self.shapeIndex = shapeIndex
+        if self._type == "polygon" == screen._shapes[shapeIndex]._type:
+            return
+        if self._type == "image" == screen._shapes[shapeIndex]._type:
+            return
+        if self._type in ["image", "polygon"]:
+            screen._delete(self._item)
+        elif self._type == "compound":
+            for item in self._item:
+                screen._delete(item)
+        self._type = screen._shapes[shapeIndex]._type
+        if self._type == "polygon":
+            self._item = screen._createpoly()
+        elif self._type == "image":
+            self._item = screen._createimage(screen._shapes["blank"]._data)
+        elif self._type == "compound":
+            self._item = [screen._createpoly() for item in
+                                          screen._shapes[shapeIndex]._data]
+
+
+class RawTurtle(TPen, TNavigator):
+    """Animation part of the RawTurtle.
+    Puts RawTurtle upon a TurtleScreen and provides tools for
+    it's animation.
+    """
+    screens = []
 
-    def radians(self):
-        """ Set the angle measurement units to radians.
+    def __init__(self, canvas=None,
+                 shape=_CFG["shape"],
+                 undobuffersize=_CFG["undobuffersize"],
+                 visible=_CFG["visible"]):
+        if isinstance(canvas, Screen):
+            self.screen = canvas
+        elif isinstance(canvas, TurtleScreen):
+            if canvas not in RawTurtle.screens:
+                RawTurtle.screens.append(canvas)
+            self.screen = canvas
+        elif isinstance(canvas, (ScrolledCanvas, Canvas)):
+            for screen in RawTurtle.screens:
+                if screen.cv == canvas:
+                    self.screen = screen
+                    break
+            else:
+                self.screen = TurtleScreen(canvas)
+                RawTurtle.screens.append(self.screen)
+        else:
+            raise TurtleGraphicsError("bad cavas argument %s" % canvas)
 
-        Example:
-        >>> turtle.radians()
-        """
-        self.degrees(2.0*pi)
+        screen = self.screen
+        TNavigator.__init__(self, screen.mode())
+        TPen.__init__(self)
+        screen._turtles.append(self)
+        self.drawingLineItem = screen._createline()
+        self.turtle = _TurtleImage(screen, shape)
+        self._poly = None
+        self._creatingPoly = False
+        self._fillitem = self._fillpath = None
+        self._shown = visible
+        self._hidden_from_screen = False
+        self.currentLineItem = screen._createline()
+        self.currentLine = [self._position]
+        self.items = [self.currentLineItem]
+        self.stampItems = []
+        self._undobuffersize = undobuffersize
+        self.undobuffer = Tbuffer(undobuffersize)
+        self._update()
 
     def reset(self):
-        """ Clear the screen, re-center the pen, and set variables to
-        the default values.
+        """Delete the turtle's drawings and restore it's default values.
 
-        Example:
+        No argument.
+,
+        Delete the turtle's drawings from the screen, re-center the turtle
+        and set variables to the default values.
+
+        Example (for a Turtle instance named turtle):
         >>> turtle.position()
-        [0.0, -22.0]
+        (0.00,-22.00)
         >>> turtle.heading()
         100.0
         >>> turtle.reset()
         >>> turtle.position()
-        [0.0, 0.0]
+        (0.00,0.00)
         >>> turtle.heading()
         0.0
         """
-        canvas = self._canvas
-        self._canvas.update()
-        width = canvas.winfo_width()
-        height = canvas.winfo_height()
-        if width <= 1:
-            width = canvas['width']
-        if height <= 1:
-            height = canvas['height']
-        self._origin = float(width)/2.0, float(height)/2.0
-        self._position = self._origin
-        self._angle = 0.0
-        self._drawing = 1
-        self._width = 1
-        self._color = "black"
-        self._filling = 0
-        self._path = []
-        self.clear()
-        canvas._root().tkraise()
+        TNavigator.reset(self)
+        TPen._reset(self)
+        self._clear()
+        self._drawturtle()
+        self._update()
+
+    def setundobuffer(self, size):
+        """Set or disable undobuffer.
+
+        Argument:
+        size -- an integer or None
+
+        If size is an integer an empty undobuffer of given size is installed.
+        Size gives the maximum number of turtle-actions that can be undone
+        by the undo() function.
+        If size is None, no undobuffer is present.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.setundobuffer(42)
+        """
+        if size is None:
+            self.undobuffer = None
+        else:
+            self.undobuffer = Tbuffer(size)
+
+    def undobufferentries(self):
+        """Return count of entries in the undobuffer.
+
+        No argument.
+
+        Example (for a Turtle instance named turtle):
+        >>> while undobufferentries():
+                undo()
+        """
+        if self.undobuffer is None:
+            return 0
+        return self.undobuffer.nr_of_items()
+
+    def _clear(self):
+        """Delete all of pen's drawings"""
+        self._fillitem = self._fillpath = None
+        for item in self.items:
+            self.screen._delete(item)
+        self.currentLineItem = self.screen._createline()
+        self.currentLine = []
+        if self._drawing:
+            self.currentLine.append(self._position)
+        self.items = [self.currentLineItem]
+        self.clearstamps()
+        self.setundobuffer(self._undobuffersize)
+
 
     def clear(self):
-        """ Clear the screen. The turtle does not move.
+        """Delete the turtle's drawings from the screen. Do not move turtle.
 
-        Example:
+        No arguments.
+
+        Delete the turtle's drawings from the screen. Do not move turtle.
+        State and position of the turtle as well as drawings of other
+        turtles are not affected.
+
+        Examples (for a Turtle instance named turtle):
         >>> turtle.clear()
         """
-        self.fill(0)
-        canvas = self._canvas
-        items = self._items
-        self._items = []
-        for item in items:
-            canvas.delete(item)
-        self._delete_turtle()
-        self._draw_turtle()
-
-    def tracer(self, flag):
-        """ Set tracing on if flag is True, and off if it is False.
-        Tracing means line are drawn more slowly, with an
-        animation of an arrow along the line.
+        self._clear()
+        self._update()
 
-        Example:
-        >>> turtle.tracer(False)   # turns off Tracer
+    def _update_data(self):
+        self.screen._incrementudc()
+        if self.screen._updatecounter != 0:
+            return
+        if len(self.currentLine)>1:
+            self.screen._drawline(self.currentLineItem, self.currentLine,
+                                  self._pencolor, self._pensize)
+
+    def _update(self):
+        """Perform a Turtle-data update.
         """
-        self._tracing = flag
-        if not self._tracing:
-            self._delete_turtle()
-        self._draw_turtle()
+        screen = self.screen
+        if screen._tracing == 0:
+            return
+        elif screen._tracing == 1:
+            self._update_data()
+            self._drawturtle()
+            screen._update()                  # TurtleScreenBase
+            screen._delay(screen._delayvalue) # TurtleScreenBase
+        else:
+            self._update_data()
+            if screen._updatecounter == 0:
+                for t in screen.turtles():
+                    t._drawturtle()
+                screen._update()
+
+    def _tracer(self, flag=None, delay=None):
+        """Turns turtle animation on/off and set delay for update drawings.
+
+        Optional arguments:
+        n -- nonnegative  integer
+        delay -- nonnegative  integer
+
+        If n is given, only each n-th regular screen update is really performed.
+        (Can be used to accelerate the drawing of complex graphics.)
+        Second arguments sets delay value (see RawTurtle.delay())
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.tracer(8, 25)
+        >>> dist = 2
+        >>> for i in range(200):
+                turtle.fd(dist)
+                turtle.rt(90)
+                dist += 2
+        """
+        return self.screen.tracer(flag, delay)
+
+    def _color(self, args):
+        return self.screen._color(args)
 
-    def forward(self, distance):
-        """ Go forward distance steps.
+    def _colorstr(self, args):
+        return self.screen._colorstr(args)
 
-        Example:
-        >>> turtle.position()
-        [0.0, 0.0]
-        >>> turtle.forward(25)
-        >>> turtle.position()
-        [25.0, 0.0]
-        >>> turtle.forward(-75)
-        >>> turtle.position()
-        [-50.0, 0.0]
+    def _cc(self, args):
+        """Convert colortriples to hexstrings.
         """
-        x0, y0 = start = self._position
-        x1 = x0 + distance * cos(self._angle*self._invradian)
-        y1 = y0 - distance * sin(self._angle*self._invradian)
-        self._goto(x1, y1)
-
-    def backward(self, distance):
-        """ Go backwards distance steps.
+        if isinstance(args, str):
+            return args
+        try:
+            r, g, b = args
+        except:
+            raise TurtleGraphicsError("bad color arguments: %s" % str(args))
+        if self.screen._colormode == 1.0:
+            r, g, b = [round(255.0*x) for x in (r, g, b)]
+        if not ((0 <= r <= 255) and (0 <= g <= 255) and (0 <= b <= 255)):
+            raise TurtleGraphicsError("bad color sequence: %s" % str(args))
+        return "#%02x%02x%02x" % (r, g, b)
+
+    def clone(self):
+        """Create and return a clone of the turtle.
+
+        No argument.
+
+        Create and return a clone of the turtle with same position, heading
+        and turtle properties.
+
+        Example (for a Turtle instance named mick):
+        mick = Turtle()
+        joe = mick.clone()
+        """
+        screen = self.screen
+        self._newLine(self._drawing)
+
+        turtle = self.turtle
+        self.screen = None
+        self.turtle = None  # too make self deepcopy-able
+
+        q = deepcopy(self)
+
+        self.screen = screen
+        self.turtle = turtle
+
+        q.screen = screen
+        q.turtle = _TurtleImage(screen, self.turtle.shapeIndex)
+
+        screen._turtles.append(q)
+        ttype = screen._shapes[self.turtle.shapeIndex]._type
+        if ttype == "polygon":
+            q.turtle._item = screen._createpoly()
+        elif ttype == "image":
+            q.turtle._item = screen._createimage(screen._shapes["blank"]._data)
+        elif ttype == "compound":
+            q.turtle._item = [screen._createpoly() for item in
+                              screen._shapes[self.turtle.shapeIndex]._data]
+        q.currentLineItem = screen._createline()
+        q._update()
+        return q
+
+    def shape(self, name=None):
+        """Set turtle shape to shape with given name / return current shapename.
+
+        Optional argument:
+        name -- a string, which is a valid shapename
+
+        Set turtle shape to shape with given name or, if name is not given,
+        return name of current shape.
+        Shape with name must exist in the TurtleScreen's shape dictionary.
+        Initially there are the following polygon shapes:
+        'arrow', 'turtle', 'circle', 'square', 'triangle', 'classic'.
+        To learn about how to deal with shapes see Screen-method register_shape.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.shape()
+        'arrow'
+        >>> turtle.shape("turtle")
+        >>> turtle.shape()
+        'turtle'
+        """
+        if name is None:
+            return self.turtle.shapeIndex
+        if not name in self.screen.getshapes():
+            raise TurtleGraphicsError("There is no shape named %s" % name)
+        self.turtle._setshape(name)
+        self._update()
+
+    def shapesize(self, stretch_wid=None, stretch_len=None, outline=None):
+        """Set/return turtle's stretchfactors/outline. Set resizemode to "user".
+
+        Optinonal arguments:
+           stretch_wid : positive number
+           stretch_len : positive number
+           outline  : positive number
+
+        Return or set the pen's attributes x/y-stretchfactors and/or outline.
+        Set resizemode to "user".
+        If and only if resizemode is set to "user", the turtle will be displayed
+        stretched according to its stretchfactors:
+        stretch_wid is stretchfactor perpendicular to orientation
+        stretch_len is stretchfactor in direction of turtles orientation.
+        outline determines the width of the shapes's outline.
+
+        Examples (for a Turtle instance named turtle):
+        >>> turtle.resizemode("user")
+        >>> turtle.shapesize(5, 5, 12)
+        >>> turtle.shapesize(outline=8)
+        """
+        if stretch_wid is None and stretch_len is None and outline == None:
+            stretch_wid, stretch_len = self._stretchfactor
+            return stretch_wid, stretch_len, self._outlinewidth
+        if stretch_wid is not None:
+            if stretch_len is None:
+                stretchfactor = stretch_wid, stretch_wid
+            else:
+                stretchfactor = stretch_wid, stretch_len
+        elif stretch_len is not None:
+            stretchfactor = self._stretchfactor[0], stretch_len
+        else:
+            stretchfactor = self._stretchfactor
+        if outline is None:
+            outline = self._outlinewidth
+        self.pen(resizemode="user",
+                 stretchfactor=stretchfactor, outline=outline)
+
+    def settiltangle(self, angle):
+        """Rotate the turtleshape to point in the specified direction
+
+        Optional argument:
+        angle -- number
+
+        Rotate the turtleshape to point in the direction specified by angle,
+        regardless of its current tilt-angle. DO NOT change the turtle's
+        heading (direction of movement).
+
+
+        Examples (for a Turtle instance named turtle):
+        >>> turtle.shape("circle")
+        >>> turtle.shapesize(5,2)
+        >>> turtle.settiltangle(45)
+        >>> stamp()
+        >>> turtle.fd(50)
+        >>> turtle.settiltangle(-45)
+        >>> stamp()
+        >>> turtle.fd(50)
+        """
+        tilt = -angle * self._degreesPerAU * self._angleOrient
+        tilt = (tilt * math.pi / 180.0) % (2*math.pi)
+        self.pen(resizemode="user", tilt=tilt)
+
+    def tiltangle(self):
+        """Return the current tilt-angle.
+
+        No argument.
+
+        Return the current tilt-angle, i. e. the angle between the
+        orientation of the turtleshape and the heading of the turtle
+        (it's direction of movement).
+
+        Examples (for a Turtle instance named turtle):
+        >>> turtle.shape("circle")
+        >>> turtle.shapesize(5,2)
+        >>> turtle.tilt(45)
+        >>> turtle.tiltangle()
+        >>>
+        """
+        tilt = -self._tilt * (180.0/math.pi) * self._angleOrient
+        return (tilt / self._degreesPerAU) % self._fullcircle
+
+    def tilt(self, angle):
+        """Rotate the turtleshape by angle.
+
+        Argument:
+        angle - a number
+
+        Rotate the turtleshape by angle from its current tilt-angle,
+        but do NOT change the turtle's heading (direction of movement).
+
+        Examples (for a Turtle instance named turtle):
+        >>> turtle.shape("circle")
+        >>> turtle.shapesize(5,2)
+        >>> turtle.tilt(30)
+        >>> turtle.fd(50)
+        >>> turtle.tilt(30)
+        >>> turtle.fd(50)
+        """
+        self.settiltangle(angle + self.tiltangle())
+
+    def _polytrafo(self, poly):
+        """Computes transformed polygon shapes from a shape
+        according to current position and heading.
+        """
+        screen = self.screen
+        p0, p1 = self._position
+        e0, e1 = self._orient
+        e = Vec2D(e0, e1 * screen.yscale / screen.xscale)
+        e0, e1 = (1.0 / abs(e)) * e
+        return [(p0+(e1*x+e0*y)/screen.xscale, p1+(-e0*x+e1*y)/screen.yscale)
+                                                           for (x, y) in poly]
+
+    def _drawturtle(self):
+        """Manages the correct rendering of the turtle with respect to
+        it's shape, resizemode, strech and tilt etc."""
+        screen = self.screen
+        shape = screen._shapes[self.turtle.shapeIndex]
+        ttype = shape._type
+        titem = self.turtle._item
+        if self._shown and screen._updatecounter == 0 and screen._tracing > 0:
+            self._hidden_from_screen = False
+            tshape = shape._data
+            if ttype == "polygon":
+                if self._resizemode == "noresize":
+                    w = 1
+                    shape = tshape
+                else:
+                    if self._resizemode == "auto":
+                        lx = ly = max(1, self._pensize/5.0)
+                        w = self._pensize
+                        tiltangle = 0
+                    elif self._resizemode == "user":
+                        lx, ly = self._stretchfactor
+                        w = self._outlinewidth
+                        tiltangle = self._tilt
+                    shape = [(lx*x, ly*y) for (x, y) in tshape]
+                    t0, t1 = math.sin(tiltangle), math.cos(tiltangle)
+                    shape = [(t1*x+t0*y, -t0*x+t1*y) for (x, y) in shape]
+                shape = self._polytrafo(shape)
+                fc, oc = self._fillcolor, self._pencolor
+                screen._drawpoly(titem, shape, fill=fc, outline=oc,
+                                                      width=w, top=True)
+            elif ttype == "image":
+                screen._drawimage(titem, self._position, tshape)
+            elif ttype == "compound":
+                lx, ly = self._stretchfactor
+                w = self._outlinewidth
+                for item, (poly, fc, oc) in zip(titem, tshape):
+                    poly = [(lx*x, ly*y) for (x, y) in poly]
+                    poly = self._polytrafo(poly)
+                    screen._drawpoly(item, poly, fill=self._cc(fc),
+                                     outline=self._cc(oc), width=w, top=True)
+        else:
+            if self._hidden_from_screen:
+                return
+            if ttype == "polygon":
+                screen._drawpoly(titem, ((0, 0), (0, 0), (0, 0)), "", "")
+            elif ttype == "image":
+                screen._drawimage(titem, self._position,
+                                          screen._shapes["blank"]._data)
+            elif ttype == "compound":
+                for item in titem:
+                    screen._drawpoly(item, ((0, 0), (0, 0), (0, 0)), "", "")
+            self._hidden_from_screen = True
+
+##############################  stamp stuff  ###############################
+
+    def stamp(self):
+        """Stamp a copy of the turtleshape onto the canvas and return it's id.
+
+        No argument.
+
+        Stamp a copy of the turtle shape onto the canvas at the current
+        turtle position. Return a stamp_id for that stamp, which can be
+        used to delete it by calling clearstamp(stamp_id).
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.color("blue")
+        >>> turtle.stamp()
+        13
+        >>> turtle.fd(50)
+        """
+        screen = self.screen
+        shape = screen._shapes[self.turtle.shapeIndex]
+        ttype = shape._type
+        tshape = shape._data
+        if ttype == "polygon":
+            stitem = screen._createpoly()
+            if self._resizemode == "noresize":
+                w = 1
+                shape = tshape
+            else:
+                if self._resizemode == "auto":
+                    lx = ly = max(1, self._pensize/5.0)
+                    w = self._pensize
+                    tiltangle = 0
+                elif self._resizemode == "user":
+                    lx, ly = self._stretchfactor
+                    w = self._outlinewidth
+                    tiltangle = self._tilt
+                shape = [(lx*x, ly*y) for (x, y) in tshape]
+                t0, t1 = math.sin(tiltangle), math.cos(tiltangle)
+                shape = [(t1*x+t0*y, -t0*x+t1*y) for (x, y) in shape]
+            shape = self._polytrafo(shape)
+            fc, oc = self._fillcolor, self._pencolor
+            screen._drawpoly(stitem, shape, fill=fc, outline=oc,
+                                                  width=w, top=True)
+        elif ttype == "image":
+            stitem = screen._createimage("")
+            screen._drawimage(stitem, self._position, tshape)
+        elif ttype == "compound":
+            stitem = []
+            for element in tshape:
+                item = screen._createpoly()
+                stitem.append(item)
+            stitem = tuple(stitem)
+            lx, ly = self._stretchfactor
+            w = self._outlinewidth
+            for item, (poly, fc, oc) in zip(stitem, tshape):
+                poly = [(lx*x, ly*y) for (x, y) in poly]
+                poly = self._polytrafo(poly)
+                screen._drawpoly(item, poly, fill=self._cc(fc),
+                                 outline=self._cc(oc), width=w, top=True)
+        self.stampItems.append(stitem)
+        self.undobuffer.push(("stamp", stitem))
+        return stitem
+
+    def _clearstamp(self, stampid):
+        """does the work for clearstamp() and clearstamps()
+        """
+        if stampid in self.stampItems:
+            if isinstance(stampid, tuple):
+                for subitem in stampid:
+                    self.screen._delete(subitem)
+            else:
+                self.screen._delete(stampid)
+            self.stampItems.remove(stampid)
+        # Delete stampitem from undobuffer if necessary
+        # if clearstamp is called directly.
+        item = ("stamp", stampid)
+        buf = self.undobuffer
+        if item not in buf.buffer:
+            return
+        index = buf.buffer.index(item)
+        buf.buffer.remove(item)
+        if index <= buf.ptr:
+            buf.ptr = (buf.ptr - 1) % buf.bufsize
+        buf.buffer.insert((buf.ptr+1)%buf.bufsize, [None])
+
+    def clearstamp(self, stampid):
+        """Delete stamp with given stampid
+
+        Argument:
+        stampid - an integer, must be return value of previous stamp() call.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.color("blue")
+        >>> astamp = turtle.stamp()
+        >>> turtle.fd(50)
+        >>> turtle.clearstamp(astamp)
+        """
+        self._clearstamp(stampid)
+        self._update()
+
+    def clearstamps(self, n=None):
+        """Delete all or first/last n of turtle's stamps.
+
+        Optional argument:
+        n -- an integer
+
+        If n is None, delete all of pen's stamps,
+        else if n > 0 delete first n stamps
+        else if n < 0 delete last n stamps.
+
+        Example (for a Turtle instance named turtle):
+        >>> for i in range(8):
+                turtle.stamp(); turtle.fd(30)
+        ...
+        >>> turtle.clearstamps(2)
+        >>> turtle.clearstamps(-2)
+        >>> turtle.clearstamps()
+        """
+        if n is None:
+            toDelete = self.stampItems[:]
+        elif n >= 0:
+            toDelete = self.stampItems[:n]
+        else:
+            toDelete = self.stampItems[n:]
+        for item in toDelete:
+            self._clearstamp(item)
+        self._update()
+
+    def _goto(self, end):
+        """Move the pen to the point end, thereby drawing a line
+        if pen is down. All other methodes for turtle movement depend
+        on this one.
+        """
+        ## Version mit undo-stuff
+        go_modes = ( self._drawing,
+                     self._pencolor,
+                     self._pensize,
+                     isinstance(self._fillpath, list))
+        screen = self.screen
+        undo_entry = ("go", self._position, end, go_modes,
+                      (self.currentLineItem,
+                      self.currentLine[:],
+                      screen._pointlist(self.currentLineItem),
+                      self.items[:])
+                      )
+        if self.undobuffer:
+            self.undobuffer.push(undo_entry)
+        start = self._position
+        if self._speed and screen._tracing == 1:
+            diff = (end-start)
+            diffsq = (diff[0]*screen.xscale)**2 + (diff[1]*screen.yscale)**2
+            nhops = 1+int((diffsq**0.5)/(3*(1.1**self._speed)*self._speed))
+            delta = diff * (1.0/nhops)
+            for n in range(1, nhops):
+                if n == 1:
+                    top = True
+                else:
+                    top = False
+                self._position = start + delta * n
+                if self._drawing:
+                    screen._drawline(self.drawingLineItem,
+                                     (start, self._position),
+                                     self._pencolor, self._pensize, top)
+                self._update()
+            if self._drawing:
+                screen._drawline(self.drawingLineItem, ((0, 0), (0, 0)),
+                                               fill="", width=self._pensize)
+        # Turtle now at end,
+        if self._drawing: # now update currentLine
+            self.currentLine.append(end)
+        if isinstance(self._fillpath, list):
+            self._fillpath.append(end)
+        ######    vererbung!!!!!!!!!!!!!!!!!!!!!!
+        self._position = end
+        if self._creatingPoly:
+            self._poly.append(end)
+        if len(self.currentLine) > 42: # 42! answer to the ultimate question
+                                       # of life, the universe and everything
+            self._newLine()
+        self._update() #count=True)
+
+    def _undogoto(self, entry):
+        """Reverse a _goto. Used for undo()
+        """
+        old, new, go_modes, coodata = entry
+        drawing, pc, ps, filling = go_modes
+        cLI, cL, pl, items = coodata
+        screen = self.screen
+        if abs(self._position - new) > 0.5:
+            print ("undogoto: HALLO-DA-STIMMT-WAS-NICHT!")
+        # restore former situation
+        self.currentLineItem = cLI
+        self.currentLine = cL
 
-        The turtle's heading does not change.
+        if pl == [(0, 0), (0, 0)]:
+            usepc = ""
+        else:
+            usepc = pc
+        screen._drawline(cLI, pl, fill=usepc, width=ps)
 
-        Example:
-        >>> turtle.position()
-        [0.0, 0.0]
-        >>> turtle.backward(30)
-        >>> turtle.position()
-        [-30.0, 0.0]
-        """
-        self.forward(-distance)
+        todelete = [i for i in self.items if (i not in items) and
+                                       (screen._type(i) == "line")]
+        for i in todelete:
+            screen._delete(i)
+            self.items.remove(i)
+
+        start = old
+        if self._speed and screen._tracing == 1:
+            diff = old - new
+            diffsq = (diff[0]*screen.xscale)**2 + (diff[1]*screen.yscale)**2
+            nhops = 1+int((diffsq**0.5)/(3*(1.1**self._speed)*self._speed))
+            delta = diff * (1.0/nhops)
+            for n in range(1, nhops):
+                if n == 1:
+                    top = True
+                else:
+                    top = False
+                self._position = new + delta * n
+                if drawing:
+                    screen._drawline(self.drawingLineItem,
+                                     (start, self._position),
+                                     pc, ps, top)
+                self._update()
+            if drawing:
+                screen._drawline(self.drawingLineItem, ((0, 0), (0, 0)),
+                                               fill="", width=ps)
+        # Turtle now at position old,
+        self._position = old
+        ##  if undo is done during crating a polygon, the last vertex
+        ##  will be deleted. if the polygon is entirel deleted,
+        ##  creatigPoly will be set to False.
+        ##  Polygons created before the last one will not be affected by undo()
+        if self._creatingPoly:
+            if len(self._poly) > 0:
+                self._poly.pop()
+            if self._poly == []:
+                self._creatingPoly = False
+                self._poly = None
+        if filling:
+            if self._fillpath == []:
+                self._fillpath = None
+                print("Unwahrscheinlich in _undogoto!")
+            elif self._fillpath is not None:
+                self._fillpath.pop()
+        self._update() #count=True)
+
+    def _rotate(self, angle):
+        """Turns pen clockwise by angle.
+        """
+        if self.undobuffer:
+            self.undobuffer.push(("rot", angle, self._degreesPerAU))
+        angle *= self._degreesPerAU
+        neworient = self._orient.rotate(angle)
+        tracing = self.screen._tracing
+        if tracing == 1 and self._speed > 0:
+            anglevel = 3.0 * self._speed
+            steps = 1 + int(abs(angle)/anglevel)
+            delta = 1.0*angle/steps
+            for _ in range(steps):
+                self._orient = self._orient.rotate(delta)
+                self._update()
+        self._orient = neworient
+        self._update()
+
+    def _newLine(self, usePos=True):
+        """Closes current line item and starts a new one.
+           Remark: if current line became too long, animation
+           performance (via _drawline) slowed down considerably.
+        """
+        if len(self.currentLine) > 1:
+            self.screen._drawline(self.currentLineItem, self.currentLine,
+                                      self._pencolor, self._pensize)
+            self.currentLineItem = self.screen._createline()
+            self.items.append(self.currentLineItem)
+        else:
+            self.screen._drawline(self.currentLineItem, top=True)
+        self.currentLine = []
+        if usePos:
+            self.currentLine = [self._position]
 
-    def left(self, angle):
-        """ Turn left angle units (units are by default degrees,
-        but can be set via the degrees() and radians() functions.)
+    def filling(self):
+        """Return fillstate (True if filling, False else).
 
-        When viewed from above, the turning happens in-place around
-        its front tip.
+        No argument.
 
-        Example:
-        >>> turtle.heading()
-        22
-        >>> turtle.left(45)
-        >>> turtle.heading()
-        67.0
+        Example (for a Turtle instance named turtle):
+        >>> turtle.begin_fill()
+        >>> if turtle.filling():
+                turtle.pensize(5)
+        else:
+                turtle.pensize(3)
         """
-        self._angle = (self._angle + angle) % self._fullcircle
-        self._draw_turtle()
+        return isinstance(self._fillpath, list)
 
-    def right(self, angle):
-        """ Turn right angle units (units are by default degrees,
-        but can be set via the degrees() and radians() functions.)
+##    def fill(self, flag=None):
+##        """Call fill(True) before drawing a shape to fill, fill(False) when done.
+##
+##        Optional argument:
+##        flag -- True/False (or 1/0 respectively)
+##
+##        Call fill(True) before drawing the shape you want to fill,
+##        and  fill(False) when done.
+##        When used without argument: return fillstate (True if filling,
+##        False else)
+##
+##        Example (for a Turtle instance named turtle):
+##        >>> turtle.fill(True)
+##        >>> turtle.forward(100)
+##        >>> turtle.left(90)
+##        >>> turtle.forward(100)
+##        >>> turtle.left(90)
+##        >>> turtle.forward(100)
+##        >>> turtle.left(90)
+##        >>> turtle.forward(100)
+##        >>> turtle.fill(False)
+##        """
+##        filling = isinstance(self._fillpath, list)
+##        if flag is None:
+##            return filling
+##        screen = self.screen
+##        entry1 = entry2 = ()
+##        if filling:
+##            if len(self._fillpath) > 2:
+##                self.screen._drawpoly(self._fillitem, self._fillpath,
+##                                      fill=self._fillcolor)
+##                entry1 = ("dofill", self._fillitem)
+##        if flag:
+##            self._fillitem = self.screen._createpoly()
+##            self.items.append(self._fillitem)
+##            self._fillpath = [self._position]
+##            entry2 = ("beginfill", self._fillitem) # , self._fillpath)
+##            self._newLine()
+##        else:
+##            self._fillitem = self._fillpath = None
+##        if self.undobuffer:
+##            if entry1 == ():
+##                if entry2 != ():
+##                    self.undobuffer.push(entry2)
+##            else:
+##                if entry2 == ():
+##                    self.undobuffer.push(entry1)
+##                else:
+##                    self.undobuffer.push(["seq", entry1, entry2])
+##        self._update()
 
-        When viewed from above, the turning happens in-place around
-        its front tip.
+    def begin_fill(self):
+        """Called just before drawing a shape to be filled.
 
-        Example:
-        >>> turtle.heading()
-        22
-        >>> turtle.right(45)
-        >>> turtle.heading()
-        337.0
+        No argument.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.color("black", "red")
+        >>> turtle.begin_fill()
+        >>> turtle.circle(60)
+        >>> turtle.end_fill()
         """
-        self.left(-angle)
+        if not self.filling():
+            self._fillitem = self.screen._createpoly()
+            self.items.append(self._fillitem)
+        self._fillpath = [self._position]
+        self._newLine()
+        if self.undobuffer:
+            self.undobuffer.push(("beginfill", self._fillitem))
+        self._update()
 
-    def up(self):
-        """ Pull the pen up -- no drawing when moving.
 
-        Example:
-        >>> turtle.up()
-        """
-        self._drawing = 0
+    def end_fill(self):
+        """Fill the shape drawn after the call begin_fill().
 
-    def down(self):
-        """ Put the pen down -- draw when moving.
+        No argument.
 
-        Example:
-        >>> turtle.down()
+        Example (for a Turtle instance named turtle):
+        >>> turtle.color("black", "red")
+        >>> turtle.begin_fill()
+        >>> turtle.circle(60)
+        >>> turtle.end_fill()
         """
-        self._drawing = 1
+        if self.filling():
+            if len(self._fillpath) > 2:
+                self.screen._drawpoly(self._fillitem, self._fillpath,
+                                      fill=self._fillcolor)
+                if self.undobuffer:
+                    self.undobuffer.push(("dofill", self._fillitem))
+            self._fillitem = self._fillpath = None
+            self._update()
+
+    def dot(self, size=None, *color):
+        """Draw a dot with diameter size, using color.
+
+        Optional argumentS:
+        size -- an integer >= 1 (if given)
+        color -- a colorstring or a numeric color tuple
+
+        Draw a circular dot with diameter size, using color.
+        If size is not given, the maximum of pensize+4 and 2*pensize is used.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.dot()
+        >>> turtle.fd(50); turtle.dot(20, "blue"); turtle.fd(50)
+        """
+        #print "dot-1:", size, color
+        if not color:
+            if isinstance(size, (str, tuple)):
+                color = self._colorstr(size)
+                size = self._pensize + max(self._pensize, 4)
+            else:
+                color = self._pencolor
+                if not size:
+                    size = self._pensize + max(self._pensize, 4)
+        else:
+            if size is None:
+                size = self._pensize + max(self._pensize, 4)
+            color = self._colorstr(color)
+        #print "dot-2:", size, color
+        if hasattr(self.screen, "_dot"):
+            item = self.screen._dot(self._position, size, color)
+            #print "dot:", size, color, "item:", item
+            self.items.append(item)
+            if self.undobuffer:
+                self.undobuffer.push(("dot", item))
+        else:
+            pen = self.pen()
+            if self.undobuffer:
+                self.undobuffer.push(["seq"])
+                self.undobuffer.cumulate = True
+            try:
+                if self.resizemode() == 'auto':
+                    self.ht()
+                self.pendown()
+                self.pensize(size)
+                self.pencolor(color)
+                self.forward(0)
+            finally:
+                self.pen(pen)
+            if self.undobuffer:
+                self.undobuffer.cumulate = False
+
+    def _write(self, txt, align, font):
+        """Performs the writing for write()
+        """
+        item, end = self.screen._write(self._position, txt, align, font,
+                                                          self._pencolor)
+        self.items.append(item)
+        if self.undobuffer:
+            self.undobuffer.push(("wri", item))
+        return end
+
+    def write(self, arg, move=False, align="left", font=("Arial", 8, "normal")):
+        """Write text at the current turtle position.
+
+        Arguments:
+        arg -- info, which is to be written to the TurtleScreen
+        move (optional) -- True/False
+        align (optional) -- one of the strings "left", "center" or right"
+        font (optional) -- a triple (fontname, fontsize, fonttype)
+
+        Write text - the string representation of arg - at the current
+        turtle position according to align ("left", "center" or right")
+        and with the given font.
+        If move is True, the pen is moved to the bottom-right corner
+        of the text. By default, move is False.
 
-    def width(self, width):
-        """ Set the line to thickness to width.
+        Example (for a Turtle instance named turtle):
+        >>> turtle.write('Home = ', True, align="center")
+        >>> turtle.write((0,0), True)
+        """
+        if self.undobuffer:
+            self.undobuffer.push(["seq"])
+            self.undobuffer.cumulate = True
+        end = self._write(str(arg), align.lower(), font)
+        if move:
+            x, y = self.pos()
+            self.setpos(end, y)
+        if self.undobuffer:
+            self.undobuffer.cumulate = False
 
-        Example:
-        >>> turtle.width(10)
-        """
-        self._width = float(width)
+    def begin_poly(self):
+        """Start recording the vertices of a polygon.
 
-    def color(self, *args):
-        """ Set the pen color.
+        No argument.
 
-        Three input formats are allowed:
+        Start recording the vertices of a polygon. Current turtle position
+        is first point of polygon.
 
-            color(s)
-            s is a Tk specification string, such as "red" or "yellow"
+        Example (for a Turtle instance named turtle):
+        >>> turtle.begin_poly()
+        """
+        self._poly = [self._position]
+        self._creatingPoly = True
 
-            color((r, g, b))
-            *a tuple* of r, g, and b, which represent, an RGB color,
-            and each of r, g, and b are in the range [0..1]
+    def end_poly(self):
+        """Stop recording the vertices of a polygon.
 
-            color(r, g, b)
-            r, g, and b represent an RGB color, and each of r, g, and b
-            are in the range [0..1]
+        No argument.
 
-        Example:
+        Stop recording the vertices of a polygon. Current turtle position is
+        last point of polygon. This will be connected with the first point.
 
-        >>> turtle.color('brown')
-        >>> tup = (0.2, 0.8, 0.55)
-        >>> turtle.color(tup)
-        >>> turtle.color(0, .5, 0)
+        Example (for a Turtle instance named turtle):
+        >>> turtle.end_poly()
         """
-        if not args:
-            raise Error("no color arguments")
-        if len(args) == 1:
-            color = args[0]
-            if type(color) == type(""):
-                # Test the color first
-                try:
-                    id = self._canvas.create_line(0, 0, 0, 0, fill=color)
-                except tkinter.TclError:
-                    raise Error("bad color string: %r" % (color,))
-                self._set_color(color)
-                return
-            try:
-                r, g, b = color
-            except:
-                raise Error("bad color sequence: %r" % (color,))
-        else:
-            try:
-                r, g, b = args
-            except:
-                raise Error("bad color arguments: %r" % (args,))
-        assert 0 <= r <= 1
-        assert 0 <= g <= 1
-        assert 0 <= b <= 1
-        x = 255.0
-        y = 0.5
-        self._set_color("#%02x%02x%02x" % (int(r*x+y), int(g*x+y), int(b*x+y)))
-
-    def _set_color(self,color):
-        self._color = color
-        self._draw_turtle()
+        self._creatingPoly = False
 
-    def write(self, text, move=False):
-        """ Write text at the current pen position.
+    def get_poly(self):
+        """Return the lastly recorded polygon.
 
-        If move is true, the pen is moved to the bottom-right corner
-        of the text. By default, move is False.
+        No argument.
 
-        Example:
-        >>> turtle.write('The race is on!')
-        >>> turtle.write('Home = (0, 0)', True)
+        Example (for a Turtle instance named turtle):
+        >>> p = turtle.get_poly()
+        >>> turtle.register_shape("myFavouriteShape", p)
         """
-        x, y  = self._position
-        x = x-1 # correction -- calibrated for Windows
-        item = self._canvas.create_text(x, y,
-                                        text=str(text), anchor="sw",
-                                        fill=self._color)
-        self._items.append(item)
-        if move:
-            x0, y0, x1, y1 = self._canvas.bbox(item)
-            self._goto(x1, y1)
-        self._draw_turtle()
-
-    def fill(self, flag):
-        """ Call fill(1) before drawing the shape you
-         want to fill, and fill(0) when done.
+        ## check if there is any poly?  -- 1st solution:
+        if self._poly is not None:
+            return tuple(self._poly)
 
-        Example:
-        >>> turtle.fill(1)
-        >>> turtle.forward(100)
-        >>> turtle.left(90)
-        >>> turtle.forward(100)
-        >>> turtle.left(90)
-        >>> turtle.forward(100)
-        >>> turtle.left(90)
-        >>> turtle.forward(100)
-        >>> turtle.fill(0)
-        """
-        if self._filling:
-            path = tuple(self._path)
-            smooth = self._filling < 0
-            if len(path) > 2:
-                item = self._canvas._create('polygon', path,
-                                            {'fill': self._color,
-                                             'smooth': smooth})
-                self._items.append(item)
-        self._path = []
-        self._filling = flag
-        if flag:
-            self._path.append(self._position)
+    def getscreen(self):
+        """Return the TurtleScreen object, the turtle is drawing  on.
 
-    def begin_fill(self):
-        """ Called just before drawing a shape to be filled.
-            Must eventually be followed by a corresponding end_fill() call.
-            Otherwise it will be ignored.
+        No argument.
 
-        Example:
-        >>> turtle.begin_fill()
-        >>> turtle.forward(100)
-        >>> turtle.left(90)
-        >>> turtle.forward(100)
-        >>> turtle.left(90)
-        >>> turtle.forward(100)
-        >>> turtle.left(90)
-        >>> turtle.forward(100)
-        >>> turtle.end_fill()
+        Return the TurtleScreen object, the turtle is drawing  on.
+        So TurtleScreen-methods can be called for that object.
+
+        Example (for a Turtle instance named turtle):
+        >>> ts = turtle.getscreen()
+        >>> ts
+        <turtle.TurtleScreen object at 0x0106B770>
+        >>> ts.bgcolor("pink")
         """
-        self._path = [self._position]
-        self._filling = 1
+        return self.screen
 
-    def end_fill(self):
-        """ Called after drawing a shape to be filled.
+    def getturtle(self):
+        """Return the Turtleobject itself.
+
+        No argument.
+
+        Only reasonable use: as a function to return the 'anonymous turtle':
 
         Example:
-        >>> turtle.begin_fill()
-        >>> turtle.forward(100)
-        >>> turtle.left(90)
-        >>> turtle.forward(100)
-        >>> turtle.left(90)
-        >>> turtle.forward(100)
-        >>> turtle.left(90)
-        >>> turtle.forward(100)
-        >>> turtle.end_fill()
+        >>> pet = getturtle()
+        >>> pet.fd(50)
+        >>> pet
+        <turtle.Turtle object at 0x0187D810>
+        >>> turtles()
+        [<turtle.Turtle object at 0x0187D810>]
         """
-        self.fill(0)
+        return self
 
-    def circle(self, radius, extent = None):
-        """ Draw a circle with given radius.
-        The center is radius units left of the turtle; extent
-        determines which part of the circle is drawn. If not given,
-        the entire circle is drawn.
+    getpen = getturtle
 
-        If extent is not a full circle, one endpoint of the arc is the
-        current pen position. The arc is drawn in a counter clockwise
-        direction if radius is positive, otherwise in a clockwise
-        direction. In the process, the direction of the turtle is
-        changed by the amount of the extent.
 
-        >>> turtle.circle(50)
-        >>> turtle.circle(120, 180)  # half a circle
-        """
-        if extent is None:
-            extent = self._fullcircle
-        frac = abs(extent)/self._fullcircle
-        steps = 1+int(min(11+abs(radius)/6.0, 59.0)*frac)
-        w = 1.0 * extent / steps
-        w2 = 0.5 * w
-        l = 2.0 * radius * sin(w2*self._invradian)
-        if radius < 0:
-            l, w, w2 = -l, -w, -w2
-        self.left(w2)
-        for i in range(steps):
-            self.forward(l)
-            self.left(w)
-        self.right(w2)
+    ################################################################
+    ### screen oriented methods recurring to methods of TurtleScreen
+    ################################################################
 
-    def heading(self):
-        """ Return the turtle's current heading.
+##    def window_width(self):
+##        """ Returns the width of the turtle window.
+##
+##        No argument.
+##
+##        Example (for a TurtleScreen instance named screen):
+##        >>> screen.window_width()
+##        640
+##        """
+##        return self.screen._window_size()[0]
+##
+##    def window_height(self):
+##        """ Return the height of the turtle window.
+##
+##        No argument.
+##
+##        Example (for a TurtleScreen instance named screen):
+##        >>> screen.window_height()
+##        480
+##        """
+##        return self.screen._window_size()[1]
 
-        Example:
-        >>> turtle.heading()
-        67.0
+    def _delay(self, delay=None):
+        """Set delay value which determines speed of turtle animation.
         """
-        return self._angle
+        return self.screen.delay(delay)
 
-    def setheading(self, angle):
-        """ Set the turtle facing the given angle.
+    #####   event binding methods   #####
 
-        Here are some common directions in degrees:
+    def onclick(self, fun, btn=1, add=None):
+        """Bind fun to mouse-click event on this turtle on canvas.
 
-           0 - east
-          90 - north
-         180 - west
-         270 - south
+        Arguments:
+        fun --  a function with two arguments, to which will be assigned
+                the coordinates of the clicked point on the canvas.
+        num --  number of the mouse-button defaults to 1 (left mouse button).
+        add --  True or False. If True, new binding will be added, otherwise
+                it will replace a former binding.
 
-        Example:
-        >>> turtle.setheading(90)
-        >>> turtle.heading()
-        90
-        >>> turtle.setheading(128)
-        >>> turtle.heading()
-        128
-        """
-        self._angle = angle
-        self._draw_turtle()
+        Example for the anonymous turtle, i. e. the procedural way:
 
-    def window_width(self):
-        """ Returns the width of the turtle window.
+        >>> def turn(x, y):
+                left(360)
 
-        Example:
-        >>> turtle.window_width()
-        640
+        >>> onclick(turn) # Now clicking into the turtle will turn it.
+        >>> onclick(None)  # event-binding will be removed
         """
-        width = self._canvas.winfo_width()
-        if width <= 1:  # the window isn't managed by a geometry manager
-            width = self._canvas['width']
-        return width
+        self.screen._onclick(self.turtle._item, fun, btn, add)
+        self._update()
 
-    def window_height(self):
-        """ Return the height of the turtle window.
+    def onrelease(self, fun, btn=1, add=None):
+        """Bind fun to mouse-button-release event on this turtle on canvas.
 
-        Example:
-        >>> turtle.window_height()
-        768
-        """
-        height = self._canvas.winfo_height()
-        if height <= 1: # the window isn't managed by a geometry manager
-            height = self._canvas['height']
-        return height
+        Arguments:
+        fun -- a function with two arguments, to which will be assigned
+                the coordinates of the clicked point on the canvas.
+        num --  number of the mouse-button defaults to 1 (left mouse button).
 
-    def position(self):
-        """ Return the current (x, y) location of the turtle.
+        Example (for a MyTurtle instance named joe):
+        >>> class MyTurtle(Turtle):
+                def glow(self,x,y):
+                        self.fillcolor("red")
+                def unglow(self,x,y):
+                        self.fillcolor("")
 
-        Example:
-        >>> turtle.position()
-        [0.0, 240.0]
+        >>> joe = MyTurtle()
+        >>> joe.onclick(joe.glow)
+        >>> joe.onrelease(joe.unglow)
+        ### clicking on joe turns fillcolor red,
+        ### unclicking turns it to transparent.
         """
-        x0, y0 = self._origin
-        x1, y1 = self._position
-        return [x1-x0, -y1+y0]
+        self.screen._onrelease(self.turtle._item, fun, btn, add)
+        self._update()
 
-    def setx(self, xpos):
-        """ Set the turtle's x coordinate to be xpos.
+    def ondrag(self, fun, btn=1, add=None):
+        """Bind fun to mouse-move event on this turtle on canvas.
 
-        Example:
-        >>> turtle.position()
-        [10.0, 240.0]
-        >>> turtle.setx(10)
-        >>> turtle.position()
-        [10.0, 240.0]
-        """
-        x0, y0 = self._origin
-        x1, y1 = self._position
-        self._goto(x0+xpos, y1)
+        Arguments:
+        fun -- a function with two arguments, to which will be assigned
+               the coordinates of the clicked point on the canvas.
+        num -- number of the mouse-button defaults to 1 (left mouse button).
 
-    def sety(self, ypos):
-        """ Set the turtle's y coordinate to be ypos.
+        Every sequence of mouse-move-events on a turtle is preceded by a
+        mouse-click event on that turtle.
 
-        Example:
-        >>> turtle.position()
-        [0.0, 0.0]
-        >>> turtle.sety(-22)
-        >>> turtle.position()
-        [0.0, -22.0]
+        Example (for a Turtle instance named turtle):
+        >>> turtle.ondrag(turtle.goto)
+
+        ### Subsequently clicking and dragging a Turtle will
+        ### move it across the screen thereby producing handdrawings
+        ### (if pen is down).
         """
-        x0, y0 = self._origin
-        x1, y1 = self._position
-        self._goto(x1, y0-ypos)
+        self.screen._ondrag(self.turtle._item, fun, btn, add)
 
-    def towards(self, *args):
-        """Returs the angle, which corresponds to the line
-        from turtle-position to point (x,y).
 
-        Argument can be two coordinates or one pair of coordinates
-        or a RawPen/Pen instance.
+    def _undo(self, action, data):
+        """Does the main part of the work for undo()
+        """
+        if self.undobuffer is None:
+            return
+        if action == "rot":
+            angle, degPAU = data
+            self._rotate(-angle*degPAU/self._degreesPerAU)
+            dummy = self.undobuffer.pop()
+        elif action == "stamp":
+            stitem = data[0]
+            self.clearstamp(stitem)
+        elif action == "go":
+            self._undogoto(data)
+        elif action in ["wri", "dot"]:
+            item = data[0]
+            self.screen._delete(item)
+            self.items.remove(item)
+        elif action == "dofill":
+            item = data[0]
+            self.screen._drawpoly(item, ((0, 0),(0, 0),(0, 0)),
+                                  fill="", outline="")
+        elif action == "beginfill":
+            item = data[0]
+            self._fillitem = self._fillpath = None
+            if item in self.items:
+                self.screen._delete(item)
+                self.items.remove(item)
+        elif action == "pen":
+            TPen.pen(self, data[0])
+            self.undobuffer.pop()
+
+    def undo(self):
+        """undo (repeatedly) the last turtle action.
+
+        No argument.
+
+        undo (repeatedly) the last turtle action.
+        Number of available undo actions is determined by the size of
+        the undobuffer.
+
+        Example (for a Turtle instance named turtle):
+        >>> for i in range(4):
+                turtle.fd(50); turtle.lt(80)
 
-        Example:
-        >>> turtle.position()
-        [10.0, 10.0]
-        >>> turtle.towards(0,0)
-        225.0
+        >>> for i in range(8):
+                turtle.undo()
         """
-        if len(args) == 2:
-            x, y = args
+        if self.undobuffer is None:
+            return
+        item = self.undobuffer.pop()
+        action = item[0]
+        data = item[1:]
+        if action == "seq":
+            while data:
+                item = data.pop()
+                self._undo(item[0], item[1:])
         else:
-            arg = args[0]
-            if isinstance(arg, RawPen):
-                x, y = arg.position()
-            else:
-                x, y = arg
-        x0, y0 = self.position()
-        dx = x - x0
-        dy = y - y0
-        return (atan2(dy,dx) / self._invradian) % self._fullcircle
+            self._undo(action, data)
 
-    def goto(self, *args):
-        """ Go to the given point.
+    turtlesize = shapesize
 
-        If the pen is down, then a line will be drawn. The turtle's
-        orientation does not change.
+RawPen = RawTurtle
 
-        Two input formats are accepted:
+###  Screen - Klasse  ########################
 
-           goto(x, y)
-           go to point (x, y)
+class Screen(TurtleScreen):
 
-           goto((x, y))
-           go to point (x, y)
+    _root = None
+    _canvas = None
+    _title = _CFG["title"]
 
-        Example:
-        >>> turtle.position()
-        [0.0, 0.0]
-        >>> turtle.goto(50, -45)
-        >>> turtle.position()
-        [50.0, -45.0]
+    # Borg-Idiom
+
+    _shared_state = {}
+
+    def __new__(cls, *args, **kwargs):
+        obj = object.__new__(cls, *args, **kwargs)
+        obj.__dict__ = cls._shared_state
+        return obj
+
+    def __init__(self):
+        if Screen._root is None:
+            Screen._root = self._root = _Root()
+            self._root.title(Screen._title)
+            self._root.ondestroy(self._destroy)
+        if Screen._canvas is None:
+            width = _CFG["width"]
+            height = _CFG["height"]
+            canvwidth = _CFG["canvwidth"]
+            canvheight = _CFG["canvheight"]
+            leftright = _CFG["leftright"]
+            topbottom = _CFG["topbottom"]
+            self._root.setupcanvas(width, height, canvwidth, canvheight)
+            Screen._canvas = self._root._getcanvas()
+            self.setup(width, height, leftright, topbottom)
+            TurtleScreen.__init__(self, Screen._canvas)
+        Turtle._screen = self
+
+    def setup(self, width=_CFG["width"], height=_CFG["height"],
+              startx=_CFG["leftright"], starty=_CFG["topbottom"]):
+        """ Set the size and position of the main window.
+
+        Arguments:
+        width: as integer a size in pixels, as float a fraction of the screen.
+          Default is 50% of screen.
+        height: as integer the height in pixels, as float a fraction of the
+          screen. Default is 75% of screen.
+        startx: if positive, starting position in pixels from the left
+          edge of the screen, if negative from the right edge
+          Default, startx=None is to center window horizontally.
+        starty: if positive, starting position in pixels from the top
+          edge of the screen, if negative from the bottom edge
+          Default, starty=None is to center window vertically.
+
+        Examples (for a Screen instance named screen):
+        >>> screen.setup (width=200, height=200, startx=0, starty=0)
+
+        sets window to 200x200 pixels, in upper left of screen
+
+        >>> screen.setup(width=.75, height=0.5, startx=None, starty=None)
+
+        sets window to 75% of screen by 50% of screen and centers
         """
-        if len(args) == 1:
-            try:
-                x, y = args[0]
-            except:
-                raise Error("bad point argument: %r" % (args[0],))
-        else:
-            try:
-                x, y = args
-            except:
-                raise Error("bad coordinates: %r" % (args[0],))
-        x0, y0 = self._origin
-        self._goto(x0+x, y0-y)
-
-    def _goto(self, x1, y1):
-        x0, y0 = self._position
-        self._position = (float(x1), float(y1))
-        if self._filling:
-            self._path.append(self._position)
-        if self._drawing:
-            if self._tracing:
-                dx = float(x1 - x0)
-                dy = float(y1 - y0)
-                distance = hypot(dx, dy)
-                nhops = int(distance)
-                item = self._canvas.create_line(x0, y0, x0, y0,
-                                                width=self._width,
-                                                capstyle="round",
-                                                fill=self._color)
-                try:
-                    for i in range(1, 1+nhops):
-                        x, y = x0 + dx*i/nhops, y0 + dy*i/nhops
-                        self._canvas.coords(item, x0, y0, x, y)
-                        self._draw_turtle((x,y))
-                        self._canvas.update()
-                        self._canvas.after(self._delay)
-                    # in case nhops==0
-                    self._canvas.coords(item, x0, y0, x1, y1)
-                    self._canvas.itemconfigure(item, arrow="none")
-                except tkinter.TclError:
-                    # Probably the window was closed!
-                    return
-            else:
-                item = self._canvas.create_line(x0, y0, x1, y1,
-                                                width=self._width,
-                                                capstyle="round",
-                                                fill=self._color)
-            self._items.append(item)
-        self._draw_turtle()
-
-    def speed(self, speed):
-        """ Set the turtle's speed.
-
-        speed must one of these five strings:
-
-            'fastest' is a 0 ms delay
-            'fast' is a 5 ms delay
-            'normal' is a 10 ms delay
-            'slow' is a 15 ms delay
-            'slowest' is a 20 ms delay
+        if not hasattr(self._root, "set_geometry"):
+            return
+        sw = self._root.win_width()
+        sh = self._root.win_height()
+        if isinstance(width, float) and 0 <= width <= 1:
+            width = sw*width
+        if startx is None:
+            startx = (sw - width) / 2
+        if isinstance(height, float) and 0 <= height <= 1:
+            height = sh*height
+        if starty is None:
+            starty = (sh - height) / 2
+        self._root.set_geometry(width, height, startx, starty)
+
+    def title(self, titlestring):
+        """Set title of turtle-window
+
+        Argument:
+        titlestring -- a string, to appear in the titlebar of the
+                       turtle graphics window.
+
+        This is a method of Screen-class. Not available for TurtleScreen-
+        objects.
+
+        Example (for a Screen instance named screen):
+        >>> screen.title("Welcome to the turtle-zoo!")
+        """
+        if Screen._root is not None:
+            Screen._root.title(titlestring)
+        Screen._title = titlestring
+
+    def _destroy(self):
+        root = self._root
+        if root is Screen._root:
+            Turtle._pen = None
+            Turtle._screen = None
+            Screen._root = None
+            Screen._canvas = None
+        TurtleScreen._RUNNING = True
+        root.destroy()
+
+    def bye(self):
+        """Shut the turtlegraphics window.
 
-         Example:
-         >>> turtle.speed('slow')
+        Example (for a TurtleScreen instance named screen):
+        >>> screen.bye()
         """
-        try:
-            speed = speed.strip().lower()
-            self._delay = speeds.index(speed) * 5
-        except:
-            raise ValueError("%r is not a valid speed. speed must be "
-                             "one of %s" % (speed, speeds))
+        self._destroy()
 
+    def exitonclick(self):
+        """Go into mainloop until the mouse is clicked.
 
-    def delay(self, delay):
-        """ Set the drawing delay in milliseconds.
+        No arguments.
 
-        This is intended to allow finer control of the drawing speed
-        than the speed() method
+        Bind bye() method to mouseclick on TurtleScreen.
+        If "using_IDLE" - value in configuration dictionary is False
+        (default value), enter mainloop.
+        If IDLE with -n switch (no subprocess) is used, this value should be
+        set to True in turtle.cfg. In this case IDLE's mainloop
+        is active also for the client script.
+
+        This is a method of the Screen-class and not available for
+        TurtleScreen instances.
+
+        Example (for a Screen instance named screen):
+        >>> screen.exitonclick()
 
-        Example:
-        >>> turtle.delay(15)
         """
-        if int(delay) < 0:
-            raise ValueError("delay must be greater than or equal to 0")
-        self._delay = int(delay)
-
-    def _draw_turtle(self, position=[]):
-        if not self._tracing:
-            self._canvas.update()
-            return
-        if position == []:
-            position = self._position
-        x,y = position
-        distance = 8
-        dx = distance * cos(self._angle*self._invradian)
-        dy = distance * sin(self._angle*self._invradian)
-        self._delete_turtle()
-        self._arrow = self._canvas.create_line(x-dx,y+dy,x,y,
-                                          width=self._width,
-                                          arrow="last",
-                                          capstyle="round",
-                                          fill=self._color)
-        self._canvas.update()
-
-    def _delete_turtle(self):
-        if self._arrow != 0:
-            self._canvas.delete(self._arrow)
-            self._arrow = 0
-
-
-_root = None
-_canvas = None
-_pen = None
-_width = 0.50                  # 50% of window width
-_height = 0.75                 # 75% of window height
-_startx = None
-_starty = None
-_title = "Turtle Graphics"     # default title
+        def exitGracefully(x, y):
+            """Screen.bye() with two dummy-parameters"""
+            self.bye()
+        self.onclick(exitGracefully)
+        if _CFG["using_IDLE"]:
+            return
+        try:
+            mainloop()
+        except AttributeError:
+            exit(0)
 
-class Pen(RawPen):
 
-    def __init__(self):
-        global _root, _canvas
-        if _root is None:
-            _root = tkinter.Tk()
-            _root.wm_protocol("WM_DELETE_WINDOW", self._destroy)
-            _root.title(_title)
-
-        if _canvas is None:
-            # XXX Should have scroll bars
-            _canvas = tkinter.Canvas(_root, background="white")
-            _canvas.pack(expand=1, fill="both")
+class Turtle(RawTurtle):
+    """RawTurtle auto-crating (scrolled) canvas.
 
-            setup(width=_width, height= _height, startx=_startx, starty=_starty)
+    When a Turtle object is created or a function derived from some
+    Turtle method is called a TurtleScreen object is automatically created.
+    """
+    _pen = None
+    _screen = None
 
-        RawPen.__init__(self, _canvas)
+    def __init__(self,
+                 shape=_CFG["shape"],
+                 undobuffersize=_CFG["undobuffersize"],
+                 visible=_CFG["visible"]):
+        if Turtle._screen is None:
+            Turtle._screen = Screen()
+        RawTurtle.__init__(self, Turtle._screen,
+                           shape=shape,
+                           undobuffersize=undobuffersize,
+                           visible=visible)
 
-    def _destroy(self):
-        global _root, _canvas, _pen
-        root = self._canvas._root()
-        if root is _root:
-            _pen = None
-            _root = None
-            _canvas = None
-        root.destroy()
+Pen = Turtle
 
 def _getpen():
-    global _pen
-    if not _pen:
-        _pen = Pen()
-    return _pen
+    """Create the 'anonymous' turtle if not already present."""
+    if Turtle._pen is None:
+        Turtle._pen = Turtle()
+    return Turtle._pen
+
+def _getscreen():
+    """Create a TurtleScreen if not already present."""
+    if Turtle._screen is None:
+        Turtle._screen = Screen()
+    return Turtle._screen
+
+def write_docstringdict(filename="turtle_docstringdict"):
+    """Create and write docstring-dictionary to file.
+
+    Optional argument:
+    filename -- a string, used as filename
+                default value is turtle_docstringdict
+
+    Has to be called explicitely, (not used by the turtle-graphics classes)
+    The docstring dictionary will be written to the Python script <filname>.py
+    It is intended to serve as a template for translation of the docstrings
+    into different languages.
+    """
+    docsdict = {}
 
-class Turtle(Pen):
-    pass
+    for methodname in _tg_screen_functions:
+        key = "Screen."+methodname
+        docsdict[key] = eval(key).__doc__
+    for methodname in _tg_turtle_functions:
+        key = "Turtle."+methodname
+        docsdict[key] = eval(key).__doc__
+
+    f = open("%s.py" % filename,"w")
+    keys = sorted([x for x in docsdict.keys()
+                        if x.split('.')[1] not in _alias_list])
+    f.write('docsdict = {\n\n')
+    for key in keys[:-1]:
+        f.write('%s :\n' % repr(key))
+        f.write('        """%s\n""",\n\n' % docsdict[key])
+    key = keys[-1]
+    f.write('%s :\n' % repr(key))
+    f.write('        """%s\n"""\n\n' % docsdict[key])
+    f.write("}\n")
+    f.close()
+
+def read_docstrings(lang):
+    """Read in docstrings from lang-specific docstring dictionary.
+
+    Transfer docstrings, translated to lang, from a dictionary-file
+    to the methods of classes Screen and Turtle and - in revised form -
+    to the corresponding functions.
+    """
+    modname = "turtle_docstringdict_%(language)s" % {'language':lang.lower()}
+    module = __import__(modname)
+    docsdict = module.docsdict
+    for key in docsdict:
+        try:
+#            eval(key).im_func.__doc__ = docsdict[key]
+            eval(key).__doc__ = docsdict[key]
+        except:
+            print("Bad docstring-entry: %s" % key)
 
-"""For documentation of the following functions see
-   the RawPen methods with the same names
-"""
+_LANGUAGE = _CFG["language"]
 
-def degrees(): _getpen().degrees()
-def radians(): _getpen().radians()
-def reset(): _getpen().reset()
-def clear(): _getpen().clear()
-def tracer(flag): _getpen().tracer(flag)
-def forward(distance): _getpen().forward(distance)
-def backward(distance): _getpen().backward(distance)
-def left(angle): _getpen().left(angle)
-def right(angle): _getpen().right(angle)
-def up(): _getpen().up()
-def down(): _getpen().down()
-def width(width): _getpen().width(width)
-def color(*args): _getpen().color(*args)
-def write(arg, move=0): _getpen().write(arg, move)
-def fill(flag): _getpen().fill(flag)
-def begin_fill(): _getpen().begin_fill()
-def end_fill(): _getpen().end_fill()
-def circle(radius, extent=None): _getpen().circle(radius, extent)
-def goto(*args): _getpen().goto(*args)
-def heading(): return _getpen().heading()
-def setheading(angle): _getpen().setheading(angle)
-def position(): return _getpen().position()
-def window_width(): return _getpen().window_width()
-def window_height(): return _getpen().window_height()
-def setx(xpos): _getpen().setx(xpos)
-def sety(ypos): _getpen().sety(ypos)
-def towards(*args): return _getpen().towards(*args)
-
-def done(): _root.mainloop()
-def delay(delay): return _getpen().delay(delay)
-def speed(speed): return _getpen().speed(speed)
-
-for methodname in dir(RawPen):
-    """ copies RawPen docstrings to module functions of same name """
-    if not methodname.startswith("_"):
-        eval(methodname).__doc__ = RawPen.__dict__[methodname].__doc__
-
-
-def setup(**geometry):
-    """ Sets the size and position of the main window.
-
-    Keywords are width, height, startx and starty:
-
-    width: either a size in pixels or a fraction of the screen.
-      Default is 50% of screen.
-    height: either the height in pixels or a fraction of the screen.
-      Default is 75% of screen.
-
-    Setting either width or height to None before drawing will force
-      use of default geometry as in older versions of turtle.py
-
-    startx: starting position in pixels from the left edge of the screen.
-      Default is to center window. Setting startx to None is the default
-      and centers window horizontally on screen.
-
-    starty: starting position in pixels from the top edge of the screen.
-      Default is to center window. Setting starty to None is the default
-      and centers window vertically on screen.
-
-    Examples:
-    >>> setup (width=200, height=200, startx=0, starty=0)
-
-    sets window to 200x200 pixels, in upper left of screen
-
-    >>> setup(width=.75, height=0.5, startx=None, starty=None)
-
-    sets window to 75% of screen by 50% of screen and centers
-
-    >>> setup(width=None)
-
-    forces use of default geometry as in older versions of turtle.py
-    """
-
-    global _width, _height, _startx, _starty
-
-    width = geometry.get('width',_width)
-    if width >= 0 or width is None:
-        _width = width
-    else:
-        raise ValueError("width can not be less than 0")
-
-    height = geometry.get('height',_height)
-    if height >= 0 or height is None:
-        _height = height
-    else:
-        raise ValueError("height can not be less than 0")
-
-    startx = geometry.get('startx', _startx)
-    if startx >= 0 or startx is None:
-        _startx = _startx
-    else:
-        raise ValueError("startx can not be less than 0")
-
-    starty = geometry.get('starty', _starty)
-    if starty >= 0 or starty is None:
-        _starty = starty
-    else:
-        raise ValueError("startx can not be less than 0")
-
-
-    if _root and _width and _height:
-        if 0 < _width <= 1:
-            _width = _root.winfo_screenwidth() * +width
-        if 0 < _height <= 1:
-            _height = _root.winfo_screenheight() * _height
-
-        # center window on screen
-        if _startx is None:
-            _startx = (_root.winfo_screenwidth() - _width) / 2
-
-        if _starty is None:
-            _starty = (_root.winfo_screenheight() - _height) / 2
-
-        _root.geometry("%dx%d+%d+%d" % (_width, _height, _startx, _starty))
-
-def title(title):
-    """Set the window title.
-
-    By default this is set to 'Turtle Graphics'
-
-    Example:
-    >>> title("My Window")
-    """
-
-    global _title
-    _title = title
-
-def demo():
-    reset()
-    tracer(1)
-    up()
-    backward(100)
-    down()
-    # draw 3 squares; the last filled
-    width(3)
-    for i in range(3):
-        if i == 2:
-            fill(1)
-        for j in range(4):
-            forward(20)
-            left(90)
-        if i == 2:
-            color("maroon")
-            fill(0)
+try:
+    if _LANGUAGE != "english":
+        read_docstrings(_LANGUAGE)
+except ImportError:
+    print("Cannot find docsdict for", _LANGUAGE)
+except:
+    print ("Unknown Error when trying to import %s-docstring-dictionary" %
+                                                                  _LANGUAGE)
+
+
+def getmethparlist(ob):
+    "Get strings describing the arguments for the given object"
+    argText1 = argText2 = ""
+    # bit of a hack for methods - turn it into a function
+    # but we drop the "self" param.
+##    if type(ob)==types.MethodType:
+##       fob = ob.im_func
+##        argOffset = 1
+##    else:
+##        fob = ob
+##        argOffset = 0
+    # Try and build one for Python defined functions
+    argOffset = 1
+##    if type(fob) in [types.FunctionType, types.LambdaType]:
+##        try:
+    counter = ob.__code__.co_argcount
+    items2 = list(ob.__code__.co_varnames[argOffset:counter])
+    realArgs = ob.__code__.co_varnames[argOffset:counter]
+    defaults = ob.__defaults__ or []
+    defaults = list(map(lambda name: "=%s" % repr(name), defaults))
+    defaults = [""] * (len(realArgs)-len(defaults)) + defaults
+    items1 = list(map(lambda arg, dflt: arg+dflt, realArgs, defaults))
+    if ob.__code__.co_flags & 0x4:
+        items1.append("*"+ob.__code__.co_varnames[counter])
+        items2.append("*"+ob.__code__.co_varnames[counter])
+        counter += 1
+    if ob.__code__.co_flags & 0x8:
+        items1.append("**"+ob.__code__.co_varnames[counter])
+        items2.append("**"+ob.__code__.co_varnames[counter])
+    argText1 = ", ".join(items1)
+    argText1 = "(%s)" % argText1
+    argText2 = ", ".join(items2)
+    argText2 = "(%s)" % argText2
+##        except:
+##            pass
+    return argText1, argText2
+
+def _turtle_docrevise(docstr):
+    """To reduce docstrings from RawTurtle class for functions
+    """
+    import re
+    if docstr is None:
+        return None
+    turtlename = _CFG["exampleturtle"]
+    newdocstr = docstr.replace("%s." % turtlename,"")
+    parexp = re.compile(r' \(.+ %s\):' % turtlename)
+    newdocstr = parexp.sub(":", newdocstr)
+    return newdocstr
+
+def _screen_docrevise(docstr):
+    """To reduce docstrings from TurtleScreen class for functions
+    """
+    import re
+    if docstr is None:
+        return None
+    screenname = _CFG["examplescreen"]
+    newdocstr = docstr.replace("%s." % screenname,"")
+    parexp = re.compile(r' \(.+ %s\):' % screenname)
+    newdocstr = parexp.sub(":", newdocstr)
+    return newdocstr
+
+## The following mechanism makes all methods of RawTurtle and Turtle available
+## as functions. So we can enhance, change, add, delete methods to these
+## classes and do not need to change anything here.
+
+
+for methodname in _tg_screen_functions:
+    pl1, pl2 = getmethparlist(eval('Screen.' + methodname))
+    if pl1 == "":
+        print(">>>>>>", pl1, pl2)
+        continue
+    defstr = ("def %(key)s%(pl1)s: return _getscreen().%(key)s%(pl2)s" %
+                                   {'key':methodname, 'pl1':pl1, 'pl2':pl2})
+##    print("Screen:", defstr)
+    exec(defstr)
+    eval(methodname).__doc__ = _screen_docrevise(eval('Screen.'+methodname).__doc__)
+
+for methodname in _tg_turtle_functions:
+    pl1, pl2 = getmethparlist(eval('Turtle.' + methodname))
+    if pl1 == "":
+        print(">>>>>>", pl1, pl2)
+        continue
+    defstr = ("def %(key)s%(pl1)s: return _getpen().%(key)s%(pl2)s" %
+                                   {'key':methodname, 'pl1':pl1, 'pl2':pl2})
+##    print("Turtle:", defstr)
+    exec(defstr)
+    eval(methodname).__doc__ = _turtle_docrevise(eval('Turtle.'+methodname).__doc__)
+
+
+done = mainloop = TK.mainloop
+#del pl1, pl2, defstr
+
+if __name__ == "__main__":
+    def switchpen():
+        if isdown():
+            pu()
+        else:
+            pd()
+
+    def demo1():
+        """Demo of old turtle.py - module"""
+        reset()
+        tracer(True)
         up()
-        forward(30)
+        backward(100)
         down()
-    width(1)
-    color("black")
-    # move out of the way
-    tracer(0)
-    up()
-    right(90)
-    forward(100)
-    right(90)
-    forward(100)
-    right(180)
-    down()
-    # some text
-    write("startstart", 1)
-    write("start", 1)
-    color("red")
-    # staircase
-    for i in range(5):
-        forward(20)
-        left(90)
-        forward(20)
-        right(90)
-    # filled staircase
-    fill(1)
-    for i in range(5):
-        forward(20)
-        left(90)
-        forward(20)
-        right(90)
-    fill(0)
-    tracer(1)
-    # more text
-    write("end")
-
-def demo2():
-    # exercises some new and improved features
-    speed('fast')
-    width(3)
-
-    # draw a segmented half-circle
-    setheading(towards(0,0))
-    x,y = position()
-    r = (x**2+y**2)**.5/2.0
-    right(90)
-    pendown = True
-    for i in range(18):
-        if pendown:
+        # draw 3 squares; the last filled
+        width(3)
+        for i in range(3):
+            if i == 2:
+                begin_fill()
+            for _ in range(4):
+                forward(20)
+                left(90)
+            if i == 2:
+                color("maroon")
+                end_fill()
             up()
-            pendown = False
-        else:
+            forward(30)
             down()
-            pendown = True
-        circle(r,10)
-    sleep(2)
-
-    reset()
-    left(90)
-
-    # draw a series of triangles
-    l = 10
-    color("green")
-    width(3)
-    left(180)
-    sp = 5
-    for i in range(-2,16):
-        if i > 0:
-            color(1.0-0.05*i,0,0.05*i)
-            fill(1)
-            color("green")
-        for j in range(3):
-            forward(l)
-            left(120)
-        l += 10
-        left(15)
-        if sp > 0:
-            sp = sp-1
-            speed(speeds[sp])
-    color(0.25,0,0.75)
-    fill(0)
-
-    # draw and fill a concave shape
-    left(120)
-    up()
-    forward(70)
-    right(30)
-    down()
-    color("red")
-    speed("fastest")
-    fill(1)
-    for i in range(4):
-        circle(50,90)
+        width(1)
+        color("black")
+        # move out of the way
+        tracer(False)
+        up()
         right(90)
-        forward(30)
+        forward(100)
         right(90)
-    color("yellow")
-    fill(0)
-    left(90)
-    up()
-    forward(30)
-    down();
-
-    color("red")
-
-    # create a second turtle and make the original pursue and catch it
-    turtle=Turtle()
-    turtle.reset()
-    turtle.left(90)
-    turtle.speed('normal')
-    turtle.up()
-    turtle.goto(280,40)
-    turtle.left(24)
-    turtle.down()
-    turtle.speed('fast')
-    turtle.color("blue")
-    turtle.width(2)
-    speed('fastest')
-
-    # turn default turtle towards new turtle object
-    setheading(towards(turtle))
-    while ( abs(position()[0]-turtle.position()[0])>4 or
-            abs(position()[1]-turtle.position()[1])>4):
-        turtle.forward(3.5)
-        turtle.left(0.6)
-        # turn default turtle towards new turtle object
+        forward(100)
+        right(180)
+        down()
+        # some text
+        write("startstart", 1)
+        write("start", 1)
+        color("red")
+        # staircase
+        for i in range(5):
+            forward(20)
+            left(90)
+            forward(20)
+            right(90)
+        # filled staircase
+        tracer(True)
+        begin_fill()
+        for i in range(5):
+            forward(20)
+            left(90)
+            forward(20)
+            right(90)
+        end_fill()
+        # more text
+
+    def demo2():
+        """Demo of some new features."""
+        speed(1)
+        st()
+        pensize(3)
+        setheading(towards(0, 0))
+        radius = distance(0, 0)/2.0
+        rt(90)
+        for _ in range(18):
+            switchpen()
+            circle(radius, 10)
+        write("wait a moment...")
+        while undobufferentries():
+            undo()
+        reset()
+        lt(90)
+        colormode(255)
+        laenge = 10
+        pencolor("green")
+        pensize(3)
+        lt(180)
+        for i in range(-2, 16):
+            if i > 0:
+                begin_fill()
+                fillcolor(255-15*i, 0, 15*i)
+            for _ in range(3):
+                fd(laenge)
+                lt(120)
+            end_fill()
+            laenge += 10
+            lt(15)
+            speed((speed()+1)%12)
+        #end_fill()
+
+        lt(120)
+        pu()
+        fd(70)
+        rt(30)
+        pd()
+        color("red","yellow")
+        speed(0)
+        begin_fill()
+        for _ in range(4):
+            circle(50, 90)
+            rt(90)
+            fd(30)
+            rt(90)
+        end_fill()
+        lt(90)
+        pu()
+        fd(30)
+        pd()
+        shape("turtle")
+
+        tri = getturtle()
+        tri.resizemode("auto")
+        turtle = Turtle()
+        turtle.resizemode("auto")
+        turtle.shape("turtle")
+        turtle.reset()
+        turtle.left(90)
+        turtle.speed(0)
+        turtle.up()
+        turtle.goto(280, 40)
+        turtle.lt(30)
+        turtle.down()
+        turtle.speed(6)
+        turtle.color("blue","orange")
+        turtle.pensize(2)
+        tri.speed(6)
         setheading(towards(turtle))
-        forward(4)
-    write("CAUGHT! ", move=True)
-
-
+        count = 1
+        while tri.distance(turtle) > 4:
+            turtle.fd(3.5)
+            turtle.lt(0.6)
+            tri.setheading(tri.towards(turtle))
+            tri.fd(4)
+            if count % 20 == 0:
+                turtle.stamp()
+                tri.stamp()
+                switchpen()
+            count += 1
+        tri.write("CAUGHT! ", font=("Arial", 16, "bold"), align="right")
+        tri.pencolor("black")
+        tri.pencolor("red")
+
+        def baba(xdummy, ydummy):
+            clearscreen()
+            bye()
+
+        time.sleep(2)
+
+        while undobufferentries():
+            tri.undo()
+            turtle.undo()
+        tri.fd(50)
+        tri.write("  Click me!", font = ("Courier", 12, "bold") )
+        tri.onclick(baba, 1)
 
-if __name__ == '__main__':
-    demo()
-    sleep(3)
+    demo1()
     demo2()
-    done()
+    exitonclick()

Modified: python/branches/py3k/Misc/ACKS
==============================================================================
--- python/branches/py3k/Misc/ACKS	(original)
+++ python/branches/py3k/Misc/ACKS	Tue Jun 10 06:44:07 2008
@@ -411,6 +411,7 @@
 Bjorn Lindqvist
 Per Lindqvist
 Eric Lindvall
+Gregor Lingl
 Nick Lockwood
 Stephanie Lockwood
 Anne Lord

From python-3000-checkins at python.org  Tue Jun 10 17:01:24 2008
From: python-3000-checkins at python.org (thomas.heller)
Date: Tue, 10 Jun 2008 17:01:24 +0200 (CEST)
Subject: [Python-3000-checkins] r64073 - in python/branches/py3k:
	PC/VC6/pythoncore.dsp PC/VS7.1/pythoncore.vcproj
	PC/VS8.0/pythoncore.vcproj PC/config.c PC/os2emx/Makefile
	PCbuild/pythoncore.vcproj
Message-ID: <20080610150124.DA7AE1E4002@bag.python.org>

Author: thomas.heller
Date: Tue Jun 10 17:01:24 2008
New Revision: 64073

Log:
Fix the Windows build by removing references to the cStringIO module
which no longer exists.


Modified:
   python/branches/py3k/PC/VC6/pythoncore.dsp
   python/branches/py3k/PC/VS7.1/pythoncore.vcproj
   python/branches/py3k/PC/VS8.0/pythoncore.vcproj
   python/branches/py3k/PC/config.c
   python/branches/py3k/PC/os2emx/Makefile
   python/branches/py3k/PCbuild/pythoncore.vcproj

Modified: python/branches/py3k/PC/VC6/pythoncore.dsp
==============================================================================
--- python/branches/py3k/PC/VC6/pythoncore.dsp	(original)
+++ python/branches/py3k/PC/VC6/pythoncore.dsp	Tue Jun 10 17:01:24 2008
@@ -293,10 +293,6 @@
 # End Source File
 # Begin Source File
 
-SOURCE=..\..\Modules\cStringIO.c
-# End Source File
-# Begin Source File
-
 SOURCE=..\..\Modules\datetimemodule.c
 # End Source File
 # Begin Source File

Modified: python/branches/py3k/PC/VS7.1/pythoncore.vcproj
==============================================================================
--- python/branches/py3k/PC/VS7.1/pythoncore.vcproj	(original)
+++ python/branches/py3k/PC/VS7.1/pythoncore.vcproj	Tue Jun 10 17:01:24 2008
@@ -479,9 +479,6 @@
 			RelativePath="..\..\PC\config.c">
 		</File>
 		<File
-			RelativePath="..\..\Modules\cStringIO.c">
-		</File>
-		<File
 			RelativePath="..\..\Modules\datetimemodule.c">
 		</File>
 		<File

Modified: python/branches/py3k/PC/VS8.0/pythoncore.vcproj
==============================================================================
--- python/branches/py3k/PC/VS8.0/pythoncore.vcproj	(original)
+++ python/branches/py3k/PC/VS8.0/pythoncore.vcproj	Tue Jun 10 17:01:24 2008
@@ -990,10 +990,10 @@
 				RelativePath="..\..\Modules\_fileio.c"
 				>
 			</File>
-                        <File^M
-                                RelativePath="..\..\Modules\_bytesio.c"^M
-                                >^M
-                        </File>^M
+                        <File^M
+                                RelativePath="..\..\Modules\_bytesio.c"^M
+                                >^M
+                        </File>^M
 			<File
 				RelativePath="..\..\Modules\_functoolsmodule.c"
 				>
@@ -1051,10 +1051,6 @@
 				>
 			</File>
 			<File
-				RelativePath="..\..\Modules\cStringIO.c"
-				>
-			</File>
-			<File
 				RelativePath="..\..\Modules\datetimemodule.c"
 				>
 			</File>

Modified: python/branches/py3k/PC/config.c
==============================================================================
--- python/branches/py3k/PC/config.c	(original)
+++ python/branches/py3k/PC/config.c	Tue Jun 10 17:01:24 2008
@@ -23,7 +23,6 @@
 extern void init_sha512(void);
 extern void inittime(void);
 extern void init_thread(void);
-extern void initcStringIO(void);
 #ifdef WIN32
 extern void initmsvcrt(void);
 extern void init_locale(void);
@@ -95,7 +94,6 @@
 #ifdef WITH_THREAD
         {"_thread", init_thread},
 #endif
-        {"cStringIO", initcStringIO},
 #ifdef WIN32
         {"msvcrt", initmsvcrt},
         {"_locale", init_locale},

Modified: python/branches/py3k/PC/os2emx/Makefile
==============================================================================
--- python/branches/py3k/PC/os2emx/Makefile	(original)
+++ python/branches/py3k/PC/os2emx/Makefile	Tue Jun 10 17:01:24 2008
@@ -287,7 +287,6 @@
 		Modules/cmathmodule.c \
 		Modules/_codecsmodule.c \
 		Modules/collectionsmodule.c \
-		Modules/cStringIO.c \
 		Modules/_csv.c \
 		Modules/datetimemodule.c \
 		Modules/errnomodule.c \

Modified: python/branches/py3k/PCbuild/pythoncore.vcproj
==============================================================================
--- python/branches/py3k/PCbuild/pythoncore.vcproj	(original)
+++ python/branches/py3k/PCbuild/pythoncore.vcproj	Tue Jun 10 17:01:24 2008
@@ -1055,10 +1055,6 @@
 				>
 			</File>
 			<File
-				RelativePath="..\Modules\cStringIO.c"
-				>
-			</File>
-			<File
 				RelativePath="..\Modules\datetimemodule.c"
 				>
 			</File>

From python-3000-checkins at python.org  Tue Jun 10 17:08:51 2008
From: python-3000-checkins at python.org (thomas.heller)
Date: Tue, 10 Jun 2008 17:08:51 +0200 (CEST)
Subject: [Python-3000-checkins] r64075 - in python/branches/py3k:
	Modules/_ctypes/callproc.c
Message-ID: <20080610150851.54A7B1E4002@bag.python.org>

Author: thomas.heller
Date: Tue Jun 10 17:08:51 2008
New Revision: 64075

Log:
Merged revisions 64070 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/trunk

........
  r64070 | thomas.heller | 2008-06-10 16:02:46 +0200 (Di, 10 Jun 2008) | 2 lines
  
  Add an optional 'offset' parameter to byref, defaultingto zero.
........


Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Modules/_ctypes/callproc.c

Modified: python/branches/py3k/Modules/_ctypes/callproc.c
==============================================================================
--- python/branches/py3k/Modules/_ctypes/callproc.c	(original)
+++ python/branches/py3k/Modules/_ctypes/callproc.c	Tue Jun 10 17:08:51 2008
@@ -1528,7 +1528,7 @@
 }
 
 static char byref_doc[] =
-"byref(C instance) -> byref-object\n"
+"byref(C instance[, offset=0]) -> byref-object\n"
 "Return a pointer lookalike to a C instance, only usable\n"
 "as function argument";
 
@@ -1537,9 +1537,21 @@
  * but still has a reference to self.
  */
 static PyObject *
-byref(PyObject *self, PyObject *obj)
+byref(PyObject *self, PyObject *args)
 {
 	PyCArgObject *parg;
+	PyObject *obj;
+	PyObject *pyoffset = NULL;
+	Py_ssize_t offset = 0;
+
+	if (!PyArg_UnpackTuple(args, "byref", 1, 2,
+			       &obj, &pyoffset))
+		return NULL;
+	if (pyoffset) {
+		offset = PyNumber_AsSsize_t(pyoffset, NULL);
+		if (offset == -1 && PyErr_Occurred())
+			return NULL;
+	}
 	if (!CDataObject_Check(obj)) {
 		PyErr_Format(PyExc_TypeError,
 			     "byref() argument must be a ctypes instance, not '%s'",
@@ -1555,7 +1567,7 @@
 	parg->pffi_type = &ffi_type_pointer;
 	Py_INCREF(obj);
 	parg->obj = obj;
-	parg->value.p = ((CDataObject *)obj)->b_ptr;
+	parg->value.p = (char *)((CDataObject *)obj)->b_ptr + offset;
 	return (PyObject *)parg;
 }
 
@@ -1835,7 +1847,7 @@
 #endif
 	{"alignment", align_func, METH_O, alignment_doc},
 	{"sizeof", sizeof_func, METH_O, sizeof_doc},
-	{"byref", byref, METH_O, byref_doc},
+	{"byref", byref, METH_VARARGS, byref_doc},
 	{"addressof", addressof, METH_O, addressof_doc},
 	{"call_function", call_function, METH_VARARGS },
 	{"call_cdeclfunction", call_cdeclfunction, METH_VARARGS },

From python-3000-checkins at python.org  Tue Jun 10 17:27:07 2008
From: python-3000-checkins at python.org (thomas.heller)
Date: Tue, 10 Jun 2008 17:27:07 +0200 (CEST)
Subject: [Python-3000-checkins] r64076 - in python/branches/py3k:
	Doc/library/ctypes.rst Modules/_ctypes/callproc.c
Message-ID: <20080610152707.9D6201E400D@bag.python.org>

Author: thomas.heller
Date: Tue Jun 10 17:26:58 2008
New Revision: 64076

Log:
Merged revisions 63988,63991 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/trunk

........
  r63988 | thomas.heller | 2008-06-06 20:37:55 +0200 (Fr, 06 Jun 2008) | 3 lines
  
  Performance improvement: Use PyDict_Get/SetItem instead of
  PyDict_Get/SetItemString.
........
  r63991 | thomas.heller | 2008-06-06 22:05:15 +0200 (Fr, 06 Jun 2008) | 5 lines
  
  Document the new ctypes features.
  
  It would be great if someone could review both sematics, markup, and
  spelling, and correct the versionadded and versionchanges markers.
........


Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Doc/library/ctypes.rst
   python/branches/py3k/Modules/_ctypes/callproc.c

Modified: python/branches/py3k/Doc/library/ctypes.rst
==============================================================================
--- python/branches/py3k/Doc/library/ctypes.rst	(original)
+++ python/branches/py3k/Doc/library/ctypes.rst	Tue Jun 10 17:26:58 2008
@@ -1335,14 +1335,14 @@
 way is to instantiate one of the following classes:
 
 
-.. class:: CDLL(name, mode=DEFAULT_MODE, handle=None)
+.. class:: CDLL(name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False)
 
    Instances of this class represent loaded shared libraries. Functions in these
    libraries use the standard C calling convention, and are assumed to return
    ``int``.
 
 
-.. class:: OleDLL(name, mode=DEFAULT_MODE, handle=None)
+.. class:: OleDLL(name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False)
 
    Windows only: Instances of this class represent loaded shared libraries,
    functions in these libraries use the ``stdcall`` calling convention, and are
@@ -1352,7 +1352,7 @@
    failure, an :class:`WindowsError` is automatically raised.
 
 
-.. class:: WinDLL(name, mode=DEFAULT_MODE, handle=None)
+.. class:: WinDLL(name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False)
 
    Windows only: Instances of this class represent loaded shared libraries,
    functions in these libraries use the ``stdcall`` calling convention, and are
@@ -1385,6 +1385,29 @@
 The *mode* parameter can be used to specify how the library is loaded.  For
 details, consult the ``dlopen(3)`` manpage, on Windows, *mode* is ignored.
 
+The *use_errno* parameter, when set to True, enables a ctypes
+mechanism that allows to access the system `errno` error number in a
+safe way.  `ctypes` maintains a thread-local copy of the systems
+`errno` variable; if you call foreign functions created with
+`use_errno=True` then the `errno` value before the function call is
+swapped with the ctypes private copy, the same happens immediately
+after the function call.
+
+The function `ctypes.get_errno()` returns the value of the ctypes
+private copy, and the function `ctypes.set_errno(value)` changes the
+ctypes private copy to `value` and returns the former value.
+
+The *use_last_error* parameter, when set to True, enables the same
+mechanism for the Windows error code which is managed by the
+GetLastError() and SetLastError() Windows api functions;
+`ctypes.get_last_error()` and `ctypes.set_last_error(value)` are used
+to request and change the ctypes private copy of the windows error
+code.
+
+.. versionchanged:: 2.6
+
+The `use_errno` and `use_last_error` parameters were added in Python
+2.6.
 
 .. data:: RTLD_GLOBAL
    :noindex:
@@ -1583,18 +1606,26 @@
 type and the argument types of the function.
 
 
-.. function:: CFUNCTYPE(restype, *argtypes)
+.. function:: CFUNCTYPE(restype, *argtypes, use_errno=False, use_last_error=False)
 
    The returned function prototype creates functions that use the standard C
    calling convention.  The function will release the GIL during the call.
+   If `use_errno` is set to True, the ctypes private copy of the system `errno`
+   variable is exchanged with the real `errno` value bafore and after the call;
+   `use_last_error` does the same for the Windows error code.
+
+   .. versionchanged:: 2.6
+
+   The optional `use_errno` and `use_last_error` parameters were added
+   in Python 2.6.
 
 
-.. function:: WINFUNCTYPE(restype, *argtypes)
+.. function:: WINFUNCTYPE(restype, *argtypes, use_errno=False, use_last_error=False)
 
    Windows only: The returned function prototype creates functions that use the
    ``stdcall`` calling convention, except on Windows CE where :func:`WINFUNCTYPE`
    is the same as :func:`CFUNCTYPE`.  The function will release the GIL during the
-   call.
+   call. `use_errno` and `use_last_error` have the same meaning as above.
 
 
 .. function:: PYFUNCTYPE(restype, *argtypes)
@@ -1846,7 +1877,22 @@
 .. function:: GetLastError()
 
    Windows only: Returns the last error code set by Windows in the calling thread.
+   This function calls the Windows `GetLastError()` function directly,
+   it does not return the ctypes-private copy of the error code.
+
+.. function:: get_errno()
+
+   Returns the current value of the ctypes-private copy of the system
+   `errno` variable in the calling thread.
+
+   .. versionadded:: 2.6
+
+.. function:: get_last_error()
 
+   Windows only: returns the current value of the ctypes-private copy of the system
+   `LastError` variable in the calling thread.
+
+   .. versionadded:: 2.6
 
 .. function:: memmove(dst, src, count)
 
@@ -1899,6 +1945,22 @@
    other systems ``('ascii', 'strict')``.
 
 
+.. function:: set_errno(value)
+
+   Set the  current value of the ctypes-private copy of the system
+   `errno` variable in the calling thread to `value` and return the
+   previous value.
+
+   .. versionadded:: 2.6
+
+.. function:: set_last_error(value)
+
+   Windows only: set the current value of the ctypes-private copy of
+   the system `LastError` variable in the calling thread to `value`
+   and return the previous value.
+
+   .. versionadded:: 2.6
+
 .. function:: sizeof(obj_or_type)
 
    Returns the size in bytes of a ctypes type or instance memory buffer. Does the

Modified: python/branches/py3k/Modules/_ctypes/callproc.c
==============================================================================
--- python/branches/py3k/Modules/_ctypes/callproc.c	(original)
+++ python/branches/py3k/Modules/_ctypes/callproc.c	Tue Jun 10 17:26:58 2008
@@ -117,12 +117,18 @@
 {
 	PyObject *dict = PyThreadState_GetDict();
 	PyObject *errobj;
+	static PyObject *error_object_name;
 	if (dict == 0) {
 		PyErr_SetString(PyExc_RuntimeError,
 				"cannot get thread state");
 		return NULL;
 	}
-	errobj = PyDict_GetItemString(dict, "ctypes.error_object");
+	if (error_object_name == NULL) {
+		error_object_name = PyString_InternFromString("ctypes.error_object");
+		if (error_object_name == NULL)
+			return NULL;
+	}
+	errobj = PyDict_GetItem(dict, error_object_name);
 	if (errobj)
 		Py_INCREF(errobj);
 	else {
@@ -133,8 +139,8 @@
 		errobj = PyCObject_FromVoidPtr(space, PyMem_Free);
 		if (errobj == NULL)
 			return NULL;
-		if (-1 == PyDict_SetItemString(dict, "ctypes.error_object",
-					       errobj)) {
+		if (-1 == PyDict_SetItem(dict, error_object_name,
+					 errobj)) {
 			Py_DECREF(errobj);
 			return NULL;
 		}

From python-3000-checkins at python.org  Tue Jun 10 17:30:51 2008
From: python-3000-checkins at python.org (thomas.heller)
Date: Tue, 10 Jun 2008 17:30:51 +0200 (CEST)
Subject: [Python-3000-checkins] r64077 -
	python/branches/py3k/Modules/_ctypes/callproc.c
Message-ID: <20080610153051.585141E4005@bag.python.org>

Author: thomas.heller
Date: Tue Jun 10 17:30:51 2008
New Revision: 64077

Log:
PyString_InternFromString -> PyUnicode_InternFromString

Modified:
   python/branches/py3k/Modules/_ctypes/callproc.c

Modified: python/branches/py3k/Modules/_ctypes/callproc.c
==============================================================================
--- python/branches/py3k/Modules/_ctypes/callproc.c	(original)
+++ python/branches/py3k/Modules/_ctypes/callproc.c	Tue Jun 10 17:30:51 2008
@@ -124,7 +124,7 @@
 		return NULL;
 	}
 	if (error_object_name == NULL) {
-		error_object_name = PyString_InternFromString("ctypes.error_object");
+		error_object_name = PyUnicode_InternFromString("ctypes.error_object");
 		if (error_object_name == NULL)
 			return NULL;
 	}

From python-3000-checkins at python.org  Tue Jun 10 17:50:56 2008
From: python-3000-checkins at python.org (georg.brandl)
Date: Tue, 10 Jun 2008 17:50:56 +0200 (CEST)
Subject: [Python-3000-checkins] r64079 - in python/branches/py3k:
	Doc/library/csv.rst Doc/library/email.message.rst
	Doc/library/pickle.rst Include/cStringIO.h
	Lib/test/test_sys.py Modules/Setup.dist
	PC/VS8.0/pythoncore.vcproj PC/os2emx/config.c
	PC/os2emx/python26.def PC/os2vacpp/config.c
	PC/os2vacpp/makefile PC/os2vacpp/makefile.omk
	PCbuild/pythoncore.vcproj
Message-ID: <20080610155056.ECD881E4011@bag.python.org>

Author: georg.brandl
Date: Tue Jun 10 17:50:56 2008
New Revision: 64079

Log:
Remove last traces of cStringIO.


Removed:
   python/branches/py3k/Include/cStringIO.h
Modified:
   python/branches/py3k/Doc/library/csv.rst
   python/branches/py3k/Doc/library/email.message.rst
   python/branches/py3k/Doc/library/pickle.rst
   python/branches/py3k/Lib/test/test_sys.py
   python/branches/py3k/Modules/Setup.dist
   python/branches/py3k/PC/VS8.0/pythoncore.vcproj
   python/branches/py3k/PC/os2emx/config.c
   python/branches/py3k/PC/os2emx/python26.def
   python/branches/py3k/PC/os2vacpp/config.c
   python/branches/py3k/PC/os2vacpp/makefile
   python/branches/py3k/PC/os2vacpp/makefile.omk
   python/branches/py3k/PCbuild/pythoncore.vcproj

Modified: python/branches/py3k/Doc/library/csv.rst
==============================================================================
--- python/branches/py3k/Doc/library/csv.rst	(original)
+++ python/branches/py3k/Doc/library/csv.rst	Tue Jun 10 17:50:56 2008
@@ -484,7 +484,7 @@
 parameter in their constructor and make sure that the data passes the real
 reader or writer encoded as UTF-8::
 
-   import csv, codecs, cStringIO
+   import csv, codecs, io
 
    class UTF8Recoder:
        """
@@ -524,7 +524,7 @@
 
        def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds):
            # Redirect output to a queue
-           self.queue = cStringIO.StringIO()
+           self.queue = io.StringIO()
            self.writer = csv.writer(self.queue, dialect=dialect, **kwds)
            self.stream = f
            self.encoder = codecs.getincrementalencoder(encoding)()

Modified: python/branches/py3k/Doc/library/email.message.rst
==============================================================================
--- python/branches/py3k/Doc/library/email.message.rst	(original)
+++ python/branches/py3k/Doc/library/email.message.rst	Tue Jun 10 17:50:56 2008
@@ -48,7 +48,7 @@
       :class:`Generator` instance and use its :meth:`flatten` method directly.
       For example::
 
-         from cStringIO import StringIO
+         from io import StringIO
          from email.generator import Generator
          fp = StringIO()
          g = Generator(fp, mangle_from_=False, maxheaderlen=60)

Modified: python/branches/py3k/Doc/library/pickle.rst
==============================================================================
--- python/branches/py3k/Doc/library/pickle.rst	(original)
+++ python/branches/py3k/Doc/library/pickle.rst	Tue Jun 10 17:50:56 2008
@@ -555,7 +555,7 @@
 Here's a silly example that *might* shed more light::
 
    import pickle
-   from cStringIO import StringIO
+   from io import StringIO
 
    src = StringIO()
    p = pickle.Pickler(src)

Deleted: python/branches/py3k/Include/cStringIO.h
==============================================================================
--- python/branches/py3k/Include/cStringIO.h	Tue Jun 10 17:50:56 2008
+++ (empty file)
@@ -1,70 +0,0 @@
-#ifndef Py_CSTRINGIO_H
-#define Py_CSTRINGIO_H
-#ifdef __cplusplus
-extern "C" {
-#endif
-/*
-
-  This header provides access to cStringIO objects from C.
-  Functions are provided for calling cStringIO objects and
-  macros are provided for testing whether you have cStringIO 
-  objects.
-
-  Before calling any of the functions or macros, you must initialize
-  the routines with:
-
-    PycString_IMPORT
-
-  This would typically be done in your init function.
-
-*/
-#define PycString_IMPORT \
-  PycStringIO = (struct PycStringIO_CAPI*)PyCObject_Import("cStringIO", \
-                                                           "cStringIO_CAPI")
-
-/* Basic functions to manipulate cStringIO objects from C */
-
-static struct PycStringIO_CAPI {
-  
- /* Read a string from an input object.  If the last argument
-    is -1, the remainder will be read.
-    */
-  int(*cread)(PyObject *, char **, Py_ssize_t);
-
- /* Read a line from an input object.  Returns the length of the read
-    line as an int and a pointer inside the object buffer as char** (so
-    the caller doesn't have to provide its own buffer as destination).
-    */
-  int(*creadline)(PyObject *, char **);
-
-  /* Write a string to an output object*/
-  int(*cwrite)(PyObject *, const char *, Py_ssize_t);
-
-  /* Get the output object as a Python string (returns new reference). */
-  PyObject *(*cgetvalue)(PyObject *);
-
-  /* Create a new output object */
-  PyObject *(*NewOutput)(int);
-
-  /* Create an input object from a Python string
-     (copies the Python string reference).
-     */
-  PyObject *(*NewInput)(PyObject *);
-
-  /* The Python types for cStringIO input and output objects.
-     Note that you can do input on an output object.
-     */
-  PyTypeObject *InputType, *OutputType;
-
-} *PycStringIO;
-
-/* These can be used to test if you have one */
-#define PycStringIO_InputCheck(O) \
-  (Py_TYPE(O)==PycStringIO->InputType)
-#define PycStringIO_OutputCheck(O) \
-  (Py_TYPE(O)==PycStringIO->OutputType)
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* !Py_CSTRINGIO_H */

Modified: python/branches/py3k/Lib/test/test_sys.py
==============================================================================
--- python/branches/py3k/Lib/test/test_sys.py	(original)
+++ python/branches/py3k/Lib/test/test_sys.py	Tue Jun 10 17:50:56 2008
@@ -297,7 +297,7 @@
         self.assert_(isinstance(vi[4], int))
 
     def test_43581(self):
-        # Can't use sys.stdout, as this is a cStringIO object when
+        # Can't use sys.stdout, as this is a StringIO object when
         # the test runs under regrtest.
         self.assertEqual(sys.__stdout__.encoding, sys.__stderr__.encoding)
 

Modified: python/branches/py3k/Modules/Setup.dist
==============================================================================
--- python/branches/py3k/Modules/Setup.dist	(original)
+++ python/branches/py3k/Modules/Setup.dist	Tue Jun 10 17:50:56 2008
@@ -339,9 +339,6 @@
 # Fred Drake's interface to the Python parser
 #parser parsermodule.c
 
-# cStringIO
-#cStringIO cStringIO.c
-
 
 # Lee Busby's SIGFPE modules.
 # The library to link fpectl with is platform specific.

Modified: python/branches/py3k/PC/VS8.0/pythoncore.vcproj
==============================================================================
--- python/branches/py3k/PC/VS8.0/pythoncore.vcproj	(original)
+++ python/branches/py3k/PC/VS8.0/pythoncore.vcproj	Tue Jun 10 17:50:56 2008
@@ -691,10 +691,6 @@
 				>
 			</File>
 			<File
-				RelativePath="..\..\Include\cStringIO.h"
-				>
-			</File>
-			<File
 				RelativePath="..\..\Include\datetime.h"
 				>
 			</File>

Modified: python/branches/py3k/PC/os2emx/config.c
==============================================================================
--- python/branches/py3k/PC/os2emx/config.c	(original)
+++ python/branches/py3k/PC/os2emx/config.c	Tue Jun 10 17:50:56 2008
@@ -50,7 +50,6 @@
 extern void init_weakref();
 extern void initarray();
 extern void initbinascii();
-extern void initcStringIO();
 extern void initcollections();
 extern void initcmath();
 extern void initdatetime();
@@ -110,7 +109,6 @@
 	{"_weakref", init_weakref},
 	{"array", initarray},
 	{"binascii", initbinascii},
-	{"cStringIO", initcStringIO},
 	{"collections", initcollections},
 	{"cmath", initcmath},
 	{"datetime", initdatetime},

Modified: python/branches/py3k/PC/os2emx/python26.def
==============================================================================
--- python/branches/py3k/PC/os2emx/python26.def	(original)
+++ python/branches/py3k/PC/os2emx/python26.def	Tue Jun 10 17:50:56 2008
@@ -1218,9 +1218,6 @@
 ;  "initcPickle"
 ;  "fast_save_leave"
 
-; From python26_s.lib(cStringIO)
-;  "initcStringIO"
-
 ; From python26_s.lib(_csv)
 ;  "init_csv"
 

Modified: python/branches/py3k/PC/os2vacpp/config.c
==============================================================================
--- python/branches/py3k/PC/os2vacpp/config.c	(original)
+++ python/branches/py3k/PC/os2vacpp/config.c	Tue Jun 10 17:50:56 2008
@@ -34,7 +34,6 @@
 extern void initstruct(void);
 extern void inittime(void);
 extern void init_thread(void);
-extern void initcStringIO(void);
 extern void initpcre(void);
 #ifdef WIN32
 extern void initmsvcrt(void);
@@ -78,7 +77,6 @@
 #ifdef WITH_THREAD
         {"_thread", init_thread},
 #endif
-        {"cStringIO", initcStringIO},
         {"pcre", initpcre},
 #ifdef WIN32
         {"msvcrt", initmsvcrt},

Modified: python/branches/py3k/PC/os2vacpp/makefile
==============================================================================
--- python/branches/py3k/PC/os2vacpp/makefile	(original)
+++ python/branches/py3k/PC/os2vacpp/makefile	Tue Jun 10 17:50:56 2008
@@ -180,7 +180,6 @@
                   $(PATHOBJ)\ArrayModule.obj   \
                   $(PATHOBJ)\BinAscii.obj      \
                   $(PATHOBJ)\CMathModule.obj   \
-                  $(PATHOBJ)\cStringIO.obj     \
                   $(PATHOBJ)\ErrnoModule.obj   \
                   $(PATHOBJ)\GCModule.obj      \
                   $(PATHOBJ)\GetBuildInfo.obj  \
@@ -440,7 +439,7 @@
 
 cpickle.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
 	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \
-	 $(PY_INCLUDE)\cstringio.h $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h \
+	 $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h \
 	 $(PY_INCLUDE)\floatobject.h $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h \
 	 $(PY_INCLUDE)\intobject.h $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h \
 	 $(PY_INCLUDE)\longobject.h $(PY_INCLUDE)\methodobject.h \
@@ -466,20 +465,6 @@
 	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h \
 	 $(PY_INCLUDE)\tupleobject.h
 
-cstringio.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h $(PY_INCLUDE)\classobject.h \
-	 $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h pyconfig.h \
-	 $(PY_INCLUDE)\cstringio.h $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h \
-	 $(PY_INCLUDE)\floatobject.h $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h \
-	 $(PY_INCLUDE)\intobject.h $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h \
-	 $(PY_INCLUDE)\longobject.h $(PY_INCLUDE)\methodobject.h \
-	 $(PY_INCLUDE)\modsupport.h $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h \
-	 $(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h \
-	 $(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h \
-	 $(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h \
-	 $(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
-	 $(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h \
-	 $(PY_INCLUDE)\tupleobject.h
-
 cursesmodule.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h \
 	 $(PY_INCLUDE)\classobject.h $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h \
 	 pyconfig.h $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h \

Modified: python/branches/py3k/PC/os2vacpp/makefile.omk
==============================================================================
--- python/branches/py3k/PC/os2vacpp/makefile.omk	(original)
+++ python/branches/py3k/PC/os2vacpp/makefile.omk	Tue Jun 10 17:50:56 2008
@@ -142,7 +142,6 @@
                   ArrayModule.obj   \
                   BinAscii.obj      \
                   CMathModule.obj   \
-                  cStringIO.obj     \
                   ErrnoModule.obj   \
                   GetBuildInfo.obj  \
                   GetPathP.obj      \
@@ -379,7 +378,7 @@
 	 stringobject.h sysmodule.h traceback.h tupleobject.h
 
 cpickle.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
-	 pyconfig.h cstringio.h dictobject.h fileobject.h floatobject.h \
+	 pyconfig.h dictobject.h fileobject.h floatobject.h \
 	 funcobject.h import.h intobject.h intrcheck.h listobject.h \
 	 longobject.h methodobject.h modsupport.h moduleobject.h mymalloc.h \
 	 mymath.h myproto.h object.h objimpl.h pydebug.h pyerrors.h pyfpe.h \
@@ -394,14 +393,6 @@
 	 pythonrun.h rangeobject.h sliceobject.h stringobject.h sysmodule.h \
 	 traceback.h tupleobject.h
 
-cstringio.obj: abstract.h ceval.h classobject.h cobject.h complexobject.h \
-	 pyconfig.h cstringio.h dictobject.h fileobject.h floatobject.h \
-	 funcobject.h import.h intobject.h intrcheck.h listobject.h \
-	 longobject.h methodobject.h modsupport.h moduleobject.h mymalloc.h \
-	 myproto.h object.h objimpl.h pydebug.h pyerrors.h pyfpe.h \
-	 pystate.h python.h pythonrun.h rangeobject.h sliceobject.h \
-	 stringobject.h sysmodule.h traceback.h tupleobject.h
-
 cursesmodule.obj: abstract.h ceval.h classobject.h cobject.h \
 	 complexobject.h pyconfig.h dictobject.h fileobject.h floatobject.h \
 	 funcobject.h import.h intobject.h intrcheck.h listobject.h \

Modified: python/branches/py3k/PCbuild/pythoncore.vcproj
==============================================================================
--- python/branches/py3k/PCbuild/pythoncore.vcproj	(original)
+++ python/branches/py3k/PCbuild/pythoncore.vcproj	Tue Jun 10 17:50:56 2008
@@ -695,10 +695,6 @@
 				>
 			</File>
 			<File
-				RelativePath="..\Include\cStringIO.h"
-				>
-			</File>
-			<File
 				RelativePath="..\Include\datetime.h"
 				>
 			</File>

From python-3000-checkins at python.org  Tue Jun 10 18:37:51 2008
From: python-3000-checkins at python.org (georg.brandl)
Date: Tue, 10 Jun 2008 18:37:51 +0200 (CEST)
Subject: [Python-3000-checkins] r64081 - in python/branches/py3k:
	Doc/ACKS.txt Doc/Makefile Doc/README.txt Doc/library/_ast.rst
	Doc/library/abc.rst Doc/library/ast.rst Doc/library/cmd.rst
	Doc/library/inspect.rst Doc/library/language.rst
	Doc/library/logging.rst Doc/library/parser.rst
	Doc/library/threading.rst Doc/whatsnew/2.5.rst
	Doc/whatsnew/2.6.rst Include/bytearrayobject.h
	Include/bytesobject.h Lib/ast.py Lib/inspect.py
	Lib/test/test_ast.py Lib/test/test_complex.py
	Lib/test/test_inspect.py Lib/test/test_threading.py
	Lib/threading.py Misc/ACKS Misc/developers.txt
	Modules/itertoolsmodule.c Objects/complexobject.c
Message-ID: <20080610163751.B22A81E4002@bag.python.org>

Author: georg.brandl
Date: Tue Jun 10 18:37:50 2008
New Revision: 64081

Log:
Merged revisions 63829-63831,63858,63865,63879,63882,63948,63970-63972,63976,63989,64014-64015,64021-64022,64063-64065,64067 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/trunk

........
  r63829 | mark.summerfield | 2008-05-31 15:05:34 +0200 (Sat, 31 May 2008) | 4 lines
  
  Added a note to [] that special forms & special chars lose their meaning
  and backrefs can't be used inside []
........
  r63830 | georg.brandl | 2008-05-31 16:40:09 +0200 (Sat, 31 May 2008) | 2 lines
  
  #3010: clarification about stdin/use_rawinput.
........
  r63831 | georg.brandl | 2008-05-31 16:45:55 +0200 (Sat, 31 May 2008) | 2 lines
  
  #3005: add explaining sentence to easydialogs docs.
........
  r63858 | georg.brandl | 2008-06-01 18:41:31 +0200 (Sun, 01 Jun 2008) | 2 lines
  
  Add plain text make target.
........
  r63865 | georg.brandl | 2008-06-01 21:24:36 +0200 (Sun, 01 Jun 2008) | 2 lines
  
  Spaces vs. tabs.
........
  r63879 | gregory.p.smith | 2008-06-02 00:57:47 +0200 (Mon, 02 Jun 2008) | 3 lines
  
  Make the _H #define's match the header file names.  Fix comments to
  mention the correct type names.
........
  r63882 | gregory.p.smith | 2008-06-02 01:48:47 +0200 (Mon, 02 Jun 2008) | 3 lines
  
  Adds a Thread.getIdent() method to provide the _get_ident() value for
  any given threading.Thread object.  feature request issue 2871.
........
  r63948 | alexandre.vassalotti | 2008-06-04 22:41:44 +0200 (Wed, 04 Jun 2008) | 2 lines
  
  Fixed complex.__getnewargs__() to not emit another complex object.
........
  r63970 | andrew.kuchling | 2008-06-06 01:33:54 +0200 (Fri, 06 Jun 2008) | 1 line
  
  Document 'utc' parameter
........
  r63971 | andrew.kuchling | 2008-06-06 01:35:31 +0200 (Fri, 06 Jun 2008) | 1 line
  
  Add various items
........
  r63972 | andrew.kuchling | 2008-06-06 01:35:48 +0200 (Fri, 06 Jun 2008) | 1 line
  
  Grammar fix
........
  r63976 | georg.brandl | 2008-06-06 09:34:50 +0200 (Fri, 06 Jun 2008) | 2 lines
  
  Markup fix.
........
  r63989 | thomas.heller | 2008-06-06 20:42:11 +0200 (Fri, 06 Jun 2008) | 2 lines
  
  Add a reminder for the maintainer of whatsnew.
........
  r64014 | georg.brandl | 2008-06-07 17:59:10 +0200 (Sat, 07 Jun 2008) | 3 lines
  
  Factor out docstring dedenting from inspect.getdoc() into inspect.cleandoc()
  to ease standalone use of the algorithm.
........
  r64015 | georg.brandl | 2008-06-07 18:04:01 +0200 (Sat, 07 Jun 2008) | 2 lines
  
  Revert unwanted changes.
........
  r64021 | georg.brandl | 2008-06-07 20:16:12 +0200 (Sat, 07 Jun 2008) | 2 lines
  
  X-ref to numbers module.
........
  r64022 | georg.brandl | 2008-06-07 20:17:37 +0200 (Sat, 07 Jun 2008) | 3 lines
  
  Document the "st" API, to avoid confusion with the "new" AST.
  Add a note about using the new AST module.
........
  r64063 | martin.v.loewis | 2008-06-10 07:03:35 +0200 (Tue, 10 Jun 2008) | 2 lines
  
  Add Gregor Lingl.
........
  r64064 | georg.brandl | 2008-06-10 09:45:28 +0200 (Tue, 10 Jun 2008) | 2 lines
  
  Add the "ast" module, containing helpers to ease use of the "_ast" classes.
........
  r64065 | raymond.hettinger | 2008-06-10 09:57:15 +0200 (Tue, 10 Jun 2008) | 1 line
  
  Add Arnaud for his efforts on multi-arg set operations.
........
  r64067 | georg.brandl | 2008-06-10 14:46:39 +0200 (Tue, 10 Jun 2008) | 2 lines
  
  #2536: fix itertools.permutations and itertools.combinations docstrings.
........


Added:
   python/branches/py3k/Doc/library/ast.rst
      - copied unchanged from r64065, /python/trunk/Doc/library/ast.rst
   python/branches/py3k/Lib/ast.py
      - copied, changed from r64065, /python/trunk/Lib/ast.py
Removed:
   python/branches/py3k/Doc/library/_ast.rst
Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Doc/ACKS.txt
   python/branches/py3k/Doc/Makefile
   python/branches/py3k/Doc/README.txt
   python/branches/py3k/Doc/library/abc.rst
   python/branches/py3k/Doc/library/cmd.rst
   python/branches/py3k/Doc/library/inspect.rst
   python/branches/py3k/Doc/library/language.rst
   python/branches/py3k/Doc/library/logging.rst
   python/branches/py3k/Doc/library/parser.rst
   python/branches/py3k/Doc/library/threading.rst
   python/branches/py3k/Doc/whatsnew/2.5.rst
   python/branches/py3k/Doc/whatsnew/2.6.rst
   python/branches/py3k/Include/bytearrayobject.h
   python/branches/py3k/Include/bytesobject.h
   python/branches/py3k/Lib/inspect.py
   python/branches/py3k/Lib/test/test_ast.py
   python/branches/py3k/Lib/test/test_complex.py
   python/branches/py3k/Lib/test/test_inspect.py
   python/branches/py3k/Lib/test/test_threading.py
   python/branches/py3k/Lib/threading.py
   python/branches/py3k/Misc/ACKS
   python/branches/py3k/Misc/developers.txt
   python/branches/py3k/Modules/itertoolsmodule.c
   python/branches/py3k/Objects/complexobject.c

Modified: python/branches/py3k/Doc/ACKS.txt
==============================================================================
--- python/branches/py3k/Doc/ACKS.txt	(original)
+++ python/branches/py3k/Doc/ACKS.txt	Tue Jun 10 18:37:50 2008
@@ -157,6 +157,7 @@
    * Bernhard Reiter
    * Armin Rigo
    * Wes Rishel
+   * Armin Ronacher
    * Jim Roskind
    * Guido van Rossum
    * Donald Wallace Rouse II

Modified: python/branches/py3k/Doc/Makefile
==============================================================================
--- python/branches/py3k/Doc/Makefile	(original)
+++ python/branches/py3k/Doc/Makefile	Tue Jun 10 18:37:50 2008
@@ -21,6 +21,7 @@
 	@echo "  web       to make file usable by Sphinx.web"
 	@echo "  htmlhelp  to make HTML files and a HTML help project"
 	@echo "  latex     to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+	@echo "  text      to make plain text files"
 	@echo "  changes   to make an overview over all changed/added/deprecated items"
 	@echo "  linkcheck to check all external links for integrity"
 	@echo "  coverage  to check documentation coverage for library and C API"
@@ -75,6 +76,10 @@
 	@echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
 	      "run these through (pdf)latex."
 
+text: BUILDER = text
+text: build
+	@echo "Build finished; the text files are in build/text."
+
 changes: BUILDER = changes
 changes: build
 	@echo "The overview file is in build/changes."

Modified: python/branches/py3k/Doc/README.txt
==============================================================================
--- python/branches/py3k/Doc/README.txt	(original)
+++ python/branches/py3k/Doc/README.txt	Tue Jun 10 18:37:50 2008
@@ -56,6 +56,8 @@
  * "latex", which builds LaTeX source files that can be run with "pdflatex"
    to produce PDF documents.
 
+ * "text", which builds a plain text file for each source file.
+
  * "linkcheck", which checks all external references to see whether they are
    broken, redirected or malformed, and outputs this information to stdout
    as well as a plain-text (.txt) file.

Deleted: python/branches/py3k/Doc/library/_ast.rst
==============================================================================
--- python/branches/py3k/Doc/library/_ast.rst	Tue Jun 10 18:37:50 2008
+++ (empty file)
@@ -1,83 +0,0 @@
-.. _ast:
-
-Abstract Syntax Trees
-=====================
-
-.. module:: _ast
-   :synopsis: Abstract Syntax Tree classes.
-
-.. sectionauthor:: Martin v. L?wis <martin at v.loewis.de>
-
-
-The ``_ast`` module helps Python applications to process trees of the Python
-abstract syntax grammar.  The abstract syntax itself might change with each
-Python release; this module helps to find out programmatically what the current
-grammar looks like.
-
-An abstract syntax tree can be generated by passing :data:`_ast.PyCF_ONLY_AST`
-as a flag to the :func:`compile` builtin function. The result will be a tree of
-objects whose classes all inherit from :class:`_ast.AST`.
-
-A modified abstract syntax tree can be compiled into a Python code object using
-the built-in :func:`compile` function.
-
-The actual classes are derived from the ``Parser/Python.asdl`` file, which is
-reproduced below. There is one class defined for each left-hand side symbol in
-the abstract grammar (for example, ``_ast.stmt`` or ``_ast.expr``). In addition,
-there is one class defined for each constructor on the right-hand side; these
-classes inherit from the classes for the left-hand side trees. For example,
-``_ast.BinOp`` inherits from ``_ast.expr``. For production rules with
-alternatives (aka "sums"), the left-hand side class is abstract: only instances
-of specific constructor nodes are ever created.
-
-Each concrete class has an attribute ``_fields`` which gives the names of all
-child nodes.
-
-Each instance of a concrete class has one attribute for each child node, of the
-type as defined in the grammar. For example, ``_ast.BinOp`` instances have an
-attribute ``left`` of type ``_ast.expr``.   Instances of ``_ast.expr`` and
-``_ast.stmt`` subclasses also have lineno and col_offset attributes.  The lineno
-is the line number of source text (1 indexed so the first line is line 1) and
-the col_offset is the utf8 byte offset of the first token that generated the
-node.  The utf8 offset is recorded because the parser uses utf8 internally.
-
-If these attributes are marked as optional in the grammar (using a question
-mark), the value might be ``None``. If the attributes can have zero-or-more
-values (marked with an asterisk), the values are represented as Python lists.
-All possible attributes must be present and have valid values when compiling an
-AST with :func:`compile`.
-
-The constructor of a class ``_ast.T`` parses their arguments as follows:
-
-* If there are positional arguments, there must be as many as there are items in
-  ``T._fields``; they will be assigned as attributes of these names.
-* If there are keyword arguments, they will set the attributes of the same names
-  to the given values.
-
-For example, to create and populate a ``UnaryOp`` node, you could use ::
-
-   node = _ast.UnaryOp()
-   node.op = _ast.USub()
-   node.operand = _ast.Num()
-   node.operand.n = 5
-   node.operand.lineno = 0
-   node.operand.col_offset = 0
-   node.lineno = 0
-   node.col_offset = 0
-
-or the more compact ::
-
-   node = _ast.UnaryOp(_ast.USub(), _ast.Num(5, lineno=0, col_offset=0),
-                       lineno=0, col_offset=0)
-
-
-
-Abstract Grammar
-----------------
-
-The module defines a string constant ``__version__`` which is the decimal
-subversion revision number of the file shown below.
-
-The abstract grammar is currently defined as follows:
-
-.. literalinclude:: ../../Parser/Python.asdl

Modified: python/branches/py3k/Doc/library/abc.rst
==============================================================================
--- python/branches/py3k/Doc/library/abc.rst	(original)
+++ python/branches/py3k/Doc/library/abc.rst	Tue Jun 10 18:37:50 2008
@@ -9,9 +9,9 @@
 .. much of the content adapted from docstrings
 
 This module provides the infrastructure for defining abstract base classes
-(ABCs) in Python, as outlined in :pep:`3119`; see the PEP for why this
-was added to Python. (See also, :pep:`3141` regarding a type hierarchy
-for numbers based on ABCs.)
+(ABCs) in Python, as outlined in :pep:`3119`; see the PEP for why this was added
+to Python. (See also :pep:`3141` and the :mod:`numbers` module regarding a type
+hierarchy for numbers based on ABCs.)
 
 The :mod:`collections` module has some concrete classes that derive from
 ABCs; these can, of course, be further derived. In addition the

Modified: python/branches/py3k/Doc/library/cmd.rst
==============================================================================
--- python/branches/py3k/Doc/library/cmd.rst	(original)
+++ python/branches/py3k/Doc/library/cmd.rst	Tue Jun 10 18:37:50 2008
@@ -26,7 +26,12 @@
 
    The optional arguments *stdin* and *stdout* specify the  input and output file
    objects that the Cmd instance or subclass  instance will use for input and
-   output. If not specified, they will default to *sys.stdin* and *sys.stdout*.
+   output. If not specified, they will default to :data:`sys.stdin` and
+   :data:`sys.stdout`.
+
+   If you want a given *stdin* to be used, make sure to set the instance's
+   :attr:`use_rawinput` attribute to ``False``, otherwise *stdin* will be
+   ignored.
 
 
 .. _cmd-objects:

Modified: python/branches/py3k/Doc/library/inspect.rst
==============================================================================
--- python/branches/py3k/Doc/library/inspect.rst	(original)
+++ python/branches/py3k/Doc/library/inspect.rst	Tue Jun 10 18:37:50 2008
@@ -320,13 +320,9 @@
 Retrieving source code
 ----------------------
 
-
 .. function:: getdoc(object)
 
-   Get the documentation string for an object. All tabs are expanded to spaces.  To
-   clean up docstrings that are indented to line up with blocks of code, any
-   whitespace than can be uniformly removed from the second line onwards is
-   removed.
+   Get the documentation string for an object, cleaned up with :func:`cleandoc`.
 
 
 .. function:: getcomments(object)
@@ -373,6 +369,15 @@
    cannot be retrieved.
 
 
+.. function:: cleandoc(doc)
+
+   Clean up indentation from docstrings that are indented to line up with blocks
+   of code.  Any whitespace that can be uniformly removed from the second line
+   onwards is removed.  Also, all tabs are expanded to spaces.
+
+   .. versionadded:: 2.6
+
+
 .. _inspect-classes-functions:
 
 Classes and functions

Modified: python/branches/py3k/Doc/library/language.rst
==============================================================================
--- python/branches/py3k/Doc/library/language.rst	(original)
+++ python/branches/py3k/Doc/library/language.rst	Tue Jun 10 18:37:50 2008
@@ -15,7 +15,7 @@
 .. toctree::
 
    parser.rst
-   _ast.rst
+   ast.rst
    symbol.rst
    token.rst
    keyword.rst

Modified: python/branches/py3k/Doc/library/logging.rst
==============================================================================
--- python/branches/py3k/Doc/library/logging.rst	(original)
+++ python/branches/py3k/Doc/library/logging.rst	Tue Jun 10 18:37:50 2008
@@ -1618,7 +1618,7 @@
 timed intervals.
 
 
-.. class:: TimedRotatingFileHandler(filename [,when [,interval [,backupCount[, encoding[, delay]]]]])
+.. class:: TimedRotatingFileHandler(filename [,when [,interval [,backupCount[, encoding[, delay[, utc]]]]]])
 
    Returns a new instance of the :class:`TimedRotatingFileHandler` class. The
    specified file is opened and used as the stream for logging. On rotating it also
@@ -1626,7 +1626,7 @@
    *interval*.
 
    You can use the *when* to specify the type of *interval*. The list of possible
-   values is, note that they are not case sensitive:
+   values is below.  Note that they are not case sensitive.
 
    +----------------+-----------------------+
    | Value          | Type of interval      |
@@ -1647,7 +1647,11 @@
    The system will save old log files by appending extensions to the filename.
    The extensions are date-and-time based, using the strftime format
    ``%Y-%m-%d_%H-%M-%S`` or a leading portion thereof, depending on the
-   rollover interval. If *backupCount* is nonzero, at most *backupCount* files
+   rollover interval. 
+   If the *utc* argument is true, times in UTC will be used; otherwise
+   local time is used.
+
+   If *backupCount* is nonzero, at most *backupCount* files
    will be kept, and if more would be created when rollover occurs, the oldest
    one is deleted. The deletion logic uses the interval to determine which
    files to delete, so changing the interval may leave old files lying around.

Modified: python/branches/py3k/Doc/library/parser.rst
==============================================================================
--- python/branches/py3k/Doc/library/parser.rst	(original)
+++ python/branches/py3k/Doc/library/parser.rst	Tue Jun 10 18:37:50 2008
@@ -24,6 +24,17 @@
 code fragment as a string because parsing is performed in a manner identical to
 the code forming the application.  It is also faster.
 
+.. note::
+
+   From Python 2.5 onward, it's much more convenient to cut in at the Abstract
+   Syntax Tree (AST) generation and compilation stage, using the :mod:`ast`
+   module.
+
+   The :mod:`parser` module exports the names documented here also with "st"
+   replaced by "ast"; this is a legacy from the time when there was no other
+   AST and has nothing to do with the AST found in Python 2.5.  This is also the
+   reason for the functions' keyword arguments being called *ast*, not *st*.
+
 There are a few things to note about this module which are important to making
 use of the data structures created.  This is not a tutorial on editing the parse
 trees for Python code, but some examples of using the :mod:`parser` module are
@@ -34,9 +45,9 @@
 to :ref:`reference-index`.  The parser
 itself is created from a grammar specification defined in the file
 :file:`Grammar/Grammar` in the standard Python distribution.  The parse trees
-stored in the AST objects created by this module are the actual output from the
+stored in the ST objects created by this module are the actual output from the
 internal parser when created by the :func:`expr` or :func:`suite` functions,
-described below.  The AST objects created by :func:`sequence2ast` faithfully
+described below.  The ST objects created by :func:`sequence2st` faithfully
 simulate those structures.  Be aware that the values of the sequences which are
 considered "correct" will vary from one version of Python to another as the
 formal grammar for the language is revised.  However, transporting code from one
@@ -46,7 +57,7 @@
 language constructs.  The parse trees are not typically compatible from one
 version to another, whereas source code has always been forward-compatible.
 
-Each element of the sequences returned by :func:`ast2list` or :func:`ast2tuple`
+Each element of the sequences returned by :func:`st2list` or :func:`st2tuple`
 has a simple form.  Sequences representing non-terminal elements in the grammar
 always have a length greater than one.  The first element is an integer which
 identifies a production in the grammar.  These integers are given symbolic names
@@ -69,19 +80,19 @@
 terminal symbols are defined in the C header file :file:`Include/token.h` and
 the Python module :mod:`token`.
 
-The AST objects are not required to support the functionality of this module,
+The ST objects are not required to support the functionality of this module,
 but are provided for three purposes: to allow an application to amortize the
 cost of processing complex parse trees, to provide a parse tree representation
 which conserves memory space when compared to the Python list or tuple
 representation, and to ease the creation of additional modules in C which
 manipulate parse trees.  A simple "wrapper" class may be created in Python to
-hide the use of AST objects.
+hide the use of ST objects.
 
 The :mod:`parser` module defines functions for a few distinct purposes.  The
-most important purposes are to create AST objects and to convert AST objects to
+most important purposes are to create ST objects and to convert ST objects to
 other representations such as parse trees and compiled code objects, but there
 are also functions which serve to query the type of parse tree represented by an
-AST object.
+ST object.
 
 
 .. seealso::
@@ -94,20 +105,20 @@
       testing node values.
 
 
-.. _creating-asts:
+.. _creating-sts:
 
-Creating AST Objects
---------------------
+Creating ST Objects
+-------------------
 
-AST objects may be created from source code or from a parse tree. When creating
-an AST object from source, different functions are used to create the ``'eval'``
+ST objects may be created from source code or from a parse tree. When creating
+an ST object from source, different functions are used to create the ``'eval'``
 and ``'exec'`` forms.
 
 
 .. function:: expr(source)
 
    The :func:`expr` function parses the parameter *source* as if it were an input
-   to ``compile(source, 'file.py', 'eval')``.  If the parse succeeds, an AST object
+   to ``compile(source, 'file.py', 'eval')``.  If the parse succeeds, an ST object
    is created to hold the internal parse tree representation, otherwise an
    appropriate exception is thrown.
 
@@ -115,22 +126,22 @@
 .. function:: suite(source)
 
    The :func:`suite` function parses the parameter *source* as if it were an input
-   to ``compile(source, 'file.py', 'exec')``.  If the parse succeeds, an AST object
+   to ``compile(source, 'file.py', 'exec')``.  If the parse succeeds, an ST object
    is created to hold the internal parse tree representation, otherwise an
    appropriate exception is thrown.
 
 
-.. function:: sequence2ast(sequence)
+.. function:: sequence2st(sequence)
 
    This function accepts a parse tree represented as a sequence and builds an
    internal representation if possible.  If it can validate that the tree conforms
    to the Python grammar and all nodes are valid node types in the host version of
-   Python, an AST object is created from the internal representation and returned
+   Python, an ST object is created from the internal representation and returned
    to the called.  If there is a problem creating the internal representation, or
    if the tree cannot be validated, a :exc:`ParserError` exception is thrown.  An
-   AST object created this way should not be assumed to compile correctly; normal
-   exceptions thrown by compilation may still be initiated when the AST object is
-   passed to :func:`compileast`.  This may indicate problems not related to syntax
+   ST object created this way should not be assumed to compile correctly; normal
+   exceptions thrown by compilation may still be initiated when the ST object is
+   passed to :func:`compilest`.  This may indicate problems not related to syntax
    (such as a :exc:`MemoryError` exception), but may also be due to constructs such
    as the result of parsing ``del f(0)``, which escapes the Python parser but is
    checked by the bytecode compiler.
@@ -142,31 +153,31 @@
    symbols in the input tree.
 
 
-.. function:: tuple2ast(sequence)
+.. function:: tuple2st(sequence)
 
-   This is the same function as :func:`sequence2ast`.  This entry point is
+   This is the same function as :func:`sequence2st`.  This entry point is
    maintained for backward compatibility.
 
 
-.. _converting-asts:
+.. _converting-sts:
 
-Converting AST Objects
-----------------------
+Converting ST Objects
+---------------------
 
-AST objects, regardless of the input used to create them, may be converted to
+ST objects, regardless of the input used to create them, may be converted to
 parse trees represented as list- or tuple- trees, or may be compiled into
 executable code objects.  Parse trees may be extracted with or without line
 numbering information.
 
 
-.. function:: ast2list(ast[, line_info])
+.. function:: st2list(ast[, line_info])
 
-   This function accepts an AST object from the caller in *ast* and returns a
+   This function accepts an ST object from the caller in *ast* and returns a
    Python list representing the equivalent parse tree.  The resulting list
    representation can be used for inspection or the creation of a new parse tree in
    list form.  This function does not fail so long as memory is available to build
    the list representation.  If the parse tree will only be used for inspection,
-   :func:`ast2tuple` should be used instead to reduce memory consumption and
+   :func:`st2tuple` should be used instead to reduce memory consumption and
    fragmentation.  When the list representation is required, this function is
    significantly faster than retrieving a tuple representation and converting that
    to nested lists.
@@ -177,31 +188,31 @@
    This information is omitted if the flag is false or omitted.
 
 
-.. function:: ast2tuple(ast[, line_info])
+.. function:: st2tuple(ast[, line_info])
 
-   This function accepts an AST object from the caller in *ast* and returns a
+   This function accepts an ST object from the caller in *ast* and returns a
    Python tuple representing the equivalent parse tree.  Other than returning a
-   tuple instead of a list, this function is identical to :func:`ast2list`.
+   tuple instead of a list, this function is identical to :func:`st2list`.
 
    If *line_info* is true, line number information will be included for all
    terminal tokens as a third element of the list representing the token.  This
    information is omitted if the flag is false or omitted.
 
 
-.. function:: compileast(ast[, filename='<ast>'])
+.. function:: compilest(ast[, filename='<syntax-tree>'])
 
    .. index::
       builtin: exec
       builtin: eval
 
-   The Python byte compiler can be invoked on an AST object to produce code objects
+   The Python byte compiler can be invoked on an ST object to produce code objects
    which can be used as part of a call to the built-in :func:`exec` or :func:`eval`
    functions. This function provides the interface to the compiler, passing the
    internal parse tree from *ast* to the parser, using the source file name
    specified by the *filename* parameter. The default value supplied for *filename*
-   indicates that the source was an AST object.
+   indicates that the source was an ST object.
 
-   Compiling an AST object may result in exceptions related to compilation; an
+   Compiling an ST object may result in exceptions related to compilation; an
    example would be a :exc:`SyntaxError` caused by the parse tree for ``del f(0)``:
    this statement is considered legal within the formal grammar for Python but is
    not a legal language construct.  The :exc:`SyntaxError` raised for this
@@ -211,15 +222,15 @@
    tree.
 
 
-.. _querying-asts:
+.. _querying-sts:
 
-Queries on AST Objects
-----------------------
+Queries on ST Objects
+---------------------
 
-Two functions are provided which allow an application to determine if an AST was
+Two functions are provided which allow an application to determine if an ST was
 created as an expression or a suite.  Neither of these functions can be used to
-determine if an AST was created from source code via :func:`expr` or
-:func:`suite` or from a parse tree via :func:`sequence2ast`.
+determine if an ST was created from source code via :func:`expr` or
+:func:`suite` or from a parse tree via :func:`sequence2st`.
 
 
 .. function:: isexpr(ast)
@@ -229,19 +240,19 @@
    When *ast* represents an ``'eval'`` form, this function returns true, otherwise
    it returns false.  This is useful, since code objects normally cannot be queried
    for this information using existing built-in functions.  Note that the code
-   objects created by :func:`compileast` cannot be queried like this either, and
+   objects created by :func:`compilest` cannot be queried like this either, and
    are identical to those created by the built-in :func:`compile` function.
 
 
 .. function:: issuite(ast)
 
-   This function mirrors :func:`isexpr` in that it reports whether an AST object
+   This function mirrors :func:`isexpr` in that it reports whether an ST object
    represents an ``'exec'`` form, commonly known as a "suite."  It is not safe to
    assume that this function is equivalent to ``not isexpr(ast)``, as additional
    syntactic fragments may be supported in the future.
 
 
-.. _ast-errors:
+.. _st-errors:
 
 Exceptions and Error Handling
 -----------------------------
@@ -257,12 +268,12 @@
    generally produced for validation failures rather than the built in
    :exc:`SyntaxError` thrown during normal parsing. The exception argument is
    either a string describing the reason of the failure or a tuple containing a
-   sequence causing the failure from a parse tree passed to :func:`sequence2ast`
-   and an explanatory string.  Calls to :func:`sequence2ast` need to be able to
+   sequence causing the failure from a parse tree passed to :func:`sequence2st`
+   and an explanatory string.  Calls to :func:`sequence2st` need to be able to
    handle either type of exception, while calls to other functions in the module
    will only need to be aware of the simple string values.
 
-Note that the functions :func:`compileast`, :func:`expr`, and :func:`suite` may
+Note that the functions :func:`compilest`, :func:`expr`, and :func:`suite` may
 throw exceptions which are normally thrown by the parsing and compilation
 process.  These include the built in exceptions :exc:`MemoryError`,
 :exc:`OverflowError`, :exc:`SyntaxError`, and :exc:`SystemError`.  In these
@@ -270,49 +281,49 @@
 Refer to the descriptions of each function for detailed information.
 
 
-.. _ast-objects:
+.. _st-objects:
 
-AST Objects
------------
+ST Objects
+----------
 
-Ordered and equality comparisons are supported between AST objects. Pickling of
-AST objects (using the :mod:`pickle` module) is also supported.
+Ordered and equality comparisons are supported between ST objects. Pickling of
+ST objects (using the :mod:`pickle` module) is also supported.
 
 
-.. data:: ASTType
+.. data:: STType
 
    The type of the objects returned by :func:`expr`, :func:`suite` and
-   :func:`sequence2ast`.
+   :func:`sequence2st`.
 
-AST objects have the following methods:
+ST objects have the following methods:
 
 
-.. method:: AST.compile([filename])
+.. method:: ST.compile([filename])
 
-   Same as ``compileast(ast, filename)``.
+   Same as ``compilest(st, filename)``.
 
 
-.. method:: AST.isexpr()
+.. method:: ST.isexpr()
 
-   Same as ``isexpr(ast)``.
+   Same as ``isexpr(st)``.
 
 
-.. method:: AST.issuite()
+.. method:: ST.issuite()
 
-   Same as ``issuite(ast)``.
+   Same as ``issuite(st)``.
 
 
-.. method:: AST.tolist([line_info])
+.. method:: ST.tolist([line_info])
 
-   Same as ``ast2list(ast, line_info)``.
+   Same as ``st2list(st, line_info)``.
 
 
-.. method:: AST.totuple([line_info])
+.. method:: ST.totuple([line_info])
 
-   Same as ``ast2tuple(ast, line_info)``.
+   Same as ``st2tuple(st, line_info)``.
 
 
-.. _ast-examples:
+.. _st-examples:
 
 Examples
 --------
@@ -340,27 +351,27 @@
    10
 
 The equivalent operation using the :mod:`parser` module is somewhat longer, and
-allows the intermediate internal parse tree to be retained as an AST object::
+allows the intermediate internal parse tree to be retained as an ST object::
 
    >>> import parser
-   >>> ast = parser.expr('a + 5')
-   >>> code = ast.compile('file.py')
+   >>> st = parser.expr('a + 5')
+   >>> code = st.compile('file.py')
    >>> a = 5
    >>> eval(code)
    10
 
-An application which needs both AST and code objects can package this code into
+An application which needs both ST and code objects can package this code into
 readily available functions::
 
    import parser
 
    def load_suite(source_string):
-       ast = parser.suite(source_string)
-       return ast, ast.compile()
+       st = parser.suite(source_string)
+       return st, st.compile()
 
    def load_expression(source_string):
-       ast = parser.expr(source_string)
-       return ast, ast.compile()
+       st = parser.expr(source_string)
+       return st, st.compile()
 
 
 Information Discovery
@@ -414,8 +425,8 @@
 
    >>> import parser
    >>> import pprint
-   >>> ast = parser.suite(open('docstring.py').read())
-   >>> tup = ast.totuple()
+   >>> st = parser.suite(open('docstring.py').read())
+   >>> tup = st.totuple()
    >>> pprint.pprint(tup)
    (257,
     (264,
@@ -670,8 +681,8 @@
 
        source = open(fileName).read()
        basename = os.path.basename(os.path.splitext(fileName)[0])
-       ast = parser.suite(source)
-       return ModuleInfo(ast.totuple(), basename)
+       st = parser.suite(source)
+       return ModuleInfo(st.totuple(), basename)
 
 This provides an easy-to-use interface to the documentation of a module.  If
 information is required which is not extracted by the code of this example, the

Modified: python/branches/py3k/Doc/library/threading.rst
==============================================================================
--- python/branches/py3k/Doc/library/threading.rst	(original)
+++ python/branches/py3k/Doc/library/threading.rst	Tue Jun 10 18:37:50 2008
@@ -643,6 +643,17 @@
    constructor.
 
 
+.. method:: Thread.getIdent()
+
+   Return the 'thread identifier' of this thread or None if the thread has not
+   been started.  This is a nonzero integer.  See the :mod:`thread` module's
+   :func:`get_ident()` function.  Thread identifiers may be recycled when a
+   thread exits and another thread is created.  The identifier is returned
+   even after the thread has exited.
+
+   .. versionadded:: 2.6
+
+
 .. method:: Thread.isAlive()
 
    Return whether the thread is alive.

Modified: python/branches/py3k/Doc/whatsnew/2.5.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/2.5.rst	(original)
+++ python/branches/py3k/Doc/whatsnew/2.5.rst	Tue Jun 10 18:37:50 2008
@@ -2205,10 +2205,10 @@
 * MacOS X (10.3 and higher): dynamic loading of modules now uses the
   :cfunc:`dlopen` function instead of MacOS-specific functions.
 
-* MacOS X: a :option:`--enable-universalsdk` switch was added to the
+* MacOS X: an :option:`--enable-universalsdk` switch was added to the
   :program:`configure` script that compiles the interpreter as a universal binary
   able to run on both PowerPC and Intel processors. (Contributed by Ronald
-  Oussoren.)
+  Oussoren; :issue:`2573`.)
 
 * Windows: :file:`.dll` is no longer supported as a filename extension for
   extension modules.  :file:`.pyd` is now the only filename extension that will be

Modified: python/branches/py3k/Doc/whatsnew/2.6.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/2.6.rst	(original)
+++ python/branches/py3k/Doc/whatsnew/2.6.rst	Tue Jun 10 18:37:50 2008
@@ -648,6 +648,7 @@
     >>> format(75.6564, '.2f')
     '75.66'
 
+
 .. seealso::
 
    :ref:`formatstrings`
@@ -1252,6 +1253,11 @@
 
   (Contributed by Alexander Belopolsky; :issue:`1686487`.)
 
+* A new built-in, ``next(*iterator*, [*default*])`` returns the next item
+  from the specified iterator.  If the *default* argument is supplied,
+  it will be returned if *iterator* has been exhausted; otherwise,
+  the :exc:`StopIteration` exception will be raised.  (:issue:`2719`)
+
 * Tuples now have an :meth:`index` method matching the list type's
   :meth:`index` method::
 
@@ -1553,6 +1559,7 @@
   :mod:`terminalcommand`.
 
   A number of old IRIX-specific modules were deprecated:
+  :mod:`al` and :mod:`AL`,
   :mod:`cd`,
   :mod:`cddb`,
   :mod:`cdplayer`,
@@ -1664,7 +1671,11 @@
 
   (Contributed by Raymond Hettinger.)
 
-* The :mod:`ctypes` module now supports a :class:`c_bool` datatype 
+* XXX Describe the new ctypes calling convention that allows safe
+  access to errno.
+  (Implemented by Thomas Heller; :issue:`1798`.)
+
+* The :mod:`ctypes` module now supports a :class:`c_bool` datatype
   that represents the C99 ``bool`` type.  (Contributed by David Remahl;
   :issue:`1649190`.)
 
@@ -1733,7 +1744,14 @@
   to drop the built-in in the 2.x series.  (Patched by 
   Christian Heimes; :issue:`1739906`.)
 
-* The :func:`glob.glob` function can now return Unicode filenames if 
+* When possible, the :mod:`getpass` module will now use
+  :file:`/dev/tty` (when available) to print
+  a prompting message and read the password, falling back to using
+  standard error and standard input.    If the password may be echoed to 
+  the terminal, a warning is printed before the prompt is displayed.
+  (Contributed by Gregory P. Smith.)
+
+* The :func:`glob.glob` function can now return Unicode filenames if
   a Unicode path was used and Unicode filenames are matched within the
   directory.  (:issue:`1001604`)
 
@@ -1752,6 +1770,10 @@
   This is more efficient than making a call to :func:`heappush` and then
   :func:`heappop`.
 
+  :mod:`heapq` is now implemented to only use less-than comparison,
+  instead of the less-than-or-equal comparison it previously used.
+  This makes :mod:`heapq`'s usage of a type match that of the 
+  :meth:`list.sort` method.
   (Contributed by Raymond Hettinger.)
 
 * An optional ``timeout`` parameter was added to the
@@ -1846,6 +1868,11 @@
   is true, opening of the log file is deferred until the first
   :meth:`emit` call is made.  (Contributed by Vinay Sajip.)
 
+  :class:`TimedRotatingFileHandler` also has a *utc* constructor 
+  parameter.  If the argument is true, UTC time will be used 
+  in determining when midnight occurs and in generating filenames;
+  otherwise local time will be used.
+
 * The :mod:`macfs` module has been removed.  This in turn required the
   :func:`macostools.touched` function to be removed because it depended on the
   :mod:`macfs` module.  (:issue:`1490190`)
@@ -2112,13 +2139,21 @@
   are written or not.
   (Contributed by Neal Norwitz and Georg Brandl.)
 
-  Information about the command-line arguments supplied to the Python 
-  interpreter are available as attributes of a ``sys.flags`` named 
-  tuple.  For example, the :attr:`verbose` attribute is true if Python 
+  Information about the command-line arguments supplied to the Python
+  interpreter is available by reading attributes of a named
+  tuple available as ``sys.flags``.  For example, the :attr:`verbose`
+  attribute is true if Python
   was executed in verbose mode, :attr:`debug` is true in debugging mode, etc.
   These attributes are all read-only.
   (Contributed by Christian Heimes.)
 
+  A new function, :func:`getsizeof`, takes a Python object and returns 
+  the amount of memory used by the object, measured in bytes.  Built-in
+  objects return correct results; third-party extensions may not,
+  but can define a :meth:`__sizeof__` method to return the 
+  object's size.
+  (Contributed by Robert Schuppenies; :issue:`2898`.)
+
   It's now possible to determine the current profiler and tracer functions
   by calling :func:`sys.getprofile` and :func:`sys.gettrace`.  
   (Contributed by Georg Brandl; :issue:`1648`.)
@@ -2204,7 +2239,11 @@
 
   (Contributed by Dwayne Bailey; :issue:`1581073`.)
 
-* The :mod:`timeit` module now accepts callables as well as strings 
+* The :mod:`threading` module's :class:`Thread` objects 
+  gained a :meth:`getIdent` method that returns the thread's 
+  identifier, a nonzero integer.  (Contributed by XXX; :issue:`2871`.)
+
+* The :mod:`timeit` module now accepts callables as well as strings
   for the statement being timed and for the setup code.
   Two convenience functions were added for creating 
   :class:`Timer` instances: 
@@ -2213,6 +2252,24 @@
   the corresponding method. (Contributed by Erik Demaine;
   :issue:`1533909`.)
 
+* The :mod:`turtle` module for turtle graphics was greatly enhanced by
+  Gregor Lingl.  New features in the module include:
+
+  * Better animation of turtle movement and rotation.
+  * Control over turtle movement using the new delay(), 
+    tracer(), and speed() methods.
+  * The ability to set new shapes for the turtle, and to 
+    define a new coordinate system.
+  * Turtles now have an undo() method that can roll back actions.
+  * Simple support for reacting to input events such as mouse and keyboard
+    activity, making it possible to write simple games.
+  * A :file:`turtle.cfg` file can be used to customize the starting appearance 
+    of the turtle's screen.
+  * The module's docstrings can be replaced by new docstrings that have been
+    translated into another language.
+  
+  (:issue:`1513695`)
+
 * An optional ``timeout`` parameter was added to the
   :func:`urllib.urlopen` function and the
   :class:`urllib.ftpwrapper` class constructor, as well as the 
@@ -2255,8 +2312,10 @@
   not necessarily correct for all applications.  Code using
   :mod:`xmlrpclib` should convert :class:`date` and :class:`time` 
   instances. (:issue:`1330538`)  The code can also handle 
-  dates before 1900.  (Contributed by Ralf Schmitt; :issue:`2014`.)
-
+  dates before 1900 (contributed by Ralf Schmitt; :issue:`2014`)
+  and 64-bit integers represented by using ``<i8>`` in XML-RPC responses
+  (contributed by XXX; :issue:`2985`).
+  
 * The :mod:`zipfile` module's :class:`ZipFile` class now has 
   :meth:`extract` and :meth:`extractall` methods that will unpack 
   a single file or all the files in the archive to the current directory, or 
@@ -2272,9 +2331,14 @@
 
   (Contributed by Alan McIntyre; :issue:`467924`.)
 
-  Also, :mod:`zipfile` now supports using Unicode filenames
-  for archived files.  (Contributed by Alexey Borzenkov; :issue:`1734346`.)
+  The :meth:`open`, :meth:`read` and :meth:`extract` methods can now 
+  take either a filename or a :class:`ZipInfo` object.  This is useful when an
+  archive accidentally contains a duplicated filename.
+  (Contributed by Graham Horler; :issue:`1775025`.)
 
+  Finally, :mod:`zipfile` now supports using Unicode filenames
+  for archived files.  (Contributed by Alexey Borzenkov; :issue:`1734346`.)
+  
 .. ======================================================================
 .. whole new modules get described in subsections here
 
@@ -2469,10 +2533,8 @@
   results, and then compiles using these results for optimization.
   (Contributed by Gregory P. Smith.)
 
-
 .. ======================================================================
 
-
 Port-Specific Changes: Windows
 -----------------------------------
 
@@ -2517,6 +2579,16 @@
 
 .. ======================================================================
 
+Port-Specific Changes: MacOS X
+-----------------------------------
+
+* When compiling a framework build of Python, you can now specify the 
+  framework name to be used by providing the 
+  :option:`--with-framework-name=` option to the 
+  :program:`configure` script.
+
+.. ======================================================================
+
 
 .. _section-other:
 

Modified: python/branches/py3k/Include/bytearrayobject.h
==============================================================================
--- python/branches/py3k/Include/bytearrayobject.h	(original)
+++ python/branches/py3k/Include/bytearrayobject.h	Tue Jun 10 18:37:50 2008
@@ -1,7 +1,7 @@
-/* Bytes object interface */
+/* ByteArray object interface */
 
-#ifndef Py_BYTESOBJECT_H
-#define Py_BYTESOBJECT_H
+#ifndef Py_BYTEARRAYOBJECT_H
+#define Py_BYTEARRAYOBJECT_H
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -50,4 +50,4 @@
 #ifdef __cplusplus
 }
 #endif
-#endif /* !Py_BYTESOBJECT_H */
+#endif /* !Py_BYTEARRAYOBJECT_H */

Modified: python/branches/py3k/Include/bytesobject.h
==============================================================================
--- python/branches/py3k/Include/bytesobject.h	(original)
+++ python/branches/py3k/Include/bytesobject.h	Tue Jun 10 18:37:50 2008
@@ -1,8 +1,8 @@
 
-/* String object interface */
+/* Bytes (String) object interface */
 
-#ifndef Py_STRINGOBJECT_H
-#define Py_STRINGOBJECT_H
+#ifndef Py_BYTESOBJECT_H
+#define Py_BYTESOBJECT_H
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -107,4 +107,4 @@
 #ifdef __cplusplus
 }
 #endif
-#endif /* !Py_STRINGOBJECT_H */
+#endif /* !Py_BYTESOBJECT_H */

Copied: python/branches/py3k/Lib/ast.py (from r64065, /python/trunk/Lib/ast.py)
==============================================================================
--- /python/trunk/Lib/ast.py	(original)
+++ python/branches/py3k/Lib/ast.py	Tue Jun 10 18:37:50 2008
@@ -44,7 +44,7 @@
     and None.
     """
     _safe_names = {'None': None, 'True': True, 'False': False}
-    if isinstance(node_or_string, basestring):
+    if isinstance(node_or_string, str):
         node_or_string = parse(node_or_string, mode='eval')
     if isinstance(node_or_string, Expression):
         node_or_string = node_or_string.body

Modified: python/branches/py3k/Lib/inspect.py
==============================================================================
--- python/branches/py3k/Lib/inspect.py	(original)
+++ python/branches/py3k/Lib/inspect.py	Tue Jun 10 18:37:50 2008
@@ -368,6 +368,13 @@
         return None
     if not isinstance(doc, str):
         return None
+    return cleandoc(doc)
+
+def cleandoc(doc):
+    """Clean up indentation from docstrings.
+
+    Any whitespace that can be uniformly removed from the second line
+    onwards is removed."""
     try:
         lines = doc.expandtabs().split('\n')
     except UnicodeError:

Modified: python/branches/py3k/Lib/test/test_ast.py
==============================================================================
--- python/branches/py3k/Lib/test/test_ast.py	(original)
+++ python/branches/py3k/Lib/test/test_ast.py	Tue Jun 10 18:37:50 2008
@@ -1,6 +1,6 @@
 import sys, unittest
 from test import support
-import _ast
+import ast
 
 def to_tuple(t):
     if t is None or isinstance(t, (str, int, complex)):
@@ -117,9 +117,9 @@
 class AST_Tests(unittest.TestCase):
 
     def _assert_order(self, ast_node, parent_pos):
-        if not isinstance(ast_node, _ast.AST) or ast_node._fields is None:
+        if not isinstance(ast_node, ast.AST) or ast_node._fields is None:
             return
-        if isinstance(ast_node, (_ast.expr, _ast.stmt, _ast.excepthandler)):
+        if isinstance(ast_node, (ast.expr, ast.stmt, ast.excepthandler)):
             node_pos = (ast_node.lineno, ast_node.col_offset)
             self.assert_(node_pos >= parent_pos)
             parent_pos = (ast_node.lineno, ast_node.col_offset)
@@ -136,29 +136,29 @@
                                     (single_tests, single_results, "single"),
                                     (eval_tests, eval_results, "eval")):
             for i, o in zip(input, output):
-                ast_tree = compile(i, "?", kind, _ast.PyCF_ONLY_AST)
+                ast_tree = compile(i, "?", kind, ast.PyCF_ONLY_AST)
                 self.assertEquals(to_tuple(ast_tree), o)
                 self._assert_order(ast_tree, (0, 0))
 
     def test_nodeclasses(self):
-        x = _ast.BinOp(1, 2, 3, lineno=0)
+        x = ast.BinOp(1, 2, 3, lineno=0)
         self.assertEquals(x.left, 1)
         self.assertEquals(x.op, 2)
         self.assertEquals(x.right, 3)
         self.assertEquals(x.lineno, 0)
 
         # node raises exception when not given enough arguments
-        self.assertRaises(TypeError, _ast.BinOp, 1, 2)
+        self.assertRaises(TypeError, ast.BinOp, 1, 2)
 
         # can set attributes through kwargs too
-        x = _ast.BinOp(left=1, op=2, right=3, lineno=0)
+        x = ast.BinOp(left=1, op=2, right=3, lineno=0)
         self.assertEquals(x.left, 1)
         self.assertEquals(x.op, 2)
         self.assertEquals(x.right, 3)
         self.assertEquals(x.lineno, 0)
 
         # this used to fail because Sub._fields was None
-        x = _ast.Sub()
+        x = ast.Sub()
 
     def test_pickling(self):
         import pickle
@@ -175,8 +175,99 @@
                     ast2 = mod.loads(mod.dumps(ast, protocol))
                     self.assertEquals(to_tuple(ast2), to_tuple(ast))
 
+
+class ASTHelpers_Test(unittest.TestCase):
+
+    def test_parse(self):
+        a = ast.parse('foo(1 + 1)')
+        b = compile('foo(1 + 1)', '<unknown>', 'exec', ast.PyCF_ONLY_AST)
+        self.assertEqual(ast.dump(a), ast.dump(b))
+
+    def test_dump(self):
+        node = ast.parse('spam(eggs, "and cheese")')
+        self.assertEqual(ast.dump(node),
+            "Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load()), "
+            "args=[Name(id='eggs', ctx=Load()), Str(s='and cheese')], "
+            "keywords=[], starargs=None, kwargs=None))])"
+        )
+        self.assertEqual(ast.dump(node, annotate_fields=False),
+            "Module([Expr(Call(Name('spam', Load()), [Name('eggs', Load()), "
+            "Str('and cheese')], [], None, None))])"
+        )
+        self.assertEqual(ast.dump(node, include_attributes=True),
+            "Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load(), "
+            "lineno=1, col_offset=0), args=[Name(id='eggs', ctx=Load(), "
+            "lineno=1, col_offset=5), Str(s='and cheese', lineno=1, "
+            "col_offset=11)], keywords=[], starargs=None, kwargs=None, "
+            "lineno=1, col_offset=0), lineno=1, col_offset=0)])"
+        )
+
+    def test_copy_location(self):
+        src = ast.parse('1 + 1', mode='eval')
+        src.body.right = ast.copy_location(ast.Num(2), src.body.right)
+        self.assertEqual(ast.dump(src, include_attributes=True),
+            'Expression(body=BinOp(left=Num(n=1, lineno=1, col_offset=0), '
+            'op=Add(), right=Num(n=2, lineno=1, col_offset=4), lineno=1, '
+            'col_offset=0))'
+        )
+
+    def test_fix_missing_locations(self):
+        src = ast.parse('write("spam")')
+        src.body.append(ast.Expr(ast.Call(ast.Name('spam', ast.Load()),
+                                          [ast.Str('eggs')], [], None, None)))
+        self.assertEqual(src, ast.fix_missing_locations(src))
+        self.assertEqual(ast.dump(src, include_attributes=True),
+            "Module(body=[Expr(value=Call(func=Name(id='write', ctx=Load(), "
+            "lineno=1, col_offset=0), args=[Str(s='spam', lineno=1, "
+            "col_offset=6)], keywords=[], starargs=None, kwargs=None, "
+            "lineno=1, col_offset=0), lineno=1, col_offset=0), "
+            "Expr(value=Call(func=Name(id='spam', ctx=Load(), lineno=1, "
+            "col_offset=0), args=[Str(s='eggs', lineno=1, col_offset=0)], "
+            "keywords=[], starargs=None, kwargs=None, lineno=1, "
+            "col_offset=0), lineno=1, col_offset=0)])"
+        )
+
+    def test_increment_lineno(self):
+        src = ast.parse('1 + 1', mode='eval')
+        self.assertEqual(ast.increment_lineno(src, n=3), src)
+        self.assertEqual(ast.dump(src, include_attributes=True),
+            'Expression(body=BinOp(left=Num(n=1, lineno=4, col_offset=0), '
+            'op=Add(), right=Num(n=1, lineno=4, col_offset=4), lineno=4, '
+            'col_offset=0))'
+        )
+
+    def test_iter_fields(self):
+        node = ast.parse('foo()', mode='eval')
+        d = dict(ast.iter_fields(node.body))
+        self.assertEqual(d.pop('func').id, 'foo')
+        self.assertEqual(d, {'keywords': [], 'kwargs': None,
+                             'args': [], 'starargs': None})
+
+    def test_iter_child_nodes(self):
+        node = ast.parse("spam(23, 42, eggs='leek')", mode='eval')
+        self.assertEqual(len(list(ast.iter_child_nodes(node.body))), 4)
+        iterator = ast.iter_child_nodes(node.body)
+        self.assertEqual(next(iterator).id, 'spam')
+        self.assertEqual(next(iterator).n, 23)
+        self.assertEqual(next(iterator).n, 42)
+        self.assertEqual(ast.dump(next(iterator)),
+            "keyword(arg='eggs', value=Str(s='leek'))"
+        )
+
+    def test_get_docstring(self):
+        node = ast.parse('def foo():\n  """line one\n  line two"""')
+        self.assertEqual(ast.get_docstring(node.body[0]),
+                         'line one\nline two')
+
+    def test_literal_eval(self):
+        self.assertEqual(ast.literal_eval('[1, 2, 3]'), [1, 2, 3])
+        self.assertEqual(ast.literal_eval('{"foo": 42}'), {"foo": 42})
+        self.assertEqual(ast.literal_eval('(True, False, None)'), (True, False, None))
+        self.assertRaises(ValueError, ast.literal_eval, 'foo()')
+
+
 def test_main():
-    support.run_unittest(AST_Tests)
+    support.run_unittest(AST_Tests, ASTHelpers_Test)
 
 def main():
     if __name__ != '__main__':

Modified: python/branches/py3k/Lib/test/test_complex.py
==============================================================================
--- python/branches/py3k/Lib/test/test_complex.py	(original)
+++ python/branches/py3k/Lib/test/test_complex.py	Tue Jun 10 18:37:50 2008
@@ -352,6 +352,14 @@
             except (OSError, IOError):
                 pass
 
+    def test_getnewargs(self):
+        self.assertEqual((1+2j).__getnewargs__(), (1.0, 2.0))
+        self.assertEqual((1-2j).__getnewargs__(), (1.0, -2.0))
+        self.assertEqual((2j).__getnewargs__(), (0.0, 2.0))
+        self.assertEqual((-0j).__getnewargs__(), (0.0, -0.0))
+        self.assertEqual(complex(0, INF).__getnewargs__(), (0.0, INF))
+        self.assertEqual(complex(INF, 0).__getnewargs__(), (INF, 0.0))
+
     if float.__getformat__("double").startswith("IEEE"):
         def test_plus_minus_0j(self):
             # test that -0j and 0j literals are not identified

Modified: python/branches/py3k/Lib/test/test_inspect.py
==============================================================================
--- python/branches/py3k/Lib/test/test_inspect.py	(original)
+++ python/branches/py3k/Lib/test/test_inspect.py	Tue Jun 10 18:37:50 2008
@@ -195,6 +195,10 @@
         self.assertEqual(inspect.getdoc(git.abuse),
                          'Another\n\ndocstring\n\ncontaining\n\ntabs')
 
+    def test_cleandoc(self):
+        self.assertEqual(inspect.cleandoc('An\n    indented\n    docstring.'),
+                         'An\nindented\ndocstring.')
+
     def test_getcomments(self):
         self.assertEqual(inspect.getcomments(mod), '# line 1\n')
         self.assertEqual(inspect.getcomments(mod.StupidGit), '# line 20\n')

Modified: python/branches/py3k/Lib/test/test_threading.py
==============================================================================
--- python/branches/py3k/Lib/test/test_threading.py	(original)
+++ python/branches/py3k/Lib/test/test_threading.py	Tue Jun 10 18:37:50 2008
@@ -3,6 +3,7 @@
 import test.support
 from test.support import verbose
 import random
+import re
 import sys
 import threading
 import _thread
@@ -71,6 +72,8 @@
         for i in range(NUMTASKS):
             t = TestThread("<thread %d>"%i, self, sema, mutex, numrunning)
             threads.append(t)
+            self.failUnlessEqual(t.getIdent(), None)
+            self.assert_(re.match('<TestThread\(.*, initial\)>', repr(t)))
             t.start()
 
         if verbose:
@@ -78,6 +81,8 @@
         for t in threads:
             t.join(NUMTASKS)
             self.assert_(not t.isAlive())
+            self.failIfEqual(t.getIdent(), 0)
+            self.assert_(re.match('<TestThread\(.*, \w+ -?\d+\)>', repr(t)))
         if verbose:
             print('all tasks done')
         self.assertEqual(numrunning.get(), 0)

Modified: python/branches/py3k/Lib/threading.py
==============================================================================
--- python/branches/py3k/Lib/threading.py	(original)
+++ python/branches/py3k/Lib/threading.py	Tue Jun 10 18:37:50 2008
@@ -401,6 +401,7 @@
         self._args = args
         self._kwargs = kwargs
         self._daemonic = self._set_daemon()
+        self._ident = None
         self._started = Event()
         self._stopped = False
         self._block = Condition(Lock())
@@ -421,7 +422,9 @@
         if self._stopped:
             status = "stopped"
         if self._daemonic:
-            status = status + " daemon"
+            status += " daemon"
+        if self._ident is not None:
+            status += " %s" % self._ident
         return "<%s(%s, %s)>" % (self.__class__.__name__, self._name, status)
 
     def start(self):
@@ -469,9 +472,10 @@
 
     def _bootstrap_inner(self):
         try:
+            self._ident = _get_ident()
             self._started.set()
             _active_limbo_lock.acquire()
-            _active[_get_ident()] = self
+            _active[self._ident] = self
             del _limbo[self]
             _active_limbo_lock.release()
             if __debug__:
@@ -536,7 +540,7 @@
             with _active_limbo_lock:
                 self._stop()
                 try:
-                    # We don't call self.__delete() because it also
+                    # We don't call self._delete() because it also
                     # grabs _active_limbo_lock.
                     del _active[_get_ident()]
                 except:
@@ -625,6 +629,10 @@
         assert self._initialized, "Thread.__init__() not called"
         self._name = str(name)
 
+    def getIdent(self):
+        assert self._initialized, "Thread.__init__() not called"
+        return self._ident
+
     def isAlive(self):
         assert self._initialized, "Thread.__init__() not called"
         return self._started.isSet() and not self._stopped

Modified: python/branches/py3k/Misc/ACKS
==============================================================================
--- python/branches/py3k/Misc/ACKS	(original)
+++ python/branches/py3k/Misc/ACKS	Tue Jun 10 18:37:50 2008
@@ -155,6 +155,7 @@
 Jonathan Dasteel
 John DeGood
 Vincent Delft
+Arnaud Delobelle
 Erik Demaine
 Roger Dev
 Raghuram Devarakonda
@@ -573,6 +574,7 @@
 Kevin Rodgers
 Giampaolo Rodola
 Mike Romberg
+Armin Ronacher
 Case Roole
 Timothy Roscoe
 Jim Roskind

Modified: python/branches/py3k/Misc/developers.txt
==============================================================================
--- python/branches/py3k/Misc/developers.txt	(original)
+++ python/branches/py3k/Misc/developers.txt	Tue Jun 10 18:37:50 2008
@@ -17,6 +17,9 @@
 Permissions History
 -------------------
 
+- Gregor Lingl was given SVN access on 10 June 2008 by MvL,
+  for work on the turtle module.
+
 - Robert Schuppenies was given SVN access on 21 May 2008 by MvL,
   for GSoC contributions.
 

Modified: python/branches/py3k/Modules/itertoolsmodule.c
==============================================================================
--- python/branches/py3k/Modules/itertoolsmodule.c	(original)
+++ python/branches/py3k/Modules/itertoolsmodule.c	Tue Jun 10 18:37:50 2008
@@ -2019,7 +2019,7 @@
 }
 
 PyDoc_STRVAR(combinations_doc,
-"combinations(iterables) --> combinations object\n\
+"combinations(iterable[, r]) --> combinations object\n\
 \n\
 Return successive r-length combinations of elements in the iterable.\n\n\
 combinations(range(4), 3) --> (0,1,2), (0,1,3), (0,2,3), (1,2,3)");
@@ -2294,10 +2294,10 @@
 }
 
 PyDoc_STRVAR(permutations_doc,
-"permutations(iterables[, r]) --> permutations object\n\
+"permutations(iterable[, r]) --> permutations object\n\
 \n\
 Return successive r-length permutations of elements in the iterable.\n\n\
-permutations(range(4), 3) --> (0,1,2), (0,1,3), (0,2,3), (1,2,3)");
+permutations(range(3), 2) --> (0,1), (0,2), (1,0), (1,2), (2,0), (2,1)");
 
 static PyTypeObject permutations_type = {
 	PyVarObject_HEAD_INIT(NULL, 0)

Modified: python/branches/py3k/Objects/complexobject.c
==============================================================================
--- python/branches/py3k/Objects/complexobject.c	(original)
+++ python/branches/py3k/Objects/complexobject.c	Tue Jun 10 18:37:50 2008
@@ -693,7 +693,8 @@
 static PyObject *
 complex_getnewargs(PyComplexObject *v)
 {
-	return Py_BuildValue("(D)", &v->cval);
+	Py_complex c = v->cval;
+	return Py_BuildValue("(dd)", c.real, c.imag);
 }
 
 #if 0

From python-3000-checkins at python.org  Tue Jun 10 18:43:26 2008
From: python-3000-checkins at python.org (alexandre.vassalotti)
Date: Tue, 10 Jun 2008 18:43:26 +0200 (CEST)
Subject: [Python-3000-checkins] r64082 -
	python/branches/py3k/Modules/_bsddb.c
Message-ID: <20080610164326.566EB1E4002@bag.python.org>

Author: alexandre.vassalotti
Date: Tue Jun 10 18:43:26 2008
New Revision: 64082

Log:
Fixed _bsddb key allocation errors.


Modified:
   python/branches/py3k/Modules/_bsddb.c

Modified: python/branches/py3k/Modules/_bsddb.c
==============================================================================
--- python/branches/py3k/Modules/_bsddb.c	(original)
+++ python/branches/py3k/Modules/_bsddb.c	Tue Jun 10 18:43:26 2008
@@ -312,6 +312,10 @@
                         "Py_buffer malloc failed");
         return NULL;
     }
+
+    if (PyObject_GetBuffer(obj, view, PyBUF_SIMPLE))
+        return NULL;
+
     if (view->ndim > 1) {
         PyErr_SetString(PyExc_BufferError,
                         "buffers must be single dimension");

From python-3000-checkins at python.org  Tue Jun 10 18:57:33 2008
From: python-3000-checkins at python.org (georg.brandl)
Date: Tue, 10 Jun 2008 18:57:33 +0200 (CEST)
Subject: [Python-3000-checkins] r64083 - in python/branches/py3k:
	Doc/c-api/bytearray.rst Doc/c-api/type.rst
	Doc/library/codecs.rst Doc/library/http.cookies.rst
	Doc/library/os.rst Doc/tutorial/controlflow.rst
	Doc/tutorial/interpreter.rst Include/object.h
	Lib/collections.py Lib/distutils/command/bdist_wininst.py
	Lib/locale.py Lib/subprocess.py Lib/tarfile.py
	Lib/test/pydoc_mod.py Lib/test/test_subprocess.py
	Lib/test/test_tarfile.py Lib/xmlrpc/client.py
	Objects/setobject.c Objects/typeobject.c
	Objects/unicodeobject.c Python/bltinmodule.c
Message-ID: <20080610165733.590B01E4005@bag.python.org>

Author: georg.brandl
Date: Tue Jun 10 18:57:31 2008
New Revision: 64083

Log:
Merged revisions 63724,63726,63732,63744,63754-63755,63757-63758,63760,63775,63781-63782,63787,63805-63808,63818-63819,63823-63824 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/trunk

........
  r63724 | gregory.p.smith | 2008-05-26 22:22:14 +0200 (Mon, 26 May 2008) | 6 lines
  
  Fixes issue2791: subprocess.Popen.communicate leaked a file descripton until
  the last reference to the Popen instance was dropped.  Adding explicit
  close() calls fixes it.
  
  Candidate for backport to release25-maint.
........
  r63726 | benjamin.peterson | 2008-05-26 22:43:24 +0200 (Mon, 26 May 2008) | 2 lines
  
  fix minor grammar typo
........
  r63732 | benjamin.peterson | 2008-05-26 23:44:26 +0200 (Mon, 26 May 2008) | 2 lines
  
  remove duplication in test module
........
  r63744 | lars.gustaebel | 2008-05-27 14:39:23 +0200 (Tue, 27 May 2008) | 3 lines
  
  Do not close external file objects passed to tarfile.open(mode='w:bz2')
  when the TarFile is closed.
........
  r63754 | benjamin.peterson | 2008-05-28 03:12:35 +0200 (Wed, 28 May 2008) | 2 lines
  
  update tutorial function with more appropiate one from Eric Smith
........
  r63755 | mark.hammond | 2008-05-28 03:54:55 +0200 (Wed, 28 May 2008) | 2 lines
  
  bdist_wininst now works correctly when both --skip-build and --plat-name are specified.
........
  r63757 | georg.brandl | 2008-05-28 13:21:39 +0200 (Wed, 28 May 2008) | 2 lines
  
  #2989: add PyType_Modified().
........
  r63758 | benjamin.peterson | 2008-05-28 13:51:41 +0200 (Wed, 28 May 2008) | 2 lines
  
  fix spelling
........
  r63760 | georg.brandl | 2008-05-28 17:41:36 +0200 (Wed, 28 May 2008) | 2 lines
  
  #2990: prevent inconsistent state while updating method cache.
........
  r63775 | georg.brandl | 2008-05-29 09:18:17 +0200 (Thu, 29 May 2008) | 2 lines
  
  Two fixes in bytearray docs.
........
  r63781 | georg.brandl | 2008-05-29 09:38:37 +0200 (Thu, 29 May 2008) | 2 lines
  
  #2988: add note about catching CookieError when parsing untrusted cookie data.
........
  r63782 | georg.brandl | 2008-05-29 09:45:26 +0200 (Thu, 29 May 2008) | 2 lines
  
  #2985: allow i8 in XMLRPC responses.
........
  r63787 | georg.brandl | 2008-05-29 16:35:39 +0200 (Thu, 29 May 2008) | 2 lines
  
  Revert #2990 patch; it's not necessary as Armin showed.
........
  r63805 | raymond.hettinger | 2008-05-30 08:37:27 +0200 (Fri, 30 May 2008) | 1 line
  
  Issue 2784: fix leaks in exception exit.
........
  r63806 | raymond.hettinger | 2008-05-30 08:49:47 +0200 (Fri, 30 May 2008) | 1 line
  
  Issue 2855: Fix obscure crasher by slowing down the entire module.  Mimics what was done to dictionaries in r59223.
........
  r63807 | raymond.hettinger | 2008-05-30 09:16:53 +0200 (Fri, 30 May 2008) | 1 line
  
  Issue 2903:  Add __name__ in globals for namedtuple namespace.
........
  r63808 | georg.brandl | 2008-05-30 09:54:16 +0200 (Fri, 30 May 2008) | 2 lines
  
  #2999: fix name of third parameter in unicode.replace()'s docstring.
........
  r63818 | georg.brandl | 2008-05-30 21:12:13 +0200 (Fri, 30 May 2008) | 2 lines
  
  getloadavg() is not available on Windows.
........
  r63819 | georg.brandl | 2008-05-30 21:17:29 +0200 (Fri, 30 May 2008) | 2 lines
  
  Better quote with single quotes.
........
  r63823 | benjamin.peterson | 2008-05-30 22:44:39 +0200 (Fri, 30 May 2008) | 2 lines
  
  fix grammar
........
  r63824 | marc-andre.lemburg | 2008-05-30 22:52:18 +0200 (Fri, 30 May 2008) | 5 lines
  
  Update the locale module alias table.
  
  Closes #3011.
........


Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Doc/c-api/bytearray.rst
   python/branches/py3k/Doc/c-api/type.rst
   python/branches/py3k/Doc/library/codecs.rst
   python/branches/py3k/Doc/library/http.cookies.rst
   python/branches/py3k/Doc/library/os.rst
   python/branches/py3k/Doc/tutorial/controlflow.rst
   python/branches/py3k/Doc/tutorial/interpreter.rst
   python/branches/py3k/Include/object.h
   python/branches/py3k/Lib/collections.py
   python/branches/py3k/Lib/distutils/command/bdist_wininst.py
   python/branches/py3k/Lib/locale.py
   python/branches/py3k/Lib/subprocess.py
   python/branches/py3k/Lib/tarfile.py
   python/branches/py3k/Lib/test/pydoc_mod.py
   python/branches/py3k/Lib/test/test_subprocess.py
   python/branches/py3k/Lib/test/test_tarfile.py
   python/branches/py3k/Lib/xmlrpc/client.py
   python/branches/py3k/Objects/setobject.c
   python/branches/py3k/Objects/typeobject.c
   python/branches/py3k/Objects/unicodeobject.c
   python/branches/py3k/Python/bltinmodule.c

Modified: python/branches/py3k/Doc/c-api/bytearray.rst
==============================================================================
--- python/branches/py3k/Doc/c-api/bytearray.rst	(original)
+++ python/branches/py3k/Doc/c-api/bytearray.rst	Tue Jun 10 18:57:31 2008
@@ -10,7 +10,7 @@
 
 .. ctype:: PyByteArrayObject
 
-   This subtype of :ctype:`PyObject` represents a Python string object.
+   This subtype of :ctype:`PyObject` represents a Python bytearray object.
 
 
 .. cvar:: PyTypeObject PyByteArray_Type
@@ -36,10 +36,12 @@
    Return a new bytearray object from any object, *o*, that implements the
    buffer protocol.
 
+   .. XXX expand about the buffer protocol, at least somewhere
+
 
 .. cfunction:: PyObject* PyByteArray_FromStringAndSize(const char *string, Py_ssize_t len)
 
-   Create a new bytearray object from *string* and it's length, *len*.  On
+   Create a new bytearray object from *string* and its length, *len*.  On
    failure, *NULL* is returned.
 
 

Modified: python/branches/py3k/Doc/c-api/type.rst
==============================================================================
--- python/branches/py3k/Doc/c-api/type.rst	(original)
+++ python/branches/py3k/Doc/c-api/type.rst	Tue Jun 10 18:57:31 2008
@@ -35,7 +35,14 @@
 
 .. cfunction:: unsigned int PyType_ClearCache(void)
 
-   Clears the internal lookup cache. Return the current version tag.
+   Clear the internal lookup cache. Return the current version tag.
+
+
+.. cfunction:: void PyType_Modified(PyTypeObject *type)
+
+   Invalidate the internal lookup cache for the type and all of its
+   subtypes.  This function must be called after any manual
+   modification of the attributes or base classes of the type.
 
 
 .. cfunction:: int PyType_HasFeature(PyObject *o, int feature)

Modified: python/branches/py3k/Doc/library/codecs.rst
==============================================================================
--- python/branches/py3k/Doc/library/codecs.rst	(original)
+++ python/branches/py3k/Doc/library/codecs.rst	Tue Jun 10 18:57:31 2008
@@ -285,7 +285,8 @@
 ------------------
 
 The :mod:`codecs` module defines a set of base classes which define the
-interface and can also be used to easily write you own codecs for use in Python.
+interface and can also be used to easily write your own codecs for use in
+Python.
 
 Each codec has to define four interfaces to make it usable as codec in Python:
 stateless encoder, stateless decoder, stream reader and stream writer. The

Modified: python/branches/py3k/Doc/library/http.cookies.rst
==============================================================================
--- python/branches/py3k/Doc/library/http.cookies.rst	(original)
+++ python/branches/py3k/Doc/library/http.cookies.rst	Tue Jun 10 18:57:31 2008
@@ -17,6 +17,12 @@
 MSIE 3.0x doesn't follow the character rules outlined in those specs.  As a
 result, the parsing rules used are a bit less strict.
 
+.. note::
+
+   On encountering an invalid cookie, :exc:`CookieError` is raised, so if your
+   cookie data comes from a browser you should always prepare for invalid data
+   and catch :exc:`CookieError` on parsing.
+
 
 .. exception:: CookieError
 

Modified: python/branches/py3k/Doc/library/os.rst
==============================================================================
--- python/branches/py3k/Doc/library/os.rst	(original)
+++ python/branches/py3k/Doc/library/os.rst	Tue Jun 10 18:57:31 2008
@@ -1748,7 +1748,7 @@
 
    Return the number of processes in the system run queue averaged over the last
    1, 5, and 15 minutes or raises :exc:`OSError` if the load average was
-   unobtainable.
+   unobtainable.  Availability: Unix.
 
 
 .. function:: sysconf(name)

Modified: python/branches/py3k/Doc/tutorial/controlflow.rst
==============================================================================
--- python/branches/py3k/Doc/tutorial/controlflow.rst	(original)
+++ python/branches/py3k/Doc/tutorial/controlflow.rst	Tue Jun 10 18:57:31 2008
@@ -475,8 +475,8 @@
 up in a tuple.  Before the variable number of arguments, zero or more normal
 arguments may occur. ::
 
-   def fprintf(file, template, *args):
-       file.write(template.format(args))
+   def write_multiple_items(file, separator, *args):
+       file.write(separator.join(args))
 
  
 Normally, these ``variadic`` arguments will be last in the list of formal

Modified: python/branches/py3k/Doc/tutorial/interpreter.rst
==============================================================================
--- python/branches/py3k/Doc/tutorial/interpreter.rst	(original)
+++ python/branches/py3k/Doc/tutorial/interpreter.rst	Tue Jun 10 18:57:31 2008
@@ -51,8 +51,8 @@
 A second way of starting the interpreter is ``python -c command [arg] ...``,
 which executes the statement(s) in *command*, analogous to the shell's
 :option:`-c` option.  Since Python statements often contain spaces or other
-characters that are special to the shell, it is best to quote  *command* in its
-entirety with double quotes.
+characters that are special to the shell, it is usually advised to quote
+*command* in its entirety with single quotes.
 
 Some Python modules are also useful as scripts.  These can be invoked using
 ``python -m module [arg] ...``, which executes the source file for *module* as

Modified: python/branches/py3k/Include/object.h
==============================================================================
--- python/branches/py3k/Include/object.h	(original)
+++ python/branches/py3k/Include/object.h	Tue Jun 10 18:57:31 2008
@@ -417,6 +417,7 @@
 					       PyObject *, PyObject *);
 PyAPI_FUNC(PyObject *) _PyType_Lookup(PyTypeObject *, PyObject *);
 PyAPI_FUNC(unsigned int) PyType_ClearCache(void);
+PyAPI_FUNC(void) PyType_Modified(PyTypeObject *);
 
 /* Generic operations on objects */
 PyAPI_FUNC(int) PyObject_Print(PyObject *, FILE *, int);

Modified: python/branches/py3k/Lib/collections.py
==============================================================================
--- python/branches/py3k/Lib/collections.py	(original)
+++ python/branches/py3k/Lib/collections.py	Tue Jun 10 18:57:31 2008
@@ -93,8 +93,9 @@
     if verbose:
         print(template)
 
-    # Execute the template string in a temporary namespace
-    namespace = dict(itemgetter=_itemgetter)
+    # Execute the template string in a temporary namespace and
+    # support tracing utilities by setting a value for frame.f_globals['__name__']
+    namespace = dict(itemgetter=_itemgetter, __name__='namedtuple_%s' % typename)
     try:
         exec(template, namespace)
     except SyntaxError as e:

Modified: python/branches/py3k/Lib/distutils/command/bdist_wininst.py
==============================================================================
--- python/branches/py3k/Lib/distutils/command/bdist_wininst.py	(original)
+++ python/branches/py3k/Lib/distutils/command/bdist_wininst.py	Tue Jun 10 18:57:31 2008
@@ -75,6 +75,12 @@
 
     def finalize_options(self):
         if self.bdist_dir is None:
+            if self.skip_build and self.plat_name:
+                # If build is skipped and plat_name is overridden, bdist will
+                # not see the correct 'plat_name' - so set that up manually.
+                bdist = self.distribution.get_command_obj('bdist')
+                bdist.plat_name = self.plat_name
+                # next the command will be initialized using that name
             bdist_base = self.get_finalized_command('bdist').bdist_base
             self.bdist_dir = os.path.join(bdist_base, 'wininst')
         if not self.target_version:

Modified: python/branches/py3k/Lib/locale.py
==============================================================================
--- python/branches/py3k/Lib/locale.py	(original)
+++ python/branches/py3k/Lib/locale.py	Tue Jun 10 18:57:31 2008
@@ -626,6 +626,33 @@
 #    updated 'zh_cn.big5' -> 'zh_TW.eucTW' to 'zh_TW.big5'
 #    updated 'zh_tw' -> 'zh_TW.eucTW' to 'zh_TW.big5'
 #
+# MAL 2008-05-30:
+# Updated alias mapping to most recent locale.alias file
+# from X.org distribution using makelocalealias.py.
+#
+# These are the differences compared to the old mapping (Python 2.5
+# and older):
+#
+#    updated 'cs_cs.iso88592' -> 'cs_CZ.ISO8859-2' to 'cs_CS.ISO8859-2'
+#    updated 'serbocroatian' -> 'sh_YU.ISO8859-2' to 'sr_CS.ISO8859-2'
+#    updated 'sh' -> 'sh_YU.ISO8859-2' to 'sr_CS.ISO8859-2'
+#    updated 'sh_hr.iso88592' -> 'sh_HR.ISO8859-2' to 'hr_HR.ISO8859-2'
+#    updated 'sh_sp' -> 'sh_YU.ISO8859-2' to 'sr_CS.ISO8859-2'
+#    updated 'sh_yu' -> 'sh_YU.ISO8859-2' to 'sr_CS.ISO8859-2'
+#    updated 'sp' -> 'sp_YU.ISO8859-5' to 'sr_CS.ISO8859-5'
+#    updated 'sp_yu' -> 'sp_YU.ISO8859-5' to 'sr_CS.ISO8859-5'
+#    updated 'sr' -> 'sr_YU.ISO8859-5' to 'sr_CS.ISO8859-5'
+#    updated 'sr at cyrillic' -> 'sr_YU.ISO8859-5' to 'sr_CS.ISO8859-5'
+#    updated 'sr_sp' -> 'sr_SP.ISO8859-2' to 'sr_CS.ISO8859-2'
+#    updated 'sr_yu' -> 'sr_YU.ISO8859-5' to 'sr_CS.ISO8859-5'
+#    updated 'sr_yu.cp1251 at cyrillic' -> 'sr_YU.CP1251' to 'sr_CS.CP1251'
+#    updated 'sr_yu.iso88592' -> 'sr_YU.ISO8859-2' to 'sr_CS.ISO8859-2'
+#    updated 'sr_yu.iso88595' -> 'sr_YU.ISO8859-5' to 'sr_CS.ISO8859-5'
+#    updated 'sr_yu.iso88595 at cyrillic' -> 'sr_YU.ISO8859-5' to 'sr_CS.ISO8859-5'
+#    updated 'sr_yu.microsoftcp1251 at cyrillic' -> 'sr_YU.CP1251' to 'sr_CS.CP1251'
+#    updated 'sr_yu.utf8 at cyrillic' -> 'sr_YU.UTF-8' to 'sr_CS.UTF-8'
+#    updated 'sr_yu at cyrillic' -> 'sr_YU.ISO8859-5' to 'sr_CS.ISO8859-5'
+
 locale_alias = {
     'a3':                                   'a3_AZ.KOI8-C',
     'a3_az':                                'a3_AZ.KOI8-C',
@@ -634,30 +661,46 @@
     'af_za':                                'af_ZA.ISO8859-1',
     'af_za.iso88591':                       'af_ZA.ISO8859-1',
     'am':                                   'am_ET.UTF-8',
+    'am_et':                                'am_ET.UTF-8',
     'american':                             'en_US.ISO8859-1',
     'american.iso88591':                    'en_US.ISO8859-1',
     'ar':                                   'ar_AA.ISO8859-6',
     'ar_aa':                                'ar_AA.ISO8859-6',
     'ar_aa.iso88596':                       'ar_AA.ISO8859-6',
     'ar_ae':                                'ar_AE.ISO8859-6',
+    'ar_ae.iso88596':                       'ar_AE.ISO8859-6',
     'ar_bh':                                'ar_BH.ISO8859-6',
+    'ar_bh.iso88596':                       'ar_BH.ISO8859-6',
     'ar_dz':                                'ar_DZ.ISO8859-6',
+    'ar_dz.iso88596':                       'ar_DZ.ISO8859-6',
     'ar_eg':                                'ar_EG.ISO8859-6',
     'ar_eg.iso88596':                       'ar_EG.ISO8859-6',
     'ar_iq':                                'ar_IQ.ISO8859-6',
+    'ar_iq.iso88596':                       'ar_IQ.ISO8859-6',
     'ar_jo':                                'ar_JO.ISO8859-6',
+    'ar_jo.iso88596':                       'ar_JO.ISO8859-6',
     'ar_kw':                                'ar_KW.ISO8859-6',
+    'ar_kw.iso88596':                       'ar_KW.ISO8859-6',
     'ar_lb':                                'ar_LB.ISO8859-6',
+    'ar_lb.iso88596':                       'ar_LB.ISO8859-6',
     'ar_ly':                                'ar_LY.ISO8859-6',
+    'ar_ly.iso88596':                       'ar_LY.ISO8859-6',
     'ar_ma':                                'ar_MA.ISO8859-6',
+    'ar_ma.iso88596':                       'ar_MA.ISO8859-6',
     'ar_om':                                'ar_OM.ISO8859-6',
+    'ar_om.iso88596':                       'ar_OM.ISO8859-6',
     'ar_qa':                                'ar_QA.ISO8859-6',
+    'ar_qa.iso88596':                       'ar_QA.ISO8859-6',
     'ar_sa':                                'ar_SA.ISO8859-6',
     'ar_sa.iso88596':                       'ar_SA.ISO8859-6',
     'ar_sd':                                'ar_SD.ISO8859-6',
+    'ar_sd.iso88596':                       'ar_SD.ISO8859-6',
     'ar_sy':                                'ar_SY.ISO8859-6',
+    'ar_sy.iso88596':                       'ar_SY.ISO8859-6',
     'ar_tn':                                'ar_TN.ISO8859-6',
+    'ar_tn.iso88596':                       'ar_TN.ISO8859-6',
     'ar_ye':                                'ar_YE.ISO8859-6',
+    'ar_ye.iso88596':                       'ar_YE.ISO8859-6',
     'arabic':                               'ar_AA.ISO8859-6',
     'arabic.iso88596':                      'ar_AA.ISO8859-6',
     'az':                                   'az_AZ.ISO8859-9E',
@@ -673,6 +716,7 @@
     'bg_bg.iso88595':                       'bg_BG.ISO8859-5',
     'bg_bg.koi8r':                          'bg_BG.KOI8-R',
     'bg_bg.microsoftcp1251':                'bg_BG.CP1251',
+    'bn_in':                                'bn_IN.UTF-8',
     'bokmal':                               'nb_NO.ISO8859-1',
     'bokm\xe5l':                            'nb_NO.ISO8859-1',
     'br':                                   'br_FR.ISO8859-1',
@@ -680,7 +724,12 @@
     'br_fr.iso88591':                       'br_FR.ISO8859-1',
     'br_fr.iso885914':                      'br_FR.ISO8859-14',
     'br_fr.iso885915':                      'br_FR.ISO8859-15',
+    'br_fr.iso885915 at euro':                 'br_FR.ISO8859-15',
+    'br_fr.utf8 at euro':                      'br_FR.UTF-8',
     'br_fr at euro':                           'br_FR.ISO8859-15',
+    'bs':                                   'bs_BA.ISO8859-2',
+    'bs_ba':                                'bs_BA.ISO8859-2',
+    'bs_ba.iso88592':                       'bs_BA.ISO8859-2',
     'bulgarian':                            'bg_BG.CP1251',
     'c':                                    'C',
     'c-french':                             'fr_CA.ISO8859-1',
@@ -693,6 +742,8 @@
     'ca_es':                                'ca_ES.ISO8859-1',
     'ca_es.iso88591':                       'ca_ES.ISO8859-1',
     'ca_es.iso885915':                      'ca_ES.ISO8859-15',
+    'ca_es.iso885915 at euro':                 'ca_ES.ISO8859-15',
+    'ca_es.utf8 at euro':                      'ca_ES.UTF-8',
     'ca_es at euro':                           'ca_ES.ISO8859-15',
     'catalan':                              'ca_ES.ISO8859-1',
     'cextend':                              'en_US.ISO8859-1',
@@ -702,7 +753,7 @@
     'croatian':                             'hr_HR.ISO8859-2',
     'cs':                                   'cs_CZ.ISO8859-2',
     'cs_cs':                                'cs_CZ.ISO8859-2',
-    'cs_cs.iso88592':                       'cs_CZ.ISO8859-2',
+    'cs_cs.iso88592':                       'cs_CS.ISO8859-2',
     'cs_cz':                                'cs_CZ.ISO8859-2',
     'cs_cz.iso88592':                       'cs_CZ.ISO8859-2',
     'cy':                                   'cy_GB.ISO8859-1',
@@ -728,10 +779,14 @@
     'de_at':                                'de_AT.ISO8859-1',
     'de_at.iso88591':                       'de_AT.ISO8859-1',
     'de_at.iso885915':                      'de_AT.ISO8859-15',
+    'de_at.iso885915 at euro':                 'de_AT.ISO8859-15',
+    'de_at.utf8 at euro':                      'de_AT.UTF-8',
     'de_at at euro':                           'de_AT.ISO8859-15',
     'de_be':                                'de_BE.ISO8859-1',
     'de_be.iso88591':                       'de_BE.ISO8859-1',
     'de_be.iso885915':                      'de_BE.ISO8859-15',
+    'de_be.iso885915 at euro':                 'de_BE.ISO8859-15',
+    'de_be.utf8 at euro':                      'de_BE.UTF-8',
     'de_be at euro':                           'de_BE.ISO8859-15',
     'de_ch':                                'de_CH.ISO8859-1',
     'de_ch.iso88591':                       'de_CH.ISO8859-1',
@@ -743,10 +798,14 @@
     'de_de.885915 at euro':                    'de_DE.ISO8859-15',
     'de_de.iso88591':                       'de_DE.ISO8859-1',
     'de_de.iso885915':                      'de_DE.ISO8859-15',
+    'de_de.iso885915 at euro':                 'de_DE.ISO8859-15',
+    'de_de.utf8 at euro':                      'de_DE.UTF-8',
     'de_de at euro':                           'de_DE.ISO8859-15',
     'de_lu':                                'de_LU.ISO8859-1',
     'de_lu.iso88591':                       'de_LU.ISO8859-1',
     'de_lu.iso885915':                      'de_LU.ISO8859-15',
+    'de_lu.iso885915 at euro':                 'de_LU.ISO8859-15',
+    'de_lu.utf8 at euro':                      'de_LU.UTF-8',
     'de_lu at euro':                           'de_LU.ISO8859-15',
     'deutsch':                              'de_DE.ISO8859-1',
     'dutch':                                'nl_NL.ISO8859-1',
@@ -766,6 +825,7 @@
     'en_be':                                'en_BE.ISO8859-1',
     'en_be at euro':                           'en_BE.ISO8859-15',
     'en_bw':                                'en_BW.ISO8859-1',
+    'en_bw.iso88591':                       'en_BW.ISO8859-1',
     'en_ca':                                'en_CA.ISO8859-1',
     'en_ca.iso88591':                       'en_CA.ISO8859-1',
     'en_gb':                                'en_GB.ISO8859-1',
@@ -774,15 +834,20 @@
     'en_gb.iso885915':                      'en_GB.ISO8859-15',
     'en_gb at euro':                           'en_GB.ISO8859-15',
     'en_hk':                                'en_HK.ISO8859-1',
+    'en_hk.iso88591':                       'en_HK.ISO8859-1',
     'en_ie':                                'en_IE.ISO8859-1',
     'en_ie.iso88591':                       'en_IE.ISO8859-1',
     'en_ie.iso885915':                      'en_IE.ISO8859-15',
+    'en_ie.iso885915 at euro':                 'en_IE.ISO8859-15',
+    'en_ie.utf8 at euro':                      'en_IE.UTF-8',
     'en_ie at euro':                           'en_IE.ISO8859-15',
     'en_in':                                'en_IN.ISO8859-1',
     'en_nz':                                'en_NZ.ISO8859-1',
     'en_nz.iso88591':                       'en_NZ.ISO8859-1',
     'en_ph':                                'en_PH.ISO8859-1',
+    'en_ph.iso88591':                       'en_PH.ISO8859-1',
     'en_sg':                                'en_SG.ISO8859-1',
+    'en_sg.iso88591':                       'en_SG.ISO8859-1',
     'en_uk':                                'en_GB.ISO8859-1',
     'en_us':                                'en_US.ISO8859-1',
     'en_us.88591':                          'en_US.ISO8859-1',
@@ -798,6 +863,7 @@
     'en_za.iso885915':                      'en_ZA.ISO8859-15',
     'en_za at euro':                           'en_ZA.ISO8859-15',
     'en_zw':                                'en_ZW.ISO8859-1',
+    'en_zw.iso88591':                       'en_ZW.ISO8859-1',
     'eng_gb':                               'en_GB.ISO8859-1',
     'eng_gb.8859':                          'en_GB.ISO8859-1',
     'english':                              'en_EN.ISO8859-1',
@@ -833,6 +899,8 @@
     'es_es.88591':                          'es_ES.ISO8859-1',
     'es_es.iso88591':                       'es_ES.ISO8859-1',
     'es_es.iso885915':                      'es_ES.ISO8859-15',
+    'es_es.iso885915 at euro':                 'es_ES.ISO8859-15',
+    'es_es.utf8 at euro':                      'es_ES.UTF-8',
     'es_es at euro':                           'es_ES.ISO8859-15',
     'es_gt':                                'es_GT.ISO8859-1',
     'es_gt.iso88591':                       'es_GT.ISO8859-1',
@@ -861,6 +929,7 @@
     'es_sv.iso885915':                      'es_SV.ISO8859-15',
     'es_sv at euro':                           'es_SV.ISO8859-15',
     'es_us':                                'es_US.ISO8859-1',
+    'es_us.iso88591':                       'es_US.ISO8859-1',
     'es_uy':                                'es_UY.ISO8859-1',
     'es_uy.iso88591':                       'es_UY.ISO8859-1',
     'es_uy.iso885915':                      'es_UY.ISO8859-15',
@@ -881,6 +950,8 @@
     'eu_es':                                'eu_ES.ISO8859-1',
     'eu_es.iso88591':                       'eu_ES.ISO8859-1',
     'eu_es.iso885915':                      'eu_ES.ISO8859-15',
+    'eu_es.iso885915 at euro':                 'eu_ES.ISO8859-15',
+    'eu_es.utf8 at euro':                      'eu_ES.UTF-8',
     'eu_es at euro':                           'eu_ES.ISO8859-15',
     'fa':                                   'fa_IR.UTF-8',
     'fa_ir':                                'fa_IR.UTF-8',
@@ -890,6 +961,7 @@
     'fi_fi.88591':                          'fi_FI.ISO8859-1',
     'fi_fi.iso88591':                       'fi_FI.ISO8859-1',
     'fi_fi.iso885915':                      'fi_FI.ISO8859-15',
+    'fi_fi.iso885915 at euro':                 'fi_FI.ISO8859-15',
     'fi_fi.utf8 at euro':                      'fi_FI.UTF-8',
     'fi_fi at euro':                           'fi_FI.ISO8859-15',
     'finnish':                              'fi_FI.ISO8859-1',
@@ -904,6 +976,8 @@
     'fr_be.88591':                          'fr_BE.ISO8859-1',
     'fr_be.iso88591':                       'fr_BE.ISO8859-1',
     'fr_be.iso885915':                      'fr_BE.ISO8859-15',
+    'fr_be.iso885915 at euro':                 'fr_BE.ISO8859-15',
+    'fr_be.utf8 at euro':                      'fr_BE.UTF-8',
     'fr_be at euro':                           'fr_BE.ISO8859-15',
     'fr_ca':                                'fr_CA.ISO8859-1',
     'fr_ca.88591':                          'fr_CA.ISO8859-1',
@@ -919,11 +993,15 @@
     'fr_fr.88591':                          'fr_FR.ISO8859-1',
     'fr_fr.iso88591':                       'fr_FR.ISO8859-1',
     'fr_fr.iso885915':                      'fr_FR.ISO8859-15',
+    'fr_fr.iso885915 at euro':                 'fr_FR.ISO8859-15',
+    'fr_fr.utf8 at euro':                      'fr_FR.UTF-8',
     'fr_fr at euro':                           'fr_FR.ISO8859-15',
     'fr_lu':                                'fr_LU.ISO8859-1',
     'fr_lu.88591':                          'fr_LU.ISO8859-1',
     'fr_lu.iso88591':                       'fr_LU.ISO8859-1',
     'fr_lu.iso885915':                      'fr_LU.ISO8859-15',
+    'fr_lu.iso885915 at euro':                 'fr_LU.ISO8859-15',
+    'fr_lu.utf8 at euro':                      'fr_LU.UTF-8',
     'fr_lu at euro':                           'fr_LU.ISO8859-15',
     'fran\xe7ais':                          'fr_FR.ISO8859-1',
     'fre_fr':                               'fr_FR.ISO8859-1',
@@ -937,6 +1015,8 @@
     'ga_ie.iso88591':                       'ga_IE.ISO8859-1',
     'ga_ie.iso885914':                      'ga_IE.ISO8859-14',
     'ga_ie.iso885915':                      'ga_IE.ISO8859-15',
+    'ga_ie.iso885915 at euro':                 'ga_IE.ISO8859-15',
+    'ga_ie.utf8 at euro':                      'ga_IE.UTF-8',
     'ga_ie at euro':                           'ga_IE.ISO8859-15',
     'galego':                               'gl_ES.ISO8859-1',
     'galician':                             'gl_ES.ISO8859-1',
@@ -956,9 +1036,12 @@
     'gl_es':                                'gl_ES.ISO8859-1',
     'gl_es.iso88591':                       'gl_ES.ISO8859-1',
     'gl_es.iso885915':                      'gl_ES.ISO8859-15',
+    'gl_es.iso885915 at euro':                 'gl_ES.ISO8859-15',
+    'gl_es.utf8 at euro':                      'gl_ES.UTF-8',
     'gl_es at euro':                           'gl_ES.ISO8859-15',
     'greek':                                'el_GR.ISO8859-7',
     'greek.iso88597':                       'el_GR.ISO8859-7',
+    'gu_in':                                'gu_IN.UTF-8',
     'gv':                                   'gv_GB.ISO8859-1',
     'gv_gb':                                'gv_GB.ISO8859-1',
     'gv_gb.iso88591':                       'gv_GB.ISO8859-1',
@@ -1009,6 +1092,8 @@
     'it_it.88591':                          'it_IT.ISO8859-1',
     'it_it.iso88591':                       'it_IT.ISO8859-1',
     'it_it.iso885915':                      'it_IT.ISO8859-15',
+    'it_it.iso885915 at euro':                 'it_IT.ISO8859-15',
+    'it_it.utf8 at euro':                      'it_IT.UTF-8',
     'it_it at euro':                           'it_IT.ISO8859-15',
     'italian':                              'it_IT.ISO8859-1',
     'italian.iso88591':                     'it_IT.ISO8859-1',
@@ -1048,6 +1133,8 @@
     'kl_gl.iso88591':                       'kl_GL.ISO8859-1',
     'kl_gl.iso885915':                      'kl_GL.ISO8859-15',
     'kl_gl at euro':                           'kl_GL.ISO8859-15',
+    'km_kh':                                'km_KH.UTF-8',
+    'kn_in':                                'kn_IN.UTF-8',
     'ko':                                   'ko_KR.eucKR',
     'ko_kr':                                'ko_KR.eucKR',
     'ko_kr.euc':                            'ko_KR.eucKR',
@@ -1060,6 +1147,8 @@
     'kw_gb.iso885914':                      'kw_GB.ISO8859-14',
     'kw_gb.iso885915':                      'kw_GB.ISO8859-15',
     'kw_gb at euro':                           'kw_GB.ISO8859-15',
+    'ky':                                   'ky_KG.UTF-8',
+    'ky_kg':                                'ky_KG.UTF-8',
     'lithuanian':                           'lt_LT.ISO8859-13',
     'lo':                                   'lo_LA.MULELAO-1',
     'lo_la':                                'lo_LA.MULELAO-1',
@@ -1082,6 +1171,7 @@
     'mk_mk.cp1251':                         'mk_MK.CP1251',
     'mk_mk.iso88595':                       'mk_MK.ISO8859-5',
     'mk_mk.microsoftcp1251':                'mk_MK.CP1251',
+    'mr_in':                                'mr_IN.UTF-8',
     'ms':                                   'ms_MY.ISO8859-1',
     'ms_my':                                'ms_MY.ISO8859-1',
     'ms_my.iso88591':                       'ms_MY.ISO8859-1',
@@ -1099,11 +1189,15 @@
     'nl_be.88591':                          'nl_BE.ISO8859-1',
     'nl_be.iso88591':                       'nl_BE.ISO8859-1',
     'nl_be.iso885915':                      'nl_BE.ISO8859-15',
+    'nl_be.iso885915 at euro':                 'nl_BE.ISO8859-15',
+    'nl_be.utf8 at euro':                      'nl_BE.UTF-8',
     'nl_be at euro':                           'nl_BE.ISO8859-15',
     'nl_nl':                                'nl_NL.ISO8859-1',
     'nl_nl.88591':                          'nl_NL.ISO8859-1',
     'nl_nl.iso88591':                       'nl_NL.ISO8859-1',
     'nl_nl.iso885915':                      'nl_NL.ISO8859-15',
+    'nl_nl.iso885915 at euro':                 'nl_NL.ISO8859-15',
+    'nl_nl.utf8 at euro':                      'nl_NL.UTF-8',
     'nl_nl at euro':                           'nl_NL.ISO8859-15',
     'nn':                                   'nn_NO.ISO8859-1',
     'nn_no':                                'nn_NO.ISO8859-1',
@@ -1120,6 +1214,12 @@
     'no_no at euro':                           'no_NO.ISO8859-15',
     'norwegian':                            'no_NO.ISO8859-1',
     'norwegian.iso88591':                   'no_NO.ISO8859-1',
+    'nr':                                   'nr_ZA.ISO8859-1',
+    'nr_za':                                'nr_ZA.ISO8859-1',
+    'nr_za.iso88591':                       'nr_ZA.ISO8859-1',
+    'nso':                                  'nso_ZA.ISO8859-15',
+    'nso_za':                               'nso_ZA.ISO8859-15',
+    'nso_za.iso885915':                     'nso_ZA.ISO8859-15',
     'ny':                                   'ny_NO.ISO8859-1',
     'ny_no':                                'ny_NO.ISO8859-1',
     'ny_no.88591':                          'ny_NO.ISO8859-1',
@@ -1132,6 +1232,7 @@
     'oc_fr.iso88591':                       'oc_FR.ISO8859-1',
     'oc_fr.iso885915':                      'oc_FR.ISO8859-15',
     'oc_fr at euro':                           'oc_FR.ISO8859-15',
+    'pa_in':                                'pa_IN.UTF-8',
     'pd':                                   'pd_US.ISO8859-1',
     'pd_de':                                'pd_DE.ISO8859-1',
     'pd_de.iso88591':                       'pd_DE.ISO8859-1',
@@ -1167,6 +1268,7 @@
     'pt_pt.88591':                          'pt_PT.ISO8859-1',
     'pt_pt.iso88591':                       'pt_PT.ISO8859-1',
     'pt_pt.iso885915':                      'pt_PT.ISO8859-15',
+    'pt_pt.iso885915 at euro':                 'pt_PT.ISO8859-15',
     'pt_pt.utf8 at euro':                      'pt_PT.UTF-8',
     'pt_pt at euro':                           'pt_PT.ISO8859-15',
     'ro':                                   'ro_RO.ISO8859-2',
@@ -1185,13 +1287,19 @@
     'ru_ua.microsoftcp1251':                'ru_UA.CP1251',
     'rumanian':                             'ro_RO.ISO8859-2',
     'russian':                              'ru_RU.ISO8859-5',
+    'rw':                                   'rw_RW.ISO8859-1',
+    'rw_rw':                                'rw_RW.ISO8859-1',
+    'rw_rw.iso88591':                       'rw_RW.ISO8859-1',
     'se_no':                                'se_NO.UTF-8',
-    'serbocroatian':                        'sh_YU.ISO8859-2',
-    'sh':                                   'sh_YU.ISO8859-2',
+    'serbocroatian':                        'sr_CS.ISO8859-2',
+    'sh':                                   'sr_CS.ISO8859-2',
     'sh_hr':                                'sh_HR.ISO8859-2',
-    'sh_hr.iso88592':                       'sh_HR.ISO8859-2',
-    'sh_sp':                                'sh_YU.ISO8859-2',
-    'sh_yu':                                'sh_YU.ISO8859-2',
+    'sh_hr.iso88592':                       'hr_HR.ISO8859-2',
+    'sh_sp':                                'sr_CS.ISO8859-2',
+    'sh_yu':                                'sr_CS.ISO8859-2',
+    'si':                                   'si_LK.UTF-8',
+    'si_lk':                                'si_LK.UTF-8',
+    'sinhala':                              'si_LK.UTF-8',
     'sk':                                   'sk_SK.ISO8859-2',
     'sk_sk':                                'sk_SK.ISO8859-2',
     'sk_sk.iso88592':                       'sk_SK.ISO8859-2',
@@ -1202,8 +1310,8 @@
     'slovak':                               'sk_SK.ISO8859-2',
     'slovene':                              'sl_SI.ISO8859-2',
     'slovenian':                            'sl_SI.ISO8859-2',
-    'sp':                                   'sp_YU.ISO8859-5',
-    'sp_yu':                                'sp_YU.ISO8859-5',
+    'sp':                                   'sr_CS.ISO8859-5',
+    'sp_yu':                                'sr_CS.ISO8859-5',
     'spanish':                              'es_ES.ISO8859-1',
     'spanish.iso88591':                     'es_ES.ISO8859-1',
     'spanish_spain':                        'es_ES.ISO8859-1',
@@ -1211,21 +1319,35 @@
     'sq':                                   'sq_AL.ISO8859-2',
     'sq_al':                                'sq_AL.ISO8859-2',
     'sq_al.iso88592':                       'sq_AL.ISO8859-2',
-    'sr':                                   'sr_YU.ISO8859-5',
-    'sr at cyrillic':                          'sr_YU.ISO8859-5',
-    'sr_sp':                                'sr_SP.ISO8859-2',
-    'sr_yu':                                'sr_YU.ISO8859-5',
-    'sr_yu.cp1251 at cyrillic':                'sr_YU.CP1251',
-    'sr_yu.iso88592':                       'sr_YU.ISO8859-2',
-    'sr_yu.iso88595':                       'sr_YU.ISO8859-5',
-    'sr_yu.iso88595 at cyrillic':              'sr_YU.ISO8859-5',
-    'sr_yu.microsoftcp1251 at cyrillic':       'sr_YU.CP1251',
-    'sr_yu.utf8 at cyrillic':                  'sr_YU.UTF-8',
-    'sr_yu at cyrillic':                       'sr_YU.ISO8859-5',
+    'sr':                                   'sr_CS.ISO8859-5',
+    'sr at cyrillic':                          'sr_CS.ISO8859-5',
+    'sr at latn':                              'sr_CS.ISO8859-2',
+    'sr_cs.iso88592':                       'sr_CS.ISO8859-2',
+    'sr_cs.iso88592 at latn':                  'sr_CS.ISO8859-2',
+    'sr_cs.iso88595':                       'sr_CS.ISO8859-5',
+    'sr_cs.utf8 at latn':                      'sr_CS.UTF-8',
+    'sr_cs at latn':                           'sr_CS.ISO8859-2',
+    'sr_sp':                                'sr_CS.ISO8859-2',
+    'sr_yu':                                'sr_CS.ISO8859-5',
+    'sr_yu.cp1251 at cyrillic':                'sr_CS.CP1251',
+    'sr_yu.iso88592':                       'sr_CS.ISO8859-2',
+    'sr_yu.iso88595':                       'sr_CS.ISO8859-5',
+    'sr_yu.iso88595 at cyrillic':              'sr_CS.ISO8859-5',
+    'sr_yu.microsoftcp1251 at cyrillic':       'sr_CS.CP1251',
+    'sr_yu.utf8 at cyrillic':                  'sr_CS.UTF-8',
+    'sr_yu at cyrillic':                       'sr_CS.ISO8859-5',
+    'ss':                                   'ss_ZA.ISO8859-1',
+    'ss_za':                                'ss_ZA.ISO8859-1',
+    'ss_za.iso88591':                       'ss_ZA.ISO8859-1',
+    'st':                                   'st_ZA.ISO8859-1',
+    'st_za':                                'st_ZA.ISO8859-1',
+    'st_za.iso88591':                       'st_ZA.ISO8859-1',
     'sv':                                   'sv_SE.ISO8859-1',
     'sv_fi':                                'sv_FI.ISO8859-1',
     'sv_fi.iso88591':                       'sv_FI.ISO8859-1',
     'sv_fi.iso885915':                      'sv_FI.ISO8859-15',
+    'sv_fi.iso885915 at euro':                 'sv_FI.ISO8859-15',
+    'sv_fi.utf8 at euro':                      'sv_FI.UTF-8',
     'sv_fi at euro':                           'sv_FI.ISO8859-15',
     'sv_se':                                'sv_SE.ISO8859-1',
     'sv_se.88591':                          'sv_SE.ISO8859-1',
@@ -1250,9 +1372,15 @@
     'tl':                                   'tl_PH.ISO8859-1',
     'tl_ph':                                'tl_PH.ISO8859-1',
     'tl_ph.iso88591':                       'tl_PH.ISO8859-1',
+    'tn':                                   'tn_ZA.ISO8859-15',
+    'tn_za':                                'tn_ZA.ISO8859-15',
+    'tn_za.iso885915':                      'tn_ZA.ISO8859-15',
     'tr':                                   'tr_TR.ISO8859-9',
     'tr_tr':                                'tr_TR.ISO8859-9',
     'tr_tr.iso88599':                       'tr_TR.ISO8859-9',
+    'ts':                                   'ts_ZA.ISO8859-1',
+    'ts_za':                                'ts_ZA.ISO8859-1',
+    'ts_za.iso88591':                       'ts_ZA.ISO8859-1',
     'tt':                                   'tt_RU.TATAR-CYR',
     'tt_ru':                                'tt_RU.TATAR-CYR',
     'tt_ru.koi8c':                          'tt_RU.KOI8-C',
@@ -1274,6 +1402,11 @@
     'ur_pk.microsoftcp1256':                'ur_PK.CP1256',
     'uz':                                   'uz_UZ.UTF-8',
     'uz_uz':                                'uz_UZ.UTF-8',
+    'uz_uz.iso88591':                       'uz_UZ.ISO8859-1',
+    'uz_uz.utf8 at cyrillic':                  'uz_UZ.UTF-8',
+    'uz_uz at cyrillic':                       'uz_UZ.UTF-8',
+    've':                                   've_ZA.UTF-8',
+    've_za':                                've_ZA.UTF-8',
     'vi':                                   'vi_VN.TCVN',
     'vi_vn':                                'vi_VN.TCVN',
     'vi_vn.tcvn':                           'vi_VN.TCVN',
@@ -1284,7 +1417,11 @@
     'wa_be':                                'wa_BE.ISO8859-1',
     'wa_be.iso88591':                       'wa_BE.ISO8859-1',
     'wa_be.iso885915':                      'wa_BE.ISO8859-15',
+    'wa_be.iso885915 at euro':                 'wa_BE.ISO8859-15',
     'wa_be at euro':                           'wa_BE.ISO8859-15',
+    'xh':                                   'xh_ZA.ISO8859-1',
+    'xh_za':                                'xh_ZA.ISO8859-1',
+    'xh_za.iso88591':                       'xh_ZA.ISO8859-1',
     'yi':                                   'yi_US.CP1255',
     'yi_us':                                'yi_US.CP1255',
     'yi_us.cp1255':                         'yi_US.CP1255',
@@ -1302,6 +1439,10 @@
     'zh_tw':                                'zh_TW.big5',
     'zh_tw.big5':                           'zh_TW.big5',
     'zh_tw.euc':                            'zh_TW.eucTW',
+    'zh_tw.euctw':                          'zh_TW.eucTW',
+    'zu':                                   'zu_ZA.ISO8859-1',
+    'zu_za':                                'zu_ZA.ISO8859-1',
+    'zu_za.iso88591':                       'zu_ZA.ISO8859-1',
 }
 
 #

Modified: python/branches/py3k/Lib/subprocess.py
==============================================================================
--- python/branches/py3k/Lib/subprocess.py	(original)
+++ python/branches/py3k/Lib/subprocess.py	Tue Jun 10 18:57:31 2008
@@ -661,8 +661,10 @@
                 self.stdin.close()
             elif self.stdout:
                 stdout = self.stdout.read()
+                self.stdout.close()
             elif self.stderr:
                 stderr = self.stderr.read()
+                self.stderr.close()
             self.wait()
             return (stdout, stderr)
 

Modified: python/branches/py3k/Lib/tarfile.py
==============================================================================
--- python/branches/py3k/Lib/tarfile.py	(original)
+++ python/branches/py3k/Lib/tarfile.py	Tue Jun 10 18:57:31 2008
@@ -669,7 +669,6 @@
         if self.mode == "w":
             raw = self.bz2obj.flush()
             self.fileobj.write(raw)
-        self.fileobj.close()
 # class _BZ2Proxy
 
 #------------------------

Modified: python/branches/py3k/Lib/test/pydoc_mod.py
==============================================================================
--- python/branches/py3k/Lib/test/pydoc_mod.py	(original)
+++ python/branches/py3k/Lib/test/pydoc_mod.py	Tue Jun 10 18:57:31 2008
@@ -25,30 +25,3 @@
 
 def nodoc_func():
     pass
-"""This is a test module for test_pydoc"""
-
-__author__ = "Benjamin Peterson"
-__credits__ = "Nobody"
-__version__ = "1.2.3.4"
-
-
-class A:
-    """Hello and goodbye"""
-    def __init__():
-        """Wow, I have no function!"""
-        pass
-
-class B(object):
-    NO_MEANING = "eggs"
-    pass
-
-def doc_func():
-    """
-    This function solves all of the world's problems:
-    hunger
-    lack of Python
-    war
-    """
-
-def nodoc_func():
-    pass

Modified: python/branches/py3k/Lib/test/test_subprocess.py
==============================================================================
--- python/branches/py3k/Lib/test/test_subprocess.py	(original)
+++ python/branches/py3k/Lib/test/test_subprocess.py	Tue Jun 10 18:57:31 2008
@@ -292,7 +292,7 @@
         self.assertEqual(stdout, None)
         # When running with a pydebug build, the # of references is outputted
         # to stderr, so just check if stderr at least started with "pinapple"
-        self.assert_(stderr.startswith(b"pineapple"))
+        self.assertEqual(remove_stderr_debug_decorations(stderr), b"pineapple")
 
     def test_communicate(self):
         p = subprocess.Popen([sys.executable, "-c",
@@ -307,6 +307,22 @@
         self.assertEqual(remove_stderr_debug_decorations(stderr),
                          b"pineapple")
 
+    # This test is Linux specific for simplicity to at least have
+    # some coverage.  It is not a platform specific bug.
+    if os.path.isdir('/proc/%d/fd' % os.getpid()):
+        # Test for the fd leak reported in http://bugs.python.org/issue2791.
+        def test_communicate_pipe_fd_leak(self):
+            fd_directory = '/proc/%d/fd' % os.getpid()
+            num_fds_before_popen = len(os.listdir(fd_directory))
+            p = subprocess.Popen([sys.executable, '-c', 'print()'],
+                                 stdout=subprocess.PIPE)
+            p.communicate()
+            num_fds_after_communicate = len(os.listdir(fd_directory))
+            del p
+            num_fds_after_destruction = len(os.listdir(fd_directory))
+            self.assertEqual(num_fds_before_popen, num_fds_after_destruction)
+            self.assertEqual(num_fds_before_popen, num_fds_after_communicate)
+
     def test_communicate_returns(self):
         # communicate() should return None if no redirection is active
         p = subprocess.Popen([sys.executable, "-c",

Modified: python/branches/py3k/Lib/test/test_tarfile.py
==============================================================================
--- python/branches/py3k/Lib/test/test_tarfile.py	(original)
+++ python/branches/py3k/Lib/test/test_tarfile.py	Tue Jun 10 18:57:31 2008
@@ -528,7 +528,19 @@
         self.assertEqual(float(tarinfo.pax_headers["ctime"]), 1041808783.0)
 
 
-class WriteTest(unittest.TestCase):
+class WriteTestBase(unittest.TestCase):
+    # Put all write tests in here that are supposed to be tested
+    # in all possible mode combinations.
+
+    def test_fileobj_no_close(self):
+        fobj = io.BytesIO()
+        tar = tarfile.open(fileobj=fobj, mode=self.mode)
+        tar.addfile(tarfile.TarInfo("foo"))
+        tar.close()
+        self.assert_(fobj.closed is False, "external fileobjs must never closed")
+
+
+class WriteTest(WriteTestBase):
 
     mode = "w:"
 
@@ -651,7 +663,7 @@
             shutil.rmtree(tempdir)
 
 
-class StreamWriteTest(unittest.TestCase):
+class StreamWriteTest(WriteTestBase):
 
     mode = "w|"
 

Modified: python/branches/py3k/Lib/xmlrpc/client.py
==============================================================================
--- python/branches/py3k/Lib/xmlrpc/client.py	(original)
+++ python/branches/py3k/Lib/xmlrpc/client.py	Tue Jun 10 18:57:31 2008
@@ -800,6 +800,7 @@
         self.append(int(data))
         self._value = 0
     dispatch["i4"] = end_int
+    dispatch["i8"] = end_int
     dispatch["int"] = end_int
 
     def end_double(self, data):

Modified: python/branches/py3k/Objects/setobject.c
==============================================================================
--- python/branches/py3k/Objects/setobject.c	(original)
+++ python/branches/py3k/Objects/setobject.c	Tue Jun 10 18:57:31 2008
@@ -96,7 +96,9 @@
 	else {
 		if (entry->hash == hash) {
 			startkey = entry->key;
+			Py_INCREF(startkey);
 			cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
+			Py_DECREF(startkey);
 			if (cmp < 0)
 				return NULL;
 			if (table == so->table && entry->key == startkey) {
@@ -127,7 +129,9 @@
 			break;
 		if (entry->hash == hash && entry->key != dummy) {
 			startkey = entry->key;
+			Py_INCREF(startkey);
 			cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
+			Py_DECREF(startkey);
 			if (cmp < 0)
 				return NULL;
 			if (table == so->table && entry->key == startkey) {

Modified: python/branches/py3k/Objects/typeobject.c
==============================================================================
--- python/branches/py3k/Objects/typeobject.c	(original)
+++ python/branches/py3k/Objects/typeobject.c	Tue Jun 10 18:57:31 2008
@@ -33,7 +33,6 @@
 
 static struct method_cache_entry method_cache[1 << MCACHE_SIZE_EXP];
 static unsigned int next_version_tag = 0;
-static void type_modified(PyTypeObject *);
 
 unsigned int
 PyType_ClearCache(void)
@@ -48,12 +47,12 @@
 	}
 	next_version_tag = 0;
 	/* mark all version tags as invalid */
-	type_modified(&PyBaseObject_Type);
+	PyType_Modified(&PyBaseObject_Type);
 	return cur_version_tag;
 }
 
-static void
-type_modified(PyTypeObject *type)
+void
+PyType_Modified(PyTypeObject *type)
 {
 	/* Invalidate any cached data for the specified type and all
 	   subclasses.  This function is called after the base
@@ -87,7 +86,7 @@
 			ref = PyList_GET_ITEM(raw, i);
 			ref = PyWeakref_GET_OBJECT(ref);
 			if (ref != Py_None) {
-				type_modified((PyTypeObject *)ref);
+				PyType_Modified((PyTypeObject *)ref);
 			}
 		}
 	}
@@ -173,7 +172,7 @@
 			Py_INCREF(Py_None);
 		}
 		/* mark all version tags as invalid */
-		type_modified(&PyBaseObject_Type);
+		PyType_Modified(&PyBaseObject_Type);
 		return 1;
 	}
 	bases = type->tp_bases;
@@ -313,7 +312,7 @@
 		return -1;
 	}
 
-	type_modified(type);
+	PyType_Modified(type);
 
 	return PyDict_SetItemString(type->tp_dict, "__module__", value);
 }
@@ -341,7 +340,7 @@
 	int res = PyDict_SetItemString(type->tp_dict,
 				       "__abstractmethods__", value);
 	if (res == 0) {
-		type_modified(type);
+		PyType_Modified(type);
 		if (value && PyObject_IsTrue(value)) {
 			type->tp_flags |= Py_TPFLAGS_IS_ABSTRACT;
 		}
@@ -1520,7 +1519,7 @@
 	   from the custom MRO */
 	type_mro_modified(type, type->tp_bases);
 
-	type_modified(type);
+	PyType_Modified(type);
 
 	return 0;
 }
@@ -5750,7 +5749,7 @@
 	   update_subclasses() recursion below, but carefully:
 	   they each have their own conditions on which to stop
 	   recursing into subclasses. */
-	type_modified(type);
+	PyType_Modified(type);
 
 	init_slotdefs();
 	pp = ptrs;

Modified: python/branches/py3k/Objects/unicodeobject.c
==============================================================================
--- python/branches/py3k/Objects/unicodeobject.c	(original)
+++ python/branches/py3k/Objects/unicodeobject.c	Tue Jun 10 18:57:31 2008
@@ -7524,11 +7524,11 @@
 }
 
 PyDoc_STRVAR(replace__doc__,
-"S.replace (old, new[, maxsplit]) -> str\n\
+"S.replace (old, new[, count]) -> str\n\
 \n\
 Return a copy of S with all occurrences of substring\n\
-old replaced by new.  If the optional argument maxsplit is\n\
-given, only the first maxsplit occurrences are replaced.");
+old replaced by new.  If the optional argument count is\n\
+given, only the first count occurrences are replaced.");
 
 static PyObject*
 unicode_replace(PyUnicodeObject *self, PyObject *args)

Modified: python/branches/py3k/Python/bltinmodule.c
==============================================================================
--- python/branches/py3k/Python/bltinmodule.c	(original)
+++ python/branches/py3k/Python/bltinmodule.c	Tue Jun 10 18:57:31 2008
@@ -1889,7 +1889,7 @@
     				return PyFloat_FromDouble(f_result);
 			}
         		if (PyFloat_CheckExact(item)) {
-				PyFPE_START_PROTECT("add", return 0)
+				PyFPE_START_PROTECT("add", Py_DECREF(item); Py_DECREF(iter); return 0)
 				f_result += PyFloat_AS_DOUBLE(item);
 				PyFPE_END_PROTECT(f_result)
 				Py_DECREF(item);
@@ -1900,7 +1900,7 @@
 				int overflow;
 				value = PyLong_AsLongAndOverflow(item, &overflow);
 				if (!overflow) {
-					PyFPE_START_PROTECT("add", return 0)
+					PyFPE_START_PROTECT("add", Py_DECREF(item); Py_DECREF(iter); return 0)
 					f_result += (double)value;
 					PyFPE_END_PROTECT(f_result)
 					Py_DECREF(item);

From python-3000-checkins at python.org  Tue Jun 10 18:58:49 2008
From: python-3000-checkins at python.org (georg.brandl)
Date: Tue, 10 Jun 2008 18:58:49 +0200 (CEST)
Subject: [Python-3000-checkins] r64084 - python/branches/py3k
Message-ID: <20080610165849.4A88A1E4002@bag.python.org>

Author: georg.brandl
Date: Tue Jun 10 18:58:49 2008
New Revision: 64084

Log:
Blocked revisions 63384,63545,63568,63914,63932,64028 via svnmerge

........
  r63384 | alexandre.vassalotti | 2008-05-16 20:03:52 +0200 (Fri, 16 May 2008) | 5 lines
  
  Patch by Quentin Gallet-Gilles: Renaming leftovers for 2.6.
  
  This fixes the omissions of configparser, copyreg, queue and
  socketserver renaming.
........
  r63545 | mark.dickinson | 2008-05-23 06:22:50 +0200 (Fri, 23 May 2008) | 6 lines
  
  Temporary checkin to get configure to report more
  information about the processor on the Debian/alpha
  buildbot.  (I'm still trying to track down the cause
  of the test_math failures for this machine.)  This
  checkin will be reverted within the next 48 hours.
........
  r63568 | mark.dickinson | 2008-05-23 20:04:06 +0200 (Fri, 23 May 2008) | 2 lines
  
  Revert temporary checkin in revision 63545.
........
  r63914 | georg.brandl | 2008-06-03 12:23:15 +0200 (Tue, 03 Jun 2008) | 2 lines
  
  Fix Tkinter sequence passing. #2906.
........
  r63932 | georg.brandl | 2008-06-04 13:17:26 +0200 (Wed, 04 Jun 2008) | 2 lines
  
  Complete revision of new turtle module's docs.
........
  r64028 | benjamin.peterson | 2008-06-07 22:44:48 +0200 (Sat, 07 Jun 2008) | 2 lines
  
  capitalization nit
........


Modified:
   python/branches/py3k/   (props changed)

From python-3000-checkins at python.org  Tue Jun 10 19:40:06 2008
From: python-3000-checkins at python.org (georg.brandl)
Date: Tue, 10 Jun 2008 19:40:06 +0200 (CEST)
Subject: [Python-3000-checkins] r64085 - in python/branches/py3k:
	Doc/library/ftplib.rst Doc/library/http.client.rst
	Doc/library/poplib.rst Doc/library/smtplib.rst
	Doc/library/socket.rst Doc/library/telnetlib.rst
	Doc/library/urllib2.rst Include/pyport.h Lib/ftplib.py
	Lib/heapq.py Lib/http/client.py Lib/poplib.py Lib/smtplib.py
	Lib/socket.py Lib/sqlite3/test/dbapi.py Lib/telnetlib.py
	Lib/test/test_datetime.py Lib/test/test_ftplib.py
	Lib/test/test_httplib.py Lib/test/test_math.py
	Lib/test/test_poplib.py Lib/test/test_smtplib.py
	Lib/test/test_socket.py Lib/test/test_telnetlib.py
	Lib/test/test_urllib.py Lib/test/test_urllib2.py
	Lib/test/test_urllib2net.py Lib/urllib.py Lib/urllib2.py
	Modules/_ctypes/libffi/configure Modules/_ctypes/libffi/configure.ac
	Modules/_ctypes/malloc_closure.c Modules/_heapqmodule.c
	Modules/_sqlite/cursor.c Modules/_sqlite/cursor.h
	Modules/datetimemodule.c Modules/mathmodule.c
	PCbuild/pyproject.vsprops Python/mysnprintf.c configure.in
	pyconfig.h.in setup.py
Message-ID: <20080610174006.F0BA21E4002@bag.python.org>

Author: georg.brandl
Date: Tue Jun 10 19:40:04 2008
New Revision: 64085

Log:
Merged revisions 63562,63570,63728,63734,63784,63788,63802,63817,63827,63839,63887,63975,63998 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/trunk

........
  r63562 | martin.v.loewis | 2008-05-23 17:06:50 +0200 (Fri, 23 May 2008) | 2 lines
  
  Patch #1722225: Support QNX 6.
........
  r63570 | trent.nelson | 2008-05-23 22:33:14 +0200 (Fri, 23 May 2008) | 1 line
  
  Introduce a user macro named $(externalsDir), which should point to the root directory of where all the external sources should live.  Developers can change this value if their external sources live elsewhere.  The default of '..\..' matches the current status quo.
........
  r63728 | gregory.p.smith | 2008-05-26 23:16:34 +0200 (Mon, 26 May 2008) | 4 lines
  
  Fix issue2589: there was a potential integer overflow leading to
  memory corruption on esoteric platforms and incorrect behavior on
  normal platforms.
........
  r63734 | gregory.p.smith | 2008-05-27 00:07:28 +0200 (Tue, 27 May 2008) | 3 lines
  
  Fix issue2588: Do not execute str[size-1] = '\0' when a 0 size is
  passed in.  (The assert won't prevent this in non-debug builds).
........
  r63784 | raymond.hettinger | 2008-05-29 10:38:23 +0200 (Thu, 29 May 2008) | 1 line
  
  Fix two typos.
........
  r63788 | facundo.batista | 2008-05-29 18:39:26 +0200 (Thu, 29 May 2008) | 6 lines
  
  
  Fixed the semantic of timeout for socket.create_connection and
  all the upper level libraries that use it, including urllib2.
  Added and fixed some tests, and changed docs correspondingly.
  Thanks to John J Lee for the patch and the pusing, :)
........
  r63802 | mark.dickinson | 2008-05-30 04:46:53 +0200 (Fri, 30 May 2008) | 2 lines
  
  Fix typo in testSum
........
  r63817 | raymond.hettinger | 2008-05-30 20:20:50 +0200 (Fri, 30 May 2008) | 8 lines
  
  * Mark intermedidate computes values (hi, lo, yr) as volatile.
  * Expand comments.
  * Swap variable names in the sum_exact code so that x and y
    are consistently chosen as the larger and smaller magnitude
    values respectively.
........
  r63827 | raymond.hettinger | 2008-05-31 05:24:31 +0200 (Sat, 31 May 2008) | 1 line
  
  Implement heapq in terms of less-than (to match list.sort()).
........
  r63839 | gerhard.haering | 2008-05-31 23:33:27 +0200 (Sat, 31 May 2008) | 2 lines
  
  Fixed rowcount for SELECT statements. They're -1 now (again), for better DB-API 2.0 compliance.
........
  r63887 | gregory.p.smith | 2008-06-02 06:05:52 +0200 (Mon, 02 Jun 2008) | 4 lines
  
  Fix issue 2782: be less strict about the format string type in strftime.
  Accept unicode and anything else ParseTuple "s#" can deal with.  This
  matches the time.strftime behavior.
........
  r63975 | neal.norwitz | 2008-06-06 06:47:01 +0200 (Fri, 06 Jun 2008) | 3 lines
  
  Aldo Cortesi confirmed this is still needed for OpenBSD 4.2 and 4.3.
  (I didn't regen configure, since I don't have a working autoconf.)
........
  r63998 | raymond.hettinger | 2008-06-06 23:47:51 +0200 (Fri, 06 Jun 2008) | 1 line
  
  Issue 3501: Make heapq support both __le__ and __lt__.
........


Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Doc/library/ftplib.rst
   python/branches/py3k/Doc/library/http.client.rst
   python/branches/py3k/Doc/library/poplib.rst
   python/branches/py3k/Doc/library/smtplib.rst
   python/branches/py3k/Doc/library/socket.rst
   python/branches/py3k/Doc/library/telnetlib.rst
   python/branches/py3k/Doc/library/urllib2.rst
   python/branches/py3k/Include/pyport.h
   python/branches/py3k/Lib/ftplib.py
   python/branches/py3k/Lib/heapq.py
   python/branches/py3k/Lib/http/client.py
   python/branches/py3k/Lib/poplib.py
   python/branches/py3k/Lib/smtplib.py
   python/branches/py3k/Lib/socket.py
   python/branches/py3k/Lib/sqlite3/test/dbapi.py
   python/branches/py3k/Lib/telnetlib.py
   python/branches/py3k/Lib/test/test_datetime.py
   python/branches/py3k/Lib/test/test_ftplib.py
   python/branches/py3k/Lib/test/test_httplib.py
   python/branches/py3k/Lib/test/test_math.py
   python/branches/py3k/Lib/test/test_poplib.py
   python/branches/py3k/Lib/test/test_smtplib.py
   python/branches/py3k/Lib/test/test_socket.py
   python/branches/py3k/Lib/test/test_telnetlib.py
   python/branches/py3k/Lib/test/test_urllib.py
   python/branches/py3k/Lib/test/test_urllib2.py
   python/branches/py3k/Lib/test/test_urllib2net.py
   python/branches/py3k/Lib/urllib.py
   python/branches/py3k/Lib/urllib2.py
   python/branches/py3k/Modules/_ctypes/libffi/configure
   python/branches/py3k/Modules/_ctypes/libffi/configure.ac
   python/branches/py3k/Modules/_ctypes/malloc_closure.c
   python/branches/py3k/Modules/_heapqmodule.c
   python/branches/py3k/Modules/_sqlite/cursor.c
   python/branches/py3k/Modules/_sqlite/cursor.h
   python/branches/py3k/Modules/datetimemodule.c
   python/branches/py3k/Modules/mathmodule.c
   python/branches/py3k/PCbuild/pyproject.vsprops
   python/branches/py3k/Python/mysnprintf.c
   python/branches/py3k/configure.in
   python/branches/py3k/pyconfig.h.in
   python/branches/py3k/setup.py

Modified: python/branches/py3k/Doc/library/ftplib.rst
==============================================================================
--- python/branches/py3k/Doc/library/ftplib.rst	(original)
+++ python/branches/py3k/Doc/library/ftplib.rst	Tue Jun 10 19:40:04 2008
@@ -44,8 +44,8 @@
    the method call ``login(user, passwd, acct)`` is made (where *passwd* and
    *acct* default to the empty string when not given).  The optional *timeout*
    parameter specifies a timeout in seconds for blocking operations like the
-   connection attempt (if is not specified, or passed as None, the global
-   default timeout setting will be used).
+   connection attempt (if is not specified, the global default timeout setting
+   will be used).
 
 
    .. attribute:: all_errors
@@ -123,10 +123,8 @@
    made.
 
    The optional *timeout* parameter specifies a timeout in seconds for the
-   connection attempt. If is not specified, or passed as None, the object
-   timeout is used (the timeout that you passed when instantiating the class);
-   if the object timeout is also None, the global default timeout setting will
-   be used.
+   connection attempt. If no *timeout* is passed, the global default timeout
+   setting will be used.
 
 
 .. method:: FTP.getwelcome()

Modified: python/branches/py3k/Doc/library/http.client.rst
==============================================================================
--- python/branches/py3k/Doc/library/http.client.rst	(original)
+++ python/branches/py3k/Doc/library/http.client.rst	Tue Jun 10 19:40:04 2008
@@ -33,7 +33,7 @@
    be raised if the status line can't be parsed as a valid HTTP/1.0 or 1.1
    status line.  If the optional *timeout* parameter is given, blocking
    operations (like connection attempts) will timeout after that many seconds
-   (if it is not given or ``None``, the global default timeout setting is used).
+   (if it is not given, the global default timeout setting is used).
 
    For example, the following calls all create instances that connect to the server
    at the same host and port::

Modified: python/branches/py3k/Doc/library/poplib.rst
==============================================================================
--- python/branches/py3k/Doc/library/poplib.rst	(original)
+++ python/branches/py3k/Doc/library/poplib.rst	Tue Jun 10 19:40:04 2008
@@ -29,8 +29,8 @@
    This class implements the actual POP3 protocol.  The connection is created when
    the instance is initialized. If *port* is omitted, the standard POP3 port (110)
    is used. The optional *timeout* parameter specifies a timeout in seconds for the
-   connection attempt (if not specified, or passed as None, the global default
-   timeout setting will be used).
+   connection attempt (if not specified, the global default timeout setting will
+   be used).
 
 
 .. class:: POP3_SSL(host[, port[, keyfile[, certfile]]])

Modified: python/branches/py3k/Doc/library/smtplib.rst
==============================================================================
--- python/branches/py3k/Doc/library/smtplib.rst	(original)
+++ python/branches/py3k/Doc/library/smtplib.rst	Tue Jun 10 19:40:04 2008
@@ -25,8 +25,8 @@
    with those parameters during initialization.  An :exc:`SMTPConnectError` is
    raised if the specified host doesn't respond correctly. The optional
    *timeout* parameter specifies a timeout in seconds for blocking operations
-   like the connection attempt (if not specified, or passed as None, the global
-   default timeout setting will be used).
+   like the connection attempt (if not specified, the global default timeout
+   setting will be used).
 
    For normal use, you should only require the initialization/connect,
    :meth:`sendmail`, and :meth:`quit` methods.  An example is included below.
@@ -42,8 +42,8 @@
    and *certfile* are also optional, and can contain a PEM formatted private key
    and certificate chain file for the SSL connection. The optional *timeout*
    parameter specifies a timeout in seconds for blocking operations like the
-   connection attempt (if not specified, or passed as None, the global default
-   timeout setting will be used).
+   connection attempt (if not specified, the global default timeout setting
+   will be used).
 
 
 .. class:: LMTP([host[, port[, local_hostname]]])

Modified: python/branches/py3k/Doc/library/socket.rst
==============================================================================
--- python/branches/py3k/Doc/library/socket.rst	(original)
+++ python/branches/py3k/Doc/library/socket.rst	Tue Jun 10 19:40:04 2008
@@ -197,12 +197,11 @@
 
 .. function:: create_connection(address[, timeout])
 
-   Connects to the *address* received (as usual, a ``(host, port)`` pair), with an
-   optional timeout for the connection.  Especially useful for higher-level
-   protocols, it is not normally used directly from application-level code.
-   Passing the optional *timeout* parameter will set the timeout on the socket
-   instance (if it is not given or ``None``, the global default timeout setting is
-   used).
+   Convenience function.  Connect to *address* (a 2-tuple ``(host, port)``),
+   and return the socket object.  Passing the optional *timeout* parameter will
+   set the timeout on the socket instance before attempting to connect.  If no
+   *timeout* is supplied, the global default timeout setting returned by
+   :func:`getdefaulttimeout` is used.
 
 
 .. function:: getaddrinfo(host, port[, family[, socktype[, proto[, flags]]]])

Modified: python/branches/py3k/Doc/library/telnetlib.rst
==============================================================================
--- python/branches/py3k/Doc/library/telnetlib.rst	(original)
+++ python/branches/py3k/Doc/library/telnetlib.rst	Tue Jun 10 19:40:04 2008
@@ -28,6 +28,11 @@
    :class:`Telnet` represents a connection to a Telnet server. The instance is
    initially not connected by default; the :meth:`open` method must be used to
    establish a connection.  Alternatively, the host name and optional port
+   and timeout can be passed to the constructor, in which case the connection to
+   the server will be established before the constructor returns.  The optional
+   *timeout* parameter specifies a timeout in seconds for the connection attempt (if
+   not specified, the global default timeout setting will be used).
+
    number can be passed to the constructor, to, in which case the connection to
    the server will be established before the constructor returns. The optional
    *timeout* parameter specifies a timeout in seconds for blocking operations
@@ -123,8 +128,7 @@
    Connect to a host. The optional second argument is the port number, which
    defaults to the standard Telnet port (23). The optional *timeout* parameter
    specifies a timeout in seconds for blocking operations like the connection
-   attempt (if not specified, or passed as None, the global default timeout
-   setting will be used).
+   attempt (if not specified, the global default timeout setting will be used).
 
    Do not try to reopen an already connected instance.
 

Modified: python/branches/py3k/Doc/library/urllib2.rst
==============================================================================
--- python/branches/py3k/Doc/library/urllib2.rst	(original)
+++ python/branches/py3k/Doc/library/urllib2.rst	Tue Jun 10 19:40:04 2008
@@ -27,9 +27,9 @@
    returns a string in this format.
 
    The optional *timeout* parameter specifies a timeout in seconds for blocking
-   operations like the connection attempt (if not specified, or passed as
-   ``None``, the global default timeout setting will be used).  This actually
-   only works for HTTP, HTTPS, FTP and FTPS connections.
+   operations like the connection attempt (if not specified, the global default
+   timeout setting will be used).  This actually only works for HTTP, HTTPS,
+   FTP and FTPS connections.
 
    This function returns a file-like object with two additional methods:
 
@@ -404,9 +404,9 @@
    the same as those of :func:`urlopen` (which simply calls the :meth:`open`
    method on the currently installed global :class:`OpenerDirector`).  The
    optional *timeout* parameter specifies a timeout in seconds for blocking
-   operations like the connection attempt (if not specified, or passed as
-   ``None``, the global default timeout setting will be used; this actually only
-   works for HTTP, HTTPS, FTP and FTPS connections).
+   operations like the connection attempt (if not specified, the global default
+   timeout setting will be usedi). The timeout feature actually works only for
+   HTTP, HTTPS, FTP and FTPS connections).
 
 
 .. method:: OpenerDirector.error(proto[, arg[, ...]])

Modified: python/branches/py3k/Include/pyport.h
==============================================================================
--- python/branches/py3k/Include/pyport.h	(original)
+++ python/branches/py3k/Include/pyport.h	Tue Jun 10 19:40:04 2008
@@ -431,6 +431,13 @@
 extern char * _getpty(int *, int, mode_t, int);
 #endif
 
+/* On QNX 6, struct termio must be declared by including sys/termio.h
+   if TCGETA, TCSETA, TCSETAW, or TCSETAF are used.  sys/termio.h must
+   be included before termios.h or it will generate an error. */
+#ifdef HAVE_SYS_TERMIO_H
+#include <sys/termio.h>
+#endif
+
 #if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
 #if !defined(HAVE_PTY_H) && !defined(HAVE_LIBUTIL_H)
 /* BSDI does not supply a prototype for the 'openpty' and 'forkpty'

Modified: python/branches/py3k/Lib/ftplib.py
==============================================================================
--- python/branches/py3k/Lib/ftplib.py	(original)
+++ python/branches/py3k/Lib/ftplib.py	Tue Jun 10 19:40:04 2008
@@ -44,6 +44,7 @@
     from socket import getfqdn; socket.getfqdn = getfqdn; del getfqdn
 except ImportError:
     import socket
+from socket import _GLOBAL_DEFAULT_TIMEOUT
 
 __all__ = ["FTP","Netrc"]
 
@@ -71,7 +72,6 @@
 # Line terminators (we always output CRLF, but accept any of CRLF, CR, LF)
 CRLF = '\r\n'
 
-
 # The class itself
 class FTP:
 
@@ -110,14 +110,15 @@
     # Initialize host to localhost, port to standard ftp port
     # Optional arguments are host (for connect()),
     # and user, passwd, acct (for login())
-    def __init__(self, host='', user='', passwd='', acct='', timeout=None):
+    def __init__(self, host='', user='', passwd='', acct='',
+                 timeout=_GLOBAL_DEFAULT_TIMEOUT):
         self.timeout = timeout
         if host:
             self.connect(host)
             if user:
                 self.login(user, passwd, acct)
 
-    def connect(self, host='', port=0, timeout=None):
+    def connect(self, host='', port=0, timeout=-999):
         '''Connect to host.  Arguments are:
          - host: hostname to connect to (string, default previous host)
          - port: port to connect to (integer, default previous port)
@@ -126,7 +127,7 @@
             self.host = host
         if port > 0:
             self.port = port
-        if timeout is not None:
+        if timeout != -999:
             self.timeout = timeout
         self.sock = socket.create_connection((self.host, self.port), self.timeout)
         self.af = self.sock.family

Modified: python/branches/py3k/Lib/heapq.py
==============================================================================
--- python/branches/py3k/Lib/heapq.py	(original)
+++ python/branches/py3k/Lib/heapq.py	Tue Jun 10 19:40:04 2008
@@ -167,7 +167,7 @@
 
 def heappushpop(heap, item):
     """Fast version of a heappush followed by a heappop."""
-    if heap and item > heap[0]:
+    if heap and heap[0] < item:
         item, heap[0] = heap[0], item
         _siftup(heap, 0)
     return item
@@ -240,10 +240,11 @@
     while pos > startpos:
         parentpos = (pos - 1) >> 1
         parent = heap[parentpos]
-        if parent <= newitem:
-            break
-        heap[pos] = parent
-        pos = parentpos
+        if newitem < parent:
+            heap[pos] = parent
+            pos = parentpos
+            continue
+        break
     heap[pos] = newitem
 
 # The child indices of heap index pos are already heaps, and we want to make
@@ -294,7 +295,7 @@
     while childpos < endpos:
         # Set childpos to index of smaller child.
         rightpos = childpos + 1
-        if rightpos < endpos and heap[rightpos] <= heap[childpos]:
+        if rightpos < endpos and not heap[childpos] < heap[rightpos]:
             childpos = rightpos
         # Move the smaller child up.
         heap[pos] = heap[childpos]

Modified: python/branches/py3k/Lib/http/client.py
==============================================================================
--- python/branches/py3k/Lib/http/client.py	(original)
+++ python/branches/py3k/Lib/http/client.py	Tue Jun 10 19:40:04 2008
@@ -664,7 +664,8 @@
     debuglevel = 0
     strict = 0
 
-    def __init__(self, host, port=None, strict=None, timeout=None):
+    def __init__(self, host, port=None, strict=None,
+                 timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
         self.timeout = timeout
         self.sock = None
         self._buffer = []
@@ -996,7 +997,7 @@
         default_port = HTTPS_PORT
 
         def __init__(self, host, port=None, key_file=None, cert_file=None,
-                     strict=None, timeout=None):
+                     strict=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
             HTTPConnection.__init__(self, host, port, strict, timeout)
             self.key_file = key_file
             self.cert_file = cert_file

Modified: python/branches/py3k/Lib/poplib.py
==============================================================================
--- python/branches/py3k/Lib/poplib.py	(original)
+++ python/branches/py3k/Lib/poplib.py	Tue Jun 10 19:40:04 2008
@@ -76,7 +76,8 @@
     """
 
 
-    def __init__(self, host, port=POP3_PORT, timeout=None):
+    def __init__(self, host, port=POP3_PORT,
+                 timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
         self.host = host
         self.port = port
         self.sock = socket.create_connection((host, port), timeout)

Modified: python/branches/py3k/Lib/smtplib.py
==============================================================================
--- python/branches/py3k/Lib/smtplib.py	(original)
+++ python/branches/py3k/Lib/smtplib.py	Tue Jun 10 19:40:04 2008
@@ -220,7 +220,8 @@
     ehlo_resp = None
     does_esmtp = 0
 
-    def __init__(self, host='', port=0, local_hostname=None, timeout=None):
+    def __init__(self, host='', port=0, local_hostname=None,
+                 timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
         """Initialize a new instance.
 
         If specified, `host' is the name of the remote host to which to
@@ -744,7 +745,8 @@
         certificate chain file for the SSL connection.
         """
         def __init__(self, host='', port=0, local_hostname=None,
-                     keyfile=None, certfile=None, timeout=None):
+                     keyfile=None, certfile=None,
+                     timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
             self.keyfile = keyfile
             self.certfile = certfile
             SMTP.__init__(self, host, port, local_hostname, timeout)

Modified: python/branches/py3k/Lib/socket.py
==============================================================================
--- python/branches/py3k/Lib/socket.py	(original)
+++ python/branches/py3k/Lib/socket.py	Tue Jun 10 19:40:04 2008
@@ -265,13 +265,17 @@
     return name
 
 
-def create_connection(address, timeout=None):
-    """Connect to address (host, port) with an optional timeout.
+_GLOBAL_DEFAULT_TIMEOUT = object()
 
-    Provides access to socketobject timeout for higher-level
-    protocols.  Passing a timeout will set the timeout on the
-    socket instance (if not present, or passed as None, the
-    default global timeout setting will be used).
+def create_connection(address, timeout=_GLOBAL_DEFAULT_TIMEOUT):
+    """Connect to *address* and return the socket object.
+
+    Convenience function.  Connect to *address* (a 2-tuple ``(host,
+    port)``) and return the socket object.  Passing the optional
+    *timeout* parameter will set the timeout on the socket instance
+    before attempting to connect.  If no *timeout* is supplied, the
+    global default timeout setting returned by :func:`getdefaulttimeout`
+    is used.
     """
 
     msg = "getaddrinfo returns an empty list"
@@ -281,7 +285,7 @@
         sock = None
         try:
             sock = socket(af, socktype, proto)
-            if timeout is not None:
+            if timeout is not _GLOBAL_DEFAULT_TIMEOUT:
                 sock.settimeout(timeout)
             sock.connect(sa)
             return sock

Modified: python/branches/py3k/Lib/sqlite3/test/dbapi.py
==============================================================================
--- python/branches/py3k/Lib/sqlite3/test/dbapi.py	(original)
+++ python/branches/py3k/Lib/sqlite3/test/dbapi.py	Tue Jun 10 19:40:04 2008
@@ -292,6 +292,15 @@
         self.cu.execute("update test set name='bar'")
         self.failUnlessEqual(self.cu.rowcount, 2)
 
+    def CheckRowcountSelect(self):
+        """
+        pysqlite does not know the rowcount of SELECT statements, because we
+        don't fetch all rows after executing the select statement. The rowcount
+        has thus to be -1.
+        """
+        self.cu.execute("select 5 union select 6")
+        self.failUnlessEqual(self.cu.rowcount, -1)
+
     def CheckRowcountExecutemany(self):
         self.cu.execute("delete from test")
         self.cu.executemany("insert into test(name) values (?)", [(1,), (2,), (3,)])

Modified: python/branches/py3k/Lib/telnetlib.py
==============================================================================
--- python/branches/py3k/Lib/telnetlib.py	(original)
+++ python/branches/py3k/Lib/telnetlib.py	Tue Jun 10 19:40:04 2008
@@ -184,13 +184,13 @@
 
     """
 
-    def __init__(self, host=None, port=0, timeout=None):
+    def __init__(self, host=None, port=0,
+                 timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
         """Constructor.
 
         When called without arguments, create an unconnected instance.
-        With a hostname argument, it connects the instance; a port
-        number is optional.
-
+        With a hostname argument, it connects the instance; port number
+        and timeout are optional.
         """
         self.debuglevel = DEBUGLEVEL
         self.host = host
@@ -208,23 +208,21 @@
         if host is not None:
             self.open(host, port, timeout)
 
-    def open(self, host, port=0, timeout=None):
+    def open(self, host, port=0, timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
         """Connect to a host.
 
         The optional second argument is the port number, which
         defaults to the standard telnet port (23).
 
         Don't try to reopen an already connected instance.
-
         """
         self.eof = 0
         if not port:
             port = TELNET_PORT
         self.host = host
         self.port = port
-        if timeout is not None:
-            self.timeout = timeout
-        self.sock = socket.create_connection((host, port), self.timeout)
+        self.timeout = timeout
+        self.sock = socket.create_connection((host, port), timeout)
 
     def __del__(self):
         """Destructor -- close the connection."""

Modified: python/branches/py3k/Lib/test/test_datetime.py
==============================================================================
--- python/branches/py3k/Lib/test/test_datetime.py	(original)
+++ python/branches/py3k/Lib/test/test_datetime.py	Tue Jun 10 19:40:04 2008
@@ -845,9 +845,13 @@
         self.assertRaises(TypeError, t.strftime, "one", "two") # too many args
         self.assertRaises(TypeError, t.strftime, 42) # arg wrong type
 
+        # test that unicode input is allowed (issue 2782)
+        self.assertEqual(t.strftime("%m"), "03")
+
         # A naive object replaces %z and %Z w/ empty strings.
         self.assertEqual(t.strftime("'%z' '%Z'"), "'' ''")
 
+
     def test_format(self):
         dt = self.theclass(2007, 9, 10)
         self.assertEqual(dt.__format__(''), str(dt))

Modified: python/branches/py3k/Lib/test/test_ftplib.py
==============================================================================
--- python/branches/py3k/Lib/test/test_ftplib.py	(original)
+++ python/branches/py3k/Lib/test/test_ftplib.py	Tue Jun 10 19:40:04 2008
@@ -54,35 +54,52 @@
         # connects
         ftp = ftplib.FTP(HOST)
         self.evt.wait()
-        ftp.sock.close()
+        ftp.close()
 
     def testTimeoutDefault(self):
-        # default
-        ftp = ftplib.FTP(HOST)
+        # default -- use global socket timeout
+        self.assert_(socket.getdefaulttimeout() is None)
+        socket.setdefaulttimeout(30)
+        try:
+            ftp = ftplib.FTP("localhost")
+        finally:
+            socket.setdefaulttimeout(None)
+        self.assertEqual(ftp.sock.gettimeout(), 30)
+        self.evt.wait()
+        ftp.close()
+
+    def testTimeoutNone(self):
+        # no timeout -- do not use global socket timeout
+        self.assert_(socket.getdefaulttimeout() is None)
+        socket.setdefaulttimeout(30)
+        try:
+            ftp = ftplib.FTP("localhost", timeout=None)
+        finally:
+            socket.setdefaulttimeout(None)
         self.assertTrue(ftp.sock.gettimeout() is None)
         self.evt.wait()
-        ftp.sock.close()
+        ftp.close()
 
     def testTimeoutValue(self):
         # a value
         ftp = ftplib.FTP(HOST, timeout=30)
         self.assertEqual(ftp.sock.gettimeout(), 30)
         self.evt.wait()
-        ftp.sock.close()
+        ftp.close()
 
     def testTimeoutConnect(self):
         ftp = ftplib.FTP()
         ftp.connect(HOST, timeout=30)
         self.assertEqual(ftp.sock.gettimeout(), 30)
         self.evt.wait()
-        ftp.sock.close()
+        ftp.close()
 
     def testTimeoutDifferentOrder(self):
         ftp = ftplib.FTP(timeout=30)
         ftp.connect(HOST)
         self.assertEqual(ftp.sock.gettimeout(), 30)
         self.evt.wait()
-        ftp.sock.close()
+        ftp.close()
 
     def testTimeoutDirectAccess(self):
         ftp = ftplib.FTP()
@@ -90,18 +107,6 @@
         ftp.connect(HOST)
         self.assertEqual(ftp.sock.gettimeout(), 30)
         self.evt.wait()
-        ftp.sock.close()
-
-    def testTimeoutNone(self):
-        # None, having other default
-        previous = socket.getdefaulttimeout()
-        socket.setdefaulttimeout(30)
-        try:
-            ftp = ftplib.FTP(HOST, timeout=None)
-        finally:
-            socket.setdefaulttimeout(previous)
-        self.assertEqual(ftp.sock.gettimeout(), 30)
-        self.evt.wait()
         ftp.close()
 
 

Modified: python/branches/py3k/Lib/test/test_httplib.py
==============================================================================
--- python/branches/py3k/Lib/test/test_httplib.py	(original)
+++ python/branches/py3k/Lib/test/test_httplib.py	Tue Jun 10 19:40:04 2008
@@ -215,27 +215,32 @@
         # This will prove that the timeout gets through HTTPConnection
         # and into the socket.
 
-        # default
-        httpConn = httplib.HTTPConnection(HOST, TimeoutTest.PORT)
-        httpConn.connect()
-        self.assertTrue(httpConn.sock.gettimeout() is None)
-        httpConn.close()
-
-        # a value
-        httpConn = httplib.HTTPConnection(HOST, TimeoutTest.PORT, timeout=30)
-        httpConn.connect()
+        # default -- use global socket timeout
+        self.assert_(socket.getdefaulttimeout() is None)
+        socket.setdefaulttimeout(30)
+        try:
+            httpConn = httplib.HTTPConnection(HOST, TimeoutTest.PORT)
+            httpConn.connect()
+        finally:
+            socket.setdefaulttimeout(None)
         self.assertEqual(httpConn.sock.gettimeout(), 30)
         httpConn.close()
 
-        # None, having other default
-        previous = socket.getdefaulttimeout()
+        # no timeout -- do not use global socket default
+        self.assert_(socket.getdefaulttimeout() is None)
         socket.setdefaulttimeout(30)
         try:
             httpConn = httplib.HTTPConnection(HOST, TimeoutTest.PORT,
                                               timeout=None)
             httpConn.connect()
         finally:
-            socket.setdefaulttimeout(previous)
+            socket.setdefaulttimeout(None)
+        self.assertEqual(httpConn.sock.gettimeout(), None)
+        httpConn.close()
+
+        # a value
+        httpConn = httplib.HTTPConnection(HOST, TimeoutTest.PORT, timeout=30)
+        httpConn.connect()
         self.assertEqual(httpConn.sock.gettimeout(), 30)
         httpConn.close()
 

Modified: python/branches/py3k/Lib/test/test_math.py
==============================================================================
--- python/branches/py3k/Lib/test/test_math.py	(original)
+++ python/branches/py3k/Lib/test/test_math.py	Tue Jun 10 19:40:04 2008
@@ -736,7 +736,7 @@
              OverflowError),
             ([2.**1023, 2.**1023, -1e307], OverflowError),
             ([1e16, 1., 1e-16], 10000000000000002.0),
-            ([1e16-2., 1.-2.**53, -(1e16-2.), -(1.-2.**53)], 0.0),
+            ([1e16-2., 1.-2.**-53, -(1e16-2.), -(1.-2.**-53)], 0.0),
         ]
 
         for i, (vals, s) in enumerate(test_values):

Modified: python/branches/py3k/Lib/test/test_poplib.py
==============================================================================
--- python/branches/py3k/Lib/test/test_poplib.py	(original)
+++ python/branches/py3k/Lib/test/test_poplib.py	Tue Jun 10 19:40:04 2008
@@ -40,28 +40,29 @@
         pop.sock.close()
 
     def testTimeoutDefault(self):
-        # default
-        pop = poplib.POP3(HOST, self.port)
-        self.assertTrue(pop.sock.gettimeout() is None)
-        pop.sock.close()
-
-    def testTimeoutValue(self):
-        # a value
-        pop = poplib.POP3(HOST, self.port, timeout=30)
+        self.assertTrue(socket.getdefaulttimeout() is None)
+        socket.setdefaulttimeout(30)
+        try:
+            pop = poplib.POP3("localhost", self.port)
+        finally:
+            socket.setdefaulttimeout(None)
         self.assertEqual(pop.sock.gettimeout(), 30)
         pop.sock.close()
 
     def testTimeoutNone(self):
-        # None, having other default
-        previous = socket.getdefaulttimeout()
+        self.assertTrue(socket.getdefaulttimeout() is None)
         socket.setdefaulttimeout(30)
         try:
             pop = poplib.POP3(HOST, self.port, timeout=None)
         finally:
-            socket.setdefaulttimeout(previous)
-        self.assertEqual(pop.sock.gettimeout(), 30)
+            socket.setdefaulttimeout(None)
+        self.assertTrue(pop.sock.gettimeout() is None)
         pop.sock.close()
 
+    def testTimeoutValue(self):
+        pop = poplib.POP3("localhost", self.port, timeout=30)
+        self.assertEqual(pop.sock.gettimeout(), 30)
+        pop.sock.close()
 
 
 def test_main(verbose=None):

Modified: python/branches/py3k/Lib/test/test_smtplib.py
==============================================================================
--- python/branches/py3k/Lib/test/test_smtplib.py	(original)
+++ python/branches/py3k/Lib/test/test_smtplib.py	Tue Jun 10 19:40:04 2008
@@ -54,41 +54,43 @@
     def testBasic1(self):
         # connects
         smtp = smtplib.SMTP(HOST, self.port)
-        smtp.sock.close()
+        smtp.close()
 
     def testBasic2(self):
         # connects, include port in host name
         smtp = smtplib.SMTP("%s:%s" % (HOST, self.port))
-        smtp.sock.close()
+        smtp.close()
 
     def testLocalHostName(self):
         # check that supplied local_hostname is used
         smtp = smtplib.SMTP(HOST, self.port, local_hostname="testhost")
         self.assertEqual(smtp.local_hostname, "testhost")
-        smtp.sock.close()
+        smtp.close()
 
     def testTimeoutDefault(self):
-        # default
-        smtp = smtplib.SMTP(HOST, self.port)
-        self.assertTrue(smtp.sock.gettimeout() is None)
-        smtp.sock.close()
-
-    def testTimeoutValue(self):
-        # a value
-        smtp = smtplib.SMTP(HOST, self.port, timeout=30)
+        self.assertTrue(socket.getdefaulttimeout() is None)
+        socket.setdefaulttimeout(30)
+        try:
+            smtp = smtplib.SMTP(HOST, self.port)
+        finally:
+            socket.setdefaulttimeout(None)
         self.assertEqual(smtp.sock.gettimeout(), 30)
-        smtp.sock.close()
+        smtp.close()
 
     def testTimeoutNone(self):
-        # None, having other default
-        previous = socket.getdefaulttimeout()
+        self.assertTrue(socket.getdefaulttimeout() is None)
         socket.setdefaulttimeout(30)
         try:
             smtp = smtplib.SMTP(HOST, self.port, timeout=None)
         finally:
-            socket.setdefaulttimeout(previous)
+            socket.setdefaulttimeout(None)
+        self.assertTrue(smtp.sock.gettimeout() is None)
+        smtp.close()
+
+    def testTimeoutValue(self):
+        smtp = smtplib.SMTP(HOST, self.port, timeout=30)
         self.assertEqual(smtp.sock.gettimeout(), 30)
-        smtp.sock.close()
+        smtp.close()
 
 
 # Test server thread using the specified SMTP server class

Modified: python/branches/py3k/Lib/test/test_socket.py
==============================================================================
--- python/branches/py3k/Lib/test/test_socket.py	(original)
+++ python/branches/py3k/Lib/test/test_socket.py	Tue Jun 10 19:40:04 2008
@@ -929,8 +929,25 @@
 
     testTimeoutDefault = _justAccept
     def _testTimeoutDefault(self):
-        self.cli = socket.create_connection((HOST, self.port))
-        self.assertTrue(self.cli.gettimeout() is None)
+        # passing no explicit timeout uses socket's global default
+        self.assert_(socket.getdefaulttimeout() is None)
+        socket.setdefaulttimeout(42)
+        try:
+            self.cli = socket.create_connection((HOST, self.port))
+        finally:
+            socket.setdefaulttimeout(None)
+        self.assertEquals(self.cli.gettimeout(), 42)
+
+    testTimeoutNone = _justAccept
+    def _testTimeoutNone(self):
+        # None timeout means the same as sock.settimeout(None)
+        self.assert_(socket.getdefaulttimeout() is None)
+        socket.setdefaulttimeout(30)
+        try:
+            self.cli = socket.create_connection((HOST, self.port), timeout=None)
+        finally:
+            socket.setdefaulttimeout(None)
+        self.assertEqual(self.cli.gettimeout(), None)
 
     testTimeoutValueNamed = _justAccept
     def _testTimeoutValueNamed(self):
@@ -942,17 +959,6 @@
         self.cli = socket.create_connection((HOST, self.port), 30)
         self.assertEqual(self.cli.gettimeout(), 30)
 
-    testTimeoutNone = _justAccept
-    def _testTimeoutNone(self):
-        previous = socket.getdefaulttimeout()
-        socket.setdefaulttimeout(30)
-        try:
-            self.cli = socket.create_connection((HOST, self.port), timeout=None)
-        finally:
-            socket.setdefaulttimeout(previous)
-        self.assertEqual(self.cli.gettimeout(), 30)
-
-
 class NetworkConnectionBehaviourTest(SocketTCPTest, ThreadableTest):
 
     def __init__(self, methodName='runTest'):

Modified: python/branches/py3k/Lib/test/test_telnetlib.py
==============================================================================
--- python/branches/py3k/Lib/test/test_telnetlib.py	(original)
+++ python/branches/py3k/Lib/test/test_telnetlib.py	Tue Jun 10 19:40:04 2008
@@ -40,34 +40,36 @@
         telnet.sock.close()
 
     def testTimeoutDefault(self):
-        # default
-        telnet = telnetlib.Telnet(HOST, self.port)
-        self.assertTrue(telnet.sock.gettimeout() is None)
-        telnet.sock.close()
-
-    def testTimeoutValue(self):
-        # a value
-        telnet = telnetlib.Telnet(HOST, self.port, timeout=30)
-        self.assertEqual(telnet.sock.gettimeout(), 30)
-        telnet.sock.close()
-
-    def testTimeoutDifferentOrder(self):
-        telnet = telnetlib.Telnet(timeout=30)
-        telnet.open(HOST, self.port)
+        self.assertTrue(socket.getdefaulttimeout() is None)
+        socket.setdefaulttimeout(30)
+        try:
+            telnet = telnetlib.Telnet("localhost", self.port)
+        finally:
+            socket.setdefaulttimeout(None)
         self.assertEqual(telnet.sock.gettimeout(), 30)
         telnet.sock.close()
 
     def testTimeoutNone(self):
         # None, having other default
-        previous = socket.getdefaulttimeout()
+        self.assertTrue(socket.getdefaulttimeout() is None)
         socket.setdefaulttimeout(30)
         try:
             telnet = telnetlib.Telnet(HOST, self.port, timeout=None)
         finally:
-            socket.setdefaulttimeout(previous)
+            socket.setdefaulttimeout(None)
+        self.assertTrue(telnet.sock.gettimeout() is None)
+        telnet.sock.close()
+
+    def testTimeoutValue(self):
+        telnet = telnetlib.Telnet("localhost", self.port, timeout=30)
         self.assertEqual(telnet.sock.gettimeout(), 30)
         telnet.sock.close()
 
+    def testTimeoutOpen(self):
+        telnet = telnetlib.Telnet()
+        telnet.open("localhost", self.port, timeout=30)
+        self.assertEqual(telnet.sock.gettimeout(), 30)
+        telnet.sock.close()
 
 
 def test_main(verbose=None):

Modified: python/branches/py3k/Lib/test/test_urllib.py
==============================================================================
--- python/branches/py3k/Lib/test/test_urllib.py	(original)
+++ python/branches/py3k/Lib/test/test_urllib.py	Tue Jun 10 19:40:04 2008
@@ -568,6 +568,7 @@
 # .   Facundo
 #
 # def server(evt):
+#     import socket, time
 #     serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 #     serv.settimeout(3)
 #     serv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
@@ -592,6 +593,7 @@
 # class FTPWrapperTests(unittest.TestCase):
 #
 #     def setUp(self):
+#         import ftplib, time, threading
 #         ftplib.FTP.port = 9093
 #         self.evt = threading.Event()
 #         threading.Thread(target=server, args=(self.evt,)).start()
@@ -603,31 +605,37 @@
 #     def testBasic(self):
 #         # connects
 #         ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, [])
-#         ftp.ftp.sock.close()
+#         ftp.close()
 #
-#     def testTimeoutDefault(self):
-#         # default
-#         ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, [])
-#         self.assertTrue(ftp.ftp.sock.gettimeout() is None)
-#         ftp.ftp.sock.close()
-#
-#     def testTimeoutValue(self):
-#         # a value
-#         ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, [], timeout=30)
+#     def testTimeoutNone(self):
+#         # global default timeout is ignored
+#         import socket
+#         self.assert_(socket.getdefaulttimeout() is None)
+#         socket.setdefaulttimeout(30)
+#         try:
+#             ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, [])
+#         finally:
+#             socket.setdefaulttimeout(None)
 #         self.assertEqual(ftp.ftp.sock.gettimeout(), 30)
-#         ftp.ftp.sock.close()
+#         ftp.close()
 #
-#     def testTimeoutNone(self):
-#         # None, having other default
-#         previous = socket.getdefaulttimeout()
+#     def testTimeoutDefault(self):
+#         # global default timeout is used
+#         import socket
+#         self.assert_(socket.getdefaulttimeout() is None)
 #         socket.setdefaulttimeout(30)
 #         try:
 #             ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, [])
 #         finally:
-#             socket.setdefaulttimeout(previous)
+#             socket.setdefaulttimeout(None)
 #         self.assertEqual(ftp.ftp.sock.gettimeout(), 30)
-#         ftp.ftp.close()
+#         ftp.close()
 #
+#     def testTimeoutValue(self):
+#         ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, [],
+#                                 timeout=30)
+#         self.assertEqual(ftp.ftp.sock.gettimeout(), 30)
+#         ftp.close()
 
 
 

Modified: python/branches/py3k/Lib/test/test_urllib2.py
==============================================================================
--- python/branches/py3k/Lib/test/test_urllib2.py	(original)
+++ python/branches/py3k/Lib/test/test_urllib2.py	Tue Jun 10 19:40:04 2008
@@ -3,6 +3,7 @@
 
 import os
 import io
+import socket
 
 import urllib2
 from urllib2 import Request, OpenerDirector
@@ -546,14 +547,15 @@
 
         class NullFTPHandler(urllib2.FTPHandler):
             def __init__(self, data): self.data = data
-            def connect_ftp(self, user, passwd, host, port, dirs, timeout=None):
+            def connect_ftp(self, user, passwd, host, port, dirs,
+                            timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
                 self.user, self.passwd = user, passwd
                 self.host, self.port = host, port
                 self.dirs = dirs
                 self.ftpwrapper = MockFTPWrapper(self.data)
                 return self.ftpwrapper
 
-        import ftplib, socket
+        import ftplib
         data = "rheum rhaponicum"
         h = NullFTPHandler(data)
         o = h.parent = MockOpener()
@@ -686,7 +688,7 @@
                 self.req_headers = []
                 self.data = None
                 self.raise_on_endheaders = False
-            def __call__(self, host, timeout=None):
+            def __call__(self, host, timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
                 self.host = host
                 self.timeout = timeout
                 return self

Modified: python/branches/py3k/Lib/test/test_urllib2net.py
==============================================================================
--- python/branches/py3k/Lib/test/test_urllib2net.py	(original)
+++ python/branches/py3k/Lib/test/test_urllib2net.py	Tue Jun 10 19:40:04 2008
@@ -188,46 +188,58 @@
 
 class TimeoutTest(unittest.TestCase):
     def test_http_basic(self):
+        self.assertTrue(socket.getdefaulttimeout() is None)
         u = _urlopen_with_retry("http://www.python.org")
         self.assertTrue(u.fp.raw.fp._sock.gettimeout() is None)
 
-    def test_http_NoneWithdefault(self):
-        prev = socket.getdefaulttimeout()
+    def test_http_default_timeout(self):
+        self.assertTrue(socket.getdefaulttimeout() is None)
+        socket.setdefaulttimeout(60)
+        try:
+            u = _urlopen_with_retry("http://www.python.org")
+        finally:
+            socket.setdefaulttimeout(None)
+        self.assertEqual(u.fp.raw.fp._sock.gettimeout(), 60)
+
+    def test_http_no_timeout(self):
+        self.assertTrue(socket.getdefaulttimeout() is None)
         socket.setdefaulttimeout(60)
         try:
             u = _urlopen_with_retry("http://www.python.org", timeout=None)
-            self.assertTrue(u.fp.raw.fp._sock.gettimeout(), 60)
         finally:
-            socket.setdefaulttimeout(prev)
+            socket.setdefaulttimeout(None)
+        self.assertTrue(u.fp.raw.fp._sock.gettimeout() is None)
 
-    def test_http_Value(self):
+    def test_http_timeout(self):
         u = _urlopen_with_retry("http://www.python.org", timeout=120)
         self.assertEqual(u.fp.raw.fp._sock.gettimeout(), 120)
 
-    def test_http_NoneNodefault(self):
-        u = _urlopen_with_retry("http://www.python.org", timeout=None)
-        self.assertTrue(u.fp.raw.fp._sock.gettimeout() is None)
-
     FTP_HOST = "ftp://ftp.mirror.nl/pub/mirror/gnu/"
 
     def test_ftp_basic(self):
+        self.assertTrue(socket.getdefaulttimeout() is None)
         u = _urlopen_with_retry(self.FTP_HOST)
         self.assertTrue(u.fp.fp.raw._sock.gettimeout() is None)
 
-    def test_ftp_NoneWithdefault(self):
-        prev = socket.getdefaulttimeout()
+    def test_ftp_default_timeout(self):
+        self.assertTrue(socket.getdefaulttimeout() is None)
         socket.setdefaulttimeout(60)
         try:
-            u = _urlopen_with_retry(self.FTP_HOST, timeout=None)
-            self.assertEqual(u.fp.fp.raw._sock.gettimeout(), 60)
+            u = _urlopen_with_retry(self.FTP_HOST)
         finally:
-            socket.setdefaulttimeout(prev)
+            socket.setdefaulttimeout(None)
+        self.assertEqual(u.fp.fp.raw._sock.gettimeout(), 60)
 
-    def test_ftp_NoneNodefault(self):
-        u = _urlopen_with_retry(self.FTP_HOST, timeout=None)
+    def test_ftp_no_timeout(self):
+        self.assertTrue(socket.getdefaulttimeout() is None)
+        socket.setdefaulttimeout(60)
+        try:
+            u = _urlopen_with_retry(self.FTP_HOST, timeout=None)
+        finally:
+            socket.setdefaulttimeout(None)
         self.assertTrue(u.fp.fp.raw._sock.gettimeout() is None)
 
-    def test_ftp_Value(self):
+    def test_ftp_timeout(self):
         u = _urlopen_with_retry(self.FTP_HOST, timeout=60)
         self.assertEqual(u.fp.fp.raw._sock.gettimeout(), 60)
 

Modified: python/branches/py3k/Lib/urllib.py
==============================================================================
--- python/branches/py3k/Lib/urllib.py	(original)
+++ python/branches/py3k/Lib/urllib.py	Tue Jun 10 19:40:04 2008
@@ -776,7 +776,8 @@
 class ftpwrapper:
     """Class used by open_ftp() for cache of open FTP connections."""
 
-    def __init__(self, user, passwd, host, port, dirs, timeout=None):
+    def __init__(self, user, passwd, host, port, dirs,
+                 timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
         self.user = user
         self.passwd = passwd
         self.host = host

Modified: python/branches/py3k/Lib/urllib2.py
==============================================================================
--- python/branches/py3k/Lib/urllib2.py	(original)
+++ python/branches/py3k/Lib/urllib2.py	Tue Jun 10 19:40:04 2008
@@ -115,7 +115,7 @@
 __version__ = sys.version[:3]
 
 _opener = None
-def urlopen(url, data=None, timeout=None):
+def urlopen(url, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
     global _opener
     if _opener is None:
         _opener = build_opener()
@@ -357,7 +357,7 @@
             if result is not None:
                 return result
 
-    def open(self, fullurl, data=None, timeout=None):
+    def open(self, fullurl, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
         # accept a URL or a Request object
         if isinstance(fullurl, str):
             req = Request(fullurl, data)

Modified: python/branches/py3k/Modules/_ctypes/libffi/configure
==============================================================================
--- python/branches/py3k/Modules/_ctypes/libffi/configure	(original)
+++ python/branches/py3k/Modules/_ctypes/libffi/configure	Tue Jun 10 19:40:04 2008
@@ -20406,6 +20406,9 @@
   i?86-*-solaris2.1[0-9]*)
 	TARGET=X86_64; TARGETDIR=x86
 	;;
+  i*86-*-nto-qnx*)
+        TARGET=X86; TARGETDIR=x86
+        ;;
   i?86-*-*)
 	TARGET=X86; TARGETDIR=x86
 	;;

Modified: python/branches/py3k/Modules/_ctypes/libffi/configure.ac
==============================================================================
--- python/branches/py3k/Modules/_ctypes/libffi/configure.ac	(original)
+++ python/branches/py3k/Modules/_ctypes/libffi/configure.ac	Tue Jun 10 19:40:04 2008
@@ -86,6 +86,9 @@
   i?86-*-solaris2.1[[0-9]]*)
 	TARGET=X86_64; TARGETDIR=x86
 	;;
+  i*86-*-nto-qnx*) 
+        TARGET=X86; TARGETDIR=x86
+        ;;
   i?86-*-*)
 	TARGET=X86; TARGETDIR=x86
 	;;

Modified: python/branches/py3k/Modules/_ctypes/malloc_closure.c
==============================================================================
--- python/branches/py3k/Modules/_ctypes/malloc_closure.c	(original)
+++ python/branches/py3k/Modules/_ctypes/malloc_closure.c	Tue Jun 10 19:40:04 2008
@@ -44,7 +44,11 @@
 	}
 #else
 	if (!_pagesize) {
+#ifdef _SC_PAGESIZE
+		_pagesize = sysconf(_SC_PAGESIZE);
+#else
 		_pagesize = getpagesize();
+#endif
 	}
 #endif
 

Modified: python/branches/py3k/Modules/_heapqmodule.c
==============================================================================
--- python/branches/py3k/Modules/_heapqmodule.c	(original)
+++ python/branches/py3k/Modules/_heapqmodule.c	Tue Jun 10 19:40:04 2008
@@ -8,6 +8,25 @@
 
 #include "Python.h"
 
+/* Older implementations of heapq used Py_LE for comparisons.  Now, it uses
+   Py_LT so it will match min(), sorted(), and bisect().  Unfortunately, some
+   client code (Twisted for example) relied on Py_LE, so this little function
+   restores compatability by trying both.
+*/
+static int
+cmp_lt(PyObject *x, PyObject *y)
+{
+	int cmp;
+	cmp = PyObject_RichCompareBool(x, y, Py_LT);
+	if (cmp == -1 && PyErr_ExceptionMatches(PyExc_AttributeError)) {
+		PyErr_Clear();
+		cmp = PyObject_RichCompareBool(y, x, Py_LE);
+		if (cmp != -1)
+			cmp = 1 - cmp;
+	}
+	return cmp;
+}
+
 static int
 _siftdown(PyListObject *heap, Py_ssize_t startpos, Py_ssize_t pos)
 {
@@ -28,12 +47,12 @@
 	while (pos > startpos){
 		parentpos = (pos - 1) >> 1;
 		parent = PyList_GET_ITEM(heap, parentpos);
-		cmp = PyObject_RichCompareBool(parent, newitem, Py_LE);
+		cmp = cmp_lt(newitem, parent);
 		if (cmp == -1) {
 			Py_DECREF(newitem);
 			return -1;
 		}
-		if (cmp == 1)
+		if (cmp == 0)
 			break;
 		Py_INCREF(parent);
 		Py_DECREF(PyList_GET_ITEM(heap, pos));
@@ -68,15 +87,14 @@
 		/* Set childpos to index of smaller child.   */
 		rightpos = childpos + 1;
 		if (rightpos < endpos) {
-			cmp = PyObject_RichCompareBool(
-				PyList_GET_ITEM(heap, rightpos),
+			cmp = cmp_lt(
 				PyList_GET_ITEM(heap, childpos),
-				Py_LE);
+				PyList_GET_ITEM(heap, rightpos));
 			if (cmp == -1) {
 				Py_DECREF(newitem);
 				return -1;
 			}
-			if (cmp == 1)
+			if (cmp == 0)
 				childpos = rightpos;
 		}
 		/* Move the smaller child up. */
@@ -214,10 +232,10 @@
 		return item;
 	}
 
-	cmp = PyObject_RichCompareBool(item, PyList_GET_ITEM(heap, 0), Py_LE);
+	cmp = cmp_lt(PyList_GET_ITEM(heap, 0), item);
 	if (cmp == -1)
 		return NULL;
-	if (cmp == 1) {
+	if (cmp == 0) {
 		Py_INCREF(item);
 		return item;
 	}
@@ -270,6 +288,7 @@
 {
 	PyObject *heap=NULL, *elem, *iterable, *sol, *it, *oldelem;
 	Py_ssize_t i, n;
+	int cmp;
 
 	if (!PyArg_ParseTuple(args, "nO:nlargest", &n, &iterable))
 		return NULL;
@@ -312,7 +331,12 @@
 			else
 				goto sortit;
 		}
-		if (PyObject_RichCompareBool(elem, sol, Py_LE)) {
+		cmp = cmp_lt(sol, elem);
+		if (cmp == -1) {
+			Py_DECREF(elem);
+			goto fail;
+		}
+		if (cmp == 0) {
 			Py_DECREF(elem);
 			continue;
 		}
@@ -362,12 +386,12 @@
 	while (pos > startpos){
 		parentpos = (pos - 1) >> 1;
 		parent = PyList_GET_ITEM(heap, parentpos);
-		cmp = PyObject_RichCompareBool(newitem, parent, Py_LE);
+		cmp = cmp_lt(parent, newitem);
 		if (cmp == -1) {
 			Py_DECREF(newitem);
 			return -1;
 		}
-		if (cmp == 1)
+		if (cmp == 0)
 			break;
 		Py_INCREF(parent);
 		Py_DECREF(PyList_GET_ITEM(heap, pos));
@@ -402,15 +426,14 @@
 		/* Set childpos to index of smaller child.   */
 		rightpos = childpos + 1;
 		if (rightpos < endpos) {
-			cmp = PyObject_RichCompareBool(
-				PyList_GET_ITEM(heap, childpos),
+			cmp = cmp_lt(
 				PyList_GET_ITEM(heap, rightpos),
-				Py_LE);
+				PyList_GET_ITEM(heap, childpos));
 			if (cmp == -1) {
 				Py_DECREF(newitem);
 				return -1;
 			}
-			if (cmp == 1)
+			if (cmp == 0)
 				childpos = rightpos;
 		}
 		/* Move the smaller child up. */
@@ -434,6 +457,7 @@
 {
 	PyObject *heap=NULL, *elem, *iterable, *los, *it, *oldelem;
 	Py_ssize_t i, n;
+	int cmp;
 
 	if (!PyArg_ParseTuple(args, "nO:nsmallest", &n, &iterable))
 		return NULL;
@@ -477,7 +501,12 @@
 			else
 				goto sortit;
 		}
-		if (PyObject_RichCompareBool(los, elem, Py_LE)) {
+		cmp = cmp_lt(elem, los);
+		if (cmp == -1) {
+			Py_DECREF(elem);
+			goto fail;
+		}
+		if (cmp == 0) {
 			Py_DECREF(elem);
 			continue;
 		}

Modified: python/branches/py3k/Modules/_sqlite/cursor.c
==============================================================================
--- python/branches/py3k/Modules/_sqlite/cursor.c	(original)
+++ python/branches/py3k/Modules/_sqlite/cursor.c	Tue Jun 10 19:40:04 2008
@@ -101,10 +101,7 @@
 
     self->arraysize = 1;
 
-    self->rowcount = PyLong_FromLong(-1L);
-    if (!self->rowcount) {
-        return -1;
-    }
+    self->rowcount = -1L;
 
     Py_INCREF(Py_None);
     self->row_factory = Py_None;
@@ -130,7 +127,6 @@
     Py_XDECREF(self->row_cast_map);
     Py_XDECREF(self->description);
     Py_XDECREF(self->lastrowid);
-    Py_XDECREF(self->rowcount);
     Py_XDECREF(self->row_factory);
     Py_XDECREF(self->next_row);
 
@@ -418,12 +414,12 @@
     int statement_type;
     PyObject* descriptor;
     PyObject* second_argument = NULL;
-    long rowcount = 0;
     int allow_8bit_chars;
 
     if (!pysqlite_check_thread(self->connection) || !pysqlite_check_connection(self->connection)) {
         return NULL;
     }
+
     /* Make shooting yourself in the foot with not utf-8 decodable 8-bit-strings harder */
     allow_8bit_chars = ((self->connection->text_factory != (PyObject*)&PyUnicode_Type) &&
         (self->connection->text_factory != (PyObject*)&PyUnicode_Type && pysqlite_OptimizedUnicode));
@@ -498,10 +494,11 @@
     if (operation == NULL)
         goto error;
 
-    /* reset description */
+    /* reset description and rowcount */
     Py_DECREF(self->description);
     Py_INCREF(Py_None);
     self->description = Py_None;
+    self->rowcount = -1L;
 
     func_args = PyTuple_New(1);
     if (!func_args) {
@@ -723,7 +720,10 @@
             case STATEMENT_DELETE:
             case STATEMENT_INSERT:
             case STATEMENT_REPLACE:
-                rowcount += (long)sqlite3_changes(self->connection->db);
+                if (self->rowcount == -1L) {
+                    self->rowcount = 0L;
+                }
+                self->rowcount += (long)sqlite3_changes(self->connection->db);
         }
 
         Py_DECREF(self->lastrowid);
@@ -757,13 +757,9 @@
     Py_XDECREF(parameters_list);
 
     if (PyErr_Occurred()) {
-        Py_DECREF(self->rowcount);
-        self->rowcount = PyLong_FromLong(-1L);
+        self->rowcount = -1L;
         return NULL;
     } else {
-        Py_DECREF(self->rowcount);
-        self->rowcount = PyLong_FromLong(rowcount);
-
         Py_INCREF(self);
         return (PyObject*)self;
     }
@@ -1053,7 +1049,7 @@
     {"description", T_OBJECT, offsetof(pysqlite_Cursor, description), READONLY},
     {"arraysize", T_INT, offsetof(pysqlite_Cursor, arraysize), 0},
     {"lastrowid", T_OBJECT, offsetof(pysqlite_Cursor, lastrowid), READONLY},
-    {"rowcount", T_OBJECT, offsetof(pysqlite_Cursor, rowcount), READONLY},
+    {"rowcount", T_LONG, offsetof(pysqlite_Cursor, rowcount), READONLY},
     {"row_factory", T_OBJECT, offsetof(pysqlite_Cursor, row_factory), 0},
     {NULL}
 };

Modified: python/branches/py3k/Modules/_sqlite/cursor.h
==============================================================================
--- python/branches/py3k/Modules/_sqlite/cursor.h	(original)
+++ python/branches/py3k/Modules/_sqlite/cursor.h	Tue Jun 10 19:40:04 2008
@@ -37,7 +37,7 @@
     PyObject* row_cast_map;
     int arraysize;
     PyObject* lastrowid;
-    PyObject* rowcount;
+    long rowcount;
     PyObject* row_factory;
     pysqlite_Statement* statement;
 

Modified: python/branches/py3k/Modules/datetimemodule.c
==============================================================================
--- python/branches/py3k/Modules/datetimemodule.c	(original)
+++ python/branches/py3k/Modules/datetimemodule.c	Tue Jun 10 19:40:04 2008
@@ -1201,17 +1201,17 @@
 	PyObject *Zreplacement = NULL;	/* py string, replacement for %Z */
 	PyObject *freplacement = NULL;	/* py string, replacement for %f */
 
-	const char *pin;/* pointer to next char in input format */
-        Py_ssize_t flen;/* length of input format */
-	char ch;	/* next char in input format */
+	const char *pin;	/* pointer to next char in input format */
+	Py_ssize_t flen;	/* length of input format */
+	char ch;		/* next char in input format */
 
 	PyObject *newfmt = NULL;	/* py string, the output format */
 	char *pnew;	/* pointer to available byte in output format */
-	int totalnew;	/* number bytes total in output format buffer,
-			   exclusive of trailing \0 */
-	int usednew;	/* number bytes used so far in output format buffer */
+	size_t totalnew;	/* number bytes total in output format buffer,
+				   exclusive of trailing \0 */
+	size_t usednew;	/* number bytes used so far in output format buffer */
 
-	const char *ptoappend;/* pointer to string to append to output buffer */
+	const char *ptoappend;	/* ptr to string to append to output buffer */
 	Py_ssize_t ntoappend;	/* # of bytes to append to output buffer */
 
 	assert(object && format && timetuple);
@@ -1335,7 +1335,7 @@
  		assert(ptoappend != NULL);
  		assert(ntoappend > 0);
  		while (usednew + ntoappend > totalnew) {
- 			int bigger = totalnew << 1;
+ 			size_t bigger = totalnew << 1;
  			if ((bigger >> 1) != totalnew) { /* overflow */
  				PyErr_NoMemory();
  				goto Done;
@@ -2444,8 +2444,8 @@
 	 * timetuple() method appropriate to self's class.
 	 */
 	PyObject *result;
-	PyObject *format;
 	PyObject *tuple;
+	PyObject *format;
 	static char *keywords[] = {"format", NULL};
 
 	if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
@@ -3211,8 +3211,8 @@
 time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
 {
 	PyObject *result;
-	PyObject *format;
 	PyObject *tuple;
+	PyObject *format;
 	static char *keywords[] = {"format", NULL};
 
 	if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
@@ -3232,7 +3232,8 @@
 	if (tuple == NULL)
 		return NULL;
 	assert(PyTuple_Size(tuple) == 9);
-	result = wrap_strftime((PyObject *)self, format, tuple, Py_None);
+	result = wrap_strftime((PyObject *)self, format, tuple,
+			       Py_None);
 	Py_DECREF(tuple);
 	return result;
 }

Modified: python/branches/py3k/Modules/mathmodule.c
==============================================================================
--- python/branches/py3k/Modules/mathmodule.c	(original)
+++ python/branches/py3k/Modules/mathmodule.c	Tue Jun 10 19:40:04 2008
@@ -373,14 +373,20 @@
    value semantics across iterations (i.e. handling -Inf + Inf).
 
    Note 2:  No provision is made for intermediate overflow handling;
-   therefore, sum([1e+308, 1e-308, 1e+308]) returns result 1e+308 while
+   therefore, sum([1e+308, 1e-308, 1e+308]) returns 1e+308 while
    sum([1e+308, 1e+308, 1e-308]) raises an OverflowError due to the
    overflow of the first partial sum.
 
-   Note 3: Aggressively optimizing compilers can potentially eliminate the
-   residual values needed for accurate summation. For instance, the statements
-   "hi = x + y; lo = y - (hi - x);" could be mis-transformed to
-   "hi = x + y; lo = 0.0;" which defeats the computation of residuals.
+   Note 3: The itermediate values lo, yr, and hi are declared volatile so
+   aggressive compilers won't algebraicly reduce lo to always be exactly 0.0.
+   Also, the volatile declaration forces the values to be stored in memory as
+   regular doubles instead of extended long precision (80-bit) values.  This
+   prevents double rounding because any addition or substraction of two doubles
+   can be resolved exactly into double-sized hi and lo values.  As long as the 
+   hi value gets forced into a double before yr and lo are computed, the extra
+   bits in downstream extended precision operations (x87 for example) will be
+   exactly zero and therefore can be losslessly stored back into a double,
+   thereby preventing double rounding.
 
    Note 4: A similar implementation is in Modules/cmathmodule.c.
    Be sure to update both when making changes.
@@ -457,7 +463,8 @@
 {
 	PyObject *item, *iter, *sum = NULL;
 	Py_ssize_t i, j, n = 0, m = NUM_PARTIALS;
-	double x, y, hi, lo=0.0, ps[NUM_PARTIALS], *p = ps;
+	double x, y, t, ps[NUM_PARTIALS], *p = ps;
+	volatile double hi, yr, lo;
 
 	iter = PyObject_GetIter(seq);
 	if (iter == NULL)
@@ -483,10 +490,12 @@
 
 		for (i = j = 0; j < n; j++) {       /* for y in partials */
 			y = p[j];
+			if (fabs(x) < fabs(y)) {
+					t = x; x = y; y = t;
+			}
 			hi = x + y;
-			lo = fabs(x) < fabs(y)
-			   ? x - (hi - y)
-			   : y - (hi - x);
+			yr = hi - x;
+			lo = y - yr;
 			if (lo != 0.0)
 				p[i++] = lo;
 			x = hi;
@@ -506,38 +515,41 @@
 		}
 	}
 
+	hi = 0.0;
 	if (n > 0) {
 		hi = p[--n];
 		if (Py_IS_FINITE(hi)) {
 			/* sum_exact(ps, hi) from the top, stop when the sum becomes inexact. */
 			while (n > 0) {
-				x = p[--n];
-				y = hi;
+				x = hi;
+				y = p[--n];
+				assert(fabs(y) < fabs(x));
 				hi = x + y;
-				assert(fabs(x) < fabs(y));
-				lo = x - (hi - y);
+				yr = hi - x;
+				lo = y - yr;
 				if (lo != 0.0)
 					break;
 			}
-			/* Little dance to allow half-even rounding across multiple partials.
-                           Needed so that sum([1e-16, 1, 1e16]) will round-up to two instead
-                           of down to zero (the 1e16 makes the 1 slightly closer to two). */
+			/* Make half-even rounding work across multiple partials.  Needed 
+			   so that sum([1e-16, 1, 1e16]) will round-up the last digit to 
+			   two instead of down to zero (the 1e-16 makes the 1 slightly 
+			   closer to two).  With a potential 1 ULP rounding error fixed-up,
+			   math.sum() can guarantee commutativity. */
 			if (n > 0 && ((lo < 0.0 && p[n-1] < 0.0) ||
 			              (lo > 0.0 && p[n-1] > 0.0))) {
 				y = lo * 2.0;
 				x = hi + y;
-				if (y == (x - hi))
+				yr = x - hi;
+				if (y == yr)
 					hi = x;
 			}
 		}
-		else {  /* raise corresponding error */
+		else {  /* raise exception corresponding to a special value */
 			errno = Py_IS_NAN(hi) ? EDOM : ERANGE;
 			if (is_error(hi))
 				goto _sum_error;
 		}
 	}
-	else  /* default */
-		hi = 0.0;
 	sum = PyFloat_FromDouble(hi);
 
 _sum_error:

Modified: python/branches/py3k/PCbuild/pyproject.vsprops
==============================================================================
--- python/branches/py3k/PCbuild/pyproject.vsprops	(original)
+++ python/branches/py3k/PCbuild/pyproject.vsprops	Tue Jun 10 19:40:04 2008
@@ -45,6 +45,10 @@
 		Value="$(SolutionDir)\python.exe"
 	/>
 	<UserMacro
+		Name="externalsDir"
+		Value="..\.."
+	/>
+	<UserMacro
 		Name="bsddbDir"
 		Value="$(bsddb44Dir)"
 	/>
@@ -54,7 +58,7 @@
 	/>
 	<UserMacro
 		Name="bsddb44Dir"
-		Value="..\..\db-4.4.20\build_win32"
+		Value="$(externalsDir)\db-4.4.20\build_win32"
 	/>
 	<UserMacro
 		Name="bsddb44DepLibs"
@@ -62,7 +66,7 @@
 	/>
 	<UserMacro
 		Name="bsddb45Dir"
-		Value="..\..\db-4.5.20.x\build_windows"
+		Value="$(externalsDir)\db-4.5.20.x\build_windows"
 	/>
 	<UserMacro
 		Name="bsddb45DepLibs"
@@ -70,23 +74,23 @@
 	/>
 	<UserMacro
 		Name="sqlite3Dir"
-		Value="..\..\sqlite-source-3.3.4"
+		Value="$(externalsDir)\sqlite-source-3.3.4"
 	/>
 	<UserMacro
 		Name="bz2Dir"
-		Value="..\..\bzip2-1.0.3"
+		Value="$(externalsDir)\bzip2-1.0.3"
 	/>
 	<UserMacro
 		Name="opensslDir"
-		Value="..\..\openssl-0.9.8g"
+		Value="$(externalsDir)\openssl-0.9.8g"
 	/>
 	<UserMacro
 		Name="tcltkDir"
-		Value="..\..\tcltk"
+		Value="$(externalsDir)\tcltk"
 	/>
 	<UserMacro
 		Name="tcltk64Dir"
-		Value="..\..\tcltk64"
+		Value="$(externalsDir)\tcltk64"
 	/>
 	<UserMacro
 		Name="tcltkLib"

Modified: python/branches/py3k/Python/mysnprintf.c
==============================================================================
--- python/branches/py3k/Python/mysnprintf.c	(original)
+++ python/branches/py3k/Python/mysnprintf.c	Tue Jun 10 19:40:04 2008
@@ -54,18 +54,28 @@
 PyOS_vsnprintf(char *str, size_t size, const char  *format, va_list va)
 {
 	int len;  /* # bytes written, excluding \0 */
-#ifndef HAVE_SNPRINTF
+#ifdef HAVE_SNPRINTF
+#define _PyOS_vsnprintf_EXTRA_SPACE 1
+#else
+#define _PyOS_vsnprintf_EXTRA_SPACE 512
 	char *buffer;
 #endif
 	assert(str != NULL);
 	assert(size > 0);
 	assert(format != NULL);
+	/* We take a size_t as input but return an int.  Sanity check
+	 * our input so that it won't cause an overflow in the
+         * vsnprintf return value or the buffer malloc size.  */
+	if (size > INT_MAX - _PyOS_vsnprintf_EXTRA_SPACE) {
+		len = -666;
+		goto Done;
+	}
 
 #ifdef HAVE_SNPRINTF
 	len = vsnprintf(str, size, format, va);
 #else
 	/* Emulate it. */
-	buffer = PyMem_MALLOC(size + 512);
+	buffer = PyMem_MALLOC(size + _PyOS_vsnprintf_EXTRA_SPACE);
 	if (buffer == NULL) {
 		len = -666;
 		goto Done;
@@ -75,7 +85,7 @@
 	if (len < 0)
 		/* ignore the error */;
 
-	else if ((size_t)len >= size + 512)
+	else if ((size_t)len >= size + _PyOS_vsnprintf_EXTRA_SPACE)
 		Py_FatalError("Buffer overflow in PyOS_snprintf/PyOS_vsnprintf");
 
 	else {
@@ -86,8 +96,10 @@
 		str[to_copy] = '\0';
 	}
 	PyMem_FREE(buffer);
-Done:
 #endif
-	str[size-1] = '\0';
+Done:
+	if (size > 0)
+		str[size-1] = '\0';
 	return len;
+#undef _PyOS_vsnprintf_EXTRA_SPACE
 }

Modified: python/branches/py3k/configure.in
==============================================================================
--- python/branches/py3k/configure.in	(original)
+++ python/branches/py3k/configure.in	Tue Jun 10 19:40:04 2008
@@ -217,7 +217,7 @@
   # On OpenBSD, select(2) is not available if _XOPEN_SOURCE is defined,
   # even though select is a POSIX function. Reported by J. Ribbens.
   # Reconfirmed for OpenBSD 3.3 by Zachary Hamm, for 3.4 by Jason Ish.
-  OpenBSD/2.* | OpenBSD/3.@<:@0123456789@:>@ | OpenBSD/4.@<:@0@:>@) 
+  OpenBSD/2.* | OpenBSD/3.@<:@0123456789@:>@ | OpenBSD/4.@<:@0123@:>@) 
     define_xopen_source=no
     # OpenBSD undoes our definition of __BSD_VISIBLE if _XOPEN_SOURCE is
     # also defined. This can be overridden by defining _BSD_SOURCE
@@ -265,6 +265,11 @@
   Darwin/@<:@789@:>@.*)
     define_xopen_source=no
     ;;
+  # On QNX 6.3.2, defining _XOPEN_SOURCE prevents netdb.h from
+  # defining NI_NUMERICHOST.
+  QNX/6.3.2)
+    define_xopen_source=no
+    ;;
 
 esac
 
@@ -549,6 +554,10 @@
 	   LINKCC="\$(srcdir)/Modules/makexp_aix Modules/python.exp $exp_extra \$(LIBRARY); $LINKCC";;
 	Monterey64*)
 	   LINKCC="$LINKCC -L/usr/lib/ia64l64";;
+	QNX*)
+	   # qcc must be used because the other compilers do not
+	   # support -N.
+	   LINKCC=qcc;;
 	esac
 fi
 AC_MSG_RESULT($LINKCC)
@@ -1091,7 +1100,7 @@
 sys/audioio.h sys/bsdtty.h sys/epoll.h sys/event.h sys/file.h sys/loadavg.h \
 sys/lock.h sys/mkdev.h sys/modem.h \
 sys/param.h sys/poll.h sys/select.h sys/socket.h sys/statvfs.h sys/stat.h \
-sys/time.h \
+sys/termio.h sys/time.h \
 sys/times.h sys/types.h sys/un.h sys/utsname.h sys/wait.h pty.h libutil.h \
 sys/resource.h netpacket/packet.h sysexits.h bluetooth.h \
 bluetooth/bluetooth.h linux/tipc.h)
@@ -1517,7 +1526,7 @@
 			fi
 		fi
 		;;
-	Linux*|GNU*) LDSHARED='$(CC) -shared';;
+	Linux*|GNU*|QNX*) LDSHARED='$(CC) -shared';;
 	BSD/OS*/4*) LDSHARED="gcc -shared";;
 	FreeBSD*)
 		if [[ "`$CC -dM -E - </dev/null | grep __ELF__`" != "" ]]
@@ -1641,6 +1650,13 @@
 		then
 			LINKFORSHARED='-Wl,--out-implib=$(LDLIBRARY)'
 		fi;;
+	QNX*)
+		# -Wl,-E causes the symbols to be added to the dynamic
+		# symbol table so that they can be found when a module
+		# is loaded.  -N 2048K causes the stack size to be set
+		# to 2048 kilobytes so that the stack doesn't overflow
+		# when running test_compile.py.
+		LINKFORSHARED='-Wl,-E -N 2048K';;
 	esac
 fi
 AC_MSG_RESULT($LINKFORSHARED)

Modified: python/branches/py3k/pyconfig.h.in
==============================================================================
--- python/branches/py3k/pyconfig.h.in	(original)
+++ python/branches/py3k/pyconfig.h.in	Tue Jun 10 19:40:04 2008
@@ -691,6 +691,9 @@
 /* Define to 1 if you have the <sys/stat.h> header file. */
 #undef HAVE_SYS_STAT_H
 
+/* Define to 1 if you have the <sys/termio.h> header file. */
+#undef HAVE_SYS_TERMIO_H
+
 /* Define to 1 if you have the <sys/times.h> header file. */
 #undef HAVE_SYS_TIMES_H
 

Modified: python/branches/py3k/setup.py
==============================================================================
--- python/branches/py3k/setup.py	(original)
+++ python/branches/py3k/setup.py	Tue Jun 10 19:40:04 2008
@@ -939,7 +939,7 @@
                 missing.append('resource')
 
             # Sun yellow pages. Some systems have the functions in libc.
-            if platform not in ['cygwin', 'atheos']:
+            if platform not in ['cygwin', 'atheos', 'qnx6']:
                 if (self.compiler.find_library_file(lib_dirs, 'nsl')):
                     libs = ['nsl']
                 else:

From python-3000-checkins at python.org  Tue Jun 10 19:51:15 2008
From: python-3000-checkins at python.org (gregory.p.smith)
Date: Tue, 10 Jun 2008 19:51:15 +0200 (CEST)
Subject: [Python-3000-checkins] r64087 - python/branches/py3k
Message-ID: <20080610175115.BA03C1E4002@bag.python.org>

Author: gregory.p.smith
Date: Tue Jun 10 19:51:15 2008
New Revision: 64087

Log:
block a pystring/pybytes renaming change from py3k


Modified:
   python/branches/py3k/   (props changed)

From python-3000-checkins at python.org  Tue Jun 10 21:20:27 2008
From: python-3000-checkins at python.org (georg.brandl)
Date: Tue, 10 Jun 2008 21:20:27 +0200 (CEST)
Subject: [Python-3000-checkins] r64088 - in python/branches/py3k:
	Doc/library/collections.rst Doc/library/math.rst
	Doc/library/stdtypes.rst Doc/library/tokenize.rst
	Lib/collections.py Lib/test/test_collections.py
	Lib/test/test_math.py Lib/test/test_set.py
	Lib/test/test_sys.py Lib/test/test_urllib2net.py
	Modules/mathmodule.c Objects/setobject.c Objects/unicodeobject.c
Message-ID: <20080610192027.3A75F1E4002@bag.python.org>

Author: georg.brandl
Date: Tue Jun 10 21:20:26 2008
New Revision: 64088

Log:
Merged revisions 64002-64003,64012,64036-64037,64047,64050-64052,64054-64055,64066,64071 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/trunk

........
  r64002 | travis.oliphant | 2008-06-07 00:33:21 +0200 (Sat, 07 Jun 2008) | 1 line
  
  Add long double check support to configure test.
........
  r64003 | travis.oliphant | 2008-06-07 00:39:47 +0200 (Sat, 07 Jun 2008) | 1 line
  
  Remove locking part of new buffer protocol.
........
  r64012 | facundo.batista | 2008-06-07 15:36:36 +0200 (Sat, 07 Jun 2008) | 4 lines
  
  
  Finished bug #2451.  Fixed the retrying part to make it 
  more robust.
........
  r64036 | georg.brandl | 2008-06-08 10:54:40 +0200 (Sun, 08 Jun 2008) | 2 lines
  
  #3028: tokenize passes the physical line.
........
  r64037 | georg.brandl | 2008-06-08 10:59:38 +0200 (Sun, 08 Jun 2008) | 2 lines
  
  Argh, I read it wrong. Reverted 64036 and added a clarifying remark.
........
  r64047 | raymond.hettinger | 2008-06-09 03:28:30 +0200 (Mon, 09 Jun 2008) | 1 line
  
  Issue3065:  Fixed pickling of named tuples.  Added tests.
........
  r64050 | raymond.hettinger | 2008-06-09 08:54:45 +0200 (Mon, 09 Jun 2008) | 1 line
  
  Issue #2138: Add math.factorial().
........
  r64051 | raymond.hettinger | 2008-06-09 10:33:37 +0200 (Mon, 09 Jun 2008) | 1 line
  
  Let set.union() and set.update() accept multiple inputs.
........
  r64052 | raymond.hettinger | 2008-06-09 11:29:17 +0200 (Mon, 09 Jun 2008) | 1 line
  
  Address double-rounding scenarios by setting all variables to long doubles.
........
  r64054 | raymond.hettinger | 2008-06-09 13:24:47 +0200 (Mon, 09 Jun 2008) | 1 line
  
  Unhappy buildbots.  Revert 64052.  Long doubles have unexpected effects on some builds.
........
  r64055 | raymond.hettinger | 2008-06-09 15:07:27 +0200 (Mon, 09 Jun 2008) | 1 line
  
  Let set.intersection() and set.intersection_update() take multiple input arguments.
........
  r64066 | robert.schuppenies | 2008-06-10 12:10:31 +0200 (Tue, 10 Jun 2008) | 2 lines
  
  Issue 3048: Fixed sys.getsizeof for unicode objects.
........
  r64071 | thomas.heller | 2008-06-10 16:07:12 +0200 (Tue, 10 Jun 2008) | 3 lines
  
  NEWS entry for:
  Add an optional 'offset' parameter to byref, defaulting to zero.
........


Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Doc/library/collections.rst
   python/branches/py3k/Doc/library/math.rst
   python/branches/py3k/Doc/library/stdtypes.rst
   python/branches/py3k/Doc/library/tokenize.rst
   python/branches/py3k/Lib/collections.py
   python/branches/py3k/Lib/test/test_collections.py
   python/branches/py3k/Lib/test/test_math.py
   python/branches/py3k/Lib/test/test_set.py
   python/branches/py3k/Lib/test/test_sys.py
   python/branches/py3k/Lib/test/test_urllib2net.py
   python/branches/py3k/Modules/mathmodule.c
   python/branches/py3k/Objects/setobject.c
   python/branches/py3k/Objects/unicodeobject.c

Modified: python/branches/py3k/Doc/library/collections.rst
==============================================================================
--- python/branches/py3k/Doc/library/collections.rst	(original)
+++ python/branches/py3k/Doc/library/collections.rst	Tue Jun 10 21:20:26 2008
@@ -519,6 +519,9 @@
                if kwds:
                    raise ValueError('Got unexpected field names: %r' % kwds.keys())
                return result
+   <BLANKLINE>            
+        def __getnewargs__(self): 
+            return tuple(self)
    <BLANKLINE>
            x = property(itemgetter(0))
            y = property(itemgetter(1))

Modified: python/branches/py3k/Doc/library/math.rst
==============================================================================
--- python/branches/py3k/Doc/library/math.rst	(original)
+++ python/branches/py3k/Doc/library/math.rst	Tue Jun 10 21:20:26 2008
@@ -41,6 +41,10 @@
 
    Return the absolute value of *x*.
 
+.. function:: factorial(x)
+
+   Return *x* factorial.  Raises :exc:`ValueError` if *x* is not intergral or
+   is negative.
 
 .. function:: floor(x)
 

Modified: python/branches/py3k/Doc/library/stdtypes.rst
==============================================================================
--- python/branches/py3k/Doc/library/stdtypes.rst	(original)
+++ python/branches/py3k/Doc/library/stdtypes.rst	Tue Jun 10 21:20:26 2008
@@ -1501,16 +1501,22 @@
       Test whether the set is a true superset of *other*, that is, ``set >=
       other and set != other``.
 
-   .. method:: union(other)
-               set | other
+   .. method:: union(other, ...)
+               set | other | ...
 
       Return a new set with elements from both sets.
 
-   .. method:: intersection(other)
-               set & other
+      .. versionchanged:: 2.6
+         Accepts multiple input iterables.
+
+   .. method:: intersection(other, ...)
+               set & other & ...
 
       Return a new set with elements common to both sets.
 
+      .. versionchanged:: 2.6
+         Accepts multiple input iterables.
+
    .. method:: difference(other)
                set - other
 
@@ -1562,16 +1568,22 @@
    The following table lists operations available for :class:`set` that do not
    apply to immutable instances of :class:`frozenset`:
 
-   .. method:: update(other)
-               set |= other
+   .. method:: update(other, ...)
+               set |= other | ...
 
       Update the set, adding elements from *other*.
 
-   .. method:: intersection_update(other)
-               set &= other
+      .. versionchanged:: 2.6
+         Accepts multiple input iterables.
+
+   .. method:: intersection_update(other, ...)
+               set &= other & ...
 
       Update the set, keeping only elements found in it and *other*.
 
+      .. versionchanged:: 2.6
+         Accepts multiple input iterables.
+
    .. method:: difference_update(other)
                set -= other
 

Modified: python/branches/py3k/Doc/library/tokenize.rst
==============================================================================
--- python/branches/py3k/Doc/library/tokenize.rst	(original)
+++ python/branches/py3k/Doc/library/tokenize.rst	Tue Jun 10 21:20:26 2008
@@ -1,4 +1,3 @@
-
 :mod:`tokenize` --- Tokenizer for Python source
 ===============================================
 
@@ -15,7 +14,6 @@
 
 The primary entry point is a :term:`generator`:
 
-
 .. function:: tokenize(readline)
 
    The :func:`tokenize` generator requires one argument, *readline*, which
@@ -28,11 +26,11 @@
    token string; a 2-tuple ``(srow, scol)`` of ints specifying the row and 
    column where the token begins in the source; a 2-tuple ``(erow, ecol)`` of 
    ints specifying the row and column where the token ends in the source; and 
-   the line on which the token was found. The line passed is the *logical* 
-   line; continuation lines are included.
+   the line on which the token was found. The line passed (the last tuple item)
+   is the *logical* line; continuation lines are included.
    
-   tokenize determines the source encoding of the file by looking for a utf-8
-   bom or encoding cookie, according to :pep:`263`.
+   :func:`tokenize` determines the source encoding of the file by looking for a
+   UTF-8 BOM or encoding cookie, according to :pep:`263`.
 
 
 All constants from the :mod:`token` module are also exported from

Modified: python/branches/py3k/Lib/collections.py
==============================================================================
--- python/branches/py3k/Lib/collections.py	(original)
+++ python/branches/py3k/Lib/collections.py	Tue Jun 10 21:20:26 2008
@@ -87,7 +87,9 @@
             result = self._make(map(kwds.pop, %(field_names)r, self))
             if kwds:
                 raise ValueError('Got unexpected field names: %%r' %% kwds.keys())
-            return result \n\n''' % locals()
+            return result \n
+        def __getnewargs__(self):
+            return tuple(self) \n\n''' % locals()
     for i, name in enumerate(field_names):
         template += '        %s = property(itemgetter(%d))\n' % (name, i)
     if verbose:

Modified: python/branches/py3k/Lib/test/test_collections.py
==============================================================================
--- python/branches/py3k/Lib/test/test_collections.py	(original)
+++ python/branches/py3k/Lib/test/test_collections.py	Tue Jun 10 21:20:26 2008
@@ -3,6 +3,7 @@
 import unittest, doctest
 from test import support
 from collections import namedtuple
+import pickle, copy
 from collections import Hashable, Iterable, Iterator
 from collections import Sized, Container, Callable
 from collections import Set, MutableSet
@@ -10,6 +11,7 @@
 from collections import Sequence, MutableSequence
 from collections import ByteString
 
+TestNT = namedtuple('TestNT', 'x y z')    # type used for pickle tests
 
 class TestNamedTuple(unittest.TestCase):
 
@@ -111,7 +113,7 @@
         self.assertEqual(Dot(1)._replace(d=999), (999,))
         self.assertEqual(Dot(1)._fields, ('d',))
 
-        # n = 10000
+        # n = 5000
         n = 254 # SyntaxError: more than 255 arguments:
         import string, random
         names = list(set(''.join([random.choice(string.ascii_letters)
@@ -134,6 +136,23 @@
         self.assertEqual(b2, tuple(b2_expected))
         self.assertEqual(b._fields, tuple(names))
 
+    def test_pickle(self):
+        p = TestNT(x=10, y=20, z=30)
+        for module in (pickle,):
+            loads = getattr(module, 'loads')
+            dumps = getattr(module, 'dumps')
+            for protocol in -1, 0, 1, 2:
+                q = loads(dumps(p, protocol))
+                self.assertEqual(p, q)
+                self.assertEqual(p._fields, q._fields)
+
+    def test_copy(self):
+        p = TestNT(x=10, y=20, z=30)
+        for copier in copy.copy, copy.deepcopy:
+            q = copier(p)
+            self.assertEqual(p, q)
+            self.assertEqual(p._fields, q._fields)
+
 class TestOneTrickPonyABCs(unittest.TestCase):
 
     def test_Hashable(self):

Modified: python/branches/py3k/Lib/test/test_math.py
==============================================================================
--- python/branches/py3k/Lib/test/test_math.py	(original)
+++ python/branches/py3k/Lib/test/test_math.py	Tue Jun 10 21:20:26 2008
@@ -6,6 +6,7 @@
 import math
 import os
 import sys
+import random
 
 eps = 1E-05
 NAN = float('nan')
@@ -274,6 +275,20 @@
         self.ftest('fabs(0)', math.fabs(0), 0)
         self.ftest('fabs(1)', math.fabs(1), 1)
 
+    def testFactorial(self):
+        def fact(n):
+            result = 1
+            for i in range(1, int(n)+1):
+                result *= i
+            return result
+        values = list(range(10)) + [50, 100, 500]
+        random.shuffle(values)
+        for x in range(10):
+            for cast in (int, float):
+                self.assertEqual(math.factorial(cast(x)), fact(x), (x, fact(x), math.factorial(x)))
+        self.assertRaises(ValueError, math.factorial, -1)
+        self.assertRaises(ValueError, math.factorial, math.pi)
+
     def testFloor(self):
         self.assertRaises(TypeError, math.floor)
         self.assertEquals(int, type(math.floor(0.5)))

Modified: python/branches/py3k/Lib/test/test_set.py
==============================================================================
--- python/branches/py3k/Lib/test/test_set.py	(original)
+++ python/branches/py3k/Lib/test/test_set.py	Tue Jun 10 21:20:26 2008
@@ -79,6 +79,7 @@
             self.assertEqual(self.thetype('abcba').union(C('efgfe')), set('abcefg'))
             self.assertEqual(self.thetype('abcba').union(C('ccb')), set('abc'))
             self.assertEqual(self.thetype('abcba').union(C('ef')), set('abcef'))
+            self.assertEqual(self.thetype('abcba').union(C('ef'), C('fg')), set('abcefg'))
 
     def test_or(self):
         i = self.s.union(self.otherword)
@@ -103,6 +104,7 @@
             self.assertEqual(self.thetype('abcba').intersection(C('efgfe')), set(''))
             self.assertEqual(self.thetype('abcba').intersection(C('ccb')), set('bc'))
             self.assertEqual(self.thetype('abcba').intersection(C('ef')), set(''))
+            self.assertEqual(self.thetype('abcba').intersection(C('cbcf'), C('bag')), set('b'))
 
     def test_isdisjoint(self):
         def f(s1, s2):
@@ -410,6 +412,12 @@
                 s = self.thetype('abcba')
                 self.assertEqual(s.update(C(p)), None)
                 self.assertEqual(s, set(q))
+        for p in ('cdc', 'efgfe', 'ccb', 'ef', 'abcda'):
+            q = 'ahi'
+            for C in set, frozenset, dict.fromkeys, str, list, tuple:
+                s = self.thetype('abcba')
+                self.assertEqual(s.update(C(p), C(q)), None)
+                self.assertEqual(s, set(s) | set(p) | set(q))
 
     def test_ior(self):
         self.s |= set(self.otherword)
@@ -431,6 +439,11 @@
                 s = self.thetype('abcba')
                 self.assertEqual(s.intersection_update(C(p)), None)
                 self.assertEqual(s, set(q))
+                ss = 'abcba'
+                s = self.thetype(ss)
+                t = 'cbc'
+                self.assertEqual(s.intersection_update(C(p), C(t)), None)
+                self.assertEqual(s, set('abcba')&set(p)&set(t))
 
     def test_iand(self):
         self.s &= set(self.otherword)

Modified: python/branches/py3k/Lib/test/test_sys.py
==============================================================================
--- python/branches/py3k/Lib/test/test_sys.py	(original)
+++ python/branches/py3k/Lib/test/test_sys.py	Tue Jun 10 21:20:26 2008
@@ -386,11 +386,14 @@
         self.file.close()
         test.support.unlink(test.support.TESTFN)
 
-    def check_sizeof(self, o, size):
+    def check_sizeof(self, o, size, size2=None):
+        """Check size of o. Possible are size and optionally size2)."""
         result = sys.getsizeof(o)
-        msg = 'wrong size for %s: got %d, expected %d' \
-            % (type(o), result, size)
-        self.assertEqual(result, size, msg)
+        msg = 'wrong size for %s: got %d, expected ' % (type(o), result)
+        if (size2 != None) and (result != size):
+            self.assertEqual(result, size2, msg + str(size2))
+        else:
+            self.assertEqual(result, size, msg + str(size))
 
     def align(self, value):
         mod = value % self.p
@@ -486,6 +489,24 @@
         # list
         self.check_sizeof([], h + l + p + l)
         self.check_sizeof([1, 2, 3], h + l + p + l + 3*l)
+        # unicode
+        import math
+        usize = math.log(sys.maxunicode + 1, 2) / 8
+        samples = ['', '1'*100]
+        # we need to test for both sizes, because we don't know if the string
+        # has been cached
+        for s in samples:
+            basicsize =  h + l + p + l + l + p + usize * (len(s) + 1)
+            defenc = bytes(s, 'ascii')
+            self.check_sizeof(s, basicsize,
+                              size2=basicsize + sys.getsizeof(defenc))
+            # trigger caching encoded version as bytes object
+            try:
+                getattr(sys, s)
+            except AttributeError:
+                pass
+            finally:
+                self.check_sizeof(s, basicsize + sys.getsizeof(defenc))
 
         h += l
         # long
@@ -495,9 +516,6 @@
         self.check_sizeof(32768, h + self.align(2) + 2)
         self.check_sizeof(32768*32768-1, h + self.align(2) + 2)
         self.check_sizeof(32768*32768, h + self.align(2) + 4)
-        # XXX add Unicode support
-        # self.check_sizeof('', h + l + self.align(i + 1))
-        # self.check_sizeof('abc', h + l + self.align(i + 1) + 3)
 
 
 def test_main():

Modified: python/branches/py3k/Lib/test/test_urllib2net.py
==============================================================================
--- python/branches/py3k/Lib/test/test_urllib2net.py	(original)
+++ python/branches/py3k/Lib/test/test_urllib2net.py	Tue Jun 10 21:20:26 2008
@@ -11,19 +11,25 @@
 import mimetools
 
 
-def _urlopen_with_retry(host, *args, **kwargs):
-    # Connecting to remote hosts is flaky.  Make it more robust
-    # by retrying the connection several times.
+def _retry_thrice(func, exc, *args, **kwargs):
     for i in range(3):
         try:
-            return urllib2.urlopen(host, *args, **kwargs)
-        except urllib2.URLError as e:
+            return func(*args, **kwargs)
+        except exc as e:
             last_exc = e
             continue
         except:
             raise
     raise last_exc
 
+def _wrap_with_retry_thrice(func, exc):
+    def wrapped(*args, **kwargs):
+        return _retry_thrice(func, exc, *args, **kwargs)
+    return wrapped
+
+# Connecting to remote hosts is flaky.  Make it more robust by retrying
+# the connection several times.
+_urlopen_with_retry = _wrap_with_retry_thrice(urllib2.urlopen, urllib2.URLError)
 
 
 class AuthTests(unittest.TestCase):
@@ -114,7 +120,7 @@
                 'file:'+sanepathname2url(os.path.abspath(TESTFN)),
                 ('file:///nonsensename/etc/passwd', None, urllib2.URLError),
                 ]
-            self._test_urls(urls, self._extra_handlers(), urllib2.urlopen)
+            self._test_urls(urls, self._extra_handlers(), retry=True)
         finally:
             os.remove(TESTFN)
 
@@ -146,13 +152,15 @@
 
 ##             self._test_urls(urls, self._extra_handlers()+[bauth, dauth])
 
-    def _test_urls(self, urls, handlers, urlopen=_urlopen_with_retry):
+    def _test_urls(self, urls, handlers, retry=True):
         import socket
         import time
         import logging
         debug = logging.getLogger("test_urllib2").debug
 
-        urllib2.install_opener(urllib2.build_opener(*handlers))
+        urlopen = urllib2.build_opener(*handlers).open
+        if retry:
+            urlopen = _wrap_with_retry_thrice(urlopen, urllib2.URLError)
 
         for url in urls:
             if isinstance(url, tuple):

Modified: python/branches/py3k/Modules/mathmodule.c
==============================================================================
--- python/branches/py3k/Modules/mathmodule.c	(original)
+++ python/branches/py3k/Modules/mathmodule.c	Tue Jun 10 21:20:26 2008
@@ -568,6 +568,54 @@
 Assumes IEEE-754 floating point arithmetic.");
 
 static PyObject *
+math_factorial(PyObject *self, PyObject *arg)
+{
+	long i, x;
+	PyObject *result, *iobj, *newresult;
+
+	if (PyFloat_Check(arg)) {
+		double dx = PyFloat_AS_DOUBLE((PyFloatObject *)arg);
+		if (dx != floor(dx)) {
+			PyErr_SetString(PyExc_ValueError, 
+				"factorial() only accepts integral values");
+			return NULL;
+		}
+	}
+
+	x = PyLong_AsLong(arg);
+	if (x == -1 && PyErr_Occurred())
+		return NULL;
+	if (x < 0) {
+		PyErr_SetString(PyExc_ValueError, 
+			"factorial() not defined for negative values");
+		return NULL;
+	}
+
+	result = (PyObject *)PyLong_FromLong(1);
+	if (result == NULL)
+		return NULL;
+	for (i=1 ; i<=x ; i++) {
+		iobj = (PyObject *)PyLong_FromLong(i);
+		if (iobj == NULL)
+			goto error;
+		newresult = PyNumber_Multiply(result, iobj);
+		Py_DECREF(iobj);
+		if (newresult == NULL)
+			goto error;
+		Py_DECREF(result);
+		result = newresult;
+	}
+	return result;
+
+error:
+	Py_DECREF(result);
+	Py_XDECREF(iobj);
+	return NULL;
+}
+
+PyDoc_STRVAR(math_factorial_doc, "Return n!");
+
+static PyObject *
 math_trunc(PyObject *self, PyObject *number)
 {
 	static PyObject *trunc_str = NULL;
@@ -1022,6 +1070,7 @@
 	{"degrees",	math_degrees,	METH_O,		math_degrees_doc},
 	{"exp",		math_exp,	METH_O,		math_exp_doc},
 	{"fabs",	math_fabs,	METH_O,		math_fabs_doc},
+	{"factorial",	math_factorial,	METH_O,		math_factorial_doc},
 	{"floor",	math_floor,	METH_O,		math_floor_doc},
 	{"fmod",	math_fmod,	METH_VARARGS,	math_fmod_doc},
 	{"frexp",	math_frexp,	METH_O,		math_frexp_doc},

Modified: python/branches/py3k/Objects/setobject.c
==============================================================================
--- python/branches/py3k/Objects/setobject.c	(original)
+++ python/branches/py3k/Objects/setobject.c	Tue Jun 10 21:20:26 2008
@@ -959,15 +959,20 @@
 }
 
 static PyObject *
-set_update(PySetObject *so, PyObject *other)
+set_update(PySetObject *so, PyObject *args)
 {
-	if (set_update_internal(so, other) == -1)
-		return NULL;
+	Py_ssize_t i;
+
+	for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
+		PyObject *other = PyTuple_GET_ITEM(args, i);
+		if (set_update_internal(so, other) == -1)
+			return NULL;
+	}
 	Py_RETURN_NONE;
 }
 
 PyDoc_STRVAR(update_doc, 
-"Update a set with the union of itself and another.");
+"Update a set with the union of itself and others.");
 
 static PyObject *
 make_new_set(PyTypeObject *type, PyObject *iterable)
@@ -1148,35 +1153,53 @@
 PyDoc_STRVAR(clear_doc, "Remove all elements from this set.");
 
 static PyObject *
-set_union(PySetObject *so, PyObject *other)
+set_union(PySetObject *so, PyObject *args)
 {
 	PySetObject *result;
+	PyObject *other;
+	Py_ssize_t i;
 
 	result = (PySetObject *)set_copy(so);
 	if (result == NULL)
 		return NULL;
-	if ((PyObject *)so == other)
-		return (PyObject *)result;
-	if (set_update_internal(result, other) == -1) {
-		Py_DECREF(result);
-		return NULL;
+
+	for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
+		other = PyTuple_GET_ITEM(args, i);
+		if ((PyObject *)so == other)
+			return (PyObject *)result;
+		if (set_update_internal(result, other) == -1) {
+			Py_DECREF(result);
+			return NULL;
+		}
 	}
 	return (PyObject *)result;
 }
 
 PyDoc_STRVAR(union_doc,
- "Return the union of two sets as a new set.\n\
+ "Return the union of sets as a new set.\n\
 \n\
 (i.e. all elements that are in either set.)");
 
 static PyObject *
 set_or(PySetObject *so, PyObject *other)
 {
+	PySetObject *result;
+
 	if (!PyAnySet_Check(so) || !PyAnySet_Check(other)) {
 		Py_INCREF(Py_NotImplemented);
 		return Py_NotImplemented;
 	}
-	return set_union(so, other);
+
+	result = (PySetObject *)set_copy(so);
+	if (result == NULL)
+		return NULL;
+	if ((PyObject *)so == other)
+		return (PyObject *)result;
+	if (set_update_internal(result, other) == -1) {
+		Py_DECREF(result);
+		return NULL;
+	}
+	return (PyObject *)result;
 }
 
 static PyObject *
@@ -1275,6 +1298,26 @@
 	return (PyObject *)result;
 }
 
+static PyObject *
+set_intersection_multi(PySetObject *so, PyObject *args)
+{
+	Py_ssize_t i;
+	PyObject *result = (PyObject *)so;
+
+	Py_INCREF(so);
+	for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
+		PyObject *other = PyTuple_GET_ITEM(args, i);
+		PyObject *newresult = set_intersection((PySetObject *)result, other);
+		if (newresult == NULL) {
+			Py_DECREF(result);
+			return NULL;
+		}
+		Py_DECREF(result);
+		result = newresult;
+	}
+	return result;
+}
+
 PyDoc_STRVAR(intersection_doc,
 "Return the intersection of two sets as a new set.\n\
 \n\
@@ -1293,6 +1336,19 @@
 	Py_RETURN_NONE;
 }
 
+static PyObject *
+set_intersection_update_multi(PySetObject *so, PyObject *args)
+{
+	PyObject *tmp;
+
+	tmp = set_intersection_multi(so, args);
+	if (tmp == NULL)
+		return NULL;
+	set_swap_bodies(so, (PySetObject *)tmp);
+	Py_DECREF(tmp);
+	Py_RETURN_NONE;
+}
+
 PyDoc_STRVAR(intersection_update_doc,
 "Update a set with the intersection of itself and another.");
 
@@ -1911,9 +1967,9 @@
 	 difference_doc},
 	{"difference_update",	(PyCFunction)set_difference_update,	METH_O,
 	 difference_update_doc},
-	{"intersection",(PyCFunction)set_intersection,	METH_O,
+	{"intersection",(PyCFunction)set_intersection_multi,	METH_VARARGS,
 	 intersection_doc},
-	{"intersection_update",(PyCFunction)set_intersection_update,	METH_O,
+	{"intersection_update",(PyCFunction)set_intersection_update_multi,	METH_VARARGS,
 	 intersection_update_doc},
 	{"isdisjoint",	(PyCFunction)set_isdisjoint,	METH_O,
 	 isdisjoint_doc},
@@ -1935,9 +1991,9 @@
 	{"test_c_api",	(PyCFunction)test_c_api,	METH_NOARGS,
 	 test_c_api_doc},
 #endif
-	{"union",	(PyCFunction)set_union,		METH_O,
+	{"union",	(PyCFunction)set_union,		METH_VARARGS,
 	 union_doc},
-	{"update",	(PyCFunction)set_update,	METH_O,
+	{"update",	(PyCFunction)set_update,	METH_VARARGS,
 	 update_doc},
 	{NULL,		NULL}	/* sentinel */
 };
@@ -2036,7 +2092,7 @@
 	 copy_doc},
 	{"difference",	(PyCFunction)set_difference,	METH_O,
 	 difference_doc},
-	{"intersection",(PyCFunction)set_intersection,	METH_O,
+	{"intersection",(PyCFunction)set_intersection_multi,	METH_VARARGS,
 	 intersection_doc},
 	{"isdisjoint",	(PyCFunction)set_isdisjoint,	METH_O,
 	 isdisjoint_doc},
@@ -2048,7 +2104,7 @@
 	 reduce_doc},
 	{"symmetric_difference",(PyCFunction)set_symmetric_difference,	METH_O,
 	 symmetric_difference_doc},
-	{"union",	(PyCFunction)set_union,		METH_O,
+	{"union",	(PyCFunction)set_union,		METH_VARARGS,
 	 union_doc},
 	{NULL,		NULL}	/* sentinel */
 };

Modified: python/branches/py3k/Objects/unicodeobject.c
==============================================================================
--- python/branches/py3k/Objects/unicodeobject.c	(original)
+++ python/branches/py3k/Objects/unicodeobject.c	Tue Jun 10 21:20:26 2008
@@ -8301,6 +8301,28 @@
 ");
 
 static PyObject *
+unicode__sizeof__(PyUnicodeObject *v)
+{
+    PyObject *res = NULL, *defsize = NULL;
+
+    res = PyLong_FromSsize_t(sizeof(PyUnicodeObject) +
+                             sizeof(Py_UNICODE) * (v->length + 1));
+    if (v->defenc) {
+        defsize = PyObject_CallMethod(v->defenc, "__sizeof__", NULL);
+        if (defsize == NULL) {
+            Py_DECREF(res);
+            return NULL;
+        }
+        res = PyNumber_Add(res, defsize);
+        Py_DECREF(defsize);
+    }
+    return res;
+}
+
+PyDoc_STRVAR(sizeof__doc__,
+"S.__sizeof__() -> size of S in memory, in bytes");
+
+static PyObject *
 unicode_getnewargs(PyUnicodeObject *v)
 {
 	return Py_BuildValue("(u#)", v->str, v->length);
@@ -8357,6 +8379,7 @@
     {"_formatter_parser", (PyCFunction) formatter_parser, METH_NOARGS},
     {"maketrans", (PyCFunction) unicode_maketrans,
      METH_VARARGS | METH_STATIC, maketrans__doc__},
+    {"__sizeof__", (PyCFunction) unicode__sizeof__, METH_NOARGS, sizeof__doc__},
 #if 0
     {"capwords", (PyCFunction) unicode_capwords, METH_NOARGS, capwords__doc__},
 #endif

From python-3000-checkins at python.org  Tue Jun 10 23:04:15 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Tue, 10 Jun 2008 23:04:15 +0200 (CEST)
Subject: [Python-3000-checkins] r64091 - python/branches/py3k
Message-ID: <20080610210415.A52741E4002@bag.python.org>

Author: benjamin.peterson
Date: Tue Jun 10 23:04:14 2008
New Revision: 64091

Log:
Blocked revisions 64090 via svnmerge

........
  r64090 | armin.ronacher | 2008-06-10 15:52:19 -0500 (Tue, 10 Jun 2008) | 3 lines
  
  Documented the new AST constructor.
........


Modified:
   python/branches/py3k/   (props changed)

From python-3000-checkins at python.org  Tue Jun 10 23:23:05 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Tue, 10 Jun 2008 23:23:05 +0200 (CEST)
Subject: [Python-3000-checkins] r64092 -
	python/branches/py3k/Lib/test/test_xmlrpc_net.py
Message-ID: <20080610212305.D2DAF1E4003@bag.python.org>

Author: benjamin.peterson
Date: Tue Jun 10 23:23:05 2008
New Revision: 64092

Log:
Temporarily disable test_xmlrpc_net because xmlrpc.com is broken


Modified:
   python/branches/py3k/Lib/test/test_xmlrpc_net.py

Modified: python/branches/py3k/Lib/test/test_xmlrpc_net.py
==============================================================================
--- python/branches/py3k/Lib/test/test_xmlrpc_net.py	(original)
+++ python/branches/py3k/Lib/test/test_xmlrpc_net.py	Tue Jun 10 23:23:05 2008
@@ -10,7 +10,8 @@
 
 class CurrentTimeTest(unittest.TestCase):
 
-    def test_current_time(self):
+    # XXX time.xmlrpc.com seems broken which is why this is disabled
+    def Xtest_current_time(self):
         # Get the current time from xmlrpc.com.  This code exercises
         # the minimal HTTP functionality in xmlrpclib.
         server = xmlrpclib.ServerProxy("http://time.xmlrpc.com/RPC2")

From python-3000-checkins at python.org  Tue Jun 10 23:25:05 2008
From: python-3000-checkins at python.org (gregory.p.smith)
Date: Tue, 10 Jun 2008 23:25:05 +0200 (CEST)
Subject: [Python-3000-checkins] r64094 - python/branches/py3k
Message-ID: <20080610212506.0ACE01E4004@bag.python.org>

Author: gregory.p.smith
Date: Tue Jun 10 23:25:05 2008
New Revision: 64094

Log:
block 64093 as its 2.6 only.


Modified:
   python/branches/py3k/   (props changed)

From python-3000-checkins at python.org  Tue Jun 10 23:44:59 2008
From: python-3000-checkins at python.org (amaury.forgeotdarc)
Date: Tue, 10 Jun 2008 23:44:59 +0200 (CEST)
Subject: [Python-3000-checkins] r64096 -
	python/branches/py3k/Lib/test/test_platform.py
Message-ID: <20080610214459.1DBAC1E4003@bag.python.org>

Author: amaury.forgeotdarc
Date: Tue Jun 10 23:44:58 2008
New Revision: 64096

Log:
Windows has no os.uname. Use platform.uname() instead.


Modified:
   python/branches/py3k/Lib/test/test_platform.py

Modified: python/branches/py3k/Lib/test/test_platform.py
==============================================================================
--- python/branches/py3k/Lib/test/test_platform.py	(original)
+++ python/branches/py3k/Lib/test/test_platform.py	Tue Jun 10 23:44:58 2008
@@ -65,7 +65,7 @@
     def test_mac_ver(self):
         res = platform.mac_ver()
 
-        if os.uname()[0] == 'Darwin':
+        if platform.uname()[0] == 'Darwin':
             # We're on a MacOSX system, check that
             # the right version information is returned
             fd = os.popen('sw_vers', 'r')

From python-3000-checkins at python.org  Wed Jun 11 04:37:01 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Wed, 11 Jun 2008 04:37:01 +0200 (CEST)
Subject: [Python-3000-checkins] r64103 -
	python/branches/py3k/Lib/test/test_xmlrpc_net.py
Message-ID: <20080611023701.CB4F81E4003@bag.python.org>

Author: benjamin.peterson
Date: Wed Jun 11 04:37:01 2008
New Revision: 64103

Log:
revert r64092 because http://xmlrpc.com is back up


Modified:
   python/branches/py3k/Lib/test/test_xmlrpc_net.py

Modified: python/branches/py3k/Lib/test/test_xmlrpc_net.py
==============================================================================
--- python/branches/py3k/Lib/test/test_xmlrpc_net.py	(original)
+++ python/branches/py3k/Lib/test/test_xmlrpc_net.py	Wed Jun 11 04:37:01 2008
@@ -10,8 +10,7 @@
 
 class CurrentTimeTest(unittest.TestCase):
 
-    # XXX time.xmlrpc.com seems broken which is why this is disabled
-    def Xtest_current_time(self):
+    def test_current_time(self):
         # Get the current time from xmlrpc.com.  This code exercises
         # the minimal HTTP functionality in xmlrpclib.
         server = xmlrpclib.ServerProxy("http://time.xmlrpc.com/RPC2")

From python-3000-checkins at python.org  Wed Jun 11 05:41:00 2008
From: python-3000-checkins at python.org (gregory.p.smith)
Date: Wed, 11 Jun 2008 05:41:00 +0200 (CEST)
Subject: [Python-3000-checkins] r64106 - python/branches/py3k
Message-ID: <20080611034100.672A61E4003@bag.python.org>

Author: gregory.p.smith
Date: Wed Jun 11 05:41:00 2008
New Revision: 64106

Log:
block 64105


Modified:
   python/branches/py3k/   (props changed)

From python-3000-checkins at python.org  Wed Jun 11 07:26:24 2008
From: python-3000-checkins at python.org (martin.v.loewis)
Date: Wed, 11 Jun 2008 07:26:24 +0200 (CEST)
Subject: [Python-3000-checkins] r64107 - in python/branches/py3k:
	Doc/c-api/import.rst Doc/extending/extending.rst
	Include/import.h Include/modsupport.h Include/moduleobject.h
	Include/pyport.h Include/pystate.h Include/warnings.h
	Lib/test/test_sys.py Misc/NEWS Modules/_bisectmodule.c
	Modules/_bsddb.c Modules/_bytesio.c Modules/_codecsmodule.c
	Modules/_collectionsmodule.c Modules/_csv.c
	Modules/_ctypes/_ctypes.c Modules/_ctypes/_ctypes_test.c
	Modules/_curses_panel.c Modules/_cursesmodule.c
	Modules/_dbmmodule.c Modules/_elementtree.c Modules/_fileio.c
	Modules/_functoolsmodule.c Modules/_gdbmmodule.c
	Modules/_gestalt.c Modules/_hashopenssl.c
	Modules/_heapqmodule.c Modules/_json.c
	Modules/_localemodule.c Modules/_lsprof.c
	Modules/_randommodule.c Modules/_sqlite/module.c
	Modules/_sre.c Modules/_ssl.c Modules/_struct.c
	Modules/_testcapimodule.c Modules/_threadmodule.c
	Modules/_tkinter.c Modules/_weakref.c Modules/arraymodule.c
	Modules/atexitmodule.c Modules/audioop.c Modules/binascii.c
	Modules/bz2module.c Modules/cjkcodecs/cjkcodecs.h
	Modules/cjkcodecs/multibytecodec.c Modules/cmathmodule.c
	Modules/config.c.in Modules/cryptmodule.c
	Modules/datetimemodule.c Modules/errnomodule.c
	Modules/fcntlmodule.c Modules/fpectlmodule.c
	Modules/fpetestmodule.c Modules/gcmodule.c
	Modules/grpmodule.c Modules/itertoolsmodule.c
	Modules/makesetup Modules/mathmodule.c Modules/md5module.c
	Modules/mmapmodule.c Modules/nismodule.c Modules/operator.c
	Modules/ossaudiodev.c Modules/parsermodule.c
	Modules/posixmodule.c Modules/pwdmodule.c Modules/pyexpat.c
	Modules/readline.c Modules/resource.c Modules/selectmodule.c
	Modules/sha1module.c Modules/sha256module.c
	Modules/sha512module.c Modules/signalmodule.c
	Modules/socketmodule.c Modules/spwdmodule.c
	Modules/symtablemodule.c Modules/syslogmodule.c
	Modules/termios.c Modules/timemodule.c Modules/unicodedata.c
	Modules/xxmodule.c Modules/xxsubtype.c Modules/zipimport.c
	Modules/zlibmodule.c Objects/exceptions.c
	Objects/methodobject.c Objects/moduleobject.c PC/_msi.c
	PC/_subprocess.c PC/msvcrtmodule.c PC/winreg.c PC/winsound.c
	Parser/asdl_c.py Python/Python-ast.c Python/_warnings.c
	Python/bltinmodule.c Python/dynload_atheos.c
	Python/dynload_dl.c Python/dynload_hpux.c
	Python/dynload_next.c Python/dynload_os2.c
	Python/dynload_shlib.c Python/dynload_win.c Python/import.c
	Python/importdl.c Python/marshal.c Python/modsupport.c
	Python/pystate.c Python/pythonrun.c Python/sysmodule.c
Message-ID: <20080611052624.6AFF11E4003@bag.python.org>

Author: martin.v.loewis
Date: Wed Jun 11 07:26:20 2008
New Revision: 64107

Log:
Implement PEP 3121: new module initialization and finalization API.


Modified:
   python/branches/py3k/Doc/c-api/import.rst
   python/branches/py3k/Doc/extending/extending.rst
   python/branches/py3k/Include/import.h
   python/branches/py3k/Include/modsupport.h
   python/branches/py3k/Include/moduleobject.h
   python/branches/py3k/Include/pyport.h
   python/branches/py3k/Include/pystate.h
   python/branches/py3k/Include/warnings.h
   python/branches/py3k/Lib/test/test_sys.py
   python/branches/py3k/Misc/NEWS
   python/branches/py3k/Modules/_bisectmodule.c
   python/branches/py3k/Modules/_bsddb.c
   python/branches/py3k/Modules/_bytesio.c
   python/branches/py3k/Modules/_codecsmodule.c
   python/branches/py3k/Modules/_collectionsmodule.c
   python/branches/py3k/Modules/_csv.c
   python/branches/py3k/Modules/_ctypes/_ctypes.c
   python/branches/py3k/Modules/_ctypes/_ctypes_test.c
   python/branches/py3k/Modules/_curses_panel.c
   python/branches/py3k/Modules/_cursesmodule.c
   python/branches/py3k/Modules/_dbmmodule.c
   python/branches/py3k/Modules/_elementtree.c
   python/branches/py3k/Modules/_fileio.c
   python/branches/py3k/Modules/_functoolsmodule.c
   python/branches/py3k/Modules/_gdbmmodule.c
   python/branches/py3k/Modules/_gestalt.c
   python/branches/py3k/Modules/_hashopenssl.c
   python/branches/py3k/Modules/_heapqmodule.c
   python/branches/py3k/Modules/_json.c
   python/branches/py3k/Modules/_localemodule.c
   python/branches/py3k/Modules/_lsprof.c
   python/branches/py3k/Modules/_randommodule.c
   python/branches/py3k/Modules/_sqlite/module.c
   python/branches/py3k/Modules/_sre.c
   python/branches/py3k/Modules/_ssl.c
   python/branches/py3k/Modules/_struct.c
   python/branches/py3k/Modules/_testcapimodule.c
   python/branches/py3k/Modules/_threadmodule.c
   python/branches/py3k/Modules/_tkinter.c
   python/branches/py3k/Modules/_weakref.c
   python/branches/py3k/Modules/arraymodule.c
   python/branches/py3k/Modules/atexitmodule.c
   python/branches/py3k/Modules/audioop.c
   python/branches/py3k/Modules/binascii.c
   python/branches/py3k/Modules/bz2module.c
   python/branches/py3k/Modules/cjkcodecs/cjkcodecs.h
   python/branches/py3k/Modules/cjkcodecs/multibytecodec.c
   python/branches/py3k/Modules/cmathmodule.c
   python/branches/py3k/Modules/config.c.in
   python/branches/py3k/Modules/cryptmodule.c
   python/branches/py3k/Modules/datetimemodule.c
   python/branches/py3k/Modules/errnomodule.c
   python/branches/py3k/Modules/fcntlmodule.c
   python/branches/py3k/Modules/fpectlmodule.c
   python/branches/py3k/Modules/fpetestmodule.c
   python/branches/py3k/Modules/gcmodule.c
   python/branches/py3k/Modules/grpmodule.c
   python/branches/py3k/Modules/itertoolsmodule.c
   python/branches/py3k/Modules/makesetup
   python/branches/py3k/Modules/mathmodule.c
   python/branches/py3k/Modules/md5module.c
   python/branches/py3k/Modules/mmapmodule.c
   python/branches/py3k/Modules/nismodule.c
   python/branches/py3k/Modules/operator.c
   python/branches/py3k/Modules/ossaudiodev.c
   python/branches/py3k/Modules/parsermodule.c
   python/branches/py3k/Modules/posixmodule.c
   python/branches/py3k/Modules/pwdmodule.c
   python/branches/py3k/Modules/pyexpat.c
   python/branches/py3k/Modules/readline.c
   python/branches/py3k/Modules/resource.c
   python/branches/py3k/Modules/selectmodule.c
   python/branches/py3k/Modules/sha1module.c
   python/branches/py3k/Modules/sha256module.c
   python/branches/py3k/Modules/sha512module.c
   python/branches/py3k/Modules/signalmodule.c
   python/branches/py3k/Modules/socketmodule.c
   python/branches/py3k/Modules/spwdmodule.c
   python/branches/py3k/Modules/symtablemodule.c
   python/branches/py3k/Modules/syslogmodule.c
   python/branches/py3k/Modules/termios.c
   python/branches/py3k/Modules/timemodule.c
   python/branches/py3k/Modules/unicodedata.c
   python/branches/py3k/Modules/xxmodule.c
   python/branches/py3k/Modules/xxsubtype.c
   python/branches/py3k/Modules/zipimport.c
   python/branches/py3k/Modules/zlibmodule.c
   python/branches/py3k/Objects/exceptions.c
   python/branches/py3k/Objects/methodobject.c
   python/branches/py3k/Objects/moduleobject.c
   python/branches/py3k/PC/_msi.c
   python/branches/py3k/PC/_subprocess.c
   python/branches/py3k/PC/msvcrtmodule.c
   python/branches/py3k/PC/winreg.c
   python/branches/py3k/PC/winsound.c
   python/branches/py3k/Parser/asdl_c.py
   python/branches/py3k/Python/Python-ast.c
   python/branches/py3k/Python/_warnings.c
   python/branches/py3k/Python/bltinmodule.c
   python/branches/py3k/Python/dynload_atheos.c
   python/branches/py3k/Python/dynload_dl.c
   python/branches/py3k/Python/dynload_hpux.c
   python/branches/py3k/Python/dynload_next.c
   python/branches/py3k/Python/dynload_os2.c
   python/branches/py3k/Python/dynload_shlib.c
   python/branches/py3k/Python/dynload_win.c
   python/branches/py3k/Python/import.c
   python/branches/py3k/Python/importdl.c
   python/branches/py3k/Python/marshal.c
   python/branches/py3k/Python/modsupport.c
   python/branches/py3k/Python/pystate.c
   python/branches/py3k/Python/pythonrun.c
   python/branches/py3k/Python/sysmodule.c

Modified: python/branches/py3k/Doc/c-api/import.rst
==============================================================================
--- python/branches/py3k/Doc/c-api/import.rst	(original)
+++ python/branches/py3k/Doc/c-api/import.rst	Wed Jun 11 07:26:20 2008
@@ -200,7 +200,7 @@
    tricks with this to provide a dynamically created collection of frozen modules.
 
 
-.. cfunction:: int PyImport_AppendInittab(char *name, void (*initfunc)(void))
+.. cfunction:: int PyImport_AppendInittab(char *name, PyObject* (*initfunc)(void))
 
    Add a single module to the existing table of built-in modules.  This is a
    convenience wrapper around :cfunc:`PyImport_ExtendInittab`, returning ``-1`` if
@@ -221,7 +221,7 @@
 
       struct _inittab {
           char *name;
-          void (*initfunc)(void);
+          PyObject* (*initfunc)(void);
       };
 
 

Modified: python/branches/py3k/Doc/extending/extending.rst
==============================================================================
--- python/branches/py3k/Doc/extending/extending.rst	(original)
+++ python/branches/py3k/Doc/extending/extending.rst	Wed Jun 11 07:26:20 2008
@@ -191,21 +191,22 @@
 
    static PyObject *SpamError;
 
-and initialize it in your module's initialization function (:cfunc:`initspam`)
+and initialize it in your module's initialization function (:cfunc:`PyInit_spam`)
 with an exception object (leaving out the error checking for now)::
 
    PyMODINIT_FUNC
-   initspam(void)
+   PyInit_spam(void)
    {
        PyObject *m;
 
-       m = Py_InitModule("spam", SpamMethods);
+       m = PyModule_Create(&spammodule);
        if (m == NULL)
-           return;
+           return NULL;
 
        SpamError = PyErr_NewException("spam.error", NULL, NULL);
        Py_INCREF(SpamError);
        PyModule_AddObject(m, "error", SpamError);
+       return m;
    }
 
 Note that the Python name for the exception object is :exc:`spam.error`.  The
@@ -303,15 +304,26 @@
 Use :cfunc:`PyArg_ParseTupleAndKeywords` to parse the arguments to such a
 function.
 
-The method table must be passed to the interpreter in the module's
+The method table must be referenced in the module definition structure::
+
+   struct PyModuleDef spammodule = {
+      PyModuleDef_HEAD_INIT,
+      "spam",   /* name of module */
+      spam_doc, /* module documentation, may be NULL */
+      -1,       /* size of per-interpreter state of the module,
+                   or -1 if the module keeps state in global variables. */
+      SpamMethods
+   };
+
+This structure, in turn, must be passed to the interpreter in the module's
 initialization function.  The initialization function must be named
-:cfunc:`initname`, where *name* is the name of the module, and should be the
+:cfunc:`PyInit_name`, where *name* is the name of the module, and should be the
 only non-\ ``static`` item defined in the module file::
 
    PyMODINIT_FUNC
-   initspam(void)
+   PyInit_spam(void)
    {
-       (void) Py_InitModule("spam", SpamMethods);
+       return PyModule_Create(&spammodule);
    }
 
 Note that PyMODINIT_FUNC declares the function as ``void`` return type,
@@ -319,33 +331,37 @@
 declares the function as ``extern "C"``.
 
 When the Python program imports module :mod:`spam` for the first time,
-:cfunc:`initspam` is called. (See below for comments about embedding Python.)
-It calls :cfunc:`Py_InitModule`, which creates a "module object" (which is
-inserted in the dictionary ``sys.modules`` under the key ``"spam"``), and
+:cfunc:`PyInit_spam` is called. (See below for comments about embedding Python.)
+It calls :cfunc:`PyModule_Create`, which returns a module object, and
 inserts built-in function objects into the newly created module based upon the
-table (an array of :ctype:`PyMethodDef` structures) that was passed as its
-second argument. :cfunc:`Py_InitModule` returns a pointer to the module object
-that it creates (which is unused here).  It may abort with a fatal error for
+table (an array of :ctype:`PyMethodDef` structures) found in the module definition. 
+:cfunc:`PyModule_Create` returns a pointer to the module object
+that it creates.  It may abort with a fatal error for
 certain errors, or return *NULL* if the module could not be initialized
-satisfactorily.
+satisfactorily. The init function must return the module object to its caller,
+so that it then gets inserted into ``sys.modules``.
 
-When embedding Python, the :cfunc:`initspam` function is not called
+When embedding Python, the :cfunc:`PyInit_spam` function is not called
 automatically unless there's an entry in the :cdata:`_PyImport_Inittab` table.
-The easiest way to handle this is to statically initialize your
-statically-linked modules by directly calling :cfunc:`initspam` after the call
-to :cfunc:`Py_Initialize`::
+To add the module to the initialization table, use :cfunc:`PyImport_AppendInittab`,
+optionally followed by an import of the module::
 
    int
    main(int argc, char *argv[])
    {
+       /* Add a builtin module, before Py_Initialize */
+       PyImport_AppendInittab("spam", PyInit_spam);
+
        /* Pass argv[0] to the Python interpreter */
        Py_SetProgramName(argv[0]);
 
        /* Initialize the Python interpreter.  Required. */
        Py_Initialize();
 
-       /* Add a static module */
-       initspam();
+       /* Optionally import the module; alternatively,
+          import can be deferred until the embedded script
+          imports it. */
+       PyImport_ImportModule("spam");
 
 An example may be found in the file :file:`Demo/embed/demo.c` in the Python
 source distribution.
@@ -1154,15 +1170,15 @@
 function must take care of initializing the C API pointer array::
 
    PyMODINIT_FUNC
-   initspam(void)
+   PyInit_spam(void)
    {
        PyObject *m;
        static void *PySpam_API[PySpam_API_pointers];
        PyObject *c_api_object;
 
-       m = Py_InitModule("spam", SpamMethods);
+       m = PyModule_Create(&spammodule);
        if (m == NULL)
-           return;
+           return NULL;
 
        /* Initialize the C API pointer array */
        PySpam_API[PySpam_System_NUM] = (void *)PySpam_System;
@@ -1172,10 +1188,11 @@
 
        if (c_api_object != NULL)
            PyModule_AddObject(m, "_C_API", c_api_object);
+       return m;
    }
 
 Note that ``PySpam_API`` is declared ``static``; otherwise the pointer
-array would disappear when :func:`initspam` terminates!
+array would disappear when :func:`PyInit_spam` terminates!
 
 The bulk of the work is in the header file :file:`spammodule.h`, which looks
 like this::

Modified: python/branches/py3k/Include/import.h
==============================================================================
--- python/branches/py3k/Include/import.h	(original)
+++ python/branches/py3k/Include/import.h	Wed Jun 11 07:26:20 2008
@@ -33,17 +33,17 @@
 PyAPI_FUNC(void) _PyImport_ReInitLock(void);
 
 PyAPI_FUNC(PyObject *)_PyImport_FindExtension(char *, char *);
-PyAPI_FUNC(PyObject *)_PyImport_FixupExtension(char *, char *);
+PyAPI_FUNC(int)_PyImport_FixupExtension(PyObject*, char *, char *);
 
 struct _inittab {
     char *name;
-    void (*initfunc)(void);
+    PyObject* (*initfunc)(void);
 };
 
 PyAPI_DATA(PyTypeObject) PyNullImporter_Type;
 PyAPI_DATA(struct _inittab *) PyImport_Inittab;
 
-PyAPI_FUNC(int) PyImport_AppendInittab(char *name, void (*initfunc)(void));
+PyAPI_FUNC(int) PyImport_AppendInittab(char *name, PyObject* (*initfunc)(void));
 PyAPI_FUNC(int) PyImport_ExtendInittab(struct _inittab *newtab);
 
 struct _frozen {

Modified: python/branches/py3k/Include/modsupport.h
==============================================================================
--- python/branches/py3k/Include/modsupport.h	(original)
+++ python/branches/py3k/Include/modsupport.h	Wed Jun 11 07:26:20 2008
@@ -89,42 +89,18 @@
    9-Jan-1995	GvR	Initial version (incompatible with older API)
 */
 
-#ifdef MS_WINDOWS
-/* Special defines for Windows versions used to live here.  Things
-   have changed, and the "Version" is now in a global string variable.
-   Reason for this is that this for easier branding of a "custom DLL"
-   without actually needing a recompile.  */
-#endif /* MS_WINDOWS */
-
-#if SIZEOF_SIZE_T != SIZEOF_INT
-/* On a 64-bit system, rename the Py_InitModule4 so that 2.4
-   modules cannot get loaded into a 2.5 interpreter */
-#define Py_InitModule4 Py_InitModule4_64
-#endif
-
 #ifdef Py_TRACE_REFS
- /* When we are tracing reference counts, rename Py_InitModule4 so
+ /* When we are tracing reference counts, rename PyModule_New2 so
     modules compiled with incompatible settings will generate a
     link-time error. */
- #if SIZEOF_SIZE_T != SIZEOF_INT
- #undef Py_InitModule4
- #define Py_InitModule4 Py_InitModule4TraceRefs_64
- #else
- #define Py_InitModule4 Py_InitModule4TraceRefs
- #endif
+ #define PyModule_New2 PyModule_Create2TraceRefs
 #endif
 
-PyAPI_FUNC(PyObject *) Py_InitModule4(const char *name, PyMethodDef *methods,
-                                      const char *doc, PyObject *self,
-                                      int apiver);
-
-#define Py_InitModule(name, methods) \
-	Py_InitModule4(name, methods, (char *)NULL, (PyObject *)NULL, \
-		       PYTHON_API_VERSION)
+PyAPI_FUNC(PyObject *) PyModule_Create2(struct PyModuleDef*,
+                                     int apiver);
 
-#define Py_InitModule3(name, methods, doc) \
-	Py_InitModule4(name, methods, doc, (PyObject *)NULL, \
-		       PYTHON_API_VERSION)
+#define PyModule_Create(module) \
+	PyModule_Create2(module, PYTHON_API_VERSION)
 
 PyAPI_DATA(char *) _Py_PackageContext;
 

Modified: python/branches/py3k/Include/moduleobject.h
==============================================================================
--- python/branches/py3k/Include/moduleobject.h	(original)
+++ python/branches/py3k/Include/moduleobject.h	Wed Jun 11 07:26:20 2008
@@ -17,6 +17,30 @@
 PyAPI_FUNC(const char *) PyModule_GetName(PyObject *);
 PyAPI_FUNC(const char *) PyModule_GetFilename(PyObject *);
 PyAPI_FUNC(void) _PyModule_Clear(PyObject *);
+PyAPI_FUNC(struct PyModuleDef*) PyModule_GetDef(PyObject*);
+PyAPI_FUNC(void*) PyModule_GetState(PyObject*);
+
+typedef struct PyModuleDef_Base {
+  PyObject_HEAD
+  PyObject* (*m_init)(void);
+  Py_ssize_t m_index;
+  PyObject* m_copy;
+} PyModuleDef_Base;
+
+#define PyModuleDef_HEAD_INIT {PyObject_HEAD_INIT(NULL)}
+
+typedef struct PyModuleDef{
+  PyModuleDef_Base m_base;
+  const char* m_name;
+  const char* m_doc;
+  Py_ssize_t m_size;
+  PyMethodDef *m_methods;
+  inquiry m_reload;
+  traverseproc m_traverse;
+  inquiry m_clear;
+  freefunc m_free;
+}PyModuleDef;
+
 
 #ifdef __cplusplus
 }

Modified: python/branches/py3k/Include/pyport.h
==============================================================================
--- python/branches/py3k/Include/pyport.h	(original)
+++ python/branches/py3k/Include/pyport.h	Wed Jun 11 07:26:20 2008
@@ -511,9 +511,9 @@
 			/* module init functions inside the core need no external linkage */
 			/* except for Cygwin to handle embedding */
 #			if defined(__CYGWIN__)
-#				define PyMODINIT_FUNC __declspec(dllexport) void
+#				define PyMODINIT_FUNC __declspec(dllexport) PyObject*
 #			else /* __CYGWIN__ */
-#				define PyMODINIT_FUNC void
+#				define PyMODINIT_FUNC PyObject*
 #			endif /* __CYGWIN__ */
 #		else /* Py_BUILD_CORE */
 			/* Building an extension module, or an embedded situation */
@@ -526,9 +526,9 @@
 #			define PyAPI_DATA(RTYPE) extern __declspec(dllimport) RTYPE
 			/* module init functions outside the core must be exported */
 #			if defined(__cplusplus)
-#				define PyMODINIT_FUNC extern "C" __declspec(dllexport) void
+#				define PyMODINIT_FUNC extern "C" __declspec(dllexport) PyObject*
 #			else /* __cplusplus */
-#				define PyMODINIT_FUNC __declspec(dllexport) void
+#				define PyMODINIT_FUNC __declspec(dllexport) PyObject*
 #			endif /* __cplusplus */
 #		endif /* Py_BUILD_CORE */
 #	endif /* HAVE_DECLSPEC */
@@ -543,9 +543,9 @@
 #endif
 #ifndef PyMODINIT_FUNC
 #	if defined(__cplusplus)
-#		define PyMODINIT_FUNC extern "C" void
+#		define PyMODINIT_FUNC extern "C" PyObject*
 #	else /* __cplusplus */
-#		define PyMODINIT_FUNC void
+#		define PyMODINIT_FUNC PyObject*
 #	endif /* __cplusplus */
 #endif
 

Modified: python/branches/py3k/Include/pystate.h
==============================================================================
--- python/branches/py3k/Include/pystate.h	(original)
+++ python/branches/py3k/Include/pystate.h	Wed Jun 11 07:26:20 2008
@@ -19,6 +19,7 @@
     struct _ts *tstate_head;
 
     PyObject *modules;
+    PyObject *modules_by_index;
     PyObject *sysdict;
     PyObject *builtins;
     PyObject *modules_reloading;
@@ -107,6 +108,8 @@
 PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_New(void);
 PyAPI_FUNC(void) PyInterpreterState_Clear(PyInterpreterState *);
 PyAPI_FUNC(void) PyInterpreterState_Delete(PyInterpreterState *);
+PyAPI_FUNC(int) _PyState_AddModule(PyObject*, struct PyModuleDef*);
+PyAPI_FUNC(PyObject*) PyState_FindModule(struct PyModuleDef*);
 
 PyAPI_FUNC(PyThreadState *) PyThreadState_New(PyInterpreterState *);
 PyAPI_FUNC(void) PyThreadState_Clear(PyThreadState *);

Modified: python/branches/py3k/Include/warnings.h
==============================================================================
--- python/branches/py3k/Include/warnings.h	(original)
+++ python/branches/py3k/Include/warnings.h	Wed Jun 11 07:26:20 2008
@@ -4,7 +4,7 @@
 extern "C" {
 #endif
 
-PyAPI_FUNC(void) _PyWarnings_Init(void);
+PyAPI_FUNC(PyObject*) _PyWarnings_Init(void);
 
 PyAPI_FUNC(int) PyErr_WarnEx(PyObject *, const char *, Py_ssize_t);
 PyAPI_FUNC(int) PyErr_WarnExplicit(PyObject *, const char *, const char *, int,

Modified: python/branches/py3k/Lib/test/test_sys.py
==============================================================================
--- python/branches/py3k/Lib/test/test_sys.py	(original)
+++ python/branches/py3k/Lib/test/test_sys.py	Wed Jun 11 07:26:20 2008
@@ -458,7 +458,7 @@
         # builtin_function_or_method
         self.check_sizeof(abs, h + 3*p)
         # module
-        self.check_sizeof(unittest, h + p)
+        self.check_sizeof(unittest, h + 3*p)
         # range
         self.check_sizeof(range(1), h + 3*p)
         # slice

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Wed Jun 11 07:26:20 2008
@@ -12,6 +12,8 @@
 Core and Builtins
 -----------------
 
+- Implement PEP 3121: new module initialization and finalization API.
+
 - Removed the already-defunct ``-t`` option.
 
 - Issue #2957: Corrected a ValueError "recursion limit exceeded", when

Modified: python/branches/py3k/Modules/_bisectmodule.c
==============================================================================
--- python/branches/py3k/Modules/_bisectmodule.c	(original)
+++ python/branches/py3k/Modules/_bisectmodule.c	Wed Jun 11 07:26:20 2008
@@ -226,10 +226,21 @@
 expensive comparison operations, this can be an improvement over the more\n\
 common approach.\n");
 
+
+static struct PyModuleDef _bisectmodule = {
+	PyModuleDef_HEAD_INIT,
+	"_bisect",
+	module_doc,
+	-1,
+	bisect_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_bisect(void)
+PyInit__bisect(void)
 {
-	PyObject *m;
-
-	m = Py_InitModule3("_bisect", bisect_methods, module_doc);
+	return PyModule_Create(&_bisectmodule);
 }

Modified: python/branches/py3k/Modules/_bsddb.c
==============================================================================
--- python/branches/py3k/Modules/_bsddb.c	(original)
+++ python/branches/py3k/Modules/_bsddb.c	Wed Jun 11 07:26:20 2008
@@ -5646,7 +5646,20 @@
 #define MODULE_NAME_MAX_LEN     11
 static char _bsddbModuleName[MODULE_NAME_MAX_LEN+1] = "_bsddb";
 
-PyMODINIT_FUNC init_bsddb(void)
+
+static struct PyModuleDef _bsddbmodule = {
+	PyModuleDef_HEAD_INIT,
+	_bsddbModuleName,
+	NULL,
+	-1,
+	bsddb_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
+PyMODINIT_FUNC PyInit__bsddb(void)
 {
     PyObject* m;
     PyObject* d;
@@ -5673,9 +5686,9 @@
 #endif
 
     /* Create the module and add the functions */
-    m = Py_InitModule(_bsddbModuleName, bsddb_methods);
+    m = PyModule_Create(&_bsddbmodule);
     if (m == NULL)
-    	return;
+    	return NULL;
 
     /* Add some symbolic constants to the module */
     d = PyModule_GetDict(m);
@@ -6064,7 +6077,10 @@
     if (PyErr_Occurred()) {
         PyErr_Print();
         Py_FatalError("can't initialize module _bsddb");
+	Py_DECREF(m);
+	m = NULL;
     }
+    return m;
 }
 
 /* allow this module to be named _pybsddb so that it can be installed
@@ -6073,5 +6089,5 @@
 PyMODINIT_FUNC init_pybsddb(void)
 {
     strncpy(_bsddbModuleName, "_pybsddb", MODULE_NAME_MAX_LEN);
-    init_bsddb();
+    return PyInit__bsddb();
 }

Modified: python/branches/py3k/Modules/_bytesio.c
==============================================================================
--- python/branches/py3k/Modules/_bytesio.c	(original)
+++ python/branches/py3k/Modules/_bytesio.c	Wed Jun 11 07:26:20 2008
@@ -722,16 +722,30 @@
     bytesio_new,                               /*tp_new*/
 };
 
+
+static struct PyModuleDef _bytesiomodule = {
+	PyModuleDef_HEAD_INIT,
+	"_bytesio",
+	NULL,
+	-1,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_bytesio(void)
+PyInit__bytesio(void)
 {
     PyObject *m;
 
     if (PyType_Ready(&BytesIO_Type) < 0)
-        return;
-    m = Py_InitModule("_bytesio", NULL);
+        return NULL;
+    m = PyModule_Create(&_bytesiomodule);
     if (m == NULL)
-        return;
+        return NULL;
     Py_INCREF(&BytesIO_Type);
     PyModule_AddObject(m, "_BytesIO", (PyObject *)&BytesIO_Type);
+    return m;
 }

Modified: python/branches/py3k/Modules/_codecsmodule.c
==============================================================================
--- python/branches/py3k/Modules/_codecsmodule.c	(original)
+++ python/branches/py3k/Modules/_codecsmodule.c	Wed Jun 11 07:26:20 2008
@@ -1152,8 +1152,20 @@
     {NULL, NULL}		/* sentinel */
 };
 
+static struct PyModuleDef codecsmodule = {
+	PyModuleDef_HEAD_INIT,
+	"_codecs",
+	NULL,
+	-1,
+	_codecs_functions,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_codecs(void)
+PyInit__codecs(void)
 {
-    Py_InitModule("_codecs", _codecs_functions);
+	return PyModule_Create(&codecsmodule);
 }

Modified: python/branches/py3k/Modules/_collectionsmodule.c
==============================================================================
--- python/branches/py3k/Modules/_collectionsmodule.c	(original)
+++ python/branches/py3k/Modules/_collectionsmodule.c	Wed Jun 11 07:26:20 2008
@@ -1348,31 +1348,44 @@
 - defaultdict:  dict subclass with a default value factory\n\
 ");
 
+
+static struct PyModuleDef _collectionsmodule = {
+	PyModuleDef_HEAD_INIT,
+	"_collections",
+	module_doc,
+	-1,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_collections(void)
+PyInit__collections(void)
 {
 	PyObject *m;
 
-	m = Py_InitModule3("_collections", NULL, module_doc);
+	m = PyModule_Create(&_collectionsmodule);
 	if (m == NULL)
-		return;
+		return NULL;
 
 	if (PyType_Ready(&deque_type) < 0)
-		return;
+		return NULL;
 	Py_INCREF(&deque_type);
 	PyModule_AddObject(m, "deque", (PyObject *)&deque_type);
 
 	defdict_type.tp_base = &PyDict_Type;
 	if (PyType_Ready(&defdict_type) < 0)
-		return;
+		return NULL;
 	Py_INCREF(&defdict_type);
 	PyModule_AddObject(m, "defaultdict", (PyObject *)&defdict_type);
 
 	if (PyType_Ready(&dequeiter_type) < 0)
-		return;
+		return NULL;
 
 	if (PyType_Ready(&dequereviter_type) < 0)
-		return;
+		return NULL;
 
-	return;
+	return m;
 }

Modified: python/branches/py3k/Modules/_csv.c
==============================================================================
--- python/branches/py3k/Modules/_csv.c	(original)
+++ python/branches/py3k/Modules/_csv.c	Wed Jun 11 07:26:20 2008
@@ -1542,53 +1542,67 @@
 	{ NULL, NULL }
 };
 
+
+static struct PyModuleDef _csvmodule = {
+	PyModuleDef_HEAD_INIT,
+	"_csv",
+	csv_module_doc,
+	-1,
+	csv_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_csv(void)
+PyInit__csv(void)
 {
 	PyObject *module;
 	StyleDesc *style;
 
 	if (PyType_Ready(&Dialect_Type) < 0)
-		return;
+		return NULL;
 
 	if (PyType_Ready(&Reader_Type) < 0)
-		return;
+		return NULL;
 
 	if (PyType_Ready(&Writer_Type) < 0)
-		return;
+		return NULL;
 
 	/* Create the module and add the functions */
-	module = Py_InitModule3("_csv", csv_methods, csv_module_doc);
+	module = PyModule_Create(&_csvmodule);
 	if (module == NULL)
-		return;
+		return NULL;
 
 	/* Add version to the module. */
 	if (PyModule_AddStringConstant(module, "__version__",
 				       MODULE_VERSION) == -1)
-		return;
+		return NULL;
 
         /* Add _dialects dictionary */
         dialects = PyDict_New();
         if (dialects == NULL)
-                return;
+                return NULL;
         if (PyModule_AddObject(module, "_dialects", dialects))
-                return;
+                return NULL;
 
 	/* Add quote styles into dictionary */
 	for (style = quote_styles; style->name; style++) {
 		if (PyModule_AddIntConstant(module, style->name,
 					    style->style) == -1)
-			return;
+			return NULL;
 	}
 
         /* Add the Dialect type */
 	Py_INCREF(&Dialect_Type);
         if (PyModule_AddObject(module, "Dialect", (PyObject *)&Dialect_Type))
-                return;
+                return NULL;
 
 	/* Add the CSV exception object to the module. */
 	error_obj = PyErr_NewException("_csv.Error", NULL, NULL);
 	if (error_obj == NULL)
-		return;
+		return NULL;
 	PyModule_AddObject(module, "Error", error_obj);
+	return module;
 }

Modified: python/branches/py3k/Modules/_ctypes/_ctypes.c
==============================================================================
--- python/branches/py3k/Modules/_ctypes/_ctypes.c	(original)
+++ python/branches/py3k/Modules/_ctypes/_ctypes.c	Wed Jun 11 07:26:20 2008
@@ -4995,7 +4995,7 @@
  *  Module initialization.
  */
 
-static char *module_docs =
+static const char module_docs[] =
 "Create and manipulate C compatible data types in Python.";
 
 #ifdef MS_WIN32
@@ -5191,8 +5191,21 @@
 }
 #endif
 
+
+static struct PyModuleDef _ctypesmodule = {
+	PyModuleDef_HEAD_INIT,
+	"_ctypes",
+	module_docs,
+	-1,
+	module_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_ctypes(void)
+PyInit__ctypes(void)
 {
 	PyObject *m;
 
@@ -5203,30 +5216,30 @@
 #ifdef WITH_THREAD
 	PyEval_InitThreads();
 #endif
-	m = Py_InitModule3("_ctypes", module_methods, module_docs);
+	m = PyModule_Create(&_ctypesmodule);
 	if (!m)
-		return;
+		return NULL;
 
 	_pointer_type_cache = PyDict_New();
 	if (_pointer_type_cache == NULL)
-		return;
+		return NULL;
 
 	PyModule_AddObject(m, "_pointer_type_cache", (PyObject *)_pointer_type_cache);
 
 	_unpickle = PyObject_GetAttrString(m, "_unpickle");
 	if (_unpickle == NULL)
-		return;
+		return NULL;
 
 	if (PyType_Ready(&PyCArg_Type) < 0)
-		return;
+		return NULL;
 
 	if (PyType_Ready(&CThunk_Type) < 0)
-		return;
+		return NULL;
 
 	/* StgDict is derived from PyDict_Type */
 	StgDict_Type.tp_base = &PyDict_Type;
 	if (PyType_Ready(&StgDict_Type) < 0)
-		return;
+		return NULL;
 
 	/*************************************************
 	 *
@@ -5235,27 +5248,27 @@
 
 	StructType_Type.tp_base = &PyType_Type;
 	if (PyType_Ready(&StructType_Type) < 0)
-		return;
+		return NULL;
 
 	UnionType_Type.tp_base = &PyType_Type;
 	if (PyType_Ready(&UnionType_Type) < 0)
-		return;
+		return NULL;
 
 	PointerType_Type.tp_base = &PyType_Type;
 	if (PyType_Ready(&PointerType_Type) < 0)
-		return;
+		return NULL;
 
 	ArrayType_Type.tp_base = &PyType_Type;
 	if (PyType_Ready(&ArrayType_Type) < 0)
-		return;
+		return NULL;
 
 	SimpleType_Type.tp_base = &PyType_Type;
 	if (PyType_Ready(&SimpleType_Type) < 0)
-		return;
+		return NULL;
 
 	CFuncPtrType_Type.tp_base = &PyType_Type;
 	if (PyType_Ready(&CFuncPtrType_Type) < 0)
-		return;
+		return NULL;
 
 	/*************************************************
 	 *
@@ -5263,42 +5276,42 @@
 	 */
 
 	if (PyType_Ready(&CData_Type) < 0)
-		return;
+		return NULL;
 
 	Py_TYPE(&Struct_Type) = &StructType_Type;
 	Struct_Type.tp_base = &CData_Type;
 	if (PyType_Ready(&Struct_Type) < 0)
-		return;
+		return NULL;
 	PyModule_AddObject(m, "Structure", (PyObject *)&Struct_Type);
 
 	Py_TYPE(&Union_Type) = &UnionType_Type;
 	Union_Type.tp_base = &CData_Type;
 	if (PyType_Ready(&Union_Type) < 0)
-		return;
+		return NULL;
 	PyModule_AddObject(m, "Union", (PyObject *)&Union_Type);
 
 	Py_TYPE(&Pointer_Type) = &PointerType_Type;
 	Pointer_Type.tp_base = &CData_Type;
 	if (PyType_Ready(&Pointer_Type) < 0)
-		return;
+		return NULL;
 	PyModule_AddObject(m, "_Pointer", (PyObject *)&Pointer_Type);
 
 	Py_TYPE(&Array_Type) = &ArrayType_Type;
 	Array_Type.tp_base = &CData_Type;
 	if (PyType_Ready(&Array_Type) < 0)
-		return;
+		return NULL;
 	PyModule_AddObject(m, "Array", (PyObject *)&Array_Type);
 
 	Py_TYPE(&Simple_Type) = &SimpleType_Type;
 	Simple_Type.tp_base = &CData_Type;
 	if (PyType_Ready(&Simple_Type) < 0)
-		return;
+		return NULL;
 	PyModule_AddObject(m, "_SimpleCData", (PyObject *)&Simple_Type);
 
 	Py_TYPE(&CFuncPtr_Type) = &CFuncPtrType_Type;
 	CFuncPtr_Type.tp_base = &CData_Type;
 	if (PyType_Ready(&CFuncPtr_Type) < 0)
-		return;
+		return NULL;
 	PyModule_AddObject(m, "CFuncPtr", (PyObject *)&CFuncPtr_Type);
 
 	/*************************************************
@@ -5308,7 +5321,7 @@
 
 	/* CField_Type is derived from PyBaseObject_Type */
 	if (PyType_Ready(&CField_Type) < 0)
-		return;
+		return NULL;
 
 	/*************************************************
 	 *
@@ -5317,11 +5330,11 @@
 
 	DictRemover_Type.tp_new = PyType_GenericNew;
 	if (PyType_Ready(&DictRemover_Type) < 0)
-		return;
+		return NULL;
 
 #ifdef MS_WIN32
 	if (create_comerror() < 0)
-		return;
+		return NULL;
 	PyModule_AddObject(m, "COMError", ComError);
 
 	PyModule_AddObject(m, "FUNCFLAG_HRESULT", PyLong_FromLong(FUNCFLAG_HRESULT));
@@ -5366,6 +5379,7 @@
 	 * Others...
 	 */
 	init_callbacks_in_module(m);
+	return m;
 }
 
 /*

Modified: python/branches/py3k/Modules/_ctypes/_ctypes_test.c
==============================================================================
--- python/branches/py3k/Modules/_ctypes/_ctypes_test.c	(original)
+++ python/branches/py3k/Modules/_ctypes/_ctypes_test.c	Wed Jun 11 07:26:20 2008
@@ -582,8 +582,21 @@
 
 #endif
 
+
+static struct PyModuleDef _ctypes_testmodule = {
+	PyModuleDef_HEAD_INIT,
+	"_ctypes_test",
+	NULL,
+	-1,
+	module_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_ctypes_test(void)
+PyInit__ctypes_test(void)
 {
-	Py_InitModule("_ctypes_test", module_methods);
+	return PyModule_Create(&_ctypes_testmodule);
 }

Modified: python/branches/py3k/Modules/_curses_panel.c
==============================================================================
--- python/branches/py3k/Modules/_curses_panel.c	(original)
+++ python/branches/py3k/Modules/_curses_panel.c	Wed Jun 11 07:26:20 2008
@@ -451,8 +451,21 @@
 
 /* Initialization function for the module */
 
+
+static struct PyModuleDef _curses_panelmodule = {
+	PyModuleDef_HEAD_INIT,
+	"_curses_panel",
+	NULL,
+	-1,
+	PyCurses_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_curses_panel(void)
+PyInit__curses_panel(void)
 {
     PyObject *m, *d, *v;
 
@@ -462,9 +475,9 @@
     import_curses();
 
     /* Create the module and add the functions */
-    m = Py_InitModule("_curses_panel", PyCurses_methods);
+    m = PyModule_Create(&_curses_panelmodule);
     if (m == NULL)
-    	return;
+    	return NULL;
     d = PyModule_GetDict(m);
 
     /* For exception _curses_panel.error */
@@ -476,4 +489,5 @@
     PyDict_SetItemString(d, "version", v);
     PyDict_SetItemString(d, "__version__", v);
     Py_DECREF(v);
+    return m;
 }

Modified: python/branches/py3k/Modules/_cursesmodule.c
==============================================================================
--- python/branches/py3k/Modules/_cursesmodule.c	(original)
+++ python/branches/py3k/Modules/_cursesmodule.c	Wed Jun 11 07:26:20 2008
@@ -2770,8 +2770,21 @@
 
 /* Initialization function for the module */
 
+
+static struct PyModuleDef _cursesmodule = {
+	PyModuleDef_HEAD_INIT,
+	"_curses",
+	NULL,
+	-1,
+	PyCurses_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_curses(void)
+PyInit__curses(void)
 {
 	PyObject *m, *d, *v, *c_api_object;
 	static void *PyCurses_API[PyCurses_API_pointers];
@@ -2786,14 +2799,14 @@
 	PyCurses_API[3] = (void *)func_PyCursesInitialisedColor;
 
 	/* Create the module and add the functions */
-	m = Py_InitModule("_curses", PyCurses_methods);
+	m = PyModule_Create(&_cursesmodule);
 	if (m == NULL)
-    		return;
+    		return NULL;
 
 	/* Add some symbolic constants to the module */
 	d = PyModule_GetDict(m);
 	if (d == NULL)
-		return;
+		return NULL;
 	ModDict = d; /* For PyCurses_InitScr to use later */
 
 	/* Add a CObject for the C API */
@@ -2931,4 +2944,5 @@
 	  SetDictInt("KEY_MIN", KEY_MIN);
 	  SetDictInt("KEY_MAX", KEY_MAX);
 	}
+	return m;
 }

Modified: python/branches/py3k/Modules/_dbmmodule.c
==============================================================================
--- python/branches/py3k/Modules/_dbmmodule.c	(original)
+++ python/branches/py3k/Modules/_dbmmodule.c	Wed Jun 11 07:26:20 2008
@@ -390,15 +390,28 @@
 	{ 0, 0 },
 };
 
+
+static struct PyModuleDef _dbmmodule = {
+	PyModuleDef_HEAD_INIT,
+	"_dbm",
+	NULL,
+	-1,
+	dbmmodule_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_dbm(void) {
+PyInit__dbm(void) {
 	PyObject *m, *d, *s;
 
 	if (PyType_Ready(&Dbmtype) < 0)
-		return;
-	m = Py_InitModule("_dbm", dbmmodule_methods);
+		return NULL;
+	m = PyModule_Create(&_dbmmodule);
 	if (m == NULL)
-		return;
+		return NULL;
 	d = PyModule_GetDict(m);
 	if (DbmError == NULL)
 		DbmError = PyErr_NewException("_dbm.error",
@@ -410,4 +423,9 @@
 	}
 	if (DbmError != NULL)
 		PyDict_SetItemString(d, "error", DbmError);
+	if (PyErr_Occurred()) {
+		Py_DECREF(m);
+		m = NULL;
+	}
+	return m;
 }

Modified: python/branches/py3k/Modules/_elementtree.c
==============================================================================
--- python/branches/py3k/Modules/_elementtree.c	(original)
+++ python/branches/py3k/Modules/_elementtree.c	Wed Jun 11 07:26:20 2008
@@ -2549,8 +2549,21 @@
     {NULL, NULL}
 };
 
+
+static struct PyModuleDef _elementtreemodule = {
+	PyModuleDef_HEAD_INIT,
+	"_elementtree",
+	NULL,
+	-1,
+	_functions,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_elementtree(void)
+PyInit__elementtree(void)
 {
     PyObject* m;
     PyObject* g;
@@ -2565,15 +2578,21 @@
     Py_TYPE(&XMLParser_Type) = &PyType_Type;
 #endif
 
-    m = Py_InitModule("_elementtree", _functions);
+    m = PyModule_Create(&_elementtreemodule);
     if (!m)
-        return;
+        return NULL;
+
+    /* The code below requires that the module gets already added
+       to sys.modules. */
+    PyDict_SetItemString(PyImport_GetModuleDict(),
+			 _elementtreemodule.m_name,
+			 m);
 
     /* python glue code */
 
     g = PyDict_New();
     if (!g)
-        return;
+        return NULL;
 
     PyDict_SetItemString(g, "__builtins__", PyEval_GetBuiltins());
 
@@ -2748,5 +2767,6 @@
     else
         expat_capi = NULL;
 #endif
+    return m;
 
 }

Modified: python/branches/py3k/Modules/_fileio.c
==============================================================================
--- python/branches/py3k/Modules/_fileio.c	(original)
+++ python/branches/py3k/Modules/_fileio.c	Wed Jun 11 07:26:20 2008
@@ -871,17 +871,29 @@
 	{NULL, NULL}
 };
 
+static struct PyModuleDef fileiomodule = {
+	PyModuleDef_HEAD_INIT,
+	"_fileio",
+	"Fast implementation of io.FileIO.",
+	-1,
+	module_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_fileio(void)
+PyInit__fileio(void)
 {
 	PyObject *m;	/* a module object */
 
-	m = Py_InitModule3("_fileio", module_methods,
-			   "Fast implementation of io.FileIO.");
+	m = PyModule_Create(&fileiomodule);
 	if (m == NULL)
-		return;
+		return NULL;
 	if (PyType_Ready(&PyFileIO_Type) < 0)
-		return;
+		return NULL;
 	Py_INCREF(&PyFileIO_Type);
 	PyModule_AddObject(m, "_FileIO", (PyObject *) &PyFileIO_Type);
+	return m;
 }

Modified: python/branches/py3k/Modules/_functoolsmodule.c
==============================================================================
--- python/branches/py3k/Modules/_functoolsmodule.c	(original)
+++ python/branches/py3k/Modules/_functoolsmodule.c	Wed Jun 11 07:26:20 2008
@@ -326,8 +326,21 @@
  	{NULL,		NULL}		/* sentinel */
 };
 
+
+static struct PyModuleDef _functoolsmodule = {
+	PyModuleDef_HEAD_INIT,
+	"_functools",
+	module_doc,
+	-1,
+	module_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_functools(void)
+PyInit__functools(void)
 {
 	int i;
 	PyObject *m;
@@ -337,16 +350,19 @@
 		NULL
 	};
 
-	m = Py_InitModule3("_functools", module_methods, module_doc);
+	m = PyModule_Create(&_functoolsmodule);
 	if (m == NULL)
-		return;
+		return NULL;
 
 	for (i=0 ; typelist[i] != NULL ; i++) {
-		if (PyType_Ready(typelist[i]) < 0)
-			return;
+		if (PyType_Ready(typelist[i]) < 0) {
+			Py_DECREF(m);
+			return NULL;
+		}
 		name = strchr(typelist[i]->tp_name, '.');
 		assert (name != NULL);
 		Py_INCREF(typelist[i]);
 		PyModule_AddObject(m, name+1, (PyObject *)typelist[i]);
 	}
+	return m;
 }

Modified: python/branches/py3k/Modules/_gdbmmodule.c
==============================================================================
--- python/branches/py3k/Modules/_gdbmmodule.c	(original)
+++ python/branches/py3k/Modules/_gdbmmodule.c	Wed Jun 11 07:26:20 2008
@@ -511,17 +511,28 @@
     { 0, 0 },
 };
 
+
+static struct PyModuleDef _gdbmmodule = {
+	PyModuleDef_HEAD_INIT,
+	"_gdbm",
+	gdbmmodule__doc__,
+	-1,
+	dbmmodule_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_gdbm(void) {
+PyInit__gdbm(void) {
     PyObject *m, *d, *s;
 
     if (PyType_Ready(&Dbmtype) < 0)
-	    return;
-    m = Py_InitModule4("_gdbm", dbmmodule_methods,
-                       gdbmmodule__doc__, (PyObject *)NULL,
-                       PYTHON_API_VERSION);
+	    return NULL;
+    m = PyModule_Create(&_gdbmmodule);
     if (m == NULL)
-	return;
+	return NULL;
     d = PyModule_GetDict(m);
     DbmError = PyErr_NewException("_gdbm.error", PyExc_IOError, NULL);
     if (DbmError != NULL) {
@@ -530,4 +541,5 @@
         PyDict_SetItemString(d, "open_flags", s);
         Py_DECREF(s);
     }
+    return m;
 }

Modified: python/branches/py3k/Modules/_gestalt.c
==============================================================================
--- python/branches/py3k/Modules/_gestalt.c	(original)
+++ python/branches/py3k/Modules/_gestalt.c	Wed Jun 11 07:26:20 2008
@@ -65,8 +65,20 @@
     {NULL, NULL} /* Sentinel */
 };
 
+static struct PyModuleDef gestaltmodule = {
+	PyModuleDef_HEAD_INIT,
+	"_gestalt",
+	NULL,
+	-1,
+	gestalt_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 void
-init_gestalt(void)
+PyInit__gestalt(void)
 {
-    Py_InitModule("_gestalt", gestalt_methods);
+	return PyModule_Create(&gestaltmodule);
 }

Modified: python/branches/py3k/Modules/_hashopenssl.c
==============================================================================
--- python/branches/py3k/Modules/_hashopenssl.c	(original)
+++ python/branches/py3k/Modules/_hashopenssl.c	Wed Jun 11 07:26:20 2008
@@ -498,8 +498,21 @@
 
 /* Initialize this module. */
 
+
+static struct PyModuleDef _hashlibmodule = {
+	PyModuleDef_HEAD_INIT,
+	"_hashlib",
+	NULL,
+	-1,
+	EVP_functions,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_hashlib(void)
+PyInit__hashlib(void)
 {
     PyObject *m;
 
@@ -512,11 +525,11 @@
 
     Py_TYPE(&EVPtype) = &PyType_Type;
     if (PyType_Ready(&EVPtype) < 0)
-        return;
+        return NULL;
 
-    m = Py_InitModule("_hashlib", EVP_functions);
+    m = PyModule_Create(&_hashlibmodule);
     if (m == NULL)
-        return;
+        return NULL;
 
 #if HASH_OBJ_CONSTRUCTOR
     Py_INCREF(&EVPtype);
@@ -530,4 +543,5 @@
     INIT_CONSTRUCTOR_CONSTANTS(sha256);
     INIT_CONSTRUCTOR_CONSTANTS(sha384);
     INIT_CONSTRUCTOR_CONSTANTS(sha512);
+    return m;
 }

Modified: python/branches/py3k/Modules/_heapqmodule.c
==============================================================================
--- python/branches/py3k/Modules/_heapqmodule.c	(original)
+++ python/branches/py3k/Modules/_heapqmodule.c	Wed Jun 11 07:26:20 2008
@@ -679,15 +679,29 @@
 Believe me, real good tape sorts were quite spectacular to watch!\n\
 From all times, sorting has always been a Great Art! :-)\n");
 
+
+static struct PyModuleDef _heapqmodule = {
+	PyModuleDef_HEAD_INIT,
+	"_heapq",
+	module_doc,
+	-1,
+	heapq_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_heapq(void)
+PyInit__heapq(void)
 {
 	PyObject *m, *about;
 
-	m = Py_InitModule3("_heapq", heapq_methods, module_doc);
+	m = PyModule_Create(&_heapqmodule);
 	if (m == NULL)
-    		return;
+    		return NULL;
 	about = PyUnicode_DecodeUTF8(__about__, strlen(__about__), NULL);
 	PyModule_AddObject(m, "__about__", about);
+	return m;
 }
 

Modified: python/branches/py3k/Modules/_json.c
==============================================================================
--- python/branches/py3k/Modules/_json.c	(original)
+++ python/branches/py3k/Modules/_json.c	Wed Jun 11 07:26:20 2008
@@ -613,9 +613,20 @@
 PyDoc_STRVAR(module_doc,
 "json speedups\n");
 
-void
-init_json(void)
+static struct PyModuleDef jsonmodule = {
+	PyModuleDef_HEAD_INIT,
+	"_json",
+	module_doc,
+	-1,
+	json_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
+PyObject*
+PyInit__json(void)
 {
-    PyObject *m;
-    m = Py_InitModule3("_json", json_methods, module_doc);
+	return PyModule_Create(&jsonmodule);
 }

Modified: python/branches/py3k/Modules/_localemodule.c
==============================================================================
--- python/branches/py3k/Modules/_localemodule.c	(original)
+++ python/branches/py3k/Modules/_localemodule.c	Wed Jun 11 07:26:20 2008
@@ -657,17 +657,30 @@
   {NULL, NULL}
 };
 
+
+static struct PyModuleDef _localemodule = {
+	PyModuleDef_HEAD_INIT,
+	"_locale",
+	locale__doc__,
+	-1,
+	PyLocale_Methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_locale(void)
+PyInit__locale(void)
 {
     PyObject *m, *d, *x;
 #ifdef HAVE_LANGINFO_H
     int i;
 #endif
 
-    m = Py_InitModule3("_locale", PyLocale_Methods, locale__doc__);
+    m = PyModule_Create(&_localemodule);
     if (m == NULL)
-    	return;
+    	return NULL;
 
     d = PyModule_GetDict(m);
 
@@ -714,6 +727,7 @@
 				    langinfo_constants[i].value);
     }
 #endif
+    return m;
 }
 
 /* 

Modified: python/branches/py3k/Modules/_lsprof.c
==============================================================================
--- python/branches/py3k/Modules/_lsprof.c	(original)
+++ python/branches/py3k/Modules/_lsprof.c	Wed Jun 11 07:26:20 2008
@@ -857,16 +857,29 @@
 	{NULL, NULL}
 };
 
+
+static struct PyModuleDef _lsprofmodule = {
+	PyModuleDef_HEAD_INIT,
+	"_lsprof",
+	"Fast profiler",
+	-1,
+	moduleMethods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_lsprof(void)
+PyInit__lsprof(void)
 {
 	PyObject *module, *d;
-	module = Py_InitModule3("_lsprof", moduleMethods, "Fast profiler");
+	module = PyModule_Create(&_lsprofmodule);
 	if (module == NULL)
-		return;
+		return NULL;
 	d = PyModule_GetDict(module);
 	if (PyType_Ready(&PyProfiler_Type) < 0)
-		return;
+		return NULL;
 	PyDict_SetItemString(d, "Profiler", (PyObject *)&PyProfiler_Type);
 
 	if (!initialized) {
@@ -883,4 +896,5 @@
 			   (PyObject*) &StatsSubEntryType);
 	empty_tuple = PyTuple_New(0);
 	initialized = 1;
+	return module;
 }

Modified: python/branches/py3k/Modules/_randommodule.c
==============================================================================
--- python/branches/py3k/Modules/_randommodule.c	(original)
+++ python/branches/py3k/Modules/_randommodule.c	Wed Jun 11 07:26:20 2008
@@ -496,16 +496,30 @@
 PyDoc_STRVAR(module_doc,
 "Module implements the Mersenne Twister random number generator.");
 
+
+static struct PyModuleDef _randommodule = {
+	PyModuleDef_HEAD_INIT,
+	"_random",
+	module_doc,
+	-1,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_random(void)
+PyInit__random(void)
 {
 	PyObject *m;
 
 	if (PyType_Ready(&Random_Type) < 0)
-		return;
-	m = Py_InitModule3("_random", NULL, module_doc);
+		return NULL;
+	m = PyModule_Create(&_randommodule);
 	if (m == NULL)
-		return;
+		return NULL;
 	Py_INCREF(&Random_Type);
 	PyModule_AddObject(m, "Random", (PyObject *)&Random_Type);
+	return m;
 }

Modified: python/branches/py3k/Modules/_sqlite/module.c
==============================================================================
--- python/branches/py3k/Modules/_sqlite/module.c	(original)
+++ python/branches/py3k/Modules/_sqlite/module.c	Wed Jun 11 07:26:20 2008
@@ -257,13 +257,26 @@
     {(char*)NULL, 0}
 };
 
-PyMODINIT_FUNC init_sqlite3(void)
+
+static struct PyModuleDef _sqlite3module = {
+	PyModuleDef_HEAD_INIT,
+	"_sqlite3",
+	NULL,
+	-1,
+	module_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
+PyMODINIT_FUNC PyInit__sqlite3(void)
 {
     PyObject *module, *dict;
     PyObject *tmp_obj;
     int i;
 
-    module = Py_InitModule("_sqlite3", module_methods);
+    module = PyModule_Create(&_sqlite3module);
 
     if (!module ||
         (pysqlite_row_setup_types() < 0) ||
@@ -273,7 +286,8 @@
         (pysqlite_statement_setup_types() < 0) ||
         (pysqlite_prepare_protocol_setup_types() < 0)
        ) {
-        return;
+	Py_DECREF(module);
+        return NULL;
     }
 
     Py_INCREF(&pysqlite_ConnectionType);
@@ -408,5 +422,8 @@
     if (PyErr_Occurred())
     {
         PyErr_SetString(PyExc_ImportError, MODULE_NAME ": init failed");
+	Py_DECREF(module);
+	module = NULL;
     }
+    return module;
 }

Modified: python/branches/py3k/Modules/_sre.c
==============================================================================
--- python/branches/py3k/Modules/_sre.c	(original)
+++ python/branches/py3k/Modules/_sre.c	Wed Jun 11 07:26:20 2008
@@ -3387,7 +3387,19 @@
     {NULL, NULL}
 };
 
-PyMODINIT_FUNC init_sre(void)
+static struct PyModuleDef sremodule = {
+	PyModuleDef_HEAD_INIT,
+	"_" SRE_MODULE,
+	NULL,
+	-1,
+	_functions,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
+PyMODINIT_FUNC PyInit__sre(void)
 {
     PyObject* m;
     PyObject* d;
@@ -3395,15 +3407,15 @@
 
     /* Initialize object types */
     if (PyType_Ready(&Pattern_Type) < 0)
-        return;
+        return NULL;
     if (PyType_Ready(&Match_Type) < 0)
-        return;
+        return NULL;
     if (PyType_Ready(&Scanner_Type) < 0)
-        return;
+        return NULL;
 
-    m = Py_InitModule("_" SRE_MODULE, _functions);
+    m = PyModule_Create(&sremodule);
     if (m == NULL)
-    	return;
+    	return NULL;
     d = PyModule_GetDict(m);
 
     x = PyLong_FromLong(SRE_MAGIC);
@@ -3423,6 +3435,7 @@
         PyDict_SetItemString(d, "copyright", x);
         Py_DECREF(x);
     }
+    return m;
 }
 
 #endif /* !defined(SRE_RECURSIVE) */

Modified: python/branches/py3k/Modules/_ssl.c
==============================================================================
--- python/branches/py3k/Modules/_ssl.c	(original)
+++ python/branches/py3k/Modules/_ssl.c	Wed Jun 11 07:26:20 2008
@@ -1563,28 +1563,41 @@
 "Implementation module for SSL socket operations.  See the socket module\n\
 for documentation.");
 
+
+static struct PyModuleDef _sslmodule = {
+	PyModuleDef_HEAD_INIT,
+	"_ssl",
+	module_doc,
+	-1,
+	PySSL_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_ssl(void)
+PyInit__ssl(void)
 {
 	PyObject *m, *d;
 
 	Py_TYPE(&PySSL_Type) = &PyType_Type;
 
-	m = Py_InitModule3("_ssl", PySSL_methods, module_doc);
+	m = PyModule_Create(&_sslmodule);
 	if (m == NULL)
-		return;
+		return NULL;
 	d = PyModule_GetDict(m);
 
 	/* Load _socket module and its C API */
 	if (PySocketModule_ImportModuleAndAPI())
-		return;
+		return NULL;
 
 	/* Init OpenSSL */
 	SSL_load_error_strings();
 #ifdef WITH_THREAD
 	/* note that this will start threading if not already started */
 	if (!_setup_ssl_threads()) {
-		return;
+		return NULL;
 	}
 #endif
 	SSLeay_add_ssl_algorithms();
@@ -1594,12 +1607,12 @@
 					      PySocketModule.error,
 					      NULL);
 	if (PySSLErrorObject == NULL)
-		return;
+		return NULL;
 	if (PyDict_SetItemString(d, "SSLError", PySSLErrorObject) != 0)
-		return;
+		return NULL;
 	if (PyDict_SetItemString(d, "SSLType",
 				 (PyObject *)&PySSL_Type) != 0)
-		return;
+		return NULL;
 	PyModule_AddIntConstant(m, "SSL_ERROR_ZERO_RETURN",
 				PY_SSL_ERROR_ZERO_RETURN);
 	PyModule_AddIntConstant(m, "SSL_ERROR_WANT_READ",
@@ -1636,4 +1649,5 @@
 				PY_SSL_VERSION_SSL23);
 	PyModule_AddIntConstant(m, "PROTOCOL_TLSv1",
 				PY_SSL_VERSION_TLS1);
+	return m;
 }

Modified: python/branches/py3k/Modules/_struct.c
==============================================================================
--- python/branches/py3k/Modules/_struct.c	(original)
+++ python/branches/py3k/Modules/_struct.c	Wed Jun 11 07:26:20 2008
@@ -2087,28 +2087,41 @@
 \n\
 The variable struct.error is an exception raised on errors.\n");
 
+
+static struct PyModuleDef _structmodule = {
+	PyModuleDef_HEAD_INIT,
+	"_struct",
+	module_doc,
+	-1,
+	module_functions,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_struct(void)
+PyInit__struct(void)
 {
 	PyObject *ver, *m;
 
 	ver = PyBytes_FromString("0.2");
 	if (ver == NULL)
-		return;
+		return NULL;
 
-	m = Py_InitModule3("_struct", module_functions, module_doc);
+	m = PyModule_Create(&_structmodule);
 	if (m == NULL)
-		return;
+		return NULL;
 
 	Py_TYPE(&PyStructType) = &PyType_Type;
 	if (PyType_Ready(&PyStructType) < 0)
-		return;
+		return NULL;
 
 #ifdef PY_STRUCT_OVERFLOW_MASKING
 	if (pyint_zero == NULL) {
 		pyint_zero = PyLong_FromLong(0);
 		if (pyint_zero == NULL)
-			return;
+			return NULL;
 	}
 	if (pylong_ulong_mask == NULL) {
 #if (SIZEOF_LONG == 4)
@@ -2117,7 +2130,7 @@
 		pylong_ulong_mask = PyLong_FromString("FFFFFFFFFFFFFFFF", NULL, 16);
 #endif
 		if (pylong_ulong_mask == NULL)
-			return;
+			return NULL;
 	}
 
 #else
@@ -2168,7 +2181,7 @@
 	if (StructError == NULL) {
 		StructError = PyErr_NewException("struct.error", NULL, NULL);
 		if (StructError == NULL)
-			return;
+			return NULL;
 	}
 
 	Py_INCREF(StructError);
@@ -2186,5 +2199,6 @@
 #ifdef PY_STRUCT_FLOAT_COERCE
 	PyModule_AddIntConstant(m, "_PY_STRUCT_FLOAT_COERCE", 1);
 #endif
+	return m;
 
 }

Modified: python/branches/py3k/Modules/_testcapimodule.c
==============================================================================
--- python/branches/py3k/Modules/_testcapimodule.c	(original)
+++ python/branches/py3k/Modules/_testcapimodule.c	Wed Jun 11 07:26:20 2008
@@ -1135,14 +1135,27 @@
 };
 
 
+
+static struct PyModuleDef _testcapimodule = {
+	PyModuleDef_HEAD_INIT,
+	"_testcapi",
+	NULL,
+	-1,
+	TestMethods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_testcapi(void)
+PyInit__testcapi(void)
 {
 	PyObject *m;
 
-	m = Py_InitModule("_testcapi", TestMethods);
+	m = PyModule_Create(&_testcapimodule);
 	if (m == NULL)
-		return;
+		return NULL;
 
 	Py_TYPE(&test_structmembersType)=&PyType_Type;
 	Py_INCREF(&test_structmembersType);
@@ -1173,4 +1186,5 @@
 	TestError = PyErr_NewException("_testcapi.error", NULL, NULL);
 	Py_INCREF(TestError);
 	PyModule_AddObject(m, "error", TestError);
+	return m;
 }

Modified: python/branches/py3k/Modules/_threadmodule.c
==============================================================================
--- python/branches/py3k/Modules/_threadmodule.c	(original)
+++ python/branches/py3k/Modules/_threadmodule.c	Wed Jun 11 07:26:20 2008
@@ -687,21 +687,34 @@
 unlock it.  A thread attempting to lock a lock that it has already locked\n\
 will block until another thread unlocks it.  Deadlocks may ensue.");
 
+static struct PyModuleDef threadmodule = {
+	PyModuleDef_HEAD_INIT,
+	"_thread",
+	thread_doc,
+	-1,
+	thread_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
+
 PyMODINIT_FUNC
-init_thread(void)
+PyInit__thread(void)
 {
 	PyObject *m, *d;
 	
 	/* Initialize types: */
 	if (PyType_Ready(&localtype) < 0)
-		return;
+		return NULL;
 	if (PyType_Ready(&Locktype) < 0)
-		return;
+		return NULL;
 
 	/* Create the module and add the functions */
-	m = Py_InitModule3("_thread", thread_methods, thread_doc);
+	m = PyModule_Create(&threadmodule);
 	if (m == NULL)
-		return;
+		return NULL;
 
 	/* Add a symbolic constant */
 	d = PyModule_GetDict(m);
@@ -713,8 +726,9 @@
 
 	Py_INCREF(&localtype);
 	if (PyModule_AddObject(m, "_local", (PyObject *)&localtype) < 0)
-		return;
+		return NULL;
 
 	/* Initialize the C thread library */
 	PyThread_init_thread();
+	return m;
 }

Modified: python/branches/py3k/Modules/_tkinter.c
==============================================================================
--- python/branches/py3k/Modules/_tkinter.c	(original)
+++ python/branches/py3k/Modules/_tkinter.c	Wed Jun 11 07:26:20 2008
@@ -3009,8 +3009,20 @@
 }
 
 
+static struct PyModuleDef _tkintermodule = {
+	PyModuleDef_HEAD_INIT,
+	"_tkinter",
+	NULL,
+	-1,
+	moduleMethods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_tkinter(void)
+PyInit__tkinter(void)
 {
 	PyObject *m, *d, *uexe, *cexe;
 
@@ -3020,9 +3032,9 @@
 	tcl_lock = PyThread_allocate_lock();
 #endif
 
-	m = Py_InitModule("_tkinter", moduleMethods);
+	m = PyModule_Create(&_tkintermodule);
 	if (m == NULL)
-		return;
+		return NULL;
 
 	d = PyModule_GetDict(m);
 	Tkinter_TclError = PyErr_NewException("_tkinter.TclError", NULL, NULL);
@@ -3076,8 +3088,10 @@
 		Py_DECREF(uexe);
 	}
 
-	if (PyErr_Occurred())
-		return;
+	if (PyErr_Occurred()) {
+		Py_DECREF(m);
+		return NULL;
+	}
 
 #if 0
 	/* This was not a good idea; through <Destroy> bindings,
@@ -3085,5 +3099,5 @@
 	   interpreter and thread state have already been destroyed! */
 	Py_AtExit(Tcl_Finalize);
 #endif
-
+	return m;
 }

Modified: python/branches/py3k/Modules/_weakref.c
==============================================================================
--- python/branches/py3k/Modules/_weakref.c	(original)
+++ python/branches/py3k/Modules/_weakref.c	Wed Jun 11 07:26:20 2008
@@ -88,13 +88,25 @@
 };
 
 
+static struct PyModuleDef weakrefmodule = {
+	PyModuleDef_HEAD_INIT,
+	"_weakref",
+	"Weak-reference support module.",
+	-1,
+	weakref_functions,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_weakref(void)
+PyInit__weakref(void)
 {
     PyObject *m;
 
-    m = Py_InitModule3("_weakref", weakref_functions,
-                       "Weak-reference support module.");
+    m = PyModule_Create(&weakrefmodule);
+                       
     if (m != NULL) {
         Py_INCREF(&_PyWeakref_RefType);
         PyModule_AddObject(m, "ref",
@@ -109,4 +121,5 @@
         PyModule_AddObject(m, "CallableProxyType",
                            (PyObject *) &_PyWeakref_CallableProxyType);
     }
+    return m;
 }

Modified: python/branches/py3k/Modules/arraymodule.c
==============================================================================
--- python/branches/py3k/Modules/arraymodule.c	(original)
+++ python/branches/py3k/Modules/arraymodule.c	Wed Jun 11 07:26:20 2008
@@ -2156,9 +2156,21 @@
     {NULL, NULL, 0, NULL}        /* Sentinel */
 };
 
+static struct PyModuleDef arraymodule = {
+	PyModuleDef_HEAD_INIT,
+	"array",
+	module_doc,
+	-1,
+	a_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 
 PyMODINIT_FUNC
-initarray(void)
+PyInit_array(void)
 {
 	PyObject *m;
 	PyObject *typecodes;
@@ -2167,11 +2179,11 @@
 	struct arraydescr *descr;
 
 	if (PyType_Ready(&Arraytype) < 0)
-            return;
+            return NULL;
 	Py_TYPE(&PyArrayIter_Type) = &PyType_Type;
-	m = Py_InitModule3("array", a_methods, module_doc);
+	m = PyModule_Create(&arraymodule);
 	if (m == NULL)
-		return;
+		return NULL;
 
         Py_INCREF((PyObject *)&Arraytype);
 	PyModule_AddObject(m, "ArrayType", (PyObject *)&Arraytype);
@@ -2190,5 +2202,9 @@
 
 	PyModule_AddObject(m, "typecodes", (PyObject *)typecodes);
 	
-	/* No need to check the error here, the caller will do that */
+	if (PyErr_Occurred()) {
+		Py_DECREF(m);
+		m = NULL;
+	}
+	return m;
 }

Modified: python/branches/py3k/Modules/atexitmodule.c
==============================================================================
--- python/branches/py3k/Modules/atexitmodule.c	(original)
+++ python/branches/py3k/Modules/atexitmodule.c	Wed Jun 11 07:26:20 2008
@@ -233,21 +233,35 @@
 Two public functions, register and unregister, are defined.\n\
 ");
 
+
+static struct PyModuleDef atexitmodule = {
+	PyModuleDef_HEAD_INIT,
+	"atexit",
+	atexit__doc__,
+	-1,
+	atexit_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-initatexit(void)
+PyInit_atexit(void)
 {
     PyObject *m;
     
     atexit_callbacks = PyMem_New(atexit_callback*, callback_len);
     if (atexit_callbacks == NULL)
-        return;
+        return NULL;
 
-    m = Py_InitModule3("atexit", atexit_methods, atexit__doc__);
+    m = PyModule_Create(&atexitmodule);
     if (m == NULL)
-        return;
+        return NULL;
     
     _Py_PyAtExit(atexit_callfuncs);
     /* Register a callback that will free
        atexit_callbacks, otherwise valgrind will report memory leaks. */
     Py_AtExit(atexit_cleanup);
+    return m;
 }

Modified: python/branches/py3k/Modules/audioop.c
==============================================================================
--- python/branches/py3k/Modules/audioop.c	(original)
+++ python/branches/py3k/Modules/audioop.c	Wed Jun 11 07:26:20 2008
@@ -1600,17 +1600,31 @@
         { 0,          0 }
 };
 
+
+static struct PyModuleDef audioopmodule = {
+	PyModuleDef_HEAD_INIT,
+	"audioop",
+	NULL,
+	-1,
+	audioop_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-initaudioop(void)
+PyInit_audioop(void)
 {
         PyObject *m, *d;
-        m = Py_InitModule("audioop", audioop_methods);
+        m = PyModule_Create(&audioopmodule);
         if (m == NULL)
-                return;
+                return NULL;
         d = PyModule_GetDict(m);
         if (d == NULL)
-                return;
+                return NULL;
         AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
         if (AudioopError != NULL)
              PyDict_SetItemString(d,"error",AudioopError);
+	return m;
 }

Modified: python/branches/py3k/Modules/binascii.c
==============================================================================
--- python/branches/py3k/Modules/binascii.c	(original)
+++ python/branches/py3k/Modules/binascii.c	Wed Jun 11 07:26:20 2008
@@ -1357,18 +1357,31 @@
 };
 
 
-/* Initialization function for the module (*must* be called initbinascii) */
+/* Initialization function for the module (*must* be called PyInit_binascii) */
 PyDoc_STRVAR(doc_binascii, "Conversion between binary data and ASCII");
 
+
+static struct PyModuleDef binasciimodule = {
+	PyModuleDef_HEAD_INIT,
+	"binascii",
+	doc_binascii,
+	-1,
+	binascii_module_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-initbinascii(void)
+PyInit_binascii(void)
 {
 	PyObject *m, *d;
 
 	/* Create the module and add the functions */
-	m = Py_InitModule3("binascii", binascii_module_methods, doc_binascii);
+	m = PyModule_Create(&binasciimodule);
 	if (m == NULL)
-		return;
+		return NULL;
 
 	d = PyModule_GetDict(m);
 
@@ -1376,4 +1389,9 @@
 	PyDict_SetItemString(d, "Error", Error);
 	Incomplete = PyErr_NewException("binascii.Incomplete", NULL, NULL);
 	PyDict_SetItemString(d, "Incomplete", Incomplete);
+	if (PyErr_Occurred()) {
+		Py_DECREF(m);
+		m = NULL;
+	}
+	return m;
 }

Modified: python/branches/py3k/Modules/bz2module.c
==============================================================================
--- python/branches/py3k/Modules/bz2module.c	(original)
+++ python/branches/py3k/Modules/bz2module.c	Wed Jun 11 07:26:20 2008
@@ -2026,8 +2026,21 @@
 sequential (de)compression.\n\
 ");
 
+
+static struct PyModuleDef bz2module = {
+	PyModuleDef_HEAD_INIT,
+	"bz2",
+	bz2__doc__,
+	-1,
+	bz2_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-initbz2(void)
+PyInit_bz2(void)
 {
 	PyObject *m;
 
@@ -2035,9 +2048,9 @@
 	Py_TYPE(&BZ2Comp_Type) = &PyType_Type;
 	Py_TYPE(&BZ2Decomp_Type) = &PyType_Type;
 
-	m = Py_InitModule3("bz2", bz2_methods, bz2__doc__);
+	m = PyModule_Create(&bz2module);
 	if (m == NULL)
-		return;
+		return NULL;
 
 	PyModule_AddObject(m, "__author__", PyUnicode_FromString(__author__));
 
@@ -2049,4 +2062,5 @@
 
 	Py_INCREF(&BZ2Decomp_Type);
 	PyModule_AddObject(m, "BZ2Decompressor", (PyObject *)&BZ2Decomp_Type);
+	return m;
 }

Modified: python/branches/py3k/Modules/cjkcodecs/cjkcodecs.h
==============================================================================
--- python/branches/py3k/Modules/cjkcodecs/cjkcodecs.h	(original)
+++ python/branches/py3k/Modules/cjkcodecs/cjkcodecs.h	Wed Jun 11 07:26:20 2008
@@ -389,12 +389,24 @@
 #endif
 
 #define I_AM_A_MODULE_FOR(loc)						\
-	void								\
-	init_codecs_##loc(void)						\
+	static struct PyModuleDef __module = {				\
+		PyModuleDef_HEAD_INIT,					\
+		"_codecs_"#loc,						\
+		NULL,							\
+		0,							\
+		__methods,						\
+		NULL,							\
+		NULL,							\
+		NULL,							\
+		NULL							\
+	};								\
+	PyObject*							\
+	PyInit__codecs_##loc(void)					\
 	{								\
-		PyObject *m = Py_InitModule("_codecs_" #loc, __methods);\
+		PyObject *m = PyModule_Create(&__module);		\
 		if (m != NULL)						\
 			(void)register_maps(m);				\
+		return m;						\
 	}
 
 #endif

Modified: python/branches/py3k/Modules/cjkcodecs/multibytecodec.c
==============================================================================
--- python/branches/py3k/Modules/cjkcodecs/multibytecodec.c	(original)
+++ python/branches/py3k/Modules/cjkcodecs/multibytecodec.c	Wed Jun 11 07:26:20 2008
@@ -1778,8 +1778,21 @@
 	{NULL, NULL},
 };
 
+
+static struct PyModuleDef _multibytecodecmodule = {
+	PyModuleDef_HEAD_INIT,
+	"_multibytecodec",
+	NULL,
+	-1,
+	__methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_multibytecodec(void)
+PyInit__multibytecodec(void)
 {
 	int i;
 	PyObject *m;
@@ -1792,20 +1805,24 @@
 	};
 
 	if (PyType_Ready(&MultibyteCodec_Type) < 0)
-		return;
+		return NULL;
 
-	m = Py_InitModule("_multibytecodec", __methods);
+	m = PyModule_Create(&_multibytecodecmodule);
 	if (m == NULL)
-		return;
+		return NULL;
 
 	for (i = 0; typelist[i] != NULL; i++) {
 		if (PyType_Ready(typelist[i]) < 0)
-			return;
+			return NULL;
 		Py_INCREF(typelist[i]);
 		PyModule_AddObject(m, typelist[i]->tp_name,
 				   (PyObject *)typelist[i]);
 	}
 
-	if (PyErr_Occurred())
+	if (PyErr_Occurred()) {
 		Py_FatalError("can't initialize the _multibytecodec module");
+		Py_DECREF(m);
+		m = NULL;
+	}
+	return m;
 }

Modified: python/branches/py3k/Modules/cmathmodule.c
==============================================================================
--- python/branches/py3k/Modules/cmathmodule.c	(original)
+++ python/branches/py3k/Modules/cmathmodule.c	Wed Jun 11 07:26:20 2008
@@ -1077,14 +1077,27 @@
 	{NULL,		NULL}		/* sentinel */
 };
 
+
+static struct PyModuleDef cmathmodule = {
+	PyModuleDef_HEAD_INIT,
+	"cmath",
+	module_doc,
+	-1,
+	cmath_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-initcmath(void)
+PyInit_cmath(void)
 {
 	PyObject *m;
 
-	m = Py_InitModule3("cmath", cmath_methods, module_doc);
+	m = PyModule_Create(&cmathmodule);
 	if (m == NULL)
-		return;
+		return NULL;
 
 	PyModule_AddObject(m, "pi",
                            PyFloat_FromDouble(Py_MATH_PI));
@@ -1204,4 +1217,5 @@
 	  C(INF,N) C(U,U) C(INF,-0.) C(INF,0.)   C(U,U) C(INF,N) C(INF,N)
 	  C(N,N)   C(N,N) C(N,0.)    C(N,0.)     C(N,N) C(N,N)   C(N,N)
 	})
+        return m;
 }

Modified: python/branches/py3k/Modules/config.c.in
==============================================================================
--- python/branches/py3k/Modules/config.c.in	(original)
+++ python/branches/py3k/Modules/config.c.in	Wed Jun 11 07:26:20 2008
@@ -24,11 +24,11 @@
 
 /* -- ADDMODULE MARKER 1 -- */
 
-extern void PyMarshal_Init(void);
-extern void initimp(void);
-extern void initgc(void);
-extern void init_ast(void);
-extern void _PyWarnings_Init(void);
+extern PyObject* PyMarshal_Init(void);
+extern PyObject* PyInit_imp(void);
+extern PyObject* PyInit_gc(void);
+extern PyObject* PyInit__ast(void);
+extern PyObject* _PyWarnings_Init(void);
 
 struct _inittab _PyImport_Inittab[] = {
 
@@ -38,10 +38,10 @@
 	{"marshal", PyMarshal_Init},
 
 	/* This lives in import.c */
-	{"imp", initimp},
+	{"imp", PyInit_imp},
 
 	/* This lives in Python/Python-ast.c */
-	{"_ast", init_ast},
+	{"_ast", PyInit__ast},
 
 	/* These entries are here for sys.builtin_module_names */
 	{"__main__", NULL},
@@ -49,7 +49,7 @@
 	{"sys", NULL},
 
 	/* This lives in gcmodule.c */
-	{"gc", initgc},
+	{"gc", PyInit_gc},
 
     /* This lives in _warnings.c */
     {"_warnings", _PyWarnings_Init},

Modified: python/branches/py3k/Modules/cryptmodule.c
==============================================================================
--- python/branches/py3k/Modules/cryptmodule.c	(original)
+++ python/branches/py3k/Modules/cryptmodule.c	Wed Jun 11 07:26:20 2008
@@ -42,8 +42,21 @@
 	{NULL,		NULL}		/* sentinel */
 };
 
+
+static struct PyModuleDef cryptmodule = {
+	PyModuleDef_HEAD_INIT,
+	"crypt",
+	NULL,
+	-1,
+	crypt_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-initcrypt(void)
+PyInit_crypt(void)
 {
-	Py_InitModule("crypt", crypt_methods);
+	return PyModule_Create(&cryptmodule);
 }

Modified: python/branches/py3k/Modules/datetimemodule.c
==============================================================================
--- python/branches/py3k/Modules/datetimemodule.c	(original)
+++ python/branches/py3k/Modules/datetimemodule.c	Wed Jun 11 07:26:20 2008
@@ -4661,45 +4661,57 @@
 };
 
 
+
+static struct PyModuleDef datetimemodule = {
+	PyModuleDef_HEAD_INIT,
+	"datetime",
+	"Fast implementation of the datetime type.",
+	-1,
+	module_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-initdatetime(void)
+PyInit_datetime(void)
 {
 	PyObject *m;	/* a module object */
 	PyObject *d;	/* its dict */
 	PyObject *x;
 
-	m = Py_InitModule3("datetime", module_methods,
-			   "Fast implementation of the datetime type.");
+	m = PyModule_Create(&datetimemodule);
 	if (m == NULL)
-		return;
+		return NULL;
 
 	if (PyType_Ready(&PyDateTime_DateType) < 0)
-		return;
+		return NULL;
 	if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
-		return;
+		return NULL;
 	if (PyType_Ready(&PyDateTime_DeltaType) < 0)
-		return;
+		return NULL;
 	if (PyType_Ready(&PyDateTime_TimeType) < 0)
-		return;
+		return NULL;
 	if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
-		return;
+		return NULL;
 
 	/* timedelta values */
 	d = PyDateTime_DeltaType.tp_dict;
 
 	x = new_delta(0, 0, 1, 0);
 	if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
-		return;
+		return NULL;
 	Py_DECREF(x);
 
 	x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
 	if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
-		return;
+		return NULL;
 	Py_DECREF(x);
 
 	x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
 	if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
-		return;
+		return NULL;
 	Py_DECREF(x);
 
 	/* date values */
@@ -4707,17 +4719,17 @@
 
 	x = new_date(1, 1, 1);
 	if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
-		return;
+		return NULL;
 	Py_DECREF(x);
 
 	x = new_date(MAXYEAR, 12, 31);
 	if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
-		return;
+		return NULL;
 	Py_DECREF(x);
 
 	x = new_delta(1, 0, 0, 0);
 	if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
-		return;
+		return NULL;
 	Py_DECREF(x);
 
 	/* time values */
@@ -4725,17 +4737,17 @@
 
 	x = new_time(0, 0, 0, 0, Py_None);
 	if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
-		return;
+		return NULL;
 	Py_DECREF(x);
 
 	x = new_time(23, 59, 59, 999999, Py_None);
 	if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
-		return;
+		return NULL;
 	Py_DECREF(x);
 
 	x = new_delta(0, 0, 1, 0);
 	if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
-		return;
+		return NULL;
 	Py_DECREF(x);
 
 	/* datetime values */
@@ -4743,17 +4755,17 @@
 
 	x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None);
 	if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
-		return;
+		return NULL;
 	Py_DECREF(x);
 
 	x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None);
 	if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
-		return;
+		return NULL;
 	Py_DECREF(x);
 
 	x = new_delta(0, 0, 1, 0);
 	if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
-		return;
+		return NULL;
 	Py_DECREF(x);
 
 	/* module initialization */
@@ -4779,7 +4791,7 @@
         x = PyCObject_FromVoidPtrAndDesc(&CAPI, (void*) DATETIME_API_MAGIC,
                 NULL);
         if (x == NULL)
-            return;
+            return NULL;
         PyModule_AddObject(m, "datetime_CAPI", x);
 
 	/* A 4-year cycle has an extra leap day over what we'd get from
@@ -4807,7 +4819,7 @@
 	seconds_per_day = PyLong_FromLong(24 * 3600);
 	if (us_per_us == NULL || us_per_ms == NULL || us_per_second == NULL ||
 	    us_per_minute == NULL || seconds_per_day == NULL)
-		return;
+		return NULL;
 
 	/* The rest are too big for 32-bit ints, but even
 	 * us_per_week fits in 40 bits, so doubles should be exact.
@@ -4816,7 +4828,8 @@
 	us_per_day = PyLong_FromDouble(86400000000.0);
 	us_per_week = PyLong_FromDouble(604800000000.0);
 	if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
-		return;
+		return NULL;
+	return m;
 }
 
 /* ---------------------------------------------------------------------------

Modified: python/branches/py3k/Modules/errnomodule.c
==============================================================================
--- python/branches/py3k/Modules/errnomodule.c	(original)
+++ python/branches/py3k/Modules/errnomodule.c	Wed Jun 11 07:26:20 2008
@@ -53,17 +53,29 @@
 To map error codes to error messages, use the function os.strerror(),\n\
 e.g. os.strerror(2) could return 'No such file or directory'.");
 
+static struct PyModuleDef errnomodule = {
+	PyModuleDef_HEAD_INIT,
+	"errno",
+	errno__doc__,
+	-1,
+	errno_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-initerrno(void)
+PyInit_errno(void)
 {
 	PyObject *m, *d, *de;
-	m = Py_InitModule3("errno", errno_methods, errno__doc__);
+	m = PyModule_Create(&errnomodule);
 	if (m == NULL)
-		return;
+		return NULL;
 	d = PyModule_GetDict(m);
 	de = PyDict_New();
 	if (!d || !de || PyDict_SetItemString(d, "errorcode", de) < 0)
-		return;
+		return NULL;
 
 /* Macro so I don't have to edit each and every line below... */
 #define inscode(d, ds, de, name, code, comment) _inscode(d, de, name, code)
@@ -786,4 +798,5 @@
 #endif
 
 	Py_DECREF(de);
+	return m;
 }

Modified: python/branches/py3k/Modules/fcntlmodule.c
==============================================================================
--- python/branches/py3k/Modules/fcntlmodule.c	(original)
+++ python/branches/py3k/Modules/fcntlmodule.c	Wed Jun 11 07:26:20 2008
@@ -599,17 +599,31 @@
 	return 0;
 }
 
+
+static struct PyModuleDef fcntlmodule = {
+	PyModuleDef_HEAD_INIT,
+	"fcntl",
+	module_doc,
+	-1,
+	fcntl_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-initfcntl(void)
+PyInit_fcntl(void)
 {
 	PyObject *m, *d;
 
 	/* Create the module and add the functions and documentation */
-	m = Py_InitModule3("fcntl", fcntl_methods, module_doc);
+	m = PyModule_Create(&fcntlmodule);
 	if (m == NULL)
-		return;
+		return NULL;
 
 	/* Add some symbolic constants to the module */
 	d = PyModule_GetDict(m);
 	all_ins(d);
+	return m;
 }

Modified: python/branches/py3k/Modules/fpectlmodule.c
==============================================================================
--- python/branches/py3k/Modules/fpectlmodule.c	(original)
+++ python/branches/py3k/Modules/fpectlmodule.c	Wed Jun 11 07:26:20 2008
@@ -90,7 +90,8 @@
 static void fpe_reset(Sigfunc *);
 
 static PyObject *fpe_error;
-PyMODINIT_FUNC initfpectl(void);
+
+PyMODINIT_FUNC PyInit_fpectl(void);
 static PyObject *turnon_sigfpe            (PyObject *self,PyObject *args);
 static PyObject *turnoff_sigfpe           (PyObject *self,PyObject *args);
 
@@ -286,16 +287,29 @@
     }
 }
 
-PyMODINIT_FUNC initfpectl(void)
+static struct PyModuleDef fpectlmodule = {
+	PyModuleDef_HEAD_INIT,
+	"fpectl",
+	NULL,
+	-1,
+	fpectl_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
+PyMODINIT_FUNC PyInit_fpectl(void)
 {
     PyObject *m, *d;
-    m = Py_InitModule("fpectl", fpectl_methods);
+    m = PyModule_Create("fpectl", fpectl_methods);
     if (m == NULL)
-    	return;
+    	return NULL;
     d = PyModule_GetDict(m);
     fpe_error = PyErr_NewException("fpectl.error", NULL, NULL);
     if (fpe_error != NULL)
 	PyDict_SetItemString(d, "error", fpe_error);
+    return m;
 }
 
 #ifdef __cplusplus

Modified: python/branches/py3k/Modules/fpetestmodule.c
==============================================================================
--- python/branches/py3k/Modules/fpetestmodule.c	(original)
+++ python/branches/py3k/Modules/fpetestmodule.c	Wed Jun 11 07:26:20 2008
@@ -44,7 +44,8 @@
 #include "Python.h"
 
 static PyObject *fpe_error;
-PyMODINIT_FUNC initfpetest(void);
+
+PyMODINIT_FUNC PyInit_fpetest(void);
 static PyObject *test(PyObject *self,PyObject *args);
 static double db0(double);
 static double overflow(double);
@@ -172,15 +173,28 @@
   return a;
 }
 
-PyMODINIT_FUNC initfpetest(void)
+static struct PyModuleDef fpetestmodule = {
+	PyModuleDef_HEAD_INIT,
+	"fpetest",
+	NULL,
+	-1,
+	fpetest_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
+PyMODINIT_FUNC PyInit_fpetest(void)
 {
     PyObject *m, *d;
 
-    m = Py_InitModule("fpetest", fpetest_methods);
+    m = PyModule_Create(&fpetestmodule);
     if (m == NULL)
-    	return;
+    	return NULL;
     d = PyModule_GetDict(m);
     fpe_error = PyErr_NewException("fpetest.error", NULL, NULL);
     if (fpe_error != NULL)
 	    PyDict_SetItemString(d, "error", fpe_error);
+    return m;
 }

Modified: python/branches/py3k/Modules/gcmodule.c
==============================================================================
--- python/branches/py3k/Modules/gcmodule.c	(original)
+++ python/branches/py3k/Modules/gcmodule.c	Wed Jun 11 07:26:20 2008
@@ -1192,27 +1192,37 @@
 	{NULL,	NULL}		/* Sentinel */
 };
 
+static struct PyModuleDef gcmodule = {
+	PyModuleDef_HEAD_INIT,
+	"gc",
+	gc__doc__,
+	-1,
+	GcMethods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
+
 PyMODINIT_FUNC
-initgc(void)
+PyInit_gc(void)
 {
 	PyObject *m;
 
-	m = Py_InitModule4("gc",
-			      GcMethods,
-			      gc__doc__,
-			      NULL,
-			      PYTHON_API_VERSION);
+	m = PyModule_Create(&gcmodule);
+
 	if (m == NULL)
-		return;
+		return NULL;
 
 	if (garbage == NULL) {
 		garbage = PyList_New(0);
 		if (garbage == NULL)
-			return;
+			return NULL;
 	}
 	Py_INCREF(garbage);
 	if (PyModule_AddObject(m, "garbage", garbage) < 0)
-		return;
+		return NULL;
 
 	/* Importing can't be done in collect() because collect()
 	 * can be called via PyGC_Collect() in Py_Finalize().
@@ -1226,13 +1236,14 @@
 			PyErr_Clear();
 	}
 
-#define ADD_INT(NAME) if (PyModule_AddIntConstant(m, #NAME, NAME) < 0) return
+#define ADD_INT(NAME) if (PyModule_AddIntConstant(m, #NAME, NAME) < 0) return NULL
 	ADD_INT(DEBUG_STATS);
 	ADD_INT(DEBUG_COLLECTABLE);
 	ADD_INT(DEBUG_UNCOLLECTABLE);
 	ADD_INT(DEBUG_SAVEALL);
 	ADD_INT(DEBUG_LEAK);
 #undef ADD_INT
+	return m;
 }
 
 /* API to invoke gc.collect() from C */

Modified: python/branches/py3k/Modules/grpmodule.c
==============================================================================
--- python/branches/py3k/Modules/grpmodule.c	(original)
+++ python/branches/py3k/Modules/grpmodule.c	Wed Jun 11 07:26:20 2008
@@ -179,16 +179,30 @@
 complete membership information.)");
 
 
+
+static struct PyModuleDef grpmodule = {
+	PyModuleDef_HEAD_INIT,
+	"grp",
+	grp__doc__,
+	-1,
+	grp_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-initgrp(void)
+PyInit_grp(void)
 {
     PyObject *m, *d;
-    m = Py_InitModule3("grp", grp_methods, grp__doc__);
+    m = PyModule_Create(&grpmodule);
     if (m == NULL)
-        return;
+        return NULL;
     d = PyModule_GetDict(m);
     if (!initialized)
 	    PyStructSequence_InitType(&StructGrpType, &struct_group_type_desc);
     PyDict_SetItemString(d, "struct_group", (PyObject *) &StructGrpType);
     initialized = 1;
+    return m;
 }

Modified: python/branches/py3k/Modules/itertoolsmodule.c
==============================================================================
--- python/branches/py3k/Modules/itertoolsmodule.c	(original)
+++ python/branches/py3k/Modules/itertoolsmodule.c	Wed Jun 11 07:26:20 2008
@@ -3030,8 +3030,21 @@
  	{NULL,		NULL}		/* sentinel */
 };
 
+
+static struct PyModuleDef itertoolsmodule = {
+	PyModuleDef_HEAD_INIT,
+	"itertools",
+	module_doc,
+	-1,
+	module_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-inititertools(void)
+PyInit_itertools(void)
 {
 	int i;
 	PyObject *m;
@@ -3055,13 +3068,13 @@
 	};
 
 	Py_TYPE(&teedataobject_type) = &PyType_Type;
-	m = Py_InitModule3("itertools", module_methods, module_doc);
+	m = PyModule_Create(&itertoolsmodule);
 	if (m == NULL)
-		return;
+		return NULL;
 
 	for (i=0 ; typelist[i] != NULL ; i++) {
 		if (PyType_Ready(typelist[i]) < 0)
-			return;
+			return NULL;
 		name = strchr(typelist[i]->tp_name, '.');
 		assert (name != NULL);
 		Py_INCREF(typelist[i]);
@@ -3069,9 +3082,10 @@
 	}
 
 	if (PyType_Ready(&teedataobject_type) < 0)
-		return;
+		return NULL;
 	if (PyType_Ready(&tee_type) < 0)
-		return;
+		return NULL;
 	if (PyType_Ready(&_grouper_type) < 0)
-		return;
+		return NULL;
+	return m;
 }

Modified: python/branches/py3k/Modules/makesetup
==============================================================================
--- python/branches/py3k/Modules/makesetup	(original)
+++ python/branches/py3k/Modules/makesetup	Wed Jun 11 07:26:20 2008
@@ -24,8 +24,8 @@
 # Copying config.c.in to config.c:
 # - insert an identifying comment at the start
 # - for each <module> mentioned in Setup before *noconfig*:
-#   + insert 'extern void init<module>(void);' before MARKER 1
-#   + insert '{"<module>", initmodule},' before MARKER 2
+#   + insert 'extern PyObject* PyInit_<module>(void);' before MARKER 1
+#   + insert '{"<module>", PyInit_<module>},' before MARKER 2
 #
 # Copying Makefile.pre to Makefile:
 # - insert an identifying comment at the start
@@ -260,8 +260,8 @@
 	INITBITS=
 	for mod in $MODS
 	do
-		EXTDECLS="${EXTDECLS}extern void init$mod(void);$NL"
-		INITBITS="${INITBITS}	{\"$mod\", init$mod},$NL"
+		EXTDECLS="${EXTDECLS}extern PyObject* PyInit_$mod(void);$NL"
+		INITBITS="${INITBITS}	{\"$mod\", PyInit_$mod},$NL"
 	done
 
 

Modified: python/branches/py3k/Modules/mathmodule.c
==============================================================================
--- python/branches/py3k/Modules/mathmodule.c	(original)
+++ python/branches/py3k/Modules/mathmodule.c	Wed Jun 11 07:26:20 2008
@@ -1099,12 +1099,25 @@
 "This module is always available.  It provides access to the\n"
 "mathematical functions defined by the C standard.");
 
+
+static struct PyModuleDef mathmodule = {
+	PyModuleDef_HEAD_INIT,
+	"math",
+	module_doc,
+	-1,
+	math_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-initmath(void)
+PyInit_math(void)
 {
 	PyObject *m;
 
-	m = Py_InitModule3("math", math_methods, module_doc);
+	m = PyModule_Create(&mathmodule);
 	if (m == NULL)
 		goto finally;
 
@@ -1112,5 +1125,5 @@
 	PyModule_AddObject(m, "e", PyFloat_FromDouble(Py_MATH_E));
 
     finally:
-	return;
+	return m;
 }

Modified: python/branches/py3k/Modules/md5module.c
==============================================================================
--- python/branches/py3k/Modules/md5module.c	(original)
+++ python/branches/py3k/Modules/md5module.c	Wed Jun 11 07:26:20 2008
@@ -547,15 +547,24 @@
 
 #define insint(n,v) { PyModule_AddIntConstant(m,n,v); }
 
+
+static struct PyModuleDef _md5module = {
+	PyModuleDef_HEAD_INIT,
+	"_md5",
+	NULL,
+	-1,
+	MD5_functions,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_md5(void)
+PyInit__md5(void)
 {
-    PyObject *m;
-
     Py_TYPE(&MD5type) = &PyType_Type;
     if (PyType_Ready(&MD5type) < 0)
-        return;
-    m = Py_InitModule("_md5", MD5_functions);
-    if (m == NULL)
-	return;
+        return NULL;
+    return PyModule_Create("_md5", MD5_functions);
 }

Modified: python/branches/py3k/Modules/mmapmodule.c
==============================================================================
--- python/branches/py3k/Modules/mmapmodule.c	(original)
+++ python/branches/py3k/Modules/mmapmodule.c	Wed Jun 11 07:26:20 2008
@@ -1312,24 +1312,37 @@
 	}
 }
 
+
+static struct PyModuleDef mmapmodule = {
+	PyModuleDef_HEAD_INIT,
+	"mmap",
+	NULL,
+	-1,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-initmmap(void)
+PyInit_mmap(void)
 {
 	PyObject *dict, *module;
 
 	if (PyType_Ready(&mmap_object_type) < 0)
-		return;
+		return NULL;
 
-	module = Py_InitModule("mmap", NULL);
+	module = PyModule_Create(&mmapmodule);
 	if (module == NULL)
-		return;
+		return NULL;
 	dict = PyModule_GetDict(module);
 	if (!dict)
-		return;
+		return NULL;
 	mmap_module_error = PyErr_NewException("mmap.error",
 		PyExc_EnvironmentError , NULL);
 	if (mmap_module_error == NULL)
-		return;
+		return NULL;
 	PyDict_SetItemString(dict, "error", mmap_module_error);
 	PyDict_SetItemString(dict, "mmap", (PyObject*) &mmap_object_type);
 #ifdef PROT_EXEC
@@ -1366,4 +1379,5 @@
 	setint(dict, "ACCESS_READ", ACCESS_READ);
 	setint(dict, "ACCESS_WRITE", ACCESS_WRITE);
 	setint(dict, "ACCESS_COPY", ACCESS_COPY);
+	return module;
 }

Modified: python/branches/py3k/Modules/nismodule.c
==============================================================================
--- python/branches/py3k/Modules/nismodule.c	(original)
+++ python/branches/py3k/Modules/nismodule.c	Wed Jun 11 07:26:20 2008
@@ -430,15 +430,28 @@
 PyDoc_STRVAR(nis__doc__,
 "This module contains functions for accessing NIS maps.\n");
 
-void
-initnis (void)
+static struct PyModuleDef nismodule = {
+	PyModuleDef_HEAD_INIT,
+	"nis",
+	nis__doc__,
+	-1,
+	nis_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
+PyObject*
+PyInit_nis (void)
 {
 	PyObject *m, *d;
-	m = Py_InitModule3("nis", nis_methods, nis__doc__);
+	m = PyModule_Create(&nismodule);
 	if (m == NULL)
-		return;
+		return NULL;
 	d = PyModule_GetDict(m);
 	NisError = PyErr_NewException("nis.error", NULL, NULL);
 	if (NisError != NULL)
 		PyDict_SetItemString(d, "error", NisError);
+	return m;
 }

Modified: python/branches/py3k/Modules/operator.c
==============================================================================
--- python/branches/py3k/Modules/operator.c	(original)
+++ python/branches/py3k/Modules/operator.c	Wed Jun 11 07:26:20 2008
@@ -688,31 +688,44 @@
 };
 
 
-/* Initialization function for the module (*must* be called initoperator) */
+/* Initialization function for the module (*must* be called PyInit_operator) */
+
+
+static struct PyModuleDef operatormodule = {
+	PyModuleDef_HEAD_INIT,
+	"operator",
+	operator_doc,
+	-1,
+	operator_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
 
 PyMODINIT_FUNC
-initoperator(void)
+PyInit_operator(void)
 {
 	PyObject *m;
         
 	/* Create the module and add the functions */
-        m = Py_InitModule4("operator", operator_methods, operator_doc,
-		       (PyObject*)NULL, PYTHON_API_VERSION);
+        m = PyModule_Create(&operatormodule);
 	if (m == NULL)
-		return;
+		return NULL;
 
 	if (PyType_Ready(&itemgetter_type) < 0)
-		return;
+		return NULL;
 	Py_INCREF(&itemgetter_type);
 	PyModule_AddObject(m, "itemgetter", (PyObject *)&itemgetter_type);
 
 	if (PyType_Ready(&attrgetter_type) < 0)
-		return;
+		return NULL;
 	Py_INCREF(&attrgetter_type);
 	PyModule_AddObject(m, "attrgetter", (PyObject *)&attrgetter_type);
 
 	if (PyType_Ready(&methodcaller_type) < 0)
-		return;
+		return NULL;
 	Py_INCREF(&methodcaller_type);
 	PyModule_AddObject(m, "methodcaller", (PyObject *)&methodcaller_type);
+	return m;
 }

Modified: python/branches/py3k/Modules/ossaudiodev.c
==============================================================================
--- python/branches/py3k/Modules/ossaudiodev.c	(original)
+++ python/branches/py3k/Modules/ossaudiodev.c	Wed Jun 11 07:26:20 2008
@@ -889,7 +889,7 @@
 
 
 #define _EXPORT_INT(mod, name) \
-  if (PyModule_AddIntConstant(mod, #name, (long) (name)) == -1) return;
+  if (PyModule_AddIntConstant(mod, #name, (long) (name)) == -1) return NULL;
 
 
 static char *control_labels[] = SOUND_DEVICE_LABELS;
@@ -939,14 +939,26 @@
 }
 
 
-void
-initossaudiodev(void)
+static struct PyModuleDef ossaudiodevmodule = {
+	PyModuleDef_HEAD_INIT,
+	"ossaudiodev",
+	NULL,
+	-1,
+	ossaudiodev_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
+PyObject*
+PyInit_ossaudiodev(void)
 {
     PyObject *m;
 
-    m = Py_InitModule("ossaudiodev", ossaudiodev_methods);
+    m = PyModule_Create(&ossaudiodevmodule);
     if (m == NULL)
-	return;
+	return NULL;
 
     OSSAudioError = PyErr_NewException("ossaudiodev.OSSAudioError",
 				       NULL, NULL);
@@ -961,7 +973,7 @@
     /* Build 'control_labels' and 'control_names' lists and add them
        to the module. */
     if (build_namelists(m) == -1)       /* XXX what to do here? */
-        return;
+        return NULL;
 
     /* Expose the audio format numbers -- essential! */
     _EXPORT_INT(m, AFMT_QUERY);
@@ -1133,4 +1145,5 @@
     _EXPORT_INT(m, SNDCTL_TMR_STOP);
     _EXPORT_INT(m, SNDCTL_TMR_TEMPO);
     _EXPORT_INT(m, SNDCTL_TMR_TIMEBASE);
+    return m;
 }

Modified: python/branches/py3k/Modules/parsermodule.c
==============================================================================
--- python/branches/py3k/Modules/parsermodule.c	(original)
+++ python/branches/py3k/Modules/parsermodule.c	Wed Jun 11 07:26:20 2008
@@ -297,7 +297,7 @@
 
     static char *keywords[] = {"ast", "line_info", "col_info", NULL};
 
-    if (self == NULL) {
+    if (self == NULL || PyModule_Check(self)) {
         ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|OO:st2tuple", keywords,
                                          &PyST_Type, &self, &line_option,
                                          &col_option);
@@ -341,7 +341,7 @@
 
     static char *keywords[] = {"ast", "line_info", "col_info", NULL};
 
-    if (self == NULL)
+    if (self == NULL || PyModule_Check(self))
         ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|OO:st2list", keywords,
                                          &PyST_Type, &self, &line_option,
                                          &col_option);
@@ -383,7 +383,7 @@
 
     static char *keywords[] = {"ast", "filename", NULL};
 
-    if (self == NULL)
+    if (self == NULL || PyModule_Check(self))
         ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|s:compilest", keywords,
                                          &PyST_Type, &self, &str);
     else
@@ -412,7 +412,7 @@
 
     static char *keywords[] = {"ast", NULL};
 
-    if (self == NULL)
+    if (self == NULL || PyModule_Check(self))
         ok = PyArg_ParseTupleAndKeywords(args, kw, "O!:isexpr", keywords,
                                          &PyST_Type, &self);
     else
@@ -435,7 +435,7 @@
 
     static char *keywords[] = {"ast", NULL};
 
-    if (self == NULL)
+    if (self == NULL || PyModule_Check(self))
         ok = PyArg_ParseTupleAndKeywords(args, kw, "O!:issuite", keywords,
                                          &PyST_Type, &self);
     else
@@ -3047,33 +3047,45 @@
     };
 
 
-PyMODINIT_FUNC initparser(void);  /* supply a prototype */
+
+static struct PyModuleDef parsermodule = {
+	PyModuleDef_HEAD_INIT,
+	"parser",
+	NULL,
+	-1,
+	parser_functions,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
+PyMODINIT_FUNC PyInit_parser(void);  /* supply a prototype */
 
 PyMODINIT_FUNC
-initparser(void)
+PyInit_parser(void)
 {
     PyObject *module, *copyreg;
 
     Py_TYPE(&PyST_Type) = &PyType_Type;
-    module = Py_InitModule("parser", parser_functions);
+    module = PyModule_Create(&parsermodule);
     if (module == NULL)
-    	return;
+    	return NULL;
 
     if (parser_error == 0)
         parser_error = PyErr_NewException("parser.ParserError", NULL, NULL);
 
     if (parser_error == 0)
-        /* caller will check PyErr_Occurred() */
-        return;
+        return NULL;
     /* CAUTION:  The code next used to skip bumping the refcount on
-     * parser_error.  That's a disaster if initparser() gets called more
+     * parser_error.  That's a disaster if PyInit_parser() gets called more
      * than once.  By incref'ing, we ensure that each module dict that
      * gets created owns its reference to the shared parser_error object,
      * and the file static parser_error vrbl owns a reference too.
      */
     Py_INCREF(parser_error);
     if (PyModule_AddObject(module, "ParserError", parser_error) != 0)
-        return;
+        return NULL;
 
     Py_INCREF(&PyST_Type);
     PyModule_AddObject(module, "ASTType", (PyObject*)&PyST_Type);
@@ -3112,4 +3124,5 @@
         Py_XDECREF(pickler);
         Py_DECREF(copyreg);
     }
+    return module;
 }

Modified: python/branches/py3k/Modules/posixmodule.c
==============================================================================
--- python/branches/py3k/Modules/posixmodule.c	(original)
+++ python/branches/py3k/Modules/posixmodule.c	Wed Jun 11 07:26:20 2008
@@ -7326,41 +7326,52 @@
 
 
 #if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
-#define INITFUNC initnt
+#define INITFUNC PyInit_nt
 #define MODNAME "nt"
 
 #elif defined(PYOS_OS2)
-#define INITFUNC initos2
+#define INITFUNC PyInit_os2
 #define MODNAME "os2"
 
 #else
-#define INITFUNC initposix
+#define INITFUNC PyInit_posix
 #define MODNAME "posix"
 #endif
 
+static struct PyModuleDef posixmodule = {
+	PyModuleDef_HEAD_INIT,
+	MODNAME,
+	posix__doc__,
+	-1,
+	posix_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
+
 PyMODINIT_FUNC
 INITFUNC(void)
 {
 	PyObject *m, *v;
 
-	m = Py_InitModule3(MODNAME,
-			   posix_methods,
-			   posix__doc__);
+	m = PyModule_Create(&posixmodule);
 	if (m == NULL)
-    		return;
+    		return NULL;
 
 	/* Initialize environ dictionary */
 	v = convertenviron();
 	Py_XINCREF(v);
 	if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
-		return;
+		return NULL;
 	Py_DECREF(v);
 
         if (all_ins(m))
-                return;
+                return NULL;
 
         if (setup_confname_tables(m))
-                return;
+                return NULL;
 
 	Py_INCREF(PyExc_OSError);
 	PyModule_AddObject(m, "error", PyExc_OSError);
@@ -7403,7 +7414,7 @@
 #ifdef HAVE_FSTATVFS
 	if (fstatvfs == NULL) {
 		if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
-			return;
+			return NULL;
 		}
 	}
 #endif /* HAVE_FSTATVFS */
@@ -7411,7 +7422,7 @@
 #ifdef HAVE_STATVFS
 	if (statvfs == NULL) {
 		if (PyObject_DelAttrString(m, "statvfs") == -1) {
-			return;
+			return NULL;
 		}
 	}
 #endif /* HAVE_STATVFS */
@@ -7419,13 +7430,14 @@
 # ifdef HAVE_LCHOWN
 	if (lchown == NULL) {
 		if (PyObject_DelAttrString(m, "lchown") == -1) {
-			return;
+			return NULL;
 		}
 	}
 #endif /* HAVE_LCHOWN */
 
 
 #endif /* __APPLE__ */
+	return m;
 
 }
 

Modified: python/branches/py3k/Modules/pwdmodule.c
==============================================================================
--- python/branches/py3k/Modules/pwdmodule.c	(original)
+++ python/branches/py3k/Modules/pwdmodule.c	Wed Jun 11 07:26:20 2008
@@ -182,13 +182,26 @@
 	{NULL,		NULL}		/* sentinel */
 };
 
+static struct PyModuleDef pwdmodule = {
+	PyModuleDef_HEAD_INIT,
+	"pwd",
+	pwd__doc__,
+	-1,
+	pwd_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
+
 PyMODINIT_FUNC
-initpwd(void)
+PyInit_pwd(void)
 {
 	PyObject *m;
-	m = Py_InitModule3("pwd", pwd_methods, pwd__doc__);
+	m = PyModule_Create(&pwdmodule);
 	if (m == NULL)
-    		return;
+    		return NULL;
 
 	if (!initialized)
 		PyStructSequence_InitType(&StructPwdType, 
@@ -198,4 +211,5 @@
 	/* And for b/w compatibility (this was defined by mistake): */
 	PyModule_AddObject(m, "struct_pwent", (PyObject *) &StructPwdType);
 	initialized = 1;
+	return m;
 }

Modified: python/branches/py3k/Modules/pyexpat.c
==============================================================================
--- python/branches/py3k/Modules/pyexpat.c	(original)
+++ python/branches/py3k/Modules/pyexpat.c	Wed Jun 11 07:26:20 2008
@@ -1751,7 +1751,7 @@
 #endif
 
 #ifndef MODULE_INITFUNC
-#define MODULE_INITFUNC initpyexpat
+#define MODULE_INITFUNC PyInit_pyexpat
 #endif
 
 #ifndef PyMODINIT_FUNC
@@ -1764,6 +1764,18 @@
 
 PyMODINIT_FUNC MODULE_INITFUNC(void);  /* avoid compiler warnings */
 
+static struct PyModuleDef pyexpatmodule = {
+	PyModuleDef_HEAD_INIT,
+	MODULE_NAME,
+	pyexpat_module_documentation,
+	-1,
+	pyexpat_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
 MODULE_INITFUNC(void)
 {
@@ -1777,25 +1789,24 @@
     PyObject* capi_object;
 
     if (errmod_name == NULL)
-        return;
+        return NULL;
     modelmod_name = PyUnicode_FromString(MODULE_NAME ".model");
     if (modelmod_name == NULL)
-        return;
+        return NULL;
 
     Py_TYPE(&Xmlparsetype) = &PyType_Type;
 
     /* Create the module and add the functions */
-    m = Py_InitModule3(MODULE_NAME, pyexpat_methods,
-                       pyexpat_module_documentation);
+    m = PyModule_Create(&pyexpatmodule);
     if (m == NULL)
-	return;
+	return NULL;
 
     /* Add some symbolic constants to the module */
     if (ErrorObject == NULL) {
         ErrorObject = PyErr_NewException("xml.parsers.expat.ExpatError",
                                          NULL, NULL);
         if (ErrorObject == NULL)
-            return;
+            return NULL;
     }
     Py_INCREF(ErrorObject);
     PyModule_AddObject(m, "error", ErrorObject);
@@ -1844,7 +1855,7 @@
     Py_DECREF(modelmod_name);
     if (errors_module == NULL || model_module == NULL)
         /* Don't core dump later! */
-        return;
+        return NULL;
     
 #if XML_COMBINED_VERSION > 19505
     {
@@ -1975,6 +1986,7 @@
     capi_object = PyCObject_FromVoidPtr(&capi, NULL);
     if (capi_object)
         PyModule_AddObject(m, "expat_CAPI", capi_object);
+    return m;
 }
 
 static void

Modified: python/branches/py3k/Modules/readline.c
==============================================================================
--- python/branches/py3k/Modules/readline.c	(original)
+++ python/branches/py3k/Modules/readline.c	Wed Jun 11 07:26:20 2008
@@ -1002,16 +1002,29 @@
 PyDoc_STRVAR(doc_module,
 "Importing this module enables command line editing using GNU readline.");
 
+
+static struct PyModuleDef readlinemodule = {
+	PyModuleDef_HEAD_INIT,
+	"readline",
+	doc_module,
+	-1,
+	readline_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-initreadline(void)
+PyInit_readline(void)
 {
 	PyObject *m;
 
-	m = Py_InitModule4("readline", readline_methods, doc_module,
-			   (PyObject *)NULL, PYTHON_API_VERSION);
+	m = PyModule_Create(&readlinemodule);
 	if (m == NULL)
-		return;
+		return NULL;
 
 	PyOS_ReadlineFunctionPointer = call_readline;
 	setup_readline();
+	return m;
 }

Modified: python/branches/py3k/Modules/resource.c
==============================================================================
--- python/branches/py3k/Modules/resource.c	(original)
+++ python/branches/py3k/Modules/resource.c	Wed Jun 11 07:26:20 2008
@@ -225,15 +225,28 @@
 
 /* Module initialization */
 
+
+static struct PyModuleDef resourcemodule = {
+	PyModuleDef_HEAD_INIT,
+	"resource",
+	NULL,
+	-1,
+	resource_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-initresource(void)
+PyInit_resource(void)
 {
 	PyObject *m, *v;
 
 	/* Create the module and add the functions */
-	m = Py_InitModule("resource", resource_methods);
+	m = PyModule_Create(&resourcemodule);
 	if (m == NULL)
-		return;
+		return NULL;
 
 	/* Add some symbolic constants to the module */
 	if (ResourceError == NULL) {
@@ -326,4 +339,5 @@
 		PyModule_AddObject(m, "RLIM_INFINITY", v);
 	}
 	initialized = 1;
+	return m;
 }

Modified: python/branches/py3k/Modules/selectmodule.c
==============================================================================
--- python/branches/py3k/Modules/selectmodule.c	(original)
+++ python/branches/py3k/Modules/selectmodule.c	Wed Jun 11 07:26:20 2008
@@ -1729,13 +1729,26 @@
 *** IMPORTANT NOTICE ***\n\
 On Windows and OpenVMS, only sockets are supported; on Unix, all file descriptors.");
 
+
+static struct PyModuleDef selectmodule = {
+	PyModuleDef_HEAD_INIT,
+	"select",
+	module_doc,
+	-1,
+	select_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-initselect(void)
+PyInit_select(void)
 {
 	PyObject *m;
-	m = Py_InitModule3("select", select_methods, module_doc);
+	m = PyModule_Create(&selectmodule);
 	if (m == NULL)
-		return;
+		return NULL;
 
 	SelectError = PyErr_NewException("select.error", NULL, NULL);
 	Py_INCREF(SelectError);
@@ -1780,7 +1793,7 @@
 #ifdef HAVE_EPOLL
 	Py_TYPE(&pyEpoll_Type) = &PyType_Type;
 	if (PyType_Ready(&pyEpoll_Type) < 0)
-		return;
+		return NULL;
 
 	Py_INCREF(&pyEpoll_Type);
 	PyModule_AddObject(m, "epoll", (PyObject *) &pyEpoll_Type);
@@ -1807,14 +1820,14 @@
 	kqueue_event_Type.tp_new = PyType_GenericNew;
 	Py_TYPE(&kqueue_event_Type) = &PyType_Type;
 	if(PyType_Ready(&kqueue_event_Type) < 0)
-		return;
+		return NULL;
 
 	Py_INCREF(&kqueue_event_Type);
 	PyModule_AddObject(m, "kevent", (PyObject *)&kqueue_event_Type);
 
 	Py_TYPE(&kqueue_queue_Type) = &PyType_Type;
 	if(PyType_Ready(&kqueue_queue_Type) < 0)
-		return;
+		return NULL;
 	Py_INCREF(&kqueue_queue_Type);
 	PyModule_AddObject(m, "kqueue", (PyObject *)&kqueue_queue_Type);
 	
@@ -1875,4 +1888,5 @@
 #endif
 
 #endif /* HAVE_KQUEUE */
+	return m;
 }

Modified: python/branches/py3k/Modules/sha1module.c
==============================================================================
--- python/branches/py3k/Modules/sha1module.c	(original)
+++ python/branches/py3k/Modules/sha1module.c	Wed Jun 11 07:26:20 2008
@@ -523,15 +523,26 @@
 
 #define insint(n,v) { PyModule_AddIntConstant(m,n,v); }
 
+
+static struct PyModuleDef _sha1module = {
+	PyModuleDef_HEAD_INIT,
+	"_sha1",
+	NULL,
+	-1,
+	SHA1_functions,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_sha1(void)
+PyInit__sha1(void)
 {
     PyObject *m;
 
     Py_TYPE(&SHA1type) = &PyType_Type;
     if (PyType_Ready(&SHA1type) < 0)
-        return;
-    m = Py_InitModule("_sha1", SHA1_functions);
-    if (m == NULL)
-	return;
+        return NULL;
+    return PyModule_Create(&_sha1module);
 }

Modified: python/branches/py3k/Modules/sha256module.c
==============================================================================
--- python/branches/py3k/Modules/sha256module.c	(original)
+++ python/branches/py3k/Modules/sha256module.c	Wed Jun 11 07:26:20 2008
@@ -682,18 +682,27 @@
 
 #define insint(n,v) { PyModule_AddIntConstant(m,n,v); }
 
+
+static struct PyModuleDef _sha256module = {
+	PyModuleDef_HEAD_INIT,
+	"_sha256",
+	NULL,
+	-1,
+	SHA_functions,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_sha256(void)
+PyInit__sha256(void)
 {
-    PyObject *m;
-
     Py_TYPE(&SHA224type) = &PyType_Type;
     if (PyType_Ready(&SHA224type) < 0)
-        return;
+        return NULL;
     Py_TYPE(&SHA256type) = &PyType_Type;
     if (PyType_Ready(&SHA256type) < 0)
-        return;
-    m = Py_InitModule("_sha256", SHA_functions);
-    if (m == NULL)
-	return;
+        return NULL;
+    return PyModule_Create(&_sha256module);
 }

Modified: python/branches/py3k/Modules/sha512module.c
==============================================================================
--- python/branches/py3k/Modules/sha512module.c	(original)
+++ python/branches/py3k/Modules/sha512module.c	Wed Jun 11 07:26:20 2008
@@ -748,20 +748,29 @@
 
 #define insint(n,v) { PyModule_AddIntConstant(m,n,v); }
 
+
+static struct PyModuleDef _sha512module = {
+	PyModuleDef_HEAD_INIT,
+	"_sha512",
+	NULL,
+	-1,
+	SHA_functions,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_sha512(void)
+PyInit__sha512(void)
 {
-    PyObject *m;
-
     Py_TYPE(&SHA384type) = &PyType_Type;
     if (PyType_Ready(&SHA384type) < 0)
-        return;
+        return NULL;
     Py_TYPE(&SHA512type) = &PyType_Type;
     if (PyType_Ready(&SHA512type) < 0)
-        return;
-    m = Py_InitModule("_sha512", SHA_functions);
-    if (m == NULL)
-	return;
+        return NULL;
+    return PyModule_Create(&_sha512module);
 }
 
 #endif

Modified: python/branches/py3k/Modules/signalmodule.c
==============================================================================
--- python/branches/py3k/Modules/signalmodule.c	(original)
+++ python/branches/py3k/Modules/signalmodule.c	Wed Jun 11 07:26:20 2008
@@ -516,8 +516,20 @@
 A signal handler function is called with two arguments:\n\
 the first is the signal number, the second is the interrupted stack frame.");
 
+static struct PyModuleDef signalmodule = {
+	PyModuleDef_HEAD_INIT,
+	"signal",
+	module_doc,
+	-1,
+	signal_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-initsignal(void)
+PyInit_signal(void)
 {
 	PyObject *m, *d, *x;
 	int i;
@@ -528,9 +540,9 @@
 #endif
 
 	/* Create the module and add the functions */
-	m = Py_InitModule3("signal", signal_methods, module_doc);
+	m = PyModule_Create(&signalmodule);
 	if (m == NULL)
-		return;
+		return NULL;
 
 	/* Add some symbolic constants to the module */
 	d = PyModule_GetDict(m);
@@ -787,12 +799,13 @@
     PyDict_SetItemString(d, "ItimerError", ItimerError);
 #endif
 
-        if (!PyErr_Occurred())
-                return;
+    if (PyErr_Occurred()) {
+	    Py_DECREF(m);
+	    m = NULL;
+    }
 
-	/* Check for errors */
   finally:
-        return;
+    return m;
 }
 
 static void
@@ -893,8 +906,11 @@
 void
 PyOS_InitInterrupts(void)
 {
-	initsignal();
-	_PyImport_FixupExtension("signal", "signal");
+	PyObject *m = PyInit_signal();
+	if (m) {
+		_PyImport_FixupExtension(m, "signal", "signal");
+		Py_DECREF(m);
+	}
 }
 
 void

Modified: python/branches/py3k/Modules/socketmodule.c
==============================================================================
--- python/branches/py3k/Modules/socketmodule.c	(original)
+++ python/branches/py3k/Modules/socketmodule.c	Wed Jun 11 07:26:20 2008
@@ -695,7 +695,7 @@
 
 static double defaulttimeout = -1.0; /* Default timeout for new sockets */
 
-PyMODINIT_FUNC
+static void
 init_sockobject(PySocketSockObject *s,
 		SOCKET_T fd, int family, int type, int proto)
 {
@@ -4096,54 +4096,64 @@
 \n\
 See the socket module for documentation.");
 
+static struct PyModuleDef socketmodule = {
+	PyModuleDef_HEAD_INIT,
+	PySocket_MODULE_NAME,
+	socket_doc,
+	-1,
+	socket_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_socket(void)
+PyInit__socket(void)
 {
 	PyObject *m, *has_ipv6;
 
 	if (!os_init())
-		return;
+		return NULL;
 
 	Py_TYPE(&sock_type) = &PyType_Type;
-	m = Py_InitModule3(PySocket_MODULE_NAME,
-			   socket_methods,
-			   socket_doc);
+	m = PyModule_Create(&socketmodule);
 	if (m == NULL)
-		return;
+		return NULL;
 
 	socket_error = PyErr_NewException("socket.error",
 					  PyExc_IOError, NULL);
 	if (socket_error == NULL)
-		return;
+		return NULL;
         PySocketModuleAPI.error = socket_error;
 	Py_INCREF(socket_error);
 	PyModule_AddObject(m, "error", socket_error);
 	socket_herror = PyErr_NewException("socket.herror",
 					   socket_error, NULL);
 	if (socket_herror == NULL)
-		return;
+		return NULL;
 	Py_INCREF(socket_herror);
 	PyModule_AddObject(m, "herror", socket_herror);
 	socket_gaierror = PyErr_NewException("socket.gaierror", socket_error,
 	    NULL);
 	if (socket_gaierror == NULL)
-		return;
+		return NULL;
 	Py_INCREF(socket_gaierror);
 	PyModule_AddObject(m, "gaierror", socket_gaierror);
 	socket_timeout = PyErr_NewException("socket.timeout",
 					    socket_error, NULL);
 	if (socket_timeout == NULL)
-		return;
+		return NULL;
 	Py_INCREF(socket_timeout);
 	PyModule_AddObject(m, "timeout", socket_timeout);
 	Py_INCREF((PyObject *)&sock_type);
 	if (PyModule_AddObject(m, "SocketType",
 			       (PyObject *)&sock_type) != 0)
-		return;
+		return NULL;
 	Py_INCREF((PyObject *)&sock_type);
 	if (PyModule_AddObject(m, "socket",
 			       (PyObject *)&sock_type) != 0)
-		return;
+		return NULL;
 
 #ifdef ENABLE_IPV6
 	has_ipv6 = Py_True;
@@ -4157,7 +4167,7 @@
 	if (PyModule_AddObject(m, PySocket_CAPI_NAME,
 	       PyCObject_FromVoidPtr((void *)&PySocketModuleAPI, NULL)
 				 ) != 0)
-		return;
+		return NULL;
 
 	/* Address families (we only support AF_INET and AF_UNIX) */
 #ifdef AF_UNSPEC
@@ -4999,6 +5009,7 @@
 #if defined(USE_GETHOSTBYNAME_LOCK) || defined(USE_GETADDRINFO_LOCK)
 	netdb_lock = PyThread_allocate_lock();
 #endif
+	return m;
 }
 
 

Modified: python/branches/py3k/Modules/spwdmodule.c
==============================================================================
--- python/branches/py3k/Modules/spwdmodule.c	(original)
+++ python/branches/py3k/Modules/spwdmodule.c	Wed Jun 11 07:26:20 2008
@@ -167,17 +167,31 @@
 };
 
 
+
+static struct PyModuleDef spwdmodule = {
+	PyModuleDef_HEAD_INIT,
+	"spwd",
+	spwd__doc__,
+	-1,
+	spwd_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-initspwd(void)
+PyInit_spwd(void)
 {
 	PyObject *m;
-	m=Py_InitModule3("spwd", spwd_methods, spwd__doc__);
+	m=PyModule_Create(&spwdmodule);
 	if (m == NULL)
-		return;
+		return NULL;
 	if (!initialized)
 		PyStructSequence_InitType(&StructSpwdType, 
 					  &struct_spwd_type_desc);
 	Py_INCREF((PyObject *) &StructSpwdType);
 	PyModule_AddObject(m, "struct_spwd", (PyObject *) &StructSpwdType);
 	initialized = 1;
+	return m;
 }

Modified: python/branches/py3k/Modules/symtablemodule.c
==============================================================================
--- python/branches/py3k/Modules/symtablemodule.c	(original)
+++ python/branches/py3k/Modules/symtablemodule.c	Wed Jun 11 07:26:20 2008
@@ -47,14 +47,26 @@
 	{NULL,		NULL}		/* sentinel */
 };
 
+static struct PyModuleDef symtablemodule = {
+	PyModuleDef_HEAD_INIT,
+	"_symtable",
+	NULL,
+	-1,
+	symtable_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_symtable(void)
+PyInit__symtable(void)
 {
 	PyObject *m;
 
-	m = Py_InitModule("_symtable", symtable_methods);
+	m = PyModule_Create(&symtablemodule);
 	if (m == NULL)
-		return;
+		return NULL;
 	PyModule_AddIntConstant(m, "USE", USE);
 	PyModule_AddIntConstant(m, "DEF_GLOBAL", DEF_GLOBAL);
 	PyModule_AddIntConstant(m, "DEF_LOCAL", DEF_LOCAL);
@@ -80,4 +92,9 @@
 	PyModule_AddIntConstant(m, "GLOBAL_IMPLICIT", GLOBAL_IMPLICIT);
 	PyModule_AddIntConstant(m, "FREE", FREE);
 	PyModule_AddIntConstant(m, "CELL", CELL);
+	if (PyErr_Occurred()) {
+		Py_DECREF(m);
+		m = 0;
+	}
+	return m;
 }

Modified: python/branches/py3k/Modules/syslogmodule.c
==============================================================================
--- python/branches/py3k/Modules/syslogmodule.c	(original)
+++ python/branches/py3k/Modules/syslogmodule.c	Wed Jun 11 07:26:20 2008
@@ -163,15 +163,28 @@
 
 /* Initialization function for the module */
 
+
+static struct PyModuleDef syslogmodule = {
+	PyModuleDef_HEAD_INIT,
+	"syslog",
+	NULL,
+	-1,
+	syslog_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-initsyslog(void)
+PyInit_syslog(void)
 {
 	PyObject *m;
 
 	/* Create the module and add the functions */
-	m = Py_InitModule("syslog", syslog_methods);
+	m = PyModule_Create(&syslogmodule);
 	if (m == NULL)
-		return;
+		return NULL;
 
 	/* Add some symbolic constants to the module */
 
@@ -229,4 +242,5 @@
 	PyModule_AddIntConstant(m, "LOG_CRON",	  LOG_CRON);
 	PyModule_AddIntConstant(m, "LOG_UUCP",	  LOG_UUCP);
 	PyModule_AddIntConstant(m, "LOG_NEWS",	  LOG_NEWS);
+	return m;
 }

Modified: python/branches/py3k/Modules/termios.c
==============================================================================
--- python/branches/py3k/Modules/termios.c	(original)
+++ python/branches/py3k/Modules/termios.c	Wed Jun 11 07:26:20 2008
@@ -2,8 +2,6 @@
 
 #include "Python.h"
 
-#define PyInit_termios inittermios
-
 /* Apparently, on SGI, termios.h won't define CTRL if _XOPEN_SOURCE
    is defined, so we define it here. */
 #if defined(__sgi)
@@ -902,16 +900,27 @@
 };
 
 
+static struct PyModuleDef termiosmodule = {
+	PyModuleDef_HEAD_INIT,
+	"termios",
+	termios__doc__,
+	-1,
+	termios_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
 PyInit_termios(void)
 {
 	PyObject *m;
 	struct constant *constant = termios_constants;
 
-	m = Py_InitModule4("termios", termios_methods, termios__doc__,
-                           (PyObject *)NULL, PYTHON_API_VERSION);
+	m = PyModule_Create(&termiosmodule);
 	if (m == NULL)
-		return;
+		return NULL;
 
 	if (TermiosError == NULL) {
 		TermiosError = PyErr_NewException("termios.error", NULL, NULL);
@@ -923,4 +932,5 @@
 		PyModule_AddIntConstant(m, constant->name, constant->value);
 		++constant;
 	}
+	return m;
 }

Modified: python/branches/py3k/Modules/timemodule.c
==============================================================================
--- python/branches/py3k/Modules/timemodule.c	(original)
+++ python/branches/py3k/Modules/timemodule.c	Wed Jun 11 07:26:20 2008
@@ -661,7 +661,7 @@
 #endif /* HAVE_MKTIME */
 
 #ifdef HAVE_WORKING_TZSET
-static void inittimezone(PyObject *module);
+static void PyInit_timezone(PyObject *module);
 
 static PyObject *
 time_tzset(PyObject *self, PyObject *unused)
@@ -676,7 +676,7 @@
 	tzset();
 
 	/* Reset timezone, altzone, daylight and tzname */
-	inittimezone(m);
+	PyInit_timezone(m);
 	Py_DECREF(m);
 
 	Py_INCREF(Py_None);
@@ -698,8 +698,8 @@
 #endif /* HAVE_WORKING_TZSET */
 
 static void
-inittimezone(PyObject *m) {
-    /* This code moved from inittime wholesale to allow calling it from
+PyInit_timezone(PyObject *m) {
+    /* This code moved from PyInit_time wholesale to allow calling it from
 	time_tzset. In the future, some parts of it can be moved back
 	(for platforms that don't HAVE_WORKING_TZSET, when we know what they
 	are), and the extraneous calls to tzset(3) should be removed.
@@ -858,14 +858,27 @@
 tzset() -- change the local timezone");
 
 
+
+static struct PyModuleDef timemodule = {
+	PyModuleDef_HEAD_INIT,
+	"time",
+	module_doc,
+	-1,
+	time_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-inittime(void)
+PyInit_time(void)
 {
 	PyObject *m;
 	char *p;
-	m = Py_InitModule3("time", time_methods, module_doc);
+	m = PyModule_Create(&timemodule);
 	if (m == NULL)
-		return;
+		return NULL;
 
 	/* Accept 2-digit dates unless PYTHONY2K is set and non-empty */
 	p = Py_GETENV("PYTHONY2K");
@@ -875,7 +888,7 @@
 	Py_INCREF(moddict);
 
 	/* Set, or reset, module variables like time.timezone */
-	inittimezone(m);
+	PyInit_timezone(m);
 
 #ifdef MS_WINDOWS
 	/* Helper to allow interrupts for Windows.
@@ -893,6 +906,7 @@
 	Py_INCREF(&StructTimeType);
 	PyModule_AddObject(m, "struct_time", (PyObject*) &StructTimeType);
 	initialized = 1;
+	return m;
 }
 
 

Modified: python/branches/py3k/Modules/unicodedata.c
==============================================================================
--- python/branches/py3k/Modules/unicodedata.c	(original)
+++ python/branches/py3k/Modules/unicodedata.c	Wed Jun 11 07:26:20 2008
@@ -71,6 +71,7 @@
 
 /* forward declaration */
 static PyTypeObject UCD_Type;
+#define UCD_Check(o) (Py_TYPE(o)==&UCD_Type)
 
 static PyObject*
 new_previous_version(const char*name, const change_record* (*getrecord)(Py_UCS4),
@@ -128,7 +129,7 @@
     if (c == (Py_UCS4)-1)
         return NULL;
 
-    if (self) {
+    if (self && UCD_Check(self)) {
         const change_record *old = get_old_record(self, c);
         if (old->category_changed == 0) {
             /* unassigned */
@@ -213,7 +214,7 @@
     if (c == (Py_UCS4)-1)
         return NULL;
 
-    if (self) {
+    if (self && UCD_Check(self)) {
         const change_record *old = get_old_record(self, c);
         if (old->category_changed == 0) {
             /* unassigned */
@@ -261,7 +262,7 @@
     if (c == (Py_UCS4)-1)
         return NULL;
     index = (int) _getrecord_ex(c)->category;
-    if (self) {
+    if (self && UCD_Check(self)) {
         const change_record *old = get_old_record(self, c);
         if (old->category_changed != 0xFF)
             index = old->category_changed;
@@ -290,7 +291,7 @@
     if (c == (Py_UCS4)-1)
         return NULL;
     index = (int) _getrecord_ex(c)->bidirectional;
-    if (self) {
+    if (self && UCD_Check(self)) {
         const change_record *old = get_old_record(self, c);
         if (old->category_changed == 0)
             index = 0; /* unassigned */
@@ -321,7 +322,7 @@
     if (c == (Py_UCS4)-1)
         return NULL;
     index = (int) _getrecord_ex(c)->combining;
-    if (self) {
+    if (self && UCD_Check(self)) {
         const change_record *old = get_old_record(self, c);
         if (old->category_changed == 0)
             index = 0; /* unassigned */
@@ -350,7 +351,7 @@
     if (c == (Py_UCS4)-1)
         return NULL;
     index = (int) _getrecord_ex(c)->mirrored;
-    if (self) {
+    if (self && UCD_Check(self)) {
         const change_record *old = get_old_record(self, c);
         if (old->category_changed == 0)
             index = 0; /* unassigned */
@@ -378,7 +379,7 @@
     if (c == (Py_UCS4)-1)
         return NULL;
     index = (int) _getrecord_ex(c)->east_asian_width;
-    if (self) {
+    if (self && UCD_Check(self)) {
         const change_record *old = get_old_record(self, c);
         if (old->category_changed == 0)
             index = 0; /* unassigned */
@@ -411,7 +412,7 @@
 
     code = (int)c;
 
-    if (self) {
+    if (self && UCD_Check(self)) {
         const change_record *old = get_old_record(self, c);
         if (old->category_changed == 0)
             return PyUnicode_FromString(""); /* unassigned */
@@ -461,7 +462,8 @@
 {
     if (code >= 0x110000) {
         *index = 0;
-    } else if (self && get_old_record(self, code)->category_changed==0) {
+    } else if (self && UCD_Check(self) && 
+               get_old_record(self, code)->category_changed==0) {
         /* unassigned in old version */
         *index = 0;
     }
@@ -540,7 +542,7 @@
                 continue;
             }
             /* normalization changes */
-            if (self) {
+            if (self && UCD_Check(self)) {
                 Py_UCS4 value = ((PreviousDBVersion*)self)->normalization(code);
                 if (value != 0) {
                     stack[stackptr++] = value;
@@ -828,7 +830,7 @@
     if (code >= 0x110000)
         return 0;
 
-    if (self) {
+    if (self && UCD_Check(self)) {
         const change_record *old = get_old_record(self, code);
         if (old->category_changed == 0) {
             /* unassigned */
@@ -1183,17 +1185,29 @@
 UnicodeData File Format 4.1.0 (see\n\
 http://www.unicode.org/Public/4.1.0/ucd/UCD.html).");
 
+
+static struct PyModuleDef unicodedatamodule = {
+	PyModuleDef_HEAD_INIT,
+	"unicodedata",
+	unicodedata_docstring,
+	-1,
+	unicodedata_functions,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-initunicodedata(void)
+PyInit_unicodedata(void)
 {
     PyObject *m, *v;
 
     Py_TYPE(&UCD_Type) = &PyType_Type;
 
-    m = Py_InitModule3(
-        "unicodedata", unicodedata_functions, unicodedata_docstring);
+    m = PyModule_Create(&unicodedatamodule);
     if (!m)
-        return;
+        return NULL;
 
     PyModule_AddStringConstant(m, "unidata_version", UNIDATA_VERSION);
     Py_INCREF(&UCD_Type);
@@ -1208,6 +1222,7 @@
     v = PyCObject_FromVoidPtr((void *) &hashAPI, NULL);
     if (v != NULL)
         PyModule_AddObject(m, "ucnhash_CAPI", v);
+    return m;
 }
 
 /* 

Modified: python/branches/py3k/Modules/xxmodule.c
==============================================================================
--- python/branches/py3k/Modules/xxmodule.c	(original)
+++ python/branches/py3k/Modules/xxmodule.c	Wed Jun 11 07:26:20 2008
@@ -246,7 +246,7 @@
 	0,			/*tp_methods*/
 	0,			/*tp_members*/
 	0,			/*tp_getset*/
-	0, /* see initxx */	/*tp_base*/
+	0, /* see PyInit_xx */	/*tp_base*/
 	0,			/*tp_dict*/
 	0,			/*tp_descr_get*/
 	0,			/*tp_descr_set*/
@@ -301,14 +301,14 @@
 	0,			/*tp_methods*/
 	0,			/*tp_members*/
 	0,			/*tp_getset*/
-	0, /* see initxx */	/*tp_base*/
+	0, /* see PyInit_xx */	/*tp_base*/
 	0,			/*tp_dict*/
 	0,			/*tp_descr_get*/
 	0,			/*tp_descr_set*/
 	0,			/*tp_dictoffset*/
 	0,			/*tp_init*/
 	0,			/*tp_alloc*/
-	0, /* see initxx */	/*tp_new*/
+	0, /* see PyInit_xx */	/*tp_new*/
 	0,			/*tp_free*/
 	0,			/*tp_is_gc*/
 };
@@ -334,12 +334,25 @@
 PyDoc_STRVAR(module_doc,
 "This is a template module just for instruction.");
 
-/* Initialization function for the module (*must* be called initxx) */
+/* Initialization function for the module (*must* be called PyInit_xx) */
+
+
+static struct PyModuleDef xxmodule = {
+	PyModuleDef_HEAD_INIT,
+	"xx",
+	module_doc,
+	-1,
+	xx_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
 
 PyMODINIT_FUNC
-initxx(void)
+PyInit_xx(void)
 {
-	PyObject *m;
+	PyObject *m = NULL;
 
 	/* Due to cross platform compiler issues the slots must be filled
 	 * here. It's required for portability to Windows without requiring
@@ -351,29 +364,33 @@
 	/* Finalize the type object including setting type of the new type
 	 * object; doing it here is required for portability, too. */
 	if (PyType_Ready(&Xxo_Type) < 0)
-		return;
+		goto fail;
 
 	/* Create the module and add the functions */
-	m = Py_InitModule3("xx", xx_methods, module_doc);
+	m = PyModule_Create(&xxmodule);
 	if (m == NULL)
-		return;
+		goto fail;
 
 	/* Add some symbolic constants to the module */
 	if (ErrorObject == NULL) {
 		ErrorObject = PyErr_NewException("xx.error", NULL, NULL);
 		if (ErrorObject == NULL)
-			return;
+			goto fail;
 	}
 	Py_INCREF(ErrorObject);
 	PyModule_AddObject(m, "error", ErrorObject);
 
 	/* Add Str */
 	if (PyType_Ready(&Str_Type) < 0)
-		return;
+		goto fail;
 	PyModule_AddObject(m, "Str", (PyObject *)&Str_Type);
 
 	/* Add Null */
 	if (PyType_Ready(&Null_Type) < 0)
-		return;
+		goto fail;
 	PyModule_AddObject(m, "Null", (PyObject *)&Null_Type);
+	return m;
+ fail:
+	Py_XDECREF(m);
+	return NULL;
 }

Modified: python/branches/py3k/Modules/xxsubtype.c
==============================================================================
--- python/branches/py3k/Modules/xxsubtype.c	(original)
+++ python/branches/py3k/Modules/xxsubtype.c	Wed Jun 11 07:26:20 2008
@@ -257,8 +257,21 @@
 	{NULL,		NULL}		/* sentinel */
 };
 
+static struct PyModuleDef xxsubtypemodule = {
+	PyModuleDef_HEAD_INIT,
+	"xxsubtype",
+	xxsubtype__doc__,
+	-1,
+	xxsubtype_functions,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
+
 PyMODINIT_FUNC
-initxxsubtype(void)
+PyInit_xxsubtype(void)
 {
 	PyObject *m;
 
@@ -268,30 +281,29 @@
 	   so it's not necessary to fill in ob_type first. */
 	spamdict_type.tp_base = &PyDict_Type;
 	if (PyType_Ready(&spamdict_type) < 0)
-		return;
+		return NULL;
 
 	spamlist_type.tp_base = &PyList_Type;
 	if (PyType_Ready(&spamlist_type) < 0)
-		return;
+		return NULL;
 
-	m = Py_InitModule3("xxsubtype",
-			   xxsubtype_functions,
-			   xxsubtype__doc__);
+	m = PyModule_Create(&xxsubtypemodule);
 	if (m == NULL)
-		return;
+		return NULL;
 
 	if (PyType_Ready(&spamlist_type) < 0)
-		return;
+		return NULL;
 	if (PyType_Ready(&spamdict_type) < 0)
-		return;
+		return NULL;
 
 	Py_INCREF(&spamlist_type);
 	if (PyModule_AddObject(m, "spamlist",
 			       (PyObject *) &spamlist_type) < 0)
-		return;
+		return NULL;
 
 	Py_INCREF(&spamdict_type);
 	if (PyModule_AddObject(m, "spamdict",
 			       (PyObject *) &spamdict_type) < 0)
-		return;
+		return NULL;
+	return m;
 }

Modified: python/branches/py3k/Modules/zipimport.c
==============================================================================
--- python/branches/py3k/Modules/zipimport.c	(original)
+++ python/branches/py3k/Modules/zipimport.c	Wed Jun 11 07:26:20 2008
@@ -1145,13 +1145,25 @@
 used by the builtin import mechanism for sys.path items that are paths\n\
 to Zip archives.");
 
+static struct PyModuleDef zipimportmodule = {
+	PyModuleDef_HEAD_INIT,
+	"zipimport",
+	zipimport_doc,
+	-1,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-initzipimport(void)
+PyInit_zipimport(void)
 {
 	PyObject *mod;
 
 	if (PyType_Ready(&ZipImporter_Type) < 0)
-		return;
+		return NULL;
 
 	/* Correct directory separator */
 	zip_searchorder[0].suffix[0] = SEP;
@@ -1168,31 +1180,31 @@
 		zip_searchorder[4] = tmp;
 	}
 
-	mod = Py_InitModule4("zipimport", NULL, zipimport_doc,
-			     NULL, PYTHON_API_VERSION);
+	mod = PyModule_Create(&zipimportmodule);
 	if (mod == NULL)
-		return;
+		return NULL;
 
 	ZipImportError = PyErr_NewException("zipimport.ZipImportError",
 					    PyExc_ImportError, NULL);
 	if (ZipImportError == NULL)
-		return;
+		return NULL;
 
 	Py_INCREF(ZipImportError);
 	if (PyModule_AddObject(mod, "ZipImportError",
 			       ZipImportError) < 0)
-		return;
+		return NULL;
 
 	Py_INCREF(&ZipImporter_Type);
 	if (PyModule_AddObject(mod, "zipimporter",
 			       (PyObject *)&ZipImporter_Type) < 0)
-		return;
+		return NULL;
 
 	zip_directory_cache = PyDict_New();
 	if (zip_directory_cache == NULL)
-		return;
+		return NULL;
 	Py_INCREF(zip_directory_cache);
 	if (PyModule_AddObject(mod, "_zip_directory_cache",
 			       zip_directory_cache) < 0)
-		return;
+		return NULL;
+	return mod;
 }

Modified: python/branches/py3k/Modules/zlibmodule.c
==============================================================================
--- python/branches/py3k/Modules/zlibmodule.c	(original)
+++ python/branches/py3k/Modules/zlibmodule.c	Wed Jun 11 07:26:20 2008
@@ -53,7 +53,6 @@
 
 /* The output buffer will be increased in chunks of DEFAULTALLOC bytes. */
 #define DEFAULTALLOC (16*1024)
-#define PyInit_zlib initzlib
 
 static PyTypeObject Comptype;
 static PyTypeObject Decomptype;
@@ -1013,17 +1012,27 @@
 "Compressor objects support compress() and flush() methods; decompressor\n"
 "objects support decompress() and flush().");
 
+static struct PyModuleDef zlibmodule = {
+	PyModuleDef_HEAD_INIT,
+	"zlib",
+	zlib_module_documentation,
+	-1,
+	zlib_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
 PyInit_zlib(void)
 {
     PyObject *m, *ver;
     Py_TYPE(&Comptype) = &PyType_Type;
     Py_TYPE(&Decomptype) = &PyType_Type;
-    m = Py_InitModule4("zlib", zlib_methods,
-		       zlib_module_documentation,
-		       (PyObject*)NULL,PYTHON_API_VERSION);
+    m = PyModule_Create(&zlibmodule);
     if (m == NULL)
-	return;
+	return NULL;
 
     ZlibError = PyErr_NewException("zlib.error", NULL, NULL);
     if (ZlibError != NULL) {
@@ -1054,4 +1063,5 @@
 #ifdef WITH_THREAD
     zlib_lock = PyThread_allocate_lock();
 #endif /* WITH_THREAD */
+    return m;
 }

Modified: python/branches/py3k/Objects/exceptions.c
==============================================================================
--- python/branches/py3k/Objects/exceptions.c	(original)
+++ python/branches/py3k/Objects/exceptions.c	Wed Jun 11 07:26:20 2008
@@ -1799,7 +1799,7 @@
 #endif
 
 
-PyMODINIT_FUNC
+void
 _PyExc_Init(void)
 {
     PyObject *bltinmod, *bdict;

Modified: python/branches/py3k/Objects/methodobject.c
==============================================================================
--- python/branches/py3k/Objects/methodobject.c	(original)
+++ python/branches/py3k/Objects/methodobject.c	Wed Jun 11 07:26:20 2008
@@ -188,7 +188,7 @@
 static PyObject *
 meth_repr(PyCFunctionObject *m)
 {
-	if (m->m_self == NULL)
+	if (m->m_self == NULL || PyModule_Check(m->m_self))
 		return PyUnicode_FromFormat("<built-in function %s>",
 					   m->m_ml->ml_name);
 	return PyUnicode_FromFormat("<built-in method %s of %s object at %p>",

Modified: python/branches/py3k/Objects/moduleobject.c
==============================================================================
--- python/branches/py3k/Objects/moduleobject.c	(original)
+++ python/branches/py3k/Objects/moduleobject.c	Wed Jun 11 07:26:20 2008
@@ -4,9 +4,13 @@
 #include "Python.h"
 #include "structmember.h"
 
+static Py_ssize_t max_module_number;
+
 typedef struct {
 	PyObject_HEAD
 	PyObject *md_dict;
+	struct PyModuleDef *md_def;
+	void *md_state;
 } PyModuleObject;
 
 static PyMemberDef module_members[] = {
@@ -14,6 +18,14 @@
 	{0}
 };
 
+static PyTypeObject moduledef_type = {
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
+	"moduledef",				/* tp_name */
+	sizeof(struct PyModuleDef),		/* tp_size */
+	0,					/* tp_itemsize */
+};
+
+
 PyObject *
 PyModule_New(const char *name)
 {
@@ -22,6 +34,8 @@
 	m = PyObject_GC_New(PyModuleObject, &PyModule_Type);
 	if (m == NULL)
 		return NULL;
+	m->md_def = NULL;
+	m->md_state = NULL;
 	nameobj = PyUnicode_FromString(name);
 	m->md_dict = PyDict_New();
 	if (m->md_dict == NULL || nameobj == NULL)
@@ -42,6 +56,106 @@
 	return NULL;
 }
 
+static char api_version_warning[] =
+"Python C API version mismatch for module %.100s:\
+ This Python has API version %d, module %.100s has version %d.";
+
+PyObject *
+PyModule_Create2(struct PyModuleDef* module, int module_api_version)
+{
+	PyObject *d, *v, *n;
+	PyMethodDef *ml;
+	const char* name;
+	PyModuleObject *m;
+	if (!Py_IsInitialized())
+	    Py_FatalError("Interpreter not initialized (version mismatch?)");
+	if (PyType_Ready(&moduledef_type) < 0)
+		return NULL;
+	if (module->m_base.m_index == 0) {
+		max_module_number++;
+		Py_REFCNT(module) = 1;
+		Py_TYPE(module) = &moduledef_type;
+		module->m_base.m_index = max_module_number;
+	}
+	name = module->m_name;
+	if (module_api_version != PYTHON_API_VERSION) {
+		char message[512];
+		PyOS_snprintf(message, sizeof(message), 
+			      api_version_warning, name, 
+			      PYTHON_API_VERSION, name, 
+			      module_api_version);
+		if (PyErr_WarnEx(PyExc_RuntimeWarning, message, 1)) 
+			return NULL;
+	}
+	/* Make sure name is fully qualified.
+
+	   This is a bit of a hack: when the shared library is loaded,
+	   the module name is "package.module", but the module calls
+	   Py_InitModule*() with just "module" for the name.  The shared
+	   library loader squirrels away the true name of the module in
+	   _Py_PackageContext, and Py_InitModule*() will substitute this
+	   (if the name actually matches).
+	*/
+	if (_Py_PackageContext != NULL) {
+		char *p = strrchr(_Py_PackageContext, '.');
+		if (p != NULL && strcmp(module->m_name, p+1) == 0) {
+			name = _Py_PackageContext;
+			_Py_PackageContext = NULL;
+		}
+	}
+	if ((m = (PyModuleObject*)PyModule_New(name)) == NULL)
+		return NULL;
+
+	if (module->m_size > 0) {
+		m->md_state = PyMem_MALLOC(module->m_size);
+		if (!m->md_state) {
+			PyErr_NoMemory();
+			Py_DECREF(m);
+			return NULL;
+		}
+	}
+			
+	d = PyModule_GetDict((PyObject*)m);
+	if (module->m_methods != NULL) {
+		n = PyUnicode_FromString(name);
+		if (n == NULL)
+			return NULL;
+		for (ml = module->m_methods; ml->ml_name != NULL; ml++) {
+			if ((ml->ml_flags & METH_CLASS) ||
+			    (ml->ml_flags & METH_STATIC)) {
+				PyErr_SetString(PyExc_ValueError,
+						"module functions cannot set"
+						" METH_CLASS or METH_STATIC");
+				Py_DECREF(n);
+				return NULL;
+			}
+			v = PyCFunction_NewEx(ml, (PyObject*)m, n);
+			if (v == NULL) {
+				Py_DECREF(n);
+				return NULL;
+			}
+			if (PyDict_SetItemString(d, ml->ml_name, v) != 0) {
+				Py_DECREF(v);
+				Py_DECREF(n);
+				return NULL;
+			}
+			Py_DECREF(v);
+		}
+		Py_DECREF(n);
+	}
+	if (module->m_doc != NULL) {
+		v = PyUnicode_FromString(module->m_doc);
+		if (v == NULL || PyDict_SetItemString(d, "__doc__", v) != 0) {
+			Py_XDECREF(v);
+			return NULL;
+		}
+		Py_DECREF(v);
+	}
+	m->md_def = module;
+	return (PyObject*)m;
+}
+
+
 PyObject *
 PyModule_GetDict(PyObject *m)
 {
@@ -96,6 +210,26 @@
 	return PyUnicode_AsString(fileobj);
 }
 
+PyModuleDef*
+PyModule_GetDef(PyObject* m)
+{
+	if (!PyModule_Check(m)) {
+		PyErr_BadArgument();
+		return NULL;
+	}
+	return ((PyModuleObject *)m)->md_def;
+}
+
+void*
+PyModule_GetState(PyObject* m)
+{
+	if (!PyModule_Check(m)) {
+		PyErr_BadArgument();
+		return NULL;
+	}
+	return ((PyModuleObject *)m)->md_state;
+}
+
 void
 _PyModule_Clear(PyObject *m)
 {
@@ -174,6 +308,8 @@
 module_dealloc(PyModuleObject *m)
 {
 	PyObject_GC_UnTrack(m);
+	if (m->md_def && m->md_def->m_free)
+		m->md_def->m_free(m);
 	if (m->md_dict != NULL) {
 		_PyModule_Clear((PyObject *)m);
 		Py_DECREF(m->md_dict);
@@ -200,16 +336,31 @@
 	return PyUnicode_FromFormat("<module '%s' from '%s'>", name, filename);
 }
 
-/* We only need a traverse function, no clear function: If the module
-   is in a cycle, md_dict will be cleared as well, which will break
-   the cycle. */
 static int
 module_traverse(PyModuleObject *m, visitproc visit, void *arg)
 {
+	if (m->md_def && m->md_def->m_traverse) {
+		int res = m->md_def->m_traverse((PyObject*)m, visit, arg);
+		if (res)
+			return res;
+	}
 	Py_VISIT(m->md_dict);
 	return 0;
 }
 
+static int
+module_clear(PyModuleObject *m)
+{
+	if (m->md_def && m->md_def->m_clear) {
+		int res = m->md_def->m_clear((PyObject*)m);
+		if (res)
+			return res;
+	}
+	Py_CLEAR(m->md_dict);
+	return 0;
+}
+	
+
 PyDoc_STRVAR(module_doc,
 "module(name[, doc])\n\
 \n\
@@ -240,7 +391,7 @@
 		Py_TPFLAGS_BASETYPE,		/* tp_flags */
 	module_doc,				/* tp_doc */
 	(traverseproc)module_traverse,		/* tp_traverse */
-	0,					/* tp_clear */
+	(inquiry)module_clear,			/* tp_clear */
 	0,					/* tp_richcompare */
 	0,					/* tp_weaklistoffset */
 	0,					/* tp_iter */

Modified: python/branches/py3k/PC/_msi.c
==============================================================================
--- python/branches/py3k/PC/_msi.c	(original)
+++ python/branches/py3k/PC/_msi.c	Wed Jun 11 07:26:20 2008
@@ -997,14 +997,27 @@
 
 static char msi_doc[] = "Documentation";
 
+
+static struct PyModuleDef _msimodule = {
+	PyModuleDef_HEAD_INIT,
+	"_msi",
+	msi_doc,
+	-1,
+	msi_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_msi(void)
+PyInit__msi(void)
 {
     PyObject *m;
 
-    m = Py_InitModule3("_msi", msi_methods, msi_doc);
+    m = PyModule_Create(&_msimodule);
     if (m == NULL)
-	return;
+	return NULL;
 
     PyModule_AddIntConstant(m, "MSIDBOPEN_CREATEDIRECT", (int)MSIDBOPEN_CREATEDIRECT);
     PyModule_AddIntConstant(m, "MSIDBOPEN_CREATE", (int)MSIDBOPEN_CREATE);
@@ -1050,6 +1063,7 @@
 
     MSIError = PyErr_NewException ("_msi.MSIError", NULL, NULL);
     if (!MSIError)
-	return;
+	return NULL;
     PyModule_AddObject(m, "MSIError", MSIError);
+    return NULL;
 }

Modified: python/branches/py3k/PC/_subprocess.c
==============================================================================
--- python/branches/py3k/PC/_subprocess.c	(original)
+++ python/branches/py3k/PC/_subprocess.c	Wed Jun 11 07:26:20 2008
@@ -541,12 +541,20 @@
 	}
 }
 
-#if PY_VERSION_HEX >= 0x02030000
+static struct PyModuleDef _subprocessmodule = {
+	PyModuleDef_HEAD_INIT,
+	"_subprocess",
+	NULL,
+	-1,
+	sp_functions,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-#else
-DL_EXPORT(void)
-#endif
-init_subprocess()
+PyInit__subprocess()
 {
 	PyObject *d;
 	PyObject *m;
@@ -555,9 +563,9 @@
 	Py_TYPE(&sp_handle_type) = &PyType_Type;
 	sp_handle_as_number.nb_int = (unaryfunc) sp_handle_as_int;
 
-	m = Py_InitModule("_subprocess", sp_functions);
+	m = PyModule_Create(&_subprocessmodule);
 	if (m == NULL)
-		return;
+		return NULL;
 	d = PyModule_GetDict(m);
 
 	/* constants */
@@ -571,4 +579,5 @@
 	defint(d, "INFINITE", INFINITE);
 	defint(d, "WAIT_OBJECT_0", WAIT_OBJECT_0);
 	defint(d, "CREATE_NEW_CONSOLE", CREATE_NEW_CONSOLE);
+	return m;
 }

Modified: python/branches/py3k/PC/msvcrtmodule.c
==============================================================================
--- python/branches/py3k/PC/msvcrtmodule.c	(original)
+++ python/branches/py3k/PC/msvcrtmodule.c	Wed Jun 11 07:26:20 2008
@@ -358,13 +358,26 @@
 	{NULL,			NULL}
 };
 
+
+static struct PyModuleDef msvcrtmodule = {
+	PyModuleDef_HEAD_INIT,
+	"msvcrt",
+	NULL,
+	-1,
+	msvcrt_functions,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-initmsvcrt(void)
+PyInit_msvcrt(void)
 {
 	PyObject *d;
-	PyObject *m = Py_InitModule("msvcrt", msvcrt_functions);
+	PyObject *m = PyModule_Create(&msvcrtmodule);
 	if (m == NULL)
-		return;
+		return NULL;
 	d = PyModule_GetDict(m);
 
 	/* constants for the locking() function's mode argument */
@@ -389,4 +402,5 @@
 	insertint(d, "CRTDBG_FILE_STDOUT", (int)_CRTDBG_FILE_STDOUT);
 	insertint(d, "CRTDBG_REPORT_FILE", (int)_CRTDBG_REPORT_FILE);
 #endif
+	return m;
 }

Modified: python/branches/py3k/PC/winreg.c
==============================================================================
--- python/branches/py3k/PC/winreg.c	(original)
+++ python/branches/py3k/PC/winreg.c	Wed Jun 11 07:26:20 2008
@@ -1565,23 +1565,36 @@
 
 #define ADD_KEY(val) inskey(d, #val, val)
 
-PyMODINIT_FUNC initwinreg(void)
+
+static struct PyModuleDef winregmodule = {
+	PyModuleDef_HEAD_INIT,
+	"winreg",
+	module_doc,
+	-1,
+	winreg_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
+PyMODINIT_FUNC PyInit_winreg(void)
 {
 	PyObject *m, *d;
-	m = Py_InitModule3("winreg", winreg_methods, module_doc);
+	m = PyModule_Create(&winregmodule);
 	if (m == NULL)
-		return;
+		return NULL;
 	d = PyModule_GetDict(m);
 	Py_TYPE(&PyHKEY_Type) = &PyType_Type;
 	PyHKEY_Type.tp_doc = PyHKEY_doc;
 	Py_INCREF(&PyHKEY_Type);
 	if (PyDict_SetItemString(d, "HKEYType",
 				 (PyObject *)&PyHKEY_Type) != 0)
-		return;
+		return NULL;
 	Py_INCREF(PyExc_WindowsError);
 	if (PyDict_SetItemString(d, "error",
 				 PyExc_WindowsError) != 0)
-		return;
+		return NULL;
 
 	/* Add the relevant constants */
 	ADD_KEY(HKEY_CLASSES_ROOT);
@@ -1640,6 +1653,7 @@
 	ADD_INT(REG_RESOURCE_LIST);
 	ADD_INT(REG_FULL_RESOURCE_DESCRIPTOR);
 	ADD_INT(REG_RESOURCE_REQUIREMENTS_LIST);
+	return m;
 }
 
 

Modified: python/branches/py3k/PC/winsound.c
==============================================================================
--- python/branches/py3k/PC/winsound.c	(original)
+++ python/branches/py3k/PC/winsound.c	Wed Jun 11 07:26:20 2008
@@ -163,15 +163,26 @@
 
 #define ADD_DEFINE(tok) add_define(dict,#tok,tok)
 
+
+static struct PyModuleDef winsoundmodule = {
+	PyModuleDef_HEAD_INIT,
+	"winsound",
+	sound_module_doc,
+	-1,
+	sound_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-initwinsound(void)
+PyInit_winsound(void)
 {
 	PyObject *dict;
-	PyObject *module = Py_InitModule3("winsound",
-					  sound_methods,
-					  sound_module_doc);
+	PyObject *module = PyModule_Create(&winsoundmodule);
 	if (module == NULL)
-		return;
+		return NULL;
 	dict = PyModule_GetDict(module);
 
 	ADD_DEFINE(SND_ASYNC);
@@ -190,4 +201,5 @@
 	ADD_DEFINE(MB_ICONEXCLAMATION);
 	ADD_DEFINE(MB_ICONHAND);
 	ADD_DEFINE(MB_ICONQUESTION);
+	return module;
 }

Modified: python/branches/py3k/Parser/asdl_c.py
==============================================================================
--- python/branches/py3k/Parser/asdl_c.py	(original)
+++ python/branches/py3k/Parser/asdl_c.py	Wed Jun 11 07:26:20 2008
@@ -858,23 +858,27 @@
 class ASTModuleVisitor(PickleVisitor):
 
     def visitModule(self, mod):
+        self.emit("static struct PyModuleDef _astmodule = {", 0)
+        self.emit('  PyModuleDef_HEAD_INIT, "_ast"', 0)
+        self.emit("};", 0)
         self.emit("PyMODINIT_FUNC", 0)
-        self.emit("init_ast(void)", 0)
+        self.emit("PyInit__ast(void)", 0)
         self.emit("{", 0)
         self.emit("PyObject *m, *d;", 1)
-        self.emit("if (!init_types()) return;", 1)
-        self.emit('m = Py_InitModule3("_ast", NULL, NULL);', 1)
-        self.emit("if (!m) return;", 1)
+        self.emit("if (!init_types()) return NULL;", 1)
+        self.emit('m = PyModule_Create(&_astmodule);', 1)
+        self.emit("if (!m) return NULL;", 1)
         self.emit("d = PyModule_GetDict(m);", 1)
-        self.emit('if (PyDict_SetItemString(d, "AST", (PyObject*)&AST_type) < 0) return;', 1)
+        self.emit('if (PyDict_SetItemString(d, "AST", (PyObject*)&AST_type) < 0) return NULL;', 1)
         self.emit('if (PyModule_AddIntConstant(m, "PyCF_ONLY_AST", PyCF_ONLY_AST) < 0)', 1)
-        self.emit("return;", 2)
+        self.emit("return NULL;", 2)
         # Value of version: "$Revision$"
         self.emit('if (PyModule_AddStringConstant(m, "__version__", "%s") < 0)'
                 % parse_version(mod), 1)
-        self.emit("return;", 2)
+        self.emit("return NULL;", 2)
         for dfn in mod.dfns:
             self.visit(dfn)
+        self.emit("return m;", 1)
         self.emit("}", 0)
 
     def visitProduct(self, prod, name):
@@ -889,7 +893,7 @@
         self.addObj(cons.name)
 
     def addObj(self, name):
-        self.emit('if (PyDict_SetItemString(d, "%s", (PyObject*)%s_type) < 0) return;' % (name, name), 1)
+        self.emit('if (PyDict_SetItemString(d, "%s", (PyObject*)%s_type) < 0) return NULL;' % (name, name), 1)
 
 
 _SPECIALIZED_SEQUENCES = ('stmt', 'expr')

Modified: python/branches/py3k/Python/Python-ast.c
==============================================================================
--- python/branches/py3k/Python/Python-ast.c	(original)
+++ python/branches/py3k/Python/Python-ast.c	Wed Jun 11 07:26:20 2008
@@ -6384,169 +6384,223 @@
 }
 
 
+static struct PyModuleDef _astmodule = {
+  PyModuleDef_HEAD_INIT, "_ast"
+};
 PyMODINIT_FUNC
-init_ast(void)
+PyInit__ast(void)
 {
         PyObject *m, *d;
-        if (!init_types()) return;
-        m = Py_InitModule3("_ast", NULL, NULL);
-        if (!m) return;
+        if (!init_types()) return NULL;
+        m = PyModule_Create(&_astmodule);
+        if (!m) return NULL;
         d = PyModule_GetDict(m);
-        if (PyDict_SetItemString(d, "AST", (PyObject*)&AST_type) < 0) return;
+        if (PyDict_SetItemString(d, "AST", (PyObject*)&AST_type) < 0) return
+            NULL;
         if (PyModule_AddIntConstant(m, "PyCF_ONLY_AST", PyCF_ONLY_AST) < 0)
-                return;
+                return NULL;
         if (PyModule_AddStringConstant(m, "__version__", "62078") < 0)
-                return;
-        if (PyDict_SetItemString(d, "mod", (PyObject*)mod_type) < 0) return;
+                return NULL;
+        if (PyDict_SetItemString(d, "mod", (PyObject*)mod_type) < 0) return
+            NULL;
         if (PyDict_SetItemString(d, "Module", (PyObject*)Module_type) < 0)
-            return;
+            return NULL;
         if (PyDict_SetItemString(d, "Interactive", (PyObject*)Interactive_type)
-            < 0) return;
+            < 0) return NULL;
         if (PyDict_SetItemString(d, "Expression", (PyObject*)Expression_type) <
-            0) return;
-        if (PyDict_SetItemString(d, "Suite", (PyObject*)Suite_type) < 0) return;
-        if (PyDict_SetItemString(d, "stmt", (PyObject*)stmt_type) < 0) return;
+            0) return NULL;
+        if (PyDict_SetItemString(d, "Suite", (PyObject*)Suite_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "stmt", (PyObject*)stmt_type) < 0) return
+            NULL;
         if (PyDict_SetItemString(d, "FunctionDef", (PyObject*)FunctionDef_type)
-            < 0) return;
+            < 0) return NULL;
         if (PyDict_SetItemString(d, "ClassDef", (PyObject*)ClassDef_type) < 0)
-            return;
+            return NULL;
         if (PyDict_SetItemString(d, "Return", (PyObject*)Return_type) < 0)
-            return;
+            return NULL;
         if (PyDict_SetItemString(d, "Delete", (PyObject*)Delete_type) < 0)
-            return;
+            return NULL;
         if (PyDict_SetItemString(d, "Assign", (PyObject*)Assign_type) < 0)
-            return;
+            return NULL;
         if (PyDict_SetItemString(d, "AugAssign", (PyObject*)AugAssign_type) <
-            0) return;
-        if (PyDict_SetItemString(d, "For", (PyObject*)For_type) < 0) return;
-        if (PyDict_SetItemString(d, "While", (PyObject*)While_type) < 0) return;
-        if (PyDict_SetItemString(d, "If", (PyObject*)If_type) < 0) return;
-        if (PyDict_SetItemString(d, "With", (PyObject*)With_type) < 0) return;
-        if (PyDict_SetItemString(d, "Raise", (PyObject*)Raise_type) < 0) return;
+            0) return NULL;
+        if (PyDict_SetItemString(d, "For", (PyObject*)For_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "While", (PyObject*)While_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "If", (PyObject*)If_type) < 0) return NULL;
+        if (PyDict_SetItemString(d, "With", (PyObject*)With_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "Raise", (PyObject*)Raise_type) < 0) return
+            NULL;
         if (PyDict_SetItemString(d, "TryExcept", (PyObject*)TryExcept_type) <
-            0) return;
+            0) return NULL;
         if (PyDict_SetItemString(d, "TryFinally", (PyObject*)TryFinally_type) <
-            0) return;
+            0) return NULL;
         if (PyDict_SetItemString(d, "Assert", (PyObject*)Assert_type) < 0)
-            return;
+            return NULL;
         if (PyDict_SetItemString(d, "Import", (PyObject*)Import_type) < 0)
-            return;
+            return NULL;
         if (PyDict_SetItemString(d, "ImportFrom", (PyObject*)ImportFrom_type) <
-            0) return;
+            0) return NULL;
         if (PyDict_SetItemString(d, "Global", (PyObject*)Global_type) < 0)
-            return;
+            return NULL;
         if (PyDict_SetItemString(d, "Nonlocal", (PyObject*)Nonlocal_type) < 0)
-            return;
-        if (PyDict_SetItemString(d, "Expr", (PyObject*)Expr_type) < 0) return;
-        if (PyDict_SetItemString(d, "Pass", (PyObject*)Pass_type) < 0) return;
-        if (PyDict_SetItemString(d, "Break", (PyObject*)Break_type) < 0) return;
+            return NULL;
+        if (PyDict_SetItemString(d, "Expr", (PyObject*)Expr_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "Pass", (PyObject*)Pass_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "Break", (PyObject*)Break_type) < 0) return
+            NULL;
         if (PyDict_SetItemString(d, "Continue", (PyObject*)Continue_type) < 0)
-            return;
-        if (PyDict_SetItemString(d, "expr", (PyObject*)expr_type) < 0) return;
+            return NULL;
+        if (PyDict_SetItemString(d, "expr", (PyObject*)expr_type) < 0) return
+            NULL;
         if (PyDict_SetItemString(d, "BoolOp", (PyObject*)BoolOp_type) < 0)
-            return;
-        if (PyDict_SetItemString(d, "BinOp", (PyObject*)BinOp_type) < 0) return;
+            return NULL;
+        if (PyDict_SetItemString(d, "BinOp", (PyObject*)BinOp_type) < 0) return
+            NULL;
         if (PyDict_SetItemString(d, "UnaryOp", (PyObject*)UnaryOp_type) < 0)
-            return;
+            return NULL;
         if (PyDict_SetItemString(d, "Lambda", (PyObject*)Lambda_type) < 0)
-            return;
-        if (PyDict_SetItemString(d, "IfExp", (PyObject*)IfExp_type) < 0) return;
-        if (PyDict_SetItemString(d, "Dict", (PyObject*)Dict_type) < 0) return;
-        if (PyDict_SetItemString(d, "Set", (PyObject*)Set_type) < 0) return;
+            return NULL;
+        if (PyDict_SetItemString(d, "IfExp", (PyObject*)IfExp_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "Dict", (PyObject*)Dict_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "Set", (PyObject*)Set_type) < 0) return
+            NULL;
         if (PyDict_SetItemString(d, "ListComp", (PyObject*)ListComp_type) < 0)
-            return;
+            return NULL;
         if (PyDict_SetItemString(d, "SetComp", (PyObject*)SetComp_type) < 0)
-            return;
+            return NULL;
         if (PyDict_SetItemString(d, "DictComp", (PyObject*)DictComp_type) < 0)
-            return;
+            return NULL;
         if (PyDict_SetItemString(d, "GeneratorExp",
-            (PyObject*)GeneratorExp_type) < 0) return;
-        if (PyDict_SetItemString(d, "Yield", (PyObject*)Yield_type) < 0) return;
+            (PyObject*)GeneratorExp_type) < 0) return NULL;
+        if (PyDict_SetItemString(d, "Yield", (PyObject*)Yield_type) < 0) return
+            NULL;
         if (PyDict_SetItemString(d, "Compare", (PyObject*)Compare_type) < 0)
-            return;
-        if (PyDict_SetItemString(d, "Call", (PyObject*)Call_type) < 0) return;
-        if (PyDict_SetItemString(d, "Num", (PyObject*)Num_type) < 0) return;
-        if (PyDict_SetItemString(d, "Str", (PyObject*)Str_type) < 0) return;
-        if (PyDict_SetItemString(d, "Bytes", (PyObject*)Bytes_type) < 0) return;
+            return NULL;
+        if (PyDict_SetItemString(d, "Call", (PyObject*)Call_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "Num", (PyObject*)Num_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "Str", (PyObject*)Str_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "Bytes", (PyObject*)Bytes_type) < 0) return
+            NULL;
         if (PyDict_SetItemString(d, "Ellipsis", (PyObject*)Ellipsis_type) < 0)
-            return;
+            return NULL;
         if (PyDict_SetItemString(d, "Attribute", (PyObject*)Attribute_type) <
-            0) return;
+            0) return NULL;
         if (PyDict_SetItemString(d, "Subscript", (PyObject*)Subscript_type) <
-            0) return;
+            0) return NULL;
         if (PyDict_SetItemString(d, "Starred", (PyObject*)Starred_type) < 0)
-            return;
-        if (PyDict_SetItemString(d, "Name", (PyObject*)Name_type) < 0) return;
-        if (PyDict_SetItemString(d, "List", (PyObject*)List_type) < 0) return;
-        if (PyDict_SetItemString(d, "Tuple", (PyObject*)Tuple_type) < 0) return;
+            return NULL;
+        if (PyDict_SetItemString(d, "Name", (PyObject*)Name_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "List", (PyObject*)List_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "Tuple", (PyObject*)Tuple_type) < 0) return
+            NULL;
         if (PyDict_SetItemString(d, "expr_context",
-            (PyObject*)expr_context_type) < 0) return;
-        if (PyDict_SetItemString(d, "Load", (PyObject*)Load_type) < 0) return;
-        if (PyDict_SetItemString(d, "Store", (PyObject*)Store_type) < 0) return;
-        if (PyDict_SetItemString(d, "Del", (PyObject*)Del_type) < 0) return;
+            (PyObject*)expr_context_type) < 0) return NULL;
+        if (PyDict_SetItemString(d, "Load", (PyObject*)Load_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "Store", (PyObject*)Store_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "Del", (PyObject*)Del_type) < 0) return
+            NULL;
         if (PyDict_SetItemString(d, "AugLoad", (PyObject*)AugLoad_type) < 0)
-            return;
+            return NULL;
         if (PyDict_SetItemString(d, "AugStore", (PyObject*)AugStore_type) < 0)
-            return;
-        if (PyDict_SetItemString(d, "Param", (PyObject*)Param_type) < 0) return;
-        if (PyDict_SetItemString(d, "slice", (PyObject*)slice_type) < 0) return;
-        if (PyDict_SetItemString(d, "Slice", (PyObject*)Slice_type) < 0) return;
+            return NULL;
+        if (PyDict_SetItemString(d, "Param", (PyObject*)Param_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "slice", (PyObject*)slice_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "Slice", (PyObject*)Slice_type) < 0) return
+            NULL;
         if (PyDict_SetItemString(d, "ExtSlice", (PyObject*)ExtSlice_type) < 0)
-            return;
-        if (PyDict_SetItemString(d, "Index", (PyObject*)Index_type) < 0) return;
+            return NULL;
+        if (PyDict_SetItemString(d, "Index", (PyObject*)Index_type) < 0) return
+            NULL;
         if (PyDict_SetItemString(d, "boolop", (PyObject*)boolop_type) < 0)
-            return;
-        if (PyDict_SetItemString(d, "And", (PyObject*)And_type) < 0) return;
-        if (PyDict_SetItemString(d, "Or", (PyObject*)Or_type) < 0) return;
+            return NULL;
+        if (PyDict_SetItemString(d, "And", (PyObject*)And_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "Or", (PyObject*)Or_type) < 0) return NULL;
         if (PyDict_SetItemString(d, "operator", (PyObject*)operator_type) < 0)
-            return;
-        if (PyDict_SetItemString(d, "Add", (PyObject*)Add_type) < 0) return;
-        if (PyDict_SetItemString(d, "Sub", (PyObject*)Sub_type) < 0) return;
-        if (PyDict_SetItemString(d, "Mult", (PyObject*)Mult_type) < 0) return;
-        if (PyDict_SetItemString(d, "Div", (PyObject*)Div_type) < 0) return;
-        if (PyDict_SetItemString(d, "Mod", (PyObject*)Mod_type) < 0) return;
-        if (PyDict_SetItemString(d, "Pow", (PyObject*)Pow_type) < 0) return;
+            return NULL;
+        if (PyDict_SetItemString(d, "Add", (PyObject*)Add_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "Sub", (PyObject*)Sub_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "Mult", (PyObject*)Mult_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "Div", (PyObject*)Div_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "Mod", (PyObject*)Mod_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "Pow", (PyObject*)Pow_type) < 0) return
+            NULL;
         if (PyDict_SetItemString(d, "LShift", (PyObject*)LShift_type) < 0)
-            return;
+            return NULL;
         if (PyDict_SetItemString(d, "RShift", (PyObject*)RShift_type) < 0)
-            return;
-        if (PyDict_SetItemString(d, "BitOr", (PyObject*)BitOr_type) < 0) return;
+            return NULL;
+        if (PyDict_SetItemString(d, "BitOr", (PyObject*)BitOr_type) < 0) return
+            NULL;
         if (PyDict_SetItemString(d, "BitXor", (PyObject*)BitXor_type) < 0)
-            return;
+            return NULL;
         if (PyDict_SetItemString(d, "BitAnd", (PyObject*)BitAnd_type) < 0)
-            return;
+            return NULL;
         if (PyDict_SetItemString(d, "FloorDiv", (PyObject*)FloorDiv_type) < 0)
-            return;
+            return NULL;
         if (PyDict_SetItemString(d, "unaryop", (PyObject*)unaryop_type) < 0)
-            return;
+            return NULL;
         if (PyDict_SetItemString(d, "Invert", (PyObject*)Invert_type) < 0)
-            return;
-        if (PyDict_SetItemString(d, "Not", (PyObject*)Not_type) < 0) return;
-        if (PyDict_SetItemString(d, "UAdd", (PyObject*)UAdd_type) < 0) return;
-        if (PyDict_SetItemString(d, "USub", (PyObject*)USub_type) < 0) return;
-        if (PyDict_SetItemString(d, "cmpop", (PyObject*)cmpop_type) < 0) return;
-        if (PyDict_SetItemString(d, "Eq", (PyObject*)Eq_type) < 0) return;
-        if (PyDict_SetItemString(d, "NotEq", (PyObject*)NotEq_type) < 0) return;
-        if (PyDict_SetItemString(d, "Lt", (PyObject*)Lt_type) < 0) return;
-        if (PyDict_SetItemString(d, "LtE", (PyObject*)LtE_type) < 0) return;
-        if (PyDict_SetItemString(d, "Gt", (PyObject*)Gt_type) < 0) return;
-        if (PyDict_SetItemString(d, "GtE", (PyObject*)GtE_type) < 0) return;
-        if (PyDict_SetItemString(d, "Is", (PyObject*)Is_type) < 0) return;
-        if (PyDict_SetItemString(d, "IsNot", (PyObject*)IsNot_type) < 0) return;
-        if (PyDict_SetItemString(d, "In", (PyObject*)In_type) < 0) return;
-        if (PyDict_SetItemString(d, "NotIn", (PyObject*)NotIn_type) < 0) return;
+            return NULL;
+        if (PyDict_SetItemString(d, "Not", (PyObject*)Not_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "UAdd", (PyObject*)UAdd_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "USub", (PyObject*)USub_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "cmpop", (PyObject*)cmpop_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "Eq", (PyObject*)Eq_type) < 0) return NULL;
+        if (PyDict_SetItemString(d, "NotEq", (PyObject*)NotEq_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "Lt", (PyObject*)Lt_type) < 0) return NULL;
+        if (PyDict_SetItemString(d, "LtE", (PyObject*)LtE_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "Gt", (PyObject*)Gt_type) < 0) return NULL;
+        if (PyDict_SetItemString(d, "GtE", (PyObject*)GtE_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "Is", (PyObject*)Is_type) < 0) return NULL;
+        if (PyDict_SetItemString(d, "IsNot", (PyObject*)IsNot_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "In", (PyObject*)In_type) < 0) return NULL;
+        if (PyDict_SetItemString(d, "NotIn", (PyObject*)NotIn_type) < 0) return
+            NULL;
         if (PyDict_SetItemString(d, "comprehension",
-            (PyObject*)comprehension_type) < 0) return;
+            (PyObject*)comprehension_type) < 0) return NULL;
         if (PyDict_SetItemString(d, "excepthandler",
-            (PyObject*)excepthandler_type) < 0) return;
+            (PyObject*)excepthandler_type) < 0) return NULL;
         if (PyDict_SetItemString(d, "ExceptHandler",
-            (PyObject*)ExceptHandler_type) < 0) return;
+            (PyObject*)ExceptHandler_type) < 0) return NULL;
         if (PyDict_SetItemString(d, "arguments", (PyObject*)arguments_type) <
-            0) return;
-        if (PyDict_SetItemString(d, "arg", (PyObject*)arg_type) < 0) return;
+            0) return NULL;
+        if (PyDict_SetItemString(d, "arg", (PyObject*)arg_type) < 0) return
+            NULL;
         if (PyDict_SetItemString(d, "keyword", (PyObject*)keyword_type) < 0)
-            return;
-        if (PyDict_SetItemString(d, "alias", (PyObject*)alias_type) < 0) return;
+            return NULL;
+        if (PyDict_SetItemString(d, "alias", (PyObject*)alias_type) < 0) return
+            NULL;
+        return m;
 }
 
 

Modified: python/branches/py3k/Python/_warnings.c
==============================================================================
--- python/branches/py3k/Python/_warnings.c	(original)
+++ python/branches/py3k/Python/_warnings.c	Wed Jun 11 07:26:20 2008
@@ -868,33 +868,46 @@
     return filters;
 }
 
+static struct PyModuleDef warningsmodule = {
+	PyModuleDef_HEAD_INIT,
+	MODULE_NAME,
+	warnings__doc__,
+	0,
+	warnings_functions,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 
 PyMODINIT_FUNC
 _PyWarnings_Init(void)
 {
     PyObject *m, *default_action;
 
-    m = Py_InitModule3(MODULE_NAME, warnings_functions, warnings__doc__);
+    m = PyModule_Create(&warningsmodule);
     if (m == NULL)
-        return;
+        return NULL;
 
     _filters = init_filters();
     if (_filters == NULL)
-        return;
+        return NULL;
     Py_INCREF(_filters);
     if (PyModule_AddObject(m, "filters", _filters) < 0)
-        return;
+        return NULL;
 
     _once_registry = PyDict_New();
     if (_once_registry == NULL)
-        return;
+        return NULL;
     Py_INCREF(_once_registry);
     if (PyModule_AddObject(m, "once_registry", _once_registry) < 0)
-        return;
+        return NULL;
 
     default_action = PyUnicode_InternFromString("default");
     if (default_action == NULL)
-        return;
+        return NULL;
     if (PyModule_AddObject(m, DEFAULT_ACTION_NAME, default_action) < 0)
-        return;
+        return NULL;
+    return m;
 }

Modified: python/branches/py3k/Python/bltinmodule.c
==============================================================================
--- python/branches/py3k/Python/bltinmodule.c	(original)
+++ python/branches/py3k/Python/bltinmodule.c	Wed Jun 11 07:26:20 2008
@@ -2231,13 +2231,24 @@
 \n\
 Noteworthy: None is the `nil' object; Ellipsis represents `...' in slices.");
 
+static struct PyModuleDef builtinsmodule = {
+	PyModuleDef_HEAD_INIT,
+	"builtins",
+	builtin_doc,
+	0,
+	builtin_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
+
 PyObject *
 _PyBuiltin_Init(void)
 {
 	PyObject *mod, *dict, *debug;
-	mod = Py_InitModule4("builtins", builtin_methods,
-			     builtin_doc, (PyObject *)NULL,
-			     PYTHON_API_VERSION);
+	mod = PyModule_Create(&builtinsmodule);
 	if (mod == NULL)
 		return NULL;
 	dict = PyModule_GetDict(mod);

Modified: python/branches/py3k/Python/dynload_atheos.c
==============================================================================
--- python/branches/py3k/Python/dynload_atheos.c	(original)
+++ python/branches/py3k/Python/dynload_atheos.c	Wed Jun 11 07:26:20 2008
@@ -34,7 +34,7 @@
 		PyErr_SetString(PyExc_ImportError, buf);
 		return NULL;
 	}
-	PyOS_snprintf(funcname, sizeof(funcname), "init%.200s", shortname);
+	PyOS_snprintf(funcname, sizeof(funcname), "PyInit_%.200s", shortname);
 	if (Py_VerboseFlag)
 		printf("get_symbol_address %s\n", funcname);
 	if (get_symbol_address(lib, funcname, -1, &p) < 0) {

Modified: python/branches/py3k/Python/dynload_dl.c
==============================================================================
--- python/branches/py3k/Python/dynload_dl.c	(original)
+++ python/branches/py3k/Python/dynload_dl.c	Wed Jun 11 07:26:20 2008
@@ -21,6 +21,6 @@
 {
 	char funcname[258];
 
-	PyOS_snprintf(funcname, sizeof(funcname), "init%.200s", shortname);
+	PyOS_snprintf(funcname, sizeof(funcname), "PyInit_%.200s", shortname);
 	return dl_loadmod(Py_GetProgramName(), pathname, funcname);
 }

Modified: python/branches/py3k/Python/dynload_hpux.c
==============================================================================
--- python/branches/py3k/Python/dynload_hpux.c	(original)
+++ python/branches/py3k/Python/dynload_hpux.c	Wed Jun 11 07:26:20 2008
@@ -8,9 +8,9 @@
 #include "importdl.h"
 
 #if defined(__hp9000s300)
-#define FUNCNAME_PATTERN "_init%.200s"
+#define FUNCNAME_PATTERN "_PyInit_%.200s"
 #else
-#define FUNCNAME_PATTERN "init%.200s"
+#define FUNCNAME_PATTERN "PyInit_%.200s"
 #endif
 
 const struct filedescr _PyImport_DynLoadFiletab[] = {

Modified: python/branches/py3k/Python/dynload_next.c
==============================================================================
--- python/branches/py3k/Python/dynload_next.c	(original)
+++ python/branches/py3k/Python/dynload_next.c	Wed Jun 11 07:26:20 2008
@@ -43,7 +43,7 @@
 	const char *errString;
 	char errBuf[512];
 
-	PyOS_snprintf(funcname, sizeof(funcname), "_init%.200s", shortname);
+	PyOS_snprintf(funcname, sizeof(funcname), "_PyInit_%.200s", shortname);
 
 #ifdef USE_DYLD_GLOBAL_NAMESPACE
 	if (NSIsSymbolNameDefined(funcname)) {

Modified: python/branches/py3k/Python/dynload_os2.c
==============================================================================
--- python/branches/py3k/Python/dynload_os2.c	(original)
+++ python/branches/py3k/Python/dynload_os2.c	Wed Jun 11 07:26:20 2008
@@ -38,7 +38,7 @@
 		return NULL;
 	}
 
-	PyOS_snprintf(funcname, sizeof(funcname), "init%.200s", shortname);
+	PyOS_snprintf(funcname, sizeof(funcname), "PyInit_%.200s", shortname);
 	rc = DosQueryProcAddr(hDLL, 0L, funcname, &p);
 	if (rc != NO_ERROR)
 		p = NULL; /* Signify Failure to Acquire Entrypoint */

Modified: python/branches/py3k/Python/dynload_shlib.c
==============================================================================
--- python/branches/py3k/Python/dynload_shlib.c	(original)
+++ python/branches/py3k/Python/dynload_shlib.c	Wed Jun 11 07:26:20 2008
@@ -82,7 +82,7 @@
 	}
 
 	PyOS_snprintf(funcname, sizeof(funcname), 
-		      LEAD_UNDERSCORE "init%.200s", shortname);
+		      LEAD_UNDERSCORE "PyInit_%.200s", shortname);
 
 	if (fp != NULL) {
 		int i;

Modified: python/branches/py3k/Python/dynload_win.c
==============================================================================
--- python/branches/py3k/Python/dynload_win.c	(original)
+++ python/branches/py3k/Python/dynload_win.c	Wed Jun 11 07:26:20 2008
@@ -165,7 +165,7 @@
 	dl_funcptr p;
 	char funcname[258], *import_python;
 
-	PyOS_snprintf(funcname, sizeof(funcname), "init%.200s", shortname);
+	PyOS_snprintf(funcname, sizeof(funcname), "PyInit_init%.200s", shortname);
 
 	{
 		HINSTANCE hDLL = NULL;

Modified: python/branches/py3k/Python/import.c
==============================================================================
--- python/branches/py3k/Python/import.c	(original)
+++ python/branches/py3k/Python/import.c	Wed Jun 11 07:26:20 2008
@@ -541,56 +541,101 @@
    dictionary is stored by calling _PyImport_FixupExtension()
    immediately after the module initialization function succeeds.  A
    copy can be retrieved from there by calling
-   _PyImport_FindExtension(). */
+   _PyImport_FindExtension(). 
 
-PyObject *
-_PyImport_FixupExtension(char *name, char *filename)
+   Modules which do support multiple multiple initialization set
+   their m_size field to a non-negative number (indicating the size
+   of the module-specific state). They are still recorded in the
+   extensions dictionary, to avoid loading shared libraries twice.
+*/
+
+int
+_PyImport_FixupExtension(PyObject *mod, char *name, char *filename)
 {
-	PyObject *modules, *mod, *dict, *copy;
+	PyObject *modules, *dict;
+	struct PyModuleDef *def;
 	if (extensions == NULL) {
 		extensions = PyDict_New();
 		if (extensions == NULL)
-			return NULL;
+			return -1;
 	}
-	modules = PyImport_GetModuleDict();
-	mod = PyDict_GetItemString(modules, name);
 	if (mod == NULL || !PyModule_Check(mod)) {
-		PyErr_Format(PyExc_SystemError,
-		  "_PyImport_FixupExtension: module %.200s not loaded", name);
-		return NULL;
+		PyErr_BadInternalCall();
+		return -1;
 	}
-	dict = PyModule_GetDict(mod);
-	if (dict == NULL)
-		return NULL;
-	copy = PyDict_Copy(dict);
-	if (copy == NULL)
-		return NULL;
-	PyDict_SetItemString(extensions, filename, copy);
-	Py_DECREF(copy);
-	return copy;
+	def = PyModule_GetDef(mod);
+	if (!def) {
+		PyErr_BadInternalCall();
+		return -1;
+	}
+	modules = PyImport_GetModuleDict();
+	if (PyDict_SetItemString(modules, name, mod) < 0)
+		return -1;
+	if (_PyState_AddModule(mod, def) < 0) {
+		PyDict_DelItemString(modules, name);
+		return -1;
+	}
+	if (def->m_size == -1) {
+		if (def->m_base.m_copy) {
+			/* Somebody already imported the module, 
+			   likely under a different name.
+			   XXX this should really not happen. */
+			Py_DECREF(def->m_base.m_copy);
+			def->m_base.m_copy = NULL;
+		}
+		dict = PyModule_GetDict(mod);
+		if (dict == NULL)
+			return -1;
+		def->m_base.m_copy = PyDict_Copy(dict);
+		if (def->m_base.m_copy == NULL)
+			return -1;
+	}
+	PyDict_SetItemString(extensions, filename, (PyObject*)def);
+	return 0;
 }
 
 PyObject *
 _PyImport_FindExtension(char *name, char *filename)
 {
-	PyObject *dict, *mod, *mdict;
+	PyObject *mod, *mdict;
+	PyModuleDef* def;
 	if (extensions == NULL)
 		return NULL;
-	dict = PyDict_GetItemString(extensions, filename);
-	if (dict == NULL)
-		return NULL;
-	mod = PyImport_AddModule(name);
-	if (mod == NULL)
+	def = (PyModuleDef*)PyDict_GetItemString(extensions, filename);
+	if (def == NULL)
 		return NULL;
-	mdict = PyModule_GetDict(mod);
-	if (mdict == NULL)
-		return NULL;
-	if (PyDict_Update(mdict, dict))
+	if (def->m_size == -1) {
+		/* Module does not support repeated initialization */
+		if (def->m_base.m_copy == NULL)
+			return NULL;
+		mod = PyImport_AddModule(name);
+		if (mod == NULL)
+			return NULL;
+		Py_INCREF(mod);
+		mdict = PyModule_GetDict(mod);
+		if (mdict == NULL)
+			return NULL;
+		if (PyDict_Update(mdict, def->m_base.m_copy))
+			return NULL;
+	}
+	else {
+		if (def->m_base.m_init == NULL)
+			return NULL;
+		mod = def->m_base.m_init();
+		if (mod == NULL)
+			return NULL;
+		PyDict_SetItemString(PyImport_GetModuleDict(), name, mod);
+	}
+	if (_PyState_AddModule(mod, def) < 0) {
+		PyDict_DelItemString(PyImport_GetModuleDict(), name);
+		Py_DECREF(mod);
 		return NULL;
+	}
 	if (Py_VerboseFlag)
 		PySys_WriteStderr("import %s # previously loaded (%s)\n",
-			name, filename);
+				  name, filename);
 	return mod;
+	
 }
 
 
@@ -1801,6 +1846,7 @@
 		return 1;
 
 	for (p = PyImport_Inittab; p->name != NULL; p++) {
+		PyObject *mod;
 		if (strcmp(name, p->name) == 0) {
 			if (p->initfunc == NULL) {
 				PyErr_Format(PyExc_ImportError,
@@ -1810,11 +1856,14 @@
 			}
 			if (Py_VerboseFlag)
 				PySys_WriteStderr("import %s # builtin\n", name);
-			(*p->initfunc)();
-			if (PyErr_Occurred())
+			mod = (*p->initfunc)();
+			if (mod == 0)
 				return -1;
-			if (_PyImport_FixupExtension(name, name) == NULL)
+			if (_PyImport_FixupExtension(mod, name, name) < 0)
 				return -1;
+			/* FixupExtension has put the module into sys.modules,
+			   so we can release our own reference. */
+			Py_DECREF(mod);
 			return 1;
 		}
 	}
@@ -3200,17 +3249,27 @@
 	PyType_GenericNew          /* tp_new */
 };
 
+static struct PyModuleDef impmodule = {
+	PyModuleDef_HEAD_INIT,
+	"imp",
+	doc_imp,
+	0,
+	imp_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
 
 PyMODINIT_FUNC
-initimp(void)
+PyInit_imp(void)
 {
 	PyObject *m, *d;
 
 	if (PyType_Ready(&PyNullImporter_Type) < 0)
-		goto failure;
+		return NULL;
 
-	m = Py_InitModule4("imp", imp_methods, doc_imp,
-			   NULL, PYTHON_API_VERSION);
+	m = PyModule_Create(&impmodule);
 	if (m == NULL)
 		goto failure;
 	d = PyModule_GetDict(m);
@@ -3230,8 +3289,11 @@
 
 	Py_INCREF(&PyNullImporter_Type);
 	PyModule_AddObject(m, "NullImporter", (PyObject *)&PyNullImporter_Type);
+	return m;
   failure:
-	;
+	Py_XDECREF(m);
+	return NULL;
+
 }
 
 
@@ -3275,7 +3337,7 @@
 /* Shorthand to add a single entry given a name and a function */
 
 int
-PyImport_AppendInittab(char *name, void (*initfunc)(void))
+PyImport_AppendInittab(char *name, PyObject* (*initfunc)(void))
 {
 	struct _inittab newtab[2];
 

Modified: python/branches/py3k/Python/importdl.c
==============================================================================
--- python/branches/py3k/Python/importdl.c	(original)
+++ python/branches/py3k/Python/importdl.c	Wed Jun 11 07:26:20 2008
@@ -24,7 +24,9 @@
 	PyObject *m;
 	PyObject *path;
 	char *lastdot, *shortname, *packagecontext, *oldcontext;
-	dl_funcptr p;
+	dl_funcptr p0;
+	PyObject* (*p)(void);
+	struct PyModuleDef *def;
 
 	if ((m = _PyImport_FindExtension(name, pathname)) != NULL) {
 		Py_INCREF(m);
@@ -40,40 +42,46 @@
 		shortname = lastdot+1;
 	}
 
-	p = _PyImport_GetDynLoadFunc(name, shortname, pathname, fp);
+	p0 = _PyImport_GetDynLoadFunc(name, shortname, pathname, fp);
+	p = (PyObject*(*)(void))p0;
 	if (PyErr_Occurred())
 		return NULL;
 	if (p == NULL) {
 		PyErr_Format(PyExc_ImportError,
-		   "dynamic module does not define init function (init%.200s)",
+		   "dynamic module does not define init function (PyInit_%.200s)",
 			     shortname);
 		return NULL;
 	}
         oldcontext = _Py_PackageContext;
 	_Py_PackageContext = packagecontext;
-	(*p)();
+	m = (*p)();
 	_Py_PackageContext = oldcontext;
-	if (PyErr_Occurred())
+	if (m == NULL)
 		return NULL;
 
-	m = PyDict_GetItemString(PyImport_GetModuleDict(), name);
-	if (m == NULL) {
-		PyErr_SetString(PyExc_SystemError,
-				"dynamic module not initialized properly");
+	if (PyErr_Occurred()) {
+		Py_DECREF(m);
+		PyErr_Format(PyExc_SystemError,
+			     "initialization of %s raised unreported exception",
+			     shortname);
 		return NULL;
 	}
+
+	/* Remember pointer to module init function. */
+	def = PyModule_GetDef(m);
+	def->m_base.m_init = p;
+
 	/* Remember the filename as the __file__ attribute */
 	path = PyUnicode_DecodeFSDefault(pathname);
 	if (PyModule_AddObject(m, "__file__", path) < 0)
 		PyErr_Clear(); /* Not important enough to report */
 
-	if (_PyImport_FixupExtension(name, pathname) == NULL)
+	if (_PyImport_FixupExtension(m, name, pathname) < 0)
 		return NULL;
 	if (Py_VerboseFlag)
 		PySys_WriteStderr(
 			"import %s # dynamically loaded from %s\n",
 			name, pathname);
-	Py_INCREF(m);
 	return m;
 }
 

Modified: python/branches/py3k/Python/marshal.c
==============================================================================
--- python/branches/py3k/Python/marshal.c	(original)
+++ python/branches/py3k/Python/marshal.c	Wed Jun 11 07:26:20 2008
@@ -1191,11 +1191,26 @@
 	{NULL,		NULL}		/* sentinel */
 };
 
+static struct PyModuleDef impmodule = {
+	PyModuleDef_HEAD_INIT,
+	"marshal",
+	NULL,
+	0,
+	marshal_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
+
+
 PyMODINIT_FUNC
 PyMarshal_Init(void)
 {
-	PyObject *mod = Py_InitModule("marshal", marshal_methods);
+	PyObject *mod = PyModule_Create(&impmodule);
 	if (mod == NULL)
-		return;
+		return NULL;
 	PyModule_AddIntConstant(mod, "version", Py_MARSHAL_VERSION);
+	return mod;
 }

Modified: python/branches/py3k/Python/modsupport.c
==============================================================================
--- python/branches/py3k/Python/modsupport.c	(original)
+++ python/branches/py3k/Python/modsupport.c	Wed Jun 11 07:26:20 2008
@@ -11,98 +11,6 @@
 /* Package context -- the full module name for package imports */
 char *_Py_PackageContext = NULL;
 
-/* Py_InitModule4() parameters:
-   - name is the module name
-   - methods is the list of top-level functions
-   - doc is the documentation string
-   - passthrough is passed as self to functions defined in the module
-   - api_version is the value of PYTHON_API_VERSION at the time the
-     module was compiled
-
-   Return value is a borrowed reference to the module object; or NULL
-   if an error occurred (in Python 1.4 and before, errors were fatal).
-   Errors may still leak memory.
-*/
-
-static char api_version_warning[] =
-"Python C API version mismatch for module %.100s:\
- This Python has API version %d, module %.100s has version %d.";
-
-PyObject *
-Py_InitModule4(const char *name, PyMethodDef *methods, const char *doc,
-	       PyObject *passthrough, int module_api_version)
-{
-	PyObject *m, *d, *v, *n;
-	PyMethodDef *ml;
-	if (!Py_IsInitialized())
-	    Py_FatalError("Interpreter not initialized (version mismatch?)");
-	if (module_api_version != PYTHON_API_VERSION) {
-		char message[512];
-		PyOS_snprintf(message, sizeof(message), 
-			      api_version_warning, name, 
-			      PYTHON_API_VERSION, name, 
-			      module_api_version);
-		if (PyErr_WarnEx(PyExc_RuntimeWarning, message, 1)) 
-			return NULL;
-	}
-	/* Make sure name is fully qualified.
-
-	   This is a bit of a hack: when the shared library is loaded,
-	   the module name is "package.module", but the module calls
-	   Py_InitModule*() with just "module" for the name.  The shared
-	   library loader squirrels away the true name of the module in
-	   _Py_PackageContext, and Py_InitModule*() will substitute this
-	   (if the name actually matches).
-	*/
-	if (_Py_PackageContext != NULL) {
-		char *p = strrchr(_Py_PackageContext, '.');
-		if (p != NULL && strcmp(name, p+1) == 0) {
-			name = _Py_PackageContext;
-			_Py_PackageContext = NULL;
-		}
-	}
-	if ((m = PyImport_AddModule(name)) == NULL)
-		return NULL;
-	d = PyModule_GetDict(m);
-	if (methods != NULL) {
-		n = PyUnicode_FromString(name);
-		if (n == NULL)
-			return NULL;
-		for (ml = methods; ml->ml_name != NULL; ml++) {
-			if ((ml->ml_flags & METH_CLASS) ||
-			    (ml->ml_flags & METH_STATIC)) {
-				PyErr_SetString(PyExc_ValueError,
-						"module functions cannot set"
-						" METH_CLASS or METH_STATIC");
-				Py_DECREF(n);
-				return NULL;
-			}
-			v = PyCFunction_NewEx(ml, passthrough, n);
-			if (v == NULL) {
-				Py_DECREF(n);
-				return NULL;
-			}
-			if (PyDict_SetItemString(d, ml->ml_name, v) != 0) {
-				Py_DECREF(v);
-				Py_DECREF(n);
-				return NULL;
-			}
-			Py_DECREF(v);
-		}
-		Py_DECREF(n);
-	}
-	if (doc != NULL) {
-		v = PyUnicode_FromString(doc);
-		if (v == NULL || PyDict_SetItemString(d, "__doc__", v) != 0) {
-			Py_XDECREF(v);
-			return NULL;
-		}
-		Py_DECREF(v);
-	}
-	return m;
-}
-
-
 /* Helper for mkvalue() to scan the length of a format */
 
 static int

Modified: python/branches/py3k/Python/pystate.c
==============================================================================
--- python/branches/py3k/Python/pystate.c	(original)
+++ python/branches/py3k/Python/pystate.c	Wed Jun 11 07:26:20 2008
@@ -69,6 +69,7 @@
 #endif
 		interp->modules = NULL;
 		interp->modules_reloading = NULL;
+		interp->modules_by_index = NULL;
 		interp->sysdict = NULL;
 		interp->builtins = NULL;
 		interp->tstate_head = NULL;
@@ -108,6 +109,7 @@
 	Py_CLEAR(interp->codec_search_cache);
 	Py_CLEAR(interp->codec_error_registry);
 	Py_CLEAR(interp->modules);
+	Py_CLEAR(interp->modules_by_index);
 	Py_CLEAR(interp->modules_reloading);
 	Py_CLEAR(interp->sysdict);
 	Py_CLEAR(interp->builtins);
@@ -208,6 +210,40 @@
 	return tstate;
 }
 
+PyObject*
+PyState_FindModule(struct PyModuleDef* m)
+{
+	Py_ssize_t index = m->m_base.m_index;
+	PyInterpreterState *state = PyThreadState_GET()->interp;
+	PyObject *res;
+	if (index == 0)
+		return NULL;
+	if (state->modules_by_index == NULL)
+		return NULL;
+	if (index > PyList_GET_SIZE(state->modules_by_index))
+		return NULL;
+	res = PyList_GET_ITEM(state->modules_by_index, index);
+	return res==Py_None ? NULL : res;
+}
+
+int
+_PyState_AddModule(PyObject* module, struct PyModuleDef* def)
+{
+	PyInterpreterState *state = PyThreadState_GET()->interp;
+	if (!def)
+		return -1;
+	if (!state->modules_by_index) {
+		state->modules_by_index = PyList_New(20);
+		if (!state->modules_by_index)
+			return -1;
+	}
+	while(PyList_GET_SIZE(state->modules_by_index) <= def->m_base.m_index)
+		if (PyList_Append(state->modules_by_index, Py_None) < 0)
+			return -1;
+	Py_INCREF(module);
+	return PyList_SetItem(state->modules_by_index, 
+			      def->m_base.m_index, module);
+}
 
 void
 PyThreadState_Clear(PyThreadState *tstate)

Modified: python/branches/py3k/Python/pythonrun.c
==============================================================================
--- python/branches/py3k/Python/pythonrun.c	(original)
+++ python/branches/py3k/Python/pythonrun.c	Wed Jun 11 07:26:20 2008
@@ -193,6 +193,7 @@
 	bimod = _PyBuiltin_Init();
 	if (bimod == NULL)
 		Py_FatalError("Py_Initialize: can't initialize builtins modules");
+	_PyImport_FixupExtension(bimod, "builtins", "builtins");
 	interp->builtins = PyModule_GetDict(bimod);
 	if (interp->builtins == NULL)
 		Py_FatalError("Py_Initialize: can't initialize builtins dict");
@@ -208,7 +209,7 @@
 	if (interp->sysdict == NULL)
 		Py_FatalError("Py_Initialize: can't initialize sys dict");
 	Py_INCREF(interp->sysdict);
-	_PyImport_FixupExtension("sys", "sys");
+	_PyImport_FixupExtension(sysmod, "sys", "sys");
 	PySys_SetPath(Py_GetPath());
 	PyDict_SetItemString(interp->sysdict, "modules",
 			     interp->modules);
@@ -223,9 +224,6 @@
 
 	_PyImport_Init();
 
-	/* phase 2 of builtins */
-	_PyImport_FixupExtension("builtins", "builtins");
-
 	_PyImportHooks_Init();
 
 	if (install_sigs)

Modified: python/branches/py3k/Python/sysmodule.c
==============================================================================
--- python/branches/py3k/Python/sysmodule.c	(original)
+++ python/branches/py3k/Python/sysmodule.c	Wed Jun 11 07:26:20 2008
@@ -1193,13 +1193,27 @@
 	return seq;
 }
 
+static struct PyModuleDef sysmodule = {
+	PyModuleDef_HEAD_INIT,
+	"sys",
+	sys_doc,
+	0,
+	sys_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
+
+
 PyObject *
 _PySys_Init(void)
 {
 	PyObject *m, *v, *sysdict;
 	char *s;
 
-	m = Py_InitModule3("sys", sys_methods, sys_doc);
+	m = PyModule_Create(&sysmodule);
 	if (m == NULL)
 		return NULL;
 	sysdict = PyModule_GetDict(m);

From python-3000-checkins at python.org  Wed Jun 11 07:37:59 2008
From: python-3000-checkins at python.org (martin.v.loewis)
Date: Wed, 11 Jun 2008 07:37:59 +0200 (CEST)
Subject: [Python-3000-checkins] r64108 - in python/branches/py3k/Modules:
	md5module.c sha1module.c
Message-ID: <20080611053759.1D2AD1E4003@bag.python.org>

Author: martin.v.loewis
Date: Wed Jun 11 07:37:58 2008
New Revision: 64108

Log:
Fix module initialization glitches.


Modified:
   python/branches/py3k/Modules/md5module.c
   python/branches/py3k/Modules/sha1module.c

Modified: python/branches/py3k/Modules/md5module.c
==============================================================================
--- python/branches/py3k/Modules/md5module.c	(original)
+++ python/branches/py3k/Modules/md5module.c	Wed Jun 11 07:37:58 2008
@@ -566,5 +566,5 @@
     Py_TYPE(&MD5type) = &PyType_Type;
     if (PyType_Ready(&MD5type) < 0)
         return NULL;
-    return PyModule_Create("_md5", MD5_functions);
+    return PyModule_Create(&_md5module);
 }

Modified: python/branches/py3k/Modules/sha1module.c
==============================================================================
--- python/branches/py3k/Modules/sha1module.c	(original)
+++ python/branches/py3k/Modules/sha1module.c	Wed Jun 11 07:37:58 2008
@@ -539,8 +539,6 @@
 PyMODINIT_FUNC
 PyInit__sha1(void)
 {
-    PyObject *m;
-
     Py_TYPE(&SHA1type) = &PyType_Type;
     if (PyType_Ready(&SHA1type) < 0)
         return NULL;

From python-3000-checkins at python.org  Wed Jun 11 07:48:29 2008
From: python-3000-checkins at python.org (martin.v.loewis)
Date: Wed, 11 Jun 2008 07:48:29 +0200 (CEST)
Subject: [Python-3000-checkins] r64109 - python/branches/py3k/PC/config.c
Message-ID: <20080611054829.8615E1E4003@bag.python.org>

Author: martin.v.loewis
Date: Wed Jun 11 07:48:29 2008
New Revision: 64109

Log:
Update to PEP 3121.


Modified:
   python/branches/py3k/PC/config.c

Modified: python/branches/py3k/PC/config.c
==============================================================================
--- python/branches/py3k/PC/config.c	(original)
+++ python/branches/py3k/PC/config.c	Wed Jun 11 07:48:29 2008
@@ -5,133 +5,134 @@
 
 #include "Python.h"
 
-extern void initarray(void);
+extern PyObject* PyInit_array(void);
 #ifndef MS_WINI64
-extern void initaudioop(void);
+extern PyObject* PyInit_audioop(void);
 #endif
-extern void initbinascii(void);
-extern void initcmath(void);
-extern void initerrno(void);
-extern void initgc(void);
-extern void initmath(void);
-extern void init_md5(void);
-extern void initnt(void);
-extern void initoperator(void);
-extern void initsignal(void);
-extern void init_sha1(void);
-extern void init_sha256(void);
-extern void init_sha512(void);
-extern void inittime(void);
-extern void init_thread(void);
+extern PyObject* PyInit_binascii(void);
+extern PyObject* PyInit_cmath(void);
+extern PyObject* PyInit_errno(void);
+extern PyObject* PyInit_gc(void);
+extern PyObject* PyInit_math(void);
+extern PyObject* PyInit__md5(void);
+extern PyObject* PyInit_nt(void);
+extern PyObject* PyInit_operator(void);
+extern PyObject* PyInit_signal(void);
+extern PyObject* PyInit__sha1(void);
+extern PyObject* PyInit__sha256(void);
+extern PyObject* PyInit__sha512(void);
+extern PyObject* PyInit_time(void);
+extern PyObject* PyInit__thread(void);
+extern PyObject* PyInit_cStringIO(void);
 #ifdef WIN32
-extern void initmsvcrt(void);
-extern void init_locale(void);
+extern PyObject* PyInit_msvcrt(void);
+extern PyObject* PyInit__locale(void);
 #endif
-extern void init_codecs(void);
-extern void init_weakref(void);
-extern void initxxsubtype(void);
-extern void initzipimport(void);
-extern void init_random(void);
-extern void inititertools(void);
-extern void init_collections(void);
-extern void init_heapq(void);
-extern void init_bisect(void);
-extern void init_symtable(void);
-extern void initmmap(void);
-extern void init_csv(void);
-extern void init_sre(void);
-extern void initparser(void);
-extern void initwinreg(void);
-extern void init_struct(void);
-extern void initdatetime(void);
-extern void init_functools(void);
-extern void init_json(void);
-extern void initzlib(void);
-
-extern void init_multibytecodec(void);
-extern void init_codecs_cn(void);
-extern void init_codecs_hk(void);
-extern void init_codecs_iso2022(void);
-extern void init_codecs_jp(void);
-extern void init_codecs_kr(void);
-extern void init_codecs_tw(void);
-extern void init_subprocess(void);
-extern void init_lsprof(void);
-extern void init_ast(void);
-extern void init_fileio(void);
-extern void init_bytesio(void);
-extern void initatexit(void);
-extern void _PyWarnings_Init(void);
+extern PyObject* PyInit__codecs(void);
+extern PyObject* PyInit__weakref(void);
+extern PyObject* PyInit_xxsubtype(void);
+extern PyObject* PyInit_zipimport(void);
+extern PyObject* PyInit__random(void);
+extern PyObject* PyInit_itertools(void);
+extern PyObject* PyInit__collections(void);
+extern PyObject* PyInit__heapq(void);
+extern PyObject* PyInit__bisect(void);
+extern PyObject* PyInit__symtable(void);
+extern PyObject* PyInit_mmap(void);
+extern PyObject* PyInit__csv(void);
+extern PyObject* PyInit__sre(void);
+extern PyObject* PyInit_parser(void);
+extern PyObject* PyInit_winreg(void);
+extern PyObject* PyInit__struct(void);
+extern PyObject* PyInit_datetime(void);
+extern PyObject* PyInit__functools(void);
+extern PyObject* PyInit__json(void);
+extern PyObject* PyInit_zlib(void);
+
+extern PyObject* PyInit__multibytecodec(void);
+extern PyObject* PyInit__codecs_cn(void);
+extern PyObject* PyInit__codecs_hk(void);
+extern PyObject* PyInit__codecs_iso2022(void);
+extern PyObject* PyInit__codecs_jp(void);
+extern PyObject* PyInit__codecs_kr(void);
+extern PyObject* PyInit__codecs_tw(void);
+extern PyObject* PyInit__subprocess(void);
+extern PyObject* PyInit__lsprof(void);
+extern PyObject* PyInit__ast(void);
+extern PyObject* PyInit__fileio(void);
+extern PyObject* PyInit__bytesio(void);
+extern PyObject* PyInit_atexit(void);
+extern PyObject* _PyWarnings_Init(void);
 
 /* tools/freeze/makeconfig.py marker for additional "extern" */
 /* -- ADDMODULE MARKER 1 -- */
 
-extern void PyMarshal_Init(void);
-extern void initimp(void);
+extern PyObject* PyMarshal_Init(void);
+extern PyObject* PyInit_imp(void);
 
 struct _inittab _PyImport_Inittab[] = {
 
-        {"array", initarray},
-	{"_ast", init_ast},
+        {"array", PyInit_array},
+	{"_ast", PyInit__ast},
 #ifdef MS_WINDOWS
 #ifndef MS_WINI64
-        {"audioop", initaudioop},
+        {"audioop", PyInit_audioop},
 #endif
 #endif
-        {"binascii", initbinascii},
-        {"cmath", initcmath},
-        {"errno", initerrno},
-        {"gc", initgc},
-        {"math", initmath},
-        {"nt", initnt}, /* Use the NT os functions, not posix */
-        {"operator", initoperator},
-        {"signal", initsignal},
-        {"_md5", init_md5},
-        {"_sha1", init_sha1},
-        {"_sha256", init_sha256},
-        {"_sha512", init_sha512},
-        {"time", inittime},
+        {"binascii", PyInit_binascii},
+        {"cmath", PyInit_cmath},
+        {"errno", PyInit_errno},
+        {"gc", PyInit_gc},
+        {"math", PyInit_math},
+        {"nt", PyInit_nt}, /* Use the NT os functions, not posix */
+        {"operator", PyInit_operator},
+        {"signal", PyInit_signal},
+        {"_md5", PyInit__md5},
+        {"_sha1", PyInit__sha1},
+        {"_sha256", PyInit__sha256},
+        {"_sha512", PyInit__sha512},
+        {"time", PyInit_time},
 #ifdef WITH_THREAD
-        {"_thread", init_thread},
+        {"_thread", PyInit__thread},
 #endif
 #ifdef WIN32
-        {"msvcrt", initmsvcrt},
-        {"_locale", init_locale},
+        {"msvcrt", PyInit_msvcrt},
+        {"_locale", PyInit__locale},
 #endif
 	/* XXX Should _subprocess go in a WIN32 block?  not WIN64? */
-	{"_subprocess", init_subprocess},
+	{"_subprocess", PyInit__subprocess},
 
-        {"_codecs", init_codecs},
-	{"_weakref", init_weakref},
-	{"_random", init_random},
-        {"_bisect", init_bisect},
-        {"_heapq", init_heapq},
-	{"_lsprof", init_lsprof},
-	{"itertools", inititertools},
-        {"_collections", init_collections},
-	{"_symtable", init_symtable},
-	{"mmap", initmmap},
-	{"_csv", init_csv},
-	{"_sre", init_sre},
-	{"parser", initparser},
-	{"winreg", initwinreg},
-	{"_struct", init_struct},
-	{"datetime", initdatetime},
-	{"_functools", init_functools},
-	{"_json", init_json},
-
-	{"xxsubtype", initxxsubtype},
-	{"zipimport", initzipimport},
-	{"zlib", initzlib},
+        {"_codecs", PyInit__codecs},
+	{"_weakref", PyInit__weakref},
+	{"_random", PyInit__random},
+        {"_bisect", PyInit__bisect},
+        {"_heapq", PyInit__heapq},
+	{"_lsprof", PyInit__lsprof},
+	{"itertools", PyInit_itertools},
+        {"_collections", PyInit__collections},
+	{"_symtable", PyInit__symtable},
+	{"mmap", PyInit_mmap},
+	{"_csv", PyInit__csv},
+	{"_sre", PyInit__sre},
+	{"parser", PyInit_parser},
+	{"winreg", PyInit_winreg},
+	{"_struct", PyInit__struct},
+	{"datetime", PyInit_datetime},
+	{"_functools", PyInit__functools},
+	{"_json", PyInit__json},
+
+	{"xxsubtype", PyInit_xxsubtype},
+	{"zipimport", PyInit_zipimport},
+	{"zlib", PyInit_zlib},
 	
 	/* CJK codecs */
-	{"_multibytecodec", init_multibytecodec},
-	{"_codecs_cn", init_codecs_cn},
-	{"_codecs_hk", init_codecs_hk},
-	{"_codecs_iso2022", init_codecs_iso2022},
-	{"_codecs_jp", init_codecs_jp},
-	{"_codecs_kr", init_codecs_kr},
-	{"_codecs_tw", init_codecs_tw},
+	{"_multibytecodec", PyInit__multibytecodec},
+	{"_codecs_cn", PyInit__codecs_cn},
+	{"_codecs_hk", PyInit__codecs_hk},
+	{"_codecs_iso2022", PyInit__codecs_iso2022},
+	{"_codecs_jp", PyInit__codecs_jp},
+	{"_codecs_kr", PyInit__codecs_kr},
+	{"_codecs_tw", PyInit__codecs_tw},
 
 /* tools/freeze/makeconfig.py marker for additional "_inittab" entries */
 /* -- ADDMODULE MARKER 2 -- */
@@ -140,7 +141,7 @@
         {"marshal", PyMarshal_Init},
 
         /* This lives it with import.c */
-        {"imp", initimp},
+        {"imp", PyInit_imp},
 
         /* These entries are here for sys.builtin_module_names */
         {"__main__", NULL},
@@ -148,9 +149,9 @@
         {"sys", NULL},
         {"_warnings", _PyWarnings_Init},
 
-        {"_fileio", init_fileio},
-        {"_bytesio", init_bytesio},
-        {"atexit", initatexit},
+        {"_fileio", PyInit__fileio},
+        {"_bytesio", PyInit__bytesio},
+        {"atexit", PyInit_atexit},
 
         /* Sentinel */
         {0, 0}

From python-3000-checkins at python.org  Wed Jun 11 07:59:46 2008
From: python-3000-checkins at python.org (martin.v.loewis)
Date: Wed, 11 Jun 2008 07:59:46 +0200 (CEST)
Subject: [Python-3000-checkins] r64110 -
	python/branches/py3k/Modules/socketmodule.c
Message-ID: <20080611055946.CA5491E4004@bag.python.org>

Author: martin.v.loewis
Date: Wed Jun 11 07:59:46 2008
New Revision: 64110

Log:
Add missing NULL return value.


Modified:
   python/branches/py3k/Modules/socketmodule.c

Modified: python/branches/py3k/Modules/socketmodule.c
==============================================================================
--- python/branches/py3k/Modules/socketmodule.c	(original)
+++ python/branches/py3k/Modules/socketmodule.c	Wed Jun 11 07:59:46 2008
@@ -4995,7 +4995,7 @@
 		PyObject *tmp;
 		tmp = PyLong_FromUnsignedLong(SIO_RCVALL);
 		if (tmp == NULL)
-			return;
+			return NULL;
 		PyModule_AddObject(m, "SIO_RCVALL", tmp);
 	}
 	PyModule_AddIntConstant(m, "RCVALL_OFF", RCVALL_OFF);

From python-3000-checkins at python.org  Wed Jun 11 08:22:47 2008
From: python-3000-checkins at python.org (martin.v.loewis)
Date: Wed, 11 Jun 2008 08:22:47 +0200 (CEST)
Subject: [Python-3000-checkins] r64111 -
	python/branches/py3k/Python/dynload_win.c
Message-ID: <20080611062247.0CBE01E400D@bag.python.org>

Author: martin.v.loewis
Date: Wed Jun 11 08:22:46 2008
New Revision: 64111

Log:
Fix typo.

Modified:
   python/branches/py3k/Python/dynload_win.c

Modified: python/branches/py3k/Python/dynload_win.c
==============================================================================
--- python/branches/py3k/Python/dynload_win.c	(original)
+++ python/branches/py3k/Python/dynload_win.c	Wed Jun 11 08:22:46 2008
@@ -165,7 +165,7 @@
 	dl_funcptr p;
 	char funcname[258], *import_python;
 
-	PyOS_snprintf(funcname, sizeof(funcname), "PyInit_init%.200s", shortname);
+	PyOS_snprintf(funcname, sizeof(funcname), "PyInit_%.200s", shortname);
 
 	{
 		HINSTANCE hDLL = NULL;

From python-3000-checkins at python.org  Wed Jun 11 08:24:11 2008
From: python-3000-checkins at python.org (martin.v.loewis)
Date: Wed, 11 Jun 2008 08:24:11 +0200 (CEST)
Subject: [Python-3000-checkins] r64112 - python/branches/py3k/PC/config.c
Message-ID: <20080611062411.051F91E4005@bag.python.org>

Author: martin.v.loewis
Date: Wed Jun 11 08:24:10 2008
New Revision: 64112

Log:
Remove PyInit_cStringIO again.

Modified:
   python/branches/py3k/PC/config.c

Modified: python/branches/py3k/PC/config.c
==============================================================================
--- python/branches/py3k/PC/config.c	(original)
+++ python/branches/py3k/PC/config.c	Wed Jun 11 08:24:10 2008
@@ -23,7 +23,6 @@
 extern PyObject* PyInit__sha512(void);
 extern PyObject* PyInit_time(void);
 extern PyObject* PyInit__thread(void);
-extern PyObject* PyInit_cStringIO(void);
 #ifdef WIN32
 extern PyObject* PyInit_msvcrt(void);
 extern PyObject* PyInit__locale(void);

From python-3000-checkins at python.org  Wed Jun 11 17:59:44 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Wed, 11 Jun 2008 17:59:44 +0200 (CEST)
Subject: [Python-3000-checkins] r64121 - in python/branches/py3k:
	Doc/library/dis.rst Doc/library/inspect.rst
	Doc/library/sys.rst Doc/reference/datamodel.rst
	Include/frameobject.h Include/opcode.h Lib/doctest.py
	Lib/inspect.py Lib/opcode.py Lib/test/test_exceptions.py
	Lib/test/test_raise.py Misc/NEWS Misc/cheatsheet
	Objects/frameobject.c Python/ceval.c Python/compile.c
	Python/import.c
Message-ID: <20080611155944.E1FB61E4005@bag.python.org>

Author: benjamin.peterson
Date: Wed Jun 11 17:59:43 2008
New Revision: 64121

Log:
#3021: Antoine Pitrou's Lexical exception handlers


Modified:
   python/branches/py3k/Doc/library/dis.rst
   python/branches/py3k/Doc/library/inspect.rst
   python/branches/py3k/Doc/library/sys.rst
   python/branches/py3k/Doc/reference/datamodel.rst
   python/branches/py3k/Include/frameobject.h
   python/branches/py3k/Include/opcode.h
   python/branches/py3k/Lib/doctest.py
   python/branches/py3k/Lib/inspect.py
   python/branches/py3k/Lib/opcode.py
   python/branches/py3k/Lib/test/test_exceptions.py
   python/branches/py3k/Lib/test/test_raise.py
   python/branches/py3k/Misc/NEWS
   python/branches/py3k/Misc/cheatsheet
   python/branches/py3k/Objects/frameobject.c
   python/branches/py3k/Python/ceval.c
   python/branches/py3k/Python/compile.c
   python/branches/py3k/Python/import.c

Modified: python/branches/py3k/Doc/library/dis.rst
==============================================================================
--- python/branches/py3k/Doc/library/dis.rst	(original)
+++ python/branches/py3k/Doc/library/dis.rst	Wed Jun 11 17:59:43 2008
@@ -397,6 +397,14 @@
    denoting nested loops, try statements, and such.
 
 
+.. opcode:: POP_EXCEPT ()
+
+   Removes one block from the block stack. The popped block must be an exception
+   handler block, as implicitly created when entering an except handler.
+   In addition to popping extraneous values from the frame stack, the
+   last three popped values are used to restore the exception state.
+
+
 .. opcode:: END_FINALLY ()
 
    Terminates a :keyword:`finally` clause.  The interpreter recalls whether the
@@ -412,24 +420,22 @@
 
 .. opcode:: WITH_CLEANUP ()
 
-   Cleans up the stack when a :keyword:`with` statement block exits.  On top of
-   the stack are 1--3 values indicating how/why the finally clause was entered:
-
-   * TOP = ``None``
-   * (TOP, SECOND) = (``WHY_{RETURN,CONTINUE}``), retval
-   * TOP = ``WHY_*``; no retval below it
-   * (TOP, SECOND, THIRD) = exc_info()
-
-   Under them is EXIT, the context manager's :meth:`__exit__` bound method.
-
-   In the last case, ``EXIT(TOP, SECOND, THIRD)`` is called, otherwise
-   ``EXIT(None, None, None)``.
-
-   EXIT is removed from the stack, leaving the values above it in the same
-   order. In addition, if the stack represents an exception, *and* the function
-   call returns a 'true' value, this information is "zapped", to prevent
-   ``END_FINALLY`` from re-raising the exception.  (But non-local gotos should
-   still be resumed.)
+   Cleans up the stack when a :keyword:`with` statement block exits.  TOS is
+   the context manager's :meth:`__exit__` bound method. Below TOS are 1--3
+   values indicating how/why the finally clause was entered:
+
+   * SECOND = ``None``
+   * (SECOND, THIRD) = (``WHY_{RETURN,CONTINUE}``), retval
+   * SECOND = ``WHY_*``; no retval below it
+   * (SECOND, THIRD, FOURTH) = exc_info()
+
+   In the last case, ``TOS(SECOND, THIRD, FOURTH)`` is called, otherwise
+   ``TOS(None, None, None)``.  In addition, TOS is removed from the stack.
+
+   If the stack represents an exception, *and* the function call returns
+   a 'true' value, this information is "zapped" and replaced with a single
+   ``WHY_SILENCED`` to prevent ``END_FINALLY`` from re-raising the exception.
+   (But non-local gotos will still be resumed.)
 
    .. XXX explain the WHY stuff!
 

Modified: python/branches/py3k/Doc/library/inspect.rst
==============================================================================
--- python/branches/py3k/Doc/library/inspect.rst	(original)
+++ python/branches/py3k/Doc/library/inspect.rst	Wed Jun 11 17:59:43 2008
@@ -94,17 +94,6 @@
 |           | f_code          | code object being         |
 |           |                 | executed in this frame    |
 +-----------+-----------------+---------------------------+
-|           | f_exc_traceback | traceback if raised in    |
-|           |                 | this frame, or ``None``   |
-+-----------+-----------------+---------------------------+
-|           | f_exc_type      | exception type if raised  |
-|           |                 | in this frame, or         |
-|           |                 | ``None``                  |
-+-----------+-----------------+---------------------------+
-|           | f_exc_value     | exception value if raised |
-|           |                 | in this frame, or         |
-|           |                 | ``None``                  |
-+-----------+-----------------+---------------------------+
 |           | f_globals       | global namespace seen by  |
 |           |                 | this frame                |
 +-----------+-----------------+---------------------------+

Modified: python/branches/py3k/Doc/library/sys.rst
==============================================================================
--- python/branches/py3k/Doc/library/sys.rst	(original)
+++ python/branches/py3k/Doc/library/sys.rst	Wed Jun 11 17:59:43 2008
@@ -136,8 +136,8 @@
    frame is not handling an exception, the information is taken from the calling
    stack frame, or its caller, and so on until a stack frame is found that is
    handling an exception.  Here, "handling an exception" is defined as "executing
-   or having executed an except clause."  For any stack frame, only information
-   about the most recently handled exception is accessible.
+   an except clause."  For any stack frame, only information about the exception
+   being currently handled is accessible.
 
    .. index:: object: traceback
 

Modified: python/branches/py3k/Doc/reference/datamodel.rst
==============================================================================
--- python/branches/py3k/Doc/reference/datamodel.rst	(original)
+++ python/branches/py3k/Doc/reference/datamodel.rst	Wed Jun 11 17:59:43 2008
@@ -875,19 +875,14 @@
 
       .. index::
          single: f_trace (frame attribute)
-         single: f_exc_type (frame attribute)
-         single: f_exc_value (frame attribute)
-         single: f_exc_traceback (frame attribute)
          single: f_lineno (frame attribute)
 
       Special writable attributes: :attr:`f_trace`, if not ``None``, is a function
       called at the start of each source code line (this is used by the debugger);
-      :attr:`f_exc_type`, :attr:`f_exc_value`, :attr:`f_exc_traceback` represent the
-      last exception raised in the parent frame provided another exception was ever
-      raised in the current frame (in all other cases they are None); :attr:`f_lineno`
-      is the current line number of the frame --- writing to this from within a trace
-      function jumps to the given line (only for the bottom-most frame).  A debugger
-      can implement a Jump command (aka Set Next Statement) by writing to f_lineno.
+      :attr:`f_lineno` is the current line number of the frame --- writing to this
+      from within a trace function jumps to the given line (only for the bottom-most
+      frame).  A debugger can implement a Jump command (aka Set Next Statement)
+      by writing to f_lineno.
 
    Traceback objects
       .. index::

Modified: python/branches/py3k/Include/frameobject.h
==============================================================================
--- python/branches/py3k/Include/frameobject.h	(original)
+++ python/branches/py3k/Include/frameobject.h	Wed Jun 11 17:59:43 2008
@@ -27,13 +27,13 @@
     PyObject **f_stacktop;
     PyObject *f_trace;		/* Trace function */
 
-    /* If an exception is raised in this frame, the next three are used to
-     * record the exception info (if any) originally in the thread state.  See
-     * comments before set_exc_info() -- it's not obvious.
-     * Invariant:  if _type is NULL, then so are _value and _traceback.
-     * Desired invariant:  all three are NULL, or all three are non-NULL.  That
-     * one isn't currently true, but "should be".
-     */
+	/* In a generator, we need to be able to swap between the exception
+	   state inside the generator and the exception state of the calling
+	   frame (which shouldn't be impacted when the generator "yields"
+	   from an except handler).
+	   These three fields exist exactly for that, and are unused for
+	   non-generator frames. See the SAVE_EXC_STATE and SWAP_EXC_STATE
+	   macros in ceval.c for details of their use. */
     PyObject *f_exc_type, *f_exc_value, *f_exc_traceback;
 
     PyThreadState *f_tstate;

Modified: python/branches/py3k/Include/opcode.h
==============================================================================
--- python/branches/py3k/Include/opcode.h	(original)
+++ python/branches/py3k/Include/opcode.h	Wed Jun 11 17:59:43 2008
@@ -70,6 +70,7 @@
 #define YIELD_VALUE	86
 #define POP_BLOCK	87
 #define END_FINALLY	88
+#define POP_EXCEPT	89
 
 #define HAVE_ARGUMENT	90	/* Opcodes from here have an argument: */
 
@@ -133,6 +134,13 @@
 #define EXTENDED_ARG  143
 
 
+/* EXCEPT_HANDLER is a special, implicit block type which is created when
+   entering an except handler. It is not an opcode but we define it here
+   as we want it to be available to both frameobject.c and ceval.c, while
+   remaining private.*/
+#define EXCEPT_HANDLER 257
+
+
 enum cmp_op {PyCmp_LT=Py_LT, PyCmp_LE=Py_LE, PyCmp_EQ=Py_EQ, PyCmp_NE=Py_NE, PyCmp_GT=Py_GT, PyCmp_GE=Py_GE,
 	     PyCmp_IN, PyCmp_NOT_IN, PyCmp_IS, PyCmp_IS_NOT, PyCmp_EXC_MATCH, PyCmp_BAD};
 

Modified: python/branches/py3k/Lib/doctest.py
==============================================================================
--- python/branches/py3k/Lib/doctest.py	(original)
+++ python/branches/py3k/Lib/doctest.py	Wed Jun 11 17:59:43 2008
@@ -1242,10 +1242,9 @@
 
             # The example raised an exception:  check if it was expected.
             else:
-                exc_info = sys.exc_info()
-                exc_msg = traceback.format_exception_only(*exc_info[:2])[-1]
+                exc_msg = traceback.format_exception_only(*exception[:2])[-1]
                 if not quiet:
-                    got += _exception_traceback(exc_info)
+                    got += _exception_traceback(exception)
 
                 # If `example.exc_msg` is None, then we weren't expecting
                 # an exception.
@@ -1275,7 +1274,7 @@
             elif outcome is BOOM:
                 if not quiet:
                     self.report_unexpected_exception(out, test, example,
-                                                     exc_info)
+                                                     exception)
                 failures += 1
             else:
                 assert False, ("unknown outcome", outcome)

Modified: python/branches/py3k/Lib/inspect.py
==============================================================================
--- python/branches/py3k/Lib/inspect.py	(original)
+++ python/branches/py3k/Lib/inspect.py	Wed Jun 11 17:59:43 2008
@@ -197,9 +197,6 @@
         f_back          next outer frame object (this frame's caller)
         f_builtins      built-in namespace seen by this frame
         f_code          code object being executed in this frame
-        f_exc_traceback traceback if raised in this frame, or None
-        f_exc_type      exception type if raised in this frame, or None
-        f_exc_value     exception value if raised in this frame, or None
         f_globals       global namespace seen by this frame
         f_lasti         index of last attempted instruction in bytecode
         f_lineno        current line number in Python source code

Modified: python/branches/py3k/Lib/opcode.py
==============================================================================
--- python/branches/py3k/Lib/opcode.py	(original)
+++ python/branches/py3k/Lib/opcode.py	Wed Jun 11 17:59:43 2008
@@ -105,6 +105,7 @@
 def_op('YIELD_VALUE', 86)
 def_op('POP_BLOCK', 87)
 def_op('END_FINALLY', 88)
+def_op('POP_EXCEPT', 89)
 
 HAVE_ARGUMENT = 90              # Opcodes from here have an argument:
 

Modified: python/branches/py3k/Lib/test/test_exceptions.py
==============================================================================
--- python/branches/py3k/Lib/test/test_exceptions.py	(original)
+++ python/branches/py3k/Lib/test/test_exceptions.py	Wed Jun 11 17:59:43 2008
@@ -427,6 +427,7 @@
             local_ref = obj
             raise MyException(obj)
 
+        # Qualified "except" with "as"
         obj = MyObj()
         wr = weakref.ref(obj)
         try:
@@ -437,6 +438,113 @@
         obj = wr()
         self.failUnless(obj is None, "%s" % obj)
 
+        # Qualified "except" without "as"
+        obj = MyObj()
+        wr = weakref.ref(obj)
+        try:
+            inner_raising_func()
+        except MyException:
+            pass
+        obj = None
+        obj = wr()
+        self.failUnless(obj is None, "%s" % obj)
+
+        # Bare "except"
+        obj = MyObj()
+        wr = weakref.ref(obj)
+        try:
+            inner_raising_func()
+        except:
+            pass
+        obj = None
+        obj = wr()
+        self.failUnless(obj is None, "%s" % obj)
+
+        # "except" with premature block leave
+        obj = MyObj()
+        wr = weakref.ref(obj)
+        for i in [0]:
+            try:
+                inner_raising_func()
+            except:
+                break
+        obj = None
+        obj = wr()
+        self.failUnless(obj is None, "%s" % obj)
+
+        # "except" block raising another exception
+        obj = MyObj()
+        wr = weakref.ref(obj)
+        try:
+            try:
+                inner_raising_func()
+            except:
+                raise KeyError
+        except KeyError:
+            obj = None
+            obj = wr()
+            self.failUnless(obj is None, "%s" % obj)
+
+        # Some complicated construct
+        obj = MyObj()
+        wr = weakref.ref(obj)
+        try:
+            inner_raising_func()
+        except MyException:
+            try:
+                try:
+                    raise
+                finally:
+                    raise
+            except MyException:
+                pass
+        obj = None
+        obj = wr()
+        self.failUnless(obj is None, "%s" % obj)
+
+        # Inside an exception-silencing "with" block
+        class Context:
+            def __enter__(self):
+                return self
+            def __exit__ (self, exc_type, exc_value, exc_tb):
+                return True
+        obj = MyObj()
+        wr = weakref.ref(obj)
+        with Context():
+            inner_raising_func()
+        obj = None
+        obj = wr()
+        self.failUnless(obj is None, "%s" % obj)
+
+    def test_generator_leaking(self):
+        # Test that generator exception state doesn't leak into the calling
+        # frame
+        def yield_raise():
+            try:
+                raise KeyError("caught")
+            except KeyError:
+                yield sys.exc_info()[0]
+                yield sys.exc_info()[0]
+            yield sys.exc_info()[0]
+        g = yield_raise()
+        self.assertEquals(next(g), KeyError)
+        self.assertEquals(sys.exc_info()[0], None)
+        self.assertEquals(next(g), KeyError)
+        self.assertEquals(sys.exc_info()[0], None)
+        self.assertEquals(next(g), None)
+
+        # Same test, but inside an exception handler
+        try:
+            raise TypeError("foo")
+        except TypeError:
+            g = yield_raise()
+            self.assertEquals(next(g), KeyError)
+            self.assertEquals(sys.exc_info()[0], TypeError)
+            self.assertEquals(next(g), KeyError)
+            self.assertEquals(sys.exc_info()[0], TypeError)
+            self.assertEquals(next(g), TypeError)
+            del g
+            self.assertEquals(sys.exc_info()[0], TypeError)
 
 def test_main():
     run_unittest(ExceptionTests)

Modified: python/branches/py3k/Lib/test/test_raise.py
==============================================================================
--- python/branches/py3k/Lib/test/test_raise.py	(original)
+++ python/branches/py3k/Lib/test/test_raise.py	Wed Jun 11 17:59:43 2008
@@ -16,6 +16,13 @@
         return sys.exc_info()[2]
 
 
+class Context:
+    def __enter__(self):
+        return self
+    def __exit__(self, exc_type, exc_value, exc_tb):
+        return True
+
+
 class TestRaise(unittest.TestCase):
     def test_invalid_reraise(self):
         try:
@@ -37,6 +44,71 @@
         else:
             self.fail("No exception raised")
 
+    def test_except_reraise(self):
+        def reraise():
+            try:
+                raise TypeError("foo")
+            except:
+                try:
+                    raise KeyError("caught")
+                except KeyError:
+                    pass
+                raise
+        self.assertRaises(TypeError, reraise)
+
+    def test_finally_reraise(self):
+        def reraise():
+            try:
+                raise TypeError("foo")
+            except:
+                try:
+                    raise KeyError("caught")
+                finally:
+                    raise
+        self.assertRaises(KeyError, reraise)
+
+    def test_nested_reraise(self):
+        def nested_reraise():
+            raise
+        def reraise():
+            try:
+                raise TypeError("foo")
+            except:
+                nested_reraise()
+        self.assertRaises(TypeError, reraise)
+
+    def test_with_reraise1(self):
+        def reraise():
+            try:
+                raise TypeError("foo")
+            except:
+                with Context():
+                    pass
+                raise
+        self.assertRaises(TypeError, reraise)
+
+    def test_with_reraise2(self):
+        def reraise():
+            try:
+                raise TypeError("foo")
+            except:
+                with Context():
+                    raise KeyError("caught")
+                raise
+        self.assertRaises(TypeError, reraise)
+
+    def test_yield_reraise(self):
+        def reraise():
+            try:
+                raise TypeError("foo")
+            except:
+                yield 1
+                raise
+        g = reraise()
+        next(g)
+        self.assertRaises(TypeError, lambda: next(g))
+        self.assertRaises(StopIteration, lambda: next(g))
+
     def test_erroneous_exception(self):
         class MyException(Exception):
             def __init__(self):
@@ -158,6 +230,5 @@
 def test_main():
     support.run_unittest(__name__)
 
-
 if __name__ == "__main__":
     unittest.main()

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Wed Jun 11 17:59:43 2008
@@ -49,6 +49,10 @@
   Exception (KeyboardInterrupt, and SystemExit) propagate instead of
   ignoring them.
 
+- #3021 Exception reraising sematics have been significantly improved.  However,
+  f_exc_type, f_exc_value, and f_exc_traceback cannot be accessed from Python
+  code anymore.
+
 Extension Modules
 -----------------
 

Modified: python/branches/py3k/Misc/cheatsheet
==============================================================================
--- python/branches/py3k/Misc/cheatsheet	(original)
+++ python/branches/py3k/Misc/cheatsheet	Wed Jun 11 17:59:43 2008
@@ -1262,9 +1262,6 @@
         f_lineno (int, R/O): current line number
         f_lasti (int, R/O): precise instruction (index into bytecode)
         f_trace (function/None, R/W): debug hook called at start of each source line
-        f_exc_type (Type/None, R/W): Most recent exception type
-        f_exc_value (any, R/W): Most recent exception value
-        f_exc_traceback (traceback/None, R/W): Most recent exception traceback
     Tracebacks:
         tb_next (frame/None, R/O): next level in stack trace (toward the frame where
                                   the exception occurred)

Modified: python/branches/py3k/Objects/frameobject.c
==============================================================================
--- python/branches/py3k/Objects/frameobject.c	(original)
+++ python/branches/py3k/Objects/frameobject.c	Wed Jun 11 17:59:43 2008
@@ -20,9 +20,6 @@
 	{"f_builtins",	T_OBJECT,	OFF(f_builtins),READONLY},
 	{"f_globals",	T_OBJECT,	OFF(f_globals),	READONLY},
 	{"f_lasti",	T_INT,		OFF(f_lasti),	READONLY},
-	{"f_exc_type",	T_OBJECT,	OFF(f_exc_type)},
-	{"f_exc_value",	T_OBJECT,	OFF(f_exc_value)},
-	{"f_exc_traceback", T_OBJECT,	OFF(f_exc_traceback)},
 	{NULL}	/* Sentinel */
 };
 

Modified: python/branches/py3k/Python/ceval.c
==============================================================================
--- python/branches/py3k/Python/ceval.c	(original)
+++ python/branches/py3k/Python/ceval.c	Wed Jun 11 17:59:43 2008
@@ -116,8 +116,6 @@
 static PyObject * cmp_outcome(int, PyObject *, PyObject *);
 static PyObject * import_from(PyObject *, PyObject *);
 static int import_all_from(PyObject *, PyObject *);
-static void set_exc_info(PyThreadState *, PyObject *, PyObject *, PyObject *);
-static void reset_exc_info(PyThreadState *);
 static void format_exc_check_arg(PyObject *, const char *, PyObject *);
 static PyObject * unicode_concatenate(PyObject *, PyObject *,
                                       PyFrameObject *, unsigned char *);
@@ -483,7 +481,8 @@
 		WHY_RETURN =	0x0008,	/* 'return' statement */
 		WHY_BREAK =	0x0010,	/* 'break' statement */
 		WHY_CONTINUE =	0x0020,	/* 'continue' statement */
-		WHY_YIELD =	0x0040	/* 'yield' operator */
+		WHY_YIELD =	0x0040,	/* 'yield' operator */
+		WHY_SILENCED = 0x0080 /* Exception silenced by 'with' */
 };
 
 static enum why_code do_raise(PyObject *, PyObject *);
@@ -692,6 +691,53 @@
 				     GETLOCAL(i) = value; \
                                      Py_XDECREF(tmp); } while (0)
 
+
+#define UNWIND_BLOCK(b) \
+	while (STACK_LEVEL() > (b)->b_level) { \
+		PyObject *v = POP(); \
+		Py_XDECREF(v); \
+	}
+
+#define UNWIND_EXCEPT_HANDLER(b) \
+	assert(STACK_LEVEL() >= (b)->b_level + 3); \
+	while (STACK_LEVEL() > (b)->b_level + 3) { \
+		PyObject *v = POP(); \
+		Py_XDECREF(v); \
+	} \
+	Py_XDECREF(tstate->exc_type); \
+	tstate->exc_type = POP(); \
+	Py_XDECREF(tstate->exc_value); \
+	tstate->exc_value = POP(); \
+	Py_XDECREF(tstate->exc_traceback); \
+	tstate->exc_traceback = POP();
+
+#define SAVE_EXC_STATE() \
+	{ \
+		Py_XINCREF(tstate->exc_type); \
+		Py_XINCREF(tstate->exc_value); \
+		Py_XINCREF(tstate->exc_traceback); \
+		Py_XDECREF(f->f_exc_type); \
+		Py_XDECREF(f->f_exc_value); \
+		Py_XDECREF(f->f_exc_traceback); \
+		f->f_exc_type = tstate->exc_type; \
+		f->f_exc_value = tstate->exc_value; \
+		f->f_exc_traceback = tstate->exc_traceback; \
+	}
+
+#define SWAP_EXC_STATE() \
+	{ \
+		PyObject *tmp; \
+		tmp = tstate->exc_type; \
+		tstate->exc_type = f->f_exc_type; \
+		f->f_exc_type = tmp; \
+		tmp = tstate->exc_value; \
+		tstate->exc_value = f->f_exc_value; \
+		f->f_exc_value = tmp; \
+		tmp = tstate->exc_traceback; \
+		tstate->exc_traceback = f->f_exc_traceback; \
+		f->f_exc_traceback = tmp; \
+	}
+
 /* Start of code */
 
 	if (f == NULL)
@@ -765,6 +811,18 @@
 	assert(stack_pointer != NULL);
 	f->f_stacktop = NULL;	/* remains NULL unless yield suspends frame */
 
+	if (f->f_code->co_flags & CO_GENERATOR) {
+		if (f->f_exc_type != NULL && f->f_exc_type != Py_None) {
+			/* We were in an except handler when we left,
+			   restore the exception state which was put aside
+			   (see YIELD_VALUE). */
+			SWAP_EXC_STATE();
+		}
+		else {
+			SAVE_EXC_STATE();
+		}
+	}
+
 #ifdef LLTRACE
 	lltrace = PyDict_GetItemString(f->f_globals, "__lltrace__") != NULL;
 #endif
@@ -1443,15 +1501,29 @@
 			retval = POP();
 			f->f_stacktop = stack_pointer;
 			why = WHY_YIELD;
+			/* Put aside the current exception state and restore
+			   that of the calling frame. This only serves when
+			   "yield" is used inside an except handler. */
+			SWAP_EXC_STATE();
 			goto fast_yield;
 
-		case POP_BLOCK:
+		case POP_EXCEPT:
 			{
 				PyTryBlock *b = PyFrame_BlockPop(f);
-				while (STACK_LEVEL() > b->b_level) {
-					v = POP();
-					Py_DECREF(v);
+				if (b->b_type != EXCEPT_HANDLER) {
+					PyErr_SetString(PyExc_SystemError,
+						"popped block is not an except handler");
+					why = WHY_EXCEPTION;
+					break;
 				}
+				UNWIND_EXCEPT_HANDLER(b);
+			}
+			continue;
+
+		case POP_BLOCK:
+			{
+				PyTryBlock *b = PyFrame_BlockPop(f);
+				UNWIND_BLOCK(b);
 			}
 			continue;
 
@@ -1464,6 +1536,22 @@
 				if (why == WHY_RETURN ||
 				    why == WHY_CONTINUE)
 					retval = POP();
+				if (why == WHY_SILENCED) {
+					/* An exception was silenced by 'with', we must
+					manually unwind the EXCEPT_HANDLER block which was
+					created when the exception was caught, otherwise
+					the stack will be in an inconsistent state. */
+					PyTryBlock *b = PyFrame_BlockPop(f);
+					if (b->b_type != EXCEPT_HANDLER) {
+						PyErr_SetString(PyExc_SystemError,
+							"popped block is not an except handler");
+						why = WHY_EXCEPTION;
+					}
+					else {
+						UNWIND_EXCEPT_HANDLER(b);
+						why = WHY_NOT;
+					}
+				}
 			}
 			else if (PyExceptionClass_Check(v)) {
 				w = POP();
@@ -1477,19 +1565,6 @@
 					"'finally' pops bad exception");
 				why = WHY_EXCEPTION;
 			}
-			/*
-			  Make sure the exception state is cleaned up before
-			  the end of an except block. This ensures objects
-			  referenced by the exception state are not kept
-			  alive too long.
-			  See #2507.
-			*/
-			if (tstate->frame->f_exc_type != NULL)
-				reset_exc_info(tstate);
-			else {
-				assert(tstate->frame->f_exc_value == NULL);
-				assert(tstate->frame->f_exc_traceback == NULL);
-			}
 			Py_DECREF(v);
 			break;
 
@@ -2056,59 +2131,33 @@
 			   should still be resumed.)
 			*/
 
-			PyObject *exit_func;
-
-			u = POP();
+			PyObject *exit_func = POP();
+			u = TOP();
 			if (u == Py_None) {
-			       	exit_func = TOP();
-				SET_TOP(u);
 				v = w = Py_None;
 			}
 			else if (PyLong_Check(u)) {
-				switch(PyLong_AS_LONG(u)) {
-				case WHY_RETURN:
-				case WHY_CONTINUE:
-					/* Retval in TOP. */
-					exit_func = SECOND();
-					SET_SECOND(TOP());
-					SET_TOP(u);
-					break;
-				default:
-					exit_func = TOP();
-					SET_TOP(u);
-					break;
-				}
 				u = v = w = Py_None;
 			}
 			else {
-				v = TOP();
-				w = SECOND();
-				exit_func = THIRD();
-				SET_TOP(u);
-				SET_SECOND(v);
-				SET_THIRD(w);
+				v = SECOND();
+				w = THIRD();
 			}
 			/* XXX Not the fastest way to call it... */
 			x = PyObject_CallFunctionObjArgs(exit_func, u, v, w,
 							 NULL);
-			if (x == NULL) {
-				Py_DECREF(exit_func);
+			Py_DECREF(exit_func);
+			if (x == NULL)
 				break; /* Go to error exit */
-			}
 			if (u != Py_None && PyObject_IsTrue(x)) {
-				/* There was an exception and a true return */
+				/* There was an exception and a True return */
 				STACKADJ(-2);
-				Py_INCREF(Py_None);
-				SET_TOP(Py_None);
+				SET_TOP(PyLong_FromLong((long) WHY_SILENCED));
 				Py_DECREF(u);
 				Py_DECREF(v);
 				Py_DECREF(w);
-			} else {
-				/* The stack was rearranged to remove EXIT
-				   above. Let END_FINALLY do its thing */
 			}
 			Py_DECREF(x);
-			Py_DECREF(exit_func);
 			PREDICT(END_FINALLY);
 			break;
 		}
@@ -2370,50 +2419,63 @@
 				break;
 			}
 
-			while (STACK_LEVEL() > b->b_level) {
-				v = POP();
-				Py_XDECREF(v);
+			if (b->b_type == EXCEPT_HANDLER) {
+				UNWIND_EXCEPT_HANDLER(b);
+				if (why == WHY_EXCEPTION) {
+					Py_CLEAR(tstate->exc_type);
+					Py_CLEAR(tstate->exc_value);
+					Py_CLEAR(tstate->exc_traceback);
+				}
+				continue;
 			}
+			UNWIND_BLOCK(b);
 			if (b->b_type == SETUP_LOOP && why == WHY_BREAK) {
 				why = WHY_NOT;
 				JUMPTO(b->b_handler);
 				break;
 			}
-			if (b->b_type == SETUP_FINALLY ||
-			    (b->b_type == SETUP_EXCEPT &&
-			     why == WHY_EXCEPTION)) {
-				if (why == WHY_EXCEPTION) {
-					PyObject *exc, *val, *tb;
-					PyErr_Fetch(&exc, &val, &tb);
-					if (val == NULL) {
-						val = Py_None;
-						Py_INCREF(val);
-					}
-					/* Make the raw exception data
-					   available to the handler,
-					   so a program can emulate the
-					   Python main loop.  Don't do
-					   this for 'finally'. */
-					if (b->b_type == SETUP_EXCEPT) {
-						PyErr_NormalizeException(
-							&exc, &val, &tb);
-						set_exc_info(tstate,
-							     exc, val, tb);
-					}
-					if (tb == NULL) {
-						Py_INCREF(Py_None);
-						PUSH(Py_None);
-					} else
-						PUSH(tb);
-					PUSH(val);
-					PUSH(exc);
+			if (why == WHY_EXCEPTION && (b->b_type == SETUP_EXCEPT
+				|| b->b_type == SETUP_FINALLY)) {
+				PyObject *exc, *val, *tb;
+				int handler = b->b_handler;
+				/* Beware, this invalidates all b->b_* fields */
+ 				PyFrame_BlockSetup(f, EXCEPT_HANDLER, -1, STACK_LEVEL());
+				PUSH(tstate->exc_traceback);
+				PUSH(tstate->exc_value);
+				if (tstate->exc_type != NULL) {
+					PUSH(tstate->exc_type);
 				}
 				else {
-					if (why & (WHY_RETURN | WHY_CONTINUE))
-						PUSH(retval);
-					v = PyLong_FromLong((long)why);
-					PUSH(v);
+					Py_INCREF(Py_None);
+					PUSH(Py_None);
 				}
+				PyErr_Fetch(&exc, &val, &tb);
+				/* Make the raw exception data
+				   available to the handler,
+				   so a program can emulate the
+				   Python main loop. */
+				PyErr_NormalizeException(
+					&exc, &val, &tb);
+				PyException_SetTraceback(val, tb);
+				Py_INCREF(exc);
+				tstate->exc_type = exc;
+				Py_INCREF(val);
+				tstate->exc_value = val;
+				tstate->exc_traceback = tb;
+				if (tb == NULL)
+					tb = Py_None;
+				Py_INCREF(tb);
+				PUSH(tb);
+				PUSH(val);
+				PUSH(exc);
+				why = WHY_NOT;
+				JUMPTO(handler);
+				break;
+			}
+			if (b->b_type == SETUP_FINALLY) {
+				if (why & (WHY_RETURN | WHY_CONTINUE))
+					PUSH(retval);
+				PUSH(PyLong_FromLong((long)why));
 				why = WHY_NOT;
 				JUMPTO(b->b_handler);
 				break;
@@ -2471,13 +2533,6 @@
 		}
 	}
 
-	if (tstate->frame->f_exc_type != NULL)
-		reset_exc_info(tstate);
-	else {
-		assert(tstate->frame->f_exc_value == NULL);
-		assert(tstate->frame->f_exc_traceback == NULL);
-	}
-
 	/* pop frame */
 exit_eval_frame:
 	Py_LeaveRecursiveCall();
@@ -2757,150 +2812,6 @@
 }
 
 
-/* Implementation notes for set_exc_info() and reset_exc_info():
-
-- Below, 'exc_ZZZ' stands for 'exc_type', 'exc_value' and
-  'exc_traceback'.  These always travel together.
-
-- tstate->curexc_ZZZ is the "hot" exception that is set by
-  PyErr_SetString(), cleared by PyErr_Clear(), and so on.
-
-- Once an exception is caught by an except clause, it is transferred
-  from tstate->curexc_ZZZ to tstate->exc_ZZZ, from which sys.exc_info()
-  can pick it up.  This is the primary task of set_exc_info().
-  XXX That can't be right:  set_exc_info() doesn't look at tstate->curexc_ZZZ.
-
-- Now let me explain the complicated dance with frame->f_exc_ZZZ.
-
-  Long ago, when none of this existed, there were just a few globals:
-  one set corresponding to the "hot" exception, and one set
-  corresponding to sys.exc_ZZZ.  (Actually, the latter weren't C
-  globals; they were simply stored as sys.exc_ZZZ.  For backwards
-  compatibility, they still are!)  The problem was that in code like
-  this:
-
-     try:
-	"something that may fail"
-     except "some exception":
-	"do something else first"
-	"print the exception from sys.exc_ZZZ."
-
-  if "do something else first" invoked something that raised and caught
-  an exception, sys.exc_ZZZ were overwritten.  That was a frequent
-  cause of subtle bugs.  I fixed this by changing the semantics as
-  follows:
-
-    - Within one frame, sys.exc_ZZZ will hold the last exception caught
-      *in that frame*.
-
-    - But initially, and as long as no exception is caught in a given
-      frame, sys.exc_ZZZ will hold the last exception caught in the
-      previous frame (or the frame before that, etc.).
-
-  The first bullet fixed the bug in the above example.  The second
-  bullet was for backwards compatibility: it was (and is) common to
-  have a function that is called when an exception is caught, and to
-  have that function access the caught exception via sys.exc_ZZZ.
-  (Example: traceback.print_exc()).
-
-  At the same time I fixed the problem that sys.exc_ZZZ weren't
-  thread-safe, by introducing sys.exc_info() which gets it from tstate;
-  but that's really a separate improvement.
-
-  The reset_exc_info() function in ceval.c restores the tstate->exc_ZZZ
-  variables to what they were before the current frame was called.  The
-  set_exc_info() function saves them on the frame so that
-  reset_exc_info() can restore them.  The invariant is that
-  frame->f_exc_ZZZ is NULL iff the current frame never caught an
-  exception (where "catching" an exception applies only to successful
-  except clauses); and if the current frame ever caught an exception,
-  frame->f_exc_ZZZ is the exception that was stored in tstate->exc_ZZZ
-  at the start of the current frame.
-
-*/
-
-static void
-set_exc_info(PyThreadState *tstate,
-	     PyObject *type, PyObject *value, PyObject *tb)
-{
-	PyFrameObject *frame = tstate->frame;
-	PyObject *tmp_type, *tmp_value, *tmp_tb;
-
-	assert(type != NULL);
-	assert(frame != NULL);
-	if (frame->f_exc_type == NULL) {
-		assert(frame->f_exc_value == NULL);
-		assert(frame->f_exc_traceback == NULL);
-		/* This frame didn't catch an exception before. */
-		/* Save previous exception of this thread in this frame. */
-		if (tstate->exc_type == NULL) {
-			/* XXX Why is this set to Py_None? */
-			Py_INCREF(Py_None);
-			tstate->exc_type = Py_None;
-		}
-		Py_INCREF(tstate->exc_type);
-		Py_XINCREF(tstate->exc_value);
-		Py_XINCREF(tstate->exc_traceback);
-		frame->f_exc_type = tstate->exc_type;
-		frame->f_exc_value = tstate->exc_value;
-		frame->f_exc_traceback = tstate->exc_traceback;
-	}
-	/* Set new exception for this thread. */
-	tmp_type = tstate->exc_type;
-	tmp_value = tstate->exc_value;
-	tmp_tb = tstate->exc_traceback;
-	Py_INCREF(type);
-	Py_XINCREF(value);
-	Py_XINCREF(tb);
-	tstate->exc_type = type;
-	tstate->exc_value = value;
-	tstate->exc_traceback = tb;
-	PyException_SetTraceback(value, tb);
-	Py_XDECREF(tmp_type);
-	Py_XDECREF(tmp_value);
-	Py_XDECREF(tmp_tb);
-}
-
-static void
-reset_exc_info(PyThreadState *tstate)
-{
-	PyFrameObject *frame;
-	PyObject *tmp_type, *tmp_value, *tmp_tb;
-
-	/* It's a precondition that the thread state's frame caught an
-	 * exception -- verify in a debug build.
-	 */
-	assert(tstate != NULL);
-	frame = tstate->frame;
-	assert(frame != NULL);
-	assert(frame->f_exc_type != NULL);
-
-	/* Copy the frame's exception info back to the thread state. */
-	tmp_type = tstate->exc_type;
-	tmp_value = tstate->exc_value;
-	tmp_tb = tstate->exc_traceback;
-	Py_INCREF(frame->f_exc_type);
-	Py_XINCREF(frame->f_exc_value);
-	Py_XINCREF(frame->f_exc_traceback);
-	tstate->exc_type = frame->f_exc_type;
-	tstate->exc_value = frame->f_exc_value;
-	tstate->exc_traceback = frame->f_exc_traceback;
-	Py_XDECREF(tmp_type);
-	Py_XDECREF(tmp_value);
-	Py_XDECREF(tmp_tb);
-
-	/* Clear the frame's exception info. */
-	tmp_type = frame->f_exc_type;
-	tmp_value = frame->f_exc_value;
-	tmp_tb = frame->f_exc_traceback;
-	frame->f_exc_type = NULL;
-	frame->f_exc_value = NULL;
-	frame->f_exc_traceback = NULL;
-	Py_DECREF(tmp_type);
-	Py_XDECREF(tmp_value);
-	Py_XDECREF(tmp_tb);
-}
-
 /* Logic for the raise statement (too complicated for inlining).
    This *consumes* a reference count to each of its arguments. */
 static enum why_code

Modified: python/branches/py3k/Python/compile.c
==============================================================================
--- python/branches/py3k/Python/compile.c	(original)
+++ python/branches/py3k/Python/compile.c	Wed Jun 11 17:59:43 2008
@@ -760,6 +760,8 @@
 
 		case POP_BLOCK:
 			return 0;
+		case POP_EXCEPT:
+			return 0;  /* -3 except if bad bytecode */
 		case END_FINALLY:
 			return -1; /* or -2 or -3 if exception occurred */
 
@@ -818,7 +820,8 @@
 			return 0;
 		case SETUP_EXCEPT:
 		case SETUP_FINALLY:
-			return 3; /* actually pushed by an exception */
+			return 6; /* can push 3 values for the new exception
+				+ 3 others for the previous exception state */
 
 		case LOAD_FAST:
 			return 1;
@@ -2031,6 +2034,7 @@
             /* second # body */
 		VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body);
 	        ADDOP(c, POP_BLOCK);
+	        ADDOP(c, POP_EXCEPT);
 	        compiler_pop_fblock(c, FINALLY_TRY, cleanup_body);
 
             /* finally: */
@@ -2050,9 +2054,20 @@
 	        compiler_pop_fblock(c, FINALLY_END, cleanup_end);
 		}
 		else {
+            basicblock *cleanup_body;
+
+            cleanup_body = compiler_new_block(c);
+            if(!cleanup_body)
+                return 0;
+
+			ADDOP(c, POP_TOP);
             ADDOP(c, POP_TOP);
-            ADDOP(c, POP_TOP);
+	        compiler_use_next_block(c, cleanup_body);
+	        if (!compiler_push_fblock(c, FINALLY_TRY, cleanup_body))
+		        return 0;
 		    VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body);
+	        ADDOP(c, POP_EXCEPT);
+	        compiler_pop_fblock(c, FINALLY_TRY, cleanup_body);
 		}
 		ADDOP_JREL(c, JUMP_FORWARD, end);
 		compiler_use_next_block(c, except);
@@ -3109,7 +3124,7 @@
 {
     static identifier enter_attr, exit_attr;
     basicblock *block, *finally;
-    identifier tmpvalue = NULL;
+    identifier tmpvalue = NULL, tmpexit = NULL;
 
     assert(s->kind == With_kind);
 
@@ -3144,6 +3159,10 @@
 	    return 0;
 	PyArena_AddPyObject(c->c_arena, tmpvalue);
     }
+	tmpexit = compiler_new_tmpname(c);
+	if (tmpexit == NULL)
+	    return 0;
+	PyArena_AddPyObject(c->c_arena, tmpexit);
 
     /* Evaluate EXPR */
     VISIT(c, expr, s->v.With.context_expr);
@@ -3151,7 +3170,8 @@
     /* Squirrel away context.__exit__ by stuffing it under context */
     ADDOP(c, DUP_TOP);
     ADDOP_O(c, LOAD_ATTR, exit_attr, names);
-    ADDOP(c, ROT_TWO);
+	if (!compiler_nameop(c, tmpexit, Store))
+	    return 0;
 
     /* Call context.__enter__() */
     ADDOP_O(c, LOAD_ATTR, enter_attr, names);
@@ -3198,6 +3218,9 @@
     /* Finally block starts; context.__exit__ is on the stack under
        the exception or return information. Just issue our magic
        opcode. */
+	if (!compiler_nameop(c, tmpexit, Load) ||
+		!compiler_nameop(c, tmpexit, Del))
+		return 0;
     ADDOP(c, WITH_CLEANUP);
 
     /* Finally block ends. */

Modified: python/branches/py3k/Python/import.c
==============================================================================
--- python/branches/py3k/Python/import.c	(original)
+++ python/branches/py3k/Python/import.c	Wed Jun 11 17:59:43 2008
@@ -86,8 +86,9 @@
 		      3100 (merge from 2.6a0, see 62151)
 		      3102 (__file__ points to source file)
        Python 3.0a4: 3110 (WITH_CLEANUP optimization).
+       Python 3.0a5: 3130 (lexical exception stacking, including POP_EXCEPT)
 */
-#define MAGIC (3110 | ((long)'\r'<<16) | ((long)'\n'<<24))
+#define MAGIC (3130 | ((long)'\r'<<16) | ((long)'\n'<<24))
 
 /* Magic word as global; note that _PyImport_Init() can change the
    value of this global to accommodate for alterations of how the

From python-3000-checkins at python.org  Wed Jun 11 18:44:06 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Wed, 11 Jun 2008 18:44:06 +0200 (CEST)
Subject: [Python-3000-checkins] r64122 - in python/branches/py3k:
	Doc/includes/mp_benchmarks.py Doc/includes/mp_distributing.py
	Doc/includes/mp_newtype.py Doc/includes/mp_pool.py
	Doc/includes/mp_synchronize.py Doc/includes/mp_webserver.py
	Doc/includes/mp_workers.py Doc/library/multiprocessing.rst
	Doc/library/someos.rst Lib/multiprocessing
	Lib/multiprocessing/__init__.py Lib/multiprocessing/connection.py
	Lib/multiprocessing/dummy/__init__.py
	Lib/multiprocessing/dummy/connection.py
	Lib/multiprocessing/forking.py Lib/multiprocessing/heap.py
	Lib/multiprocessing/managers.py Lib/multiprocessing/pool.py
	Lib/multiprocessing/process.py Lib/multiprocessing/queues.py
	Lib/multiprocessing/reduction.py Lib/multiprocessing/sharedctypes.py
	Lib/multiprocessing/synchronize.py
	Lib/multiprocessing/util.py Lib/test/test_multiprocessing.py
	Modules/_multiprocessing Modules/_multiprocessing/connection.h
	Modules/_multiprocessing/multiprocessing.c setup.py
Message-ID: <20080611164406.B34FB1E4005@bag.python.org>

Author: benjamin.peterson
Date: Wed Jun 11 18:44:04 2008
New Revision: 64122

Log:
Merged revisions 64104,64117 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/trunk

........
  r64104 | benjamin.peterson | 2008-06-10 21:40:25 -0500 (Tue, 10 Jun 2008) | 2 lines
  
  add the multiprocessing package to fulfill PEP 371
........
  r64117 | benjamin.peterson | 2008-06-11 07:26:31 -0500 (Wed, 11 Jun 2008) | 2 lines
  
  fix import of multiprocessing by juggling imports
........


Added:
   python/branches/py3k/Doc/includes/mp_benchmarks.py
      - copied unchanged from r64104, /python/trunk/Doc/includes/mp_benchmarks.py
   python/branches/py3k/Doc/includes/mp_distributing.py
      - copied, changed from r64104, /python/trunk/Doc/includes/mp_distributing.py
   python/branches/py3k/Doc/includes/mp_newtype.py
      - copied unchanged from r64104, /python/trunk/Doc/includes/mp_newtype.py
   python/branches/py3k/Doc/includes/mp_pool.py
      - copied unchanged from r64104, /python/trunk/Doc/includes/mp_pool.py
   python/branches/py3k/Doc/includes/mp_synchronize.py
      - copied unchanged from r64104, /python/trunk/Doc/includes/mp_synchronize.py
   python/branches/py3k/Doc/includes/mp_webserver.py
      - copied unchanged from r64104, /python/trunk/Doc/includes/mp_webserver.py
   python/branches/py3k/Doc/includes/mp_workers.py
      - copied unchanged from r64104, /python/trunk/Doc/includes/mp_workers.py
   python/branches/py3k/Doc/library/multiprocessing.rst
      - copied unchanged from r64104, /python/trunk/Doc/library/multiprocessing.rst
   python/branches/py3k/Lib/multiprocessing/
      - copied from r64104, /python/trunk/Lib/multiprocessing/
   python/branches/py3k/Lib/test/test_multiprocessing.py
      - copied, changed from r64104, /python/trunk/Lib/test/test_multiprocessing.py
   python/branches/py3k/Modules/_multiprocessing/
      - copied from r64104, /python/trunk/Modules/_multiprocessing/
Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Doc/library/someos.rst
   python/branches/py3k/Lib/multiprocessing/__init__.py
   python/branches/py3k/Lib/multiprocessing/connection.py
   python/branches/py3k/Lib/multiprocessing/dummy/__init__.py
   python/branches/py3k/Lib/multiprocessing/dummy/connection.py
   python/branches/py3k/Lib/multiprocessing/forking.py
   python/branches/py3k/Lib/multiprocessing/heap.py
   python/branches/py3k/Lib/multiprocessing/managers.py
   python/branches/py3k/Lib/multiprocessing/pool.py
   python/branches/py3k/Lib/multiprocessing/process.py
   python/branches/py3k/Lib/multiprocessing/queues.py
   python/branches/py3k/Lib/multiprocessing/reduction.py
   python/branches/py3k/Lib/multiprocessing/sharedctypes.py
   python/branches/py3k/Lib/multiprocessing/synchronize.py
   python/branches/py3k/Lib/multiprocessing/util.py
   python/branches/py3k/Modules/_multiprocessing/connection.h
   python/branches/py3k/Modules/_multiprocessing/multiprocessing.c
   python/branches/py3k/setup.py

Copied: python/branches/py3k/Doc/includes/mp_distributing.py (from r64104, /python/trunk/Doc/includes/mp_distributing.py)
==============================================================================
--- /python/trunk/Doc/includes/mp_distributing.py	(original)
+++ python/branches/py3k/Doc/includes/mp_distributing.py	Wed Jun 11 18:44:04 2008
@@ -1,362 +1,362 @@
-#
-# Module to allow spawning of processes on foreign host
-#
-# Depends on `multiprocessing` package -- tested with `processing-0.60`
-#
-
-__all__ = ['Cluster', 'Host', 'get_logger', 'current_process']
-
-#
-# Imports
-#
-
-import sys
-import os
-import tarfile
-import shutil
-import subprocess
-import logging
-import itertools
-import Queue
-
-try:
-    import cPickle as pickle
-except ImportError:
-    import pickle
-
-from multiprocessing import Process, current_process, cpu_count
-from multiprocessing import util, managers, connection, forking, pool
-
-#
-# Logging
-#
-
-def get_logger():
-    return _logger
-
-_logger = logging.getLogger('distributing')
-_logger.propogate = 0
-
-util.fix_up_logger(_logger)
-_formatter = logging.Formatter(util.DEFAULT_LOGGING_FORMAT)
-_handler = logging.StreamHandler()
-_handler.setFormatter(_formatter)
-_logger.addHandler(_handler)
-
-info = _logger.info
-debug = _logger.debug
-
-#
-# Get number of cpus
-#
-
-try:
-    slot_count = cpu_count()
-except NotImplemented:
-    slot_count = 1
-        
-#
-# Manager type which spawns subprocesses
-#
-
-class HostManager(managers.SyncManager):
-    '''
-    Manager type used for spawning processes on a (presumably) foreign host
-    '''    
-    def __init__(self, address, authkey):
-        managers.SyncManager.__init__(self, address, authkey)
-        self._name = 'Host-unknown'
-
-    def Process(self, group=None, target=None, name=None, args=(), kwargs={}):
-        if hasattr(sys.modules['__main__'], '__file__'):
-            main_path = os.path.basename(sys.modules['__main__'].__file__)
-        else:
-            main_path = None
-        data = pickle.dumps((target, args, kwargs))
-        p = self._RemoteProcess(data, main_path)
-        if name is None:
-            temp = self._name.split('Host-')[-1] + '/Process-%s'
-            name = temp % ':'.join(map(str, p.get_identity()))
-        p.set_name(name)
-        return p
-
-    @classmethod
-    def from_address(cls, address, authkey):
-        manager = cls(address, authkey)
-        managers.transact(address, authkey, 'dummy')
-        manager._state.value = managers.State.STARTED
-        manager._name = 'Host-%s:%s' % manager.address
-        manager.shutdown = util.Finalize(
-            manager, HostManager._finalize_host,
-            args=(manager._address, manager._authkey, manager._name),
-            exitpriority=-10
-            )
-        return manager
-
-    @staticmethod
-    def _finalize_host(address, authkey, name):
-        managers.transact(address, authkey, 'shutdown')
-        
-    def __repr__(self):
-        return '<Host(%s)>' % self._name
-
-#
-# Process subclass representing a process on (possibly) a remote machine
-#
-
-class RemoteProcess(Process):
-    '''
-    Represents a process started on a remote host
-    '''
-    def __init__(self, data, main_path):
-        assert not main_path or os.path.basename(main_path) == main_path
-        Process.__init__(self)
-        self._data = data
-        self._main_path = main_path
-        
-    def _bootstrap(self):
-        forking.prepare({'main_path': self._main_path})
-        self._target, self._args, self._kwargs = pickle.loads(self._data)
-        return Process._bootstrap(self)
-        
-    def get_identity(self):
-        return self._identity
-
-HostManager.register('_RemoteProcess', RemoteProcess)
-
-#
-# A Pool class that uses a cluster
-#
-
-class DistributedPool(pool.Pool):
-    
-    def __init__(self, cluster, processes=None, initializer=None, initargs=()):
-        self._cluster = cluster
-        self.Process = cluster.Process
-        pool.Pool.__init__(self, processes or len(cluster),
-                           initializer, initargs)
-        
-    def _setup_queues(self):
-        self._inqueue = self._cluster._SettableQueue()
-        self._outqueue = self._cluster._SettableQueue()
-        self._quick_put = self._inqueue.put
-        self._quick_get = self._outqueue.get
-
-    @staticmethod
-    def _help_stuff_finish(inqueue, task_handler, size):
-        inqueue.set_contents([None] * size)
-
-#
-# Manager type which starts host managers on other machines
-#
-
-def LocalProcess(**kwds):
-    p = Process(**kwds)
-    p.set_name('localhost/' + p.get_name())
-    return p
-
-class Cluster(managers.SyncManager):
-    '''
-    Represents collection of slots running on various hosts.
-    
-    `Cluster` is a subclass of `SyncManager` so it allows creation of
-    various types of shared objects.
-    '''
-    def __init__(self, hostlist, modules):
-        managers.SyncManager.__init__(self, address=('localhost', 0))
-        self._hostlist = hostlist
-        self._modules = modules
-        if __name__ not in modules:
-            modules.append(__name__)
-        files = [sys.modules[name].__file__ for name in modules]
-        for i, file in enumerate(files):
-            if file.endswith('.pyc') or file.endswith('.pyo'):
-                files[i] = file[:-4] + '.py'
-        self._files = [os.path.abspath(file) for file in files]
-        
-    def start(self):
-        managers.SyncManager.start(self)
-        
-        l = connection.Listener(family='AF_INET', authkey=self._authkey)
-        
-        for i, host in enumerate(self._hostlist):
-            host._start_manager(i, self._authkey, l.address, self._files)
-
-        for host in self._hostlist:
-            if host.hostname != 'localhost':
-                conn = l.accept()
-                i, address, cpus = conn.recv()
-                conn.close()
-                other_host = self._hostlist[i]
-                other_host.manager = HostManager.from_address(address,
-                                                              self._authkey)
-                other_host.slots = other_host.slots or cpus
-                other_host.Process = other_host.manager.Process
-            else:
-                host.slots = host.slots or slot_count
-                host.Process = LocalProcess
-
-        self._slotlist = [
-            Slot(host) for host in self._hostlist for i in range(host.slots)
-            ]
-        self._slot_iterator = itertools.cycle(self._slotlist)
-        self._base_shutdown = self.shutdown
-        del self.shutdown
-        
-    def shutdown(self):
-        for host in self._hostlist:
-            if host.hostname != 'localhost':
-                host.manager.shutdown()
-        self._base_shutdown()
-        
-    def Process(self, group=None, target=None, name=None, args=(), kwargs={}):
-        slot = self._slot_iterator.next()
-        return slot.Process(
-            group=group, target=target, name=name, args=args, kwargs=kwargs
-            )
-
-    def Pool(self, processes=None, initializer=None, initargs=()):
-        return DistributedPool(self, processes, initializer, initargs)
-    
-    def __getitem__(self, i):
-        return self._slotlist[i]
-
-    def __len__(self):
-        return len(self._slotlist)
-
-    def __iter__(self):
-        return iter(self._slotlist)
-
-#
-# Queue subclass used by distributed pool
-#
-
-class SettableQueue(Queue.Queue):
-    def empty(self):
-        return not self.queue
-    def full(self):
-        return self.maxsize > 0 and len(self.queue) == self.maxsize
-    def set_contents(self, contents):
-        # length of contents must be at least as large as the number of
-        # threads which have potentially called get()
-        self.not_empty.acquire()
-        try:
-            self.queue.clear()
-            self.queue.extend(contents)
-            self.not_empty.notifyAll()
-        finally:
-            self.not_empty.release()
-            
-Cluster.register('_SettableQueue', SettableQueue)
-
-#
-# Class representing a notional cpu in the cluster
-#
-
-class Slot(object):
-    def __init__(self, host):
-        self.host = host
-        self.Process = host.Process
-
-#
-# Host
-#
-
-class Host(object):
-    '''
-    Represents a host to use as a node in a cluster.
-
-    `hostname` gives the name of the host.  If hostname is not
-    "localhost" then ssh is used to log in to the host.  To log in as
-    a different user use a host name of the form
-    "username at somewhere.org"
-
-    `slots` is used to specify the number of slots for processes on
-    the host.  This affects how often processes will be allocated to
-    this host.  Normally this should be equal to the number of cpus on
-    that host.
-    '''
-    def __init__(self, hostname, slots=None):
-        self.hostname = hostname
-        self.slots = slots
-        
-    def _start_manager(self, index, authkey, address, files):
-        if self.hostname != 'localhost':
-            tempdir = copy_to_remote_temporary_directory(self.hostname, files)
-            debug('startup files copied to %s:%s', self.hostname, tempdir)
-            p = subprocess.Popen(
-                ['ssh', self.hostname, 'python', '-c',
-                 '"import os; os.chdir(%r); '
-                 'from distributing import main; main()"' % tempdir],
-                stdin=subprocess.PIPE
-                )
-            data = dict(
-                name='BoostrappingHost', index=index,
-                dist_log_level=_logger.getEffectiveLevel(),
-                dir=tempdir, authkey=str(authkey), parent_address=address
-                )
-            pickle.dump(data, p.stdin, pickle.HIGHEST_PROTOCOL)
-            p.stdin.close()
-
-#
-# Copy files to remote directory, returning name of directory
-#
-
-unzip_code = '''"
-import tempfile, os, sys, tarfile
-tempdir = tempfile.mkdtemp(prefix='distrib-')
-os.chdir(tempdir)
-tf = tarfile.open(fileobj=sys.stdin, mode='r|gz')
-for ti in tf:
-    tf.extract(ti)
-print tempdir
-"'''
-
-def copy_to_remote_temporary_directory(host, files):
-    p = subprocess.Popen(
-        ['ssh', host, 'python', '-c', unzip_code],
-        stdout=subprocess.PIPE, stdin=subprocess.PIPE
-        )
-    tf = tarfile.open(fileobj=p.stdin, mode='w|gz')
-    for name in files:
-        tf.add(name, os.path.basename(name))
-    tf.close()
-    p.stdin.close()
-    return p.stdout.read().rstrip()
-
-#
-# Code which runs a host manager
-#
-
-def main():   
-    # get data from parent over stdin
-    data = pickle.load(sys.stdin)
-    sys.stdin.close()
-
-    # set some stuff
-    _logger.setLevel(data['dist_log_level'])
-    forking.prepare(data)
-    
-    # create server for a `HostManager` object
-    server = managers.Server(HostManager._registry, ('', 0), data['authkey'])
-    current_process()._server = server
-    
-    # report server address and number of cpus back to parent
-    conn = connection.Client(data['parent_address'], authkey=data['authkey'])
-    conn.send((data['index'], server.address, slot_count))
-    conn.close()
-    
-    # set name etc
-    current_process().set_name('Host-%s:%s' % server.address)
-    util._run_after_forkers()
-    
-    # register a cleanup function
-    def cleanup(directory):
-        debug('removing directory %s', directory)
-        shutil.rmtree(directory)
-        debug('shutting down host manager')
-    util.Finalize(None, cleanup, args=[data['dir']], exitpriority=0)
-    
-    # start host manager
-    debug('remote host manager starting in %s', data['dir'])
-    server.serve_forever()
+#
+# Module to allow spawning of processes on foreign host
+#
+# Depends on `multiprocessing` package -- tested with `processing-0.60`
+#
+
+__all__ = ['Cluster', 'Host', 'get_logger', 'current_process']
+
+#
+# Imports
+#
+
+import sys
+import os
+import tarfile
+import shutil
+import subprocess
+import logging
+import itertools
+import Queue
+
+try:
+    import cPickle as pickle
+except ImportError:
+    import pickle
+
+from multiprocessing import Process, current_process, cpu_count
+from multiprocessing import util, managers, connection, forking, pool
+
+#
+# Logging
+#
+
+def get_logger():
+    return _logger
+
+_logger = logging.getLogger('distributing')
+_logger.propogate = 0
+
+util.fix_up_logger(_logger)
+_formatter = logging.Formatter(util.DEFAULT_LOGGING_FORMAT)
+_handler = logging.StreamHandler()
+_handler.setFormatter(_formatter)
+_logger.addHandler(_handler)
+
+info = _logger.info
+debug = _logger.debug
+
+#
+# Get number of cpus
+#
+
+try:
+    slot_count = cpu_count()
+except NotImplemented:
+    slot_count = 1
+
+#
+# Manager type which spawns subprocesses
+#
+
+class HostManager(managers.SyncManager):
+    '''
+    Manager type used for spawning processes on a (presumably) foreign host
+    '''
+    def __init__(self, address, authkey):
+        managers.SyncManager.__init__(self, address, authkey)
+        self._name = 'Host-unknown'
+
+    def Process(self, group=None, target=None, name=None, args=(), kwargs={}):
+        if hasattr(sys.modules['__main__'], '__file__'):
+            main_path = os.path.basename(sys.modules['__main__'].__file__)
+        else:
+            main_path = None
+        data = pickle.dumps((target, args, kwargs))
+        p = self._RemoteProcess(data, main_path)
+        if name is None:
+            temp = self._name.split('Host-')[-1] + '/Process-%s'
+            name = temp % ':'.join(map(str, p.get_identity()))
+        p.set_name(name)
+        return p
+
+    @classmethod
+    def from_address(cls, address, authkey):
+        manager = cls(address, authkey)
+        managers.transact(address, authkey, 'dummy')
+        manager._state.value = managers.State.STARTED
+        manager._name = 'Host-%s:%s' % manager.address
+        manager.shutdown = util.Finalize(
+            manager, HostManager._finalize_host,
+            args=(manager._address, manager._authkey, manager._name),
+            exitpriority=-10
+            )
+        return manager
+
+    @staticmethod
+    def _finalize_host(address, authkey, name):
+        managers.transact(address, authkey, 'shutdown')
+
+    def __repr__(self):
+        return '<Host(%s)>' % self._name
+
+#
+# Process subclass representing a process on (possibly) a remote machine
+#
+
+class RemoteProcess(Process):
+    '''
+    Represents a process started on a remote host
+    '''
+    def __init__(self, data, main_path):
+        assert not main_path or os.path.basename(main_path) == main_path
+        Process.__init__(self)
+        self._data = data
+        self._main_path = main_path
+
+    def _bootstrap(self):
+        forking.prepare({'main_path': self._main_path})
+        self._target, self._args, self._kwargs = pickle.loads(self._data)
+        return Process._bootstrap(self)
+
+    def get_identity(self):
+        return self._identity
+
+HostManager.register('_RemoteProcess', RemoteProcess)
+
+#
+# A Pool class that uses a cluster
+#
+
+class DistributedPool(pool.Pool):
+
+    def __init__(self, cluster, processes=None, initializer=None, initargs=()):
+        self._cluster = cluster
+        self.Process = cluster.Process
+        pool.Pool.__init__(self, processes or len(cluster),
+                           initializer, initargs)
+
+    def _setup_queues(self):
+        self._inqueue = self._cluster._SettableQueue()
+        self._outqueue = self._cluster._SettableQueue()
+        self._quick_put = self._inqueue.put
+        self._quick_get = self._outqueue.get
+
+    @staticmethod
+    def _help_stuff_finish(inqueue, task_handler, size):
+        inqueue.set_contents([None] * size)
+
+#
+# Manager type which starts host managers on other machines
+#
+
+def LocalProcess(**kwds):
+    p = Process(**kwds)
+    p.set_name('localhost/' + p.get_name())
+    return p
+
+class Cluster(managers.SyncManager):
+    '''
+    Represents collection of slots running on various hosts.
+
+    `Cluster` is a subclass of `SyncManager` so it allows creation of
+    various types of shared objects.
+    '''
+    def __init__(self, hostlist, modules):
+        managers.SyncManager.__init__(self, address=('localhost', 0))
+        self._hostlist = hostlist
+        self._modules = modules
+        if __name__ not in modules:
+            modules.append(__name__)
+        files = [sys.modules[name].__file__ for name in modules]
+        for i, file in enumerate(files):
+            if file.endswith('.pyc') or file.endswith('.pyo'):
+                files[i] = file[:-4] + '.py'
+        self._files = [os.path.abspath(file) for file in files]
+
+    def start(self):
+        managers.SyncManager.start(self)
+
+        l = connection.Listener(family='AF_INET', authkey=self._authkey)
+
+        for i, host in enumerate(self._hostlist):
+            host._start_manager(i, self._authkey, l.address, self._files)
+
+        for host in self._hostlist:
+            if host.hostname != 'localhost':
+                conn = l.accept()
+                i, address, cpus = conn.recv()
+                conn.close()
+                other_host = self._hostlist[i]
+                other_host.manager = HostManager.from_address(address,
+                                                              self._authkey)
+                other_host.slots = other_host.slots or cpus
+                other_host.Process = other_host.manager.Process
+            else:
+                host.slots = host.slots or slot_count
+                host.Process = LocalProcess
+
+        self._slotlist = [
+            Slot(host) for host in self._hostlist for i in range(host.slots)
+            ]
+        self._slot_iterator = itertools.cycle(self._slotlist)
+        self._base_shutdown = self.shutdown
+        del self.shutdown
+
+    def shutdown(self):
+        for host in self._hostlist:
+            if host.hostname != 'localhost':
+                host.manager.shutdown()
+        self._base_shutdown()
+
+    def Process(self, group=None, target=None, name=None, args=(), kwargs={}):
+        slot = self._slot_iterator.next()
+        return slot.Process(
+            group=group, target=target, name=name, args=args, kwargs=kwargs
+            )
+
+    def Pool(self, processes=None, initializer=None, initargs=()):
+        return DistributedPool(self, processes, initializer, initargs)
+
+    def __getitem__(self, i):
+        return self._slotlist[i]
+
+    def __len__(self):
+        return len(self._slotlist)
+
+    def __iter__(self):
+        return iter(self._slotlist)
+
+#
+# Queue subclass used by distributed pool
+#
+
+class SettableQueue(Queue.Queue):
+    def empty(self):
+        return not self.queue
+    def full(self):
+        return self.maxsize > 0 and len(self.queue) == self.maxsize
+    def set_contents(self, contents):
+        # length of contents must be at least as large as the number of
+        # threads which have potentially called get()
+        self.not_empty.acquire()
+        try:
+            self.queue.clear()
+            self.queue.extend(contents)
+            self.not_empty.notifyAll()
+        finally:
+            self.not_empty.release()
+
+Cluster.register('_SettableQueue', SettableQueue)
+
+#
+# Class representing a notional cpu in the cluster
+#
+
+class Slot(object):
+    def __init__(self, host):
+        self.host = host
+        self.Process = host.Process
+
+#
+# Host
+#
+
+class Host(object):
+    '''
+    Represents a host to use as a node in a cluster.
+
+    `hostname` gives the name of the host.  If hostname is not
+    "localhost" then ssh is used to log in to the host.  To log in as
+    a different user use a host name of the form
+    "username at somewhere.org"
+
+    `slots` is used to specify the number of slots for processes on
+    the host.  This affects how often processes will be allocated to
+    this host.  Normally this should be equal to the number of cpus on
+    that host.
+    '''
+    def __init__(self, hostname, slots=None):
+        self.hostname = hostname
+        self.slots = slots
+
+    def _start_manager(self, index, authkey, address, files):
+        if self.hostname != 'localhost':
+            tempdir = copy_to_remote_temporary_directory(self.hostname, files)
+            debug('startup files copied to %s:%s', self.hostname, tempdir)
+            p = subprocess.Popen(
+                ['ssh', self.hostname, 'python', '-c',
+                 '"import os; os.chdir(%r); '
+                 'from distributing import main; main()"' % tempdir],
+                stdin=subprocess.PIPE
+                )
+            data = dict(
+                name='BoostrappingHost', index=index,
+                dist_log_level=_logger.getEffectiveLevel(),
+                dir=tempdir, authkey=str(authkey), parent_address=address
+                )
+            pickle.dump(data, p.stdin, pickle.HIGHEST_PROTOCOL)
+            p.stdin.close()
+
+#
+# Copy files to remote directory, returning name of directory
+#
+
+unzip_code = '''"
+import tempfile, os, sys, tarfile
+tempdir = tempfile.mkdtemp(prefix='distrib-')
+os.chdir(tempdir)
+tf = tarfile.open(fileobj=sys.stdin, mode='r|gz')
+for ti in tf:
+    tf.extract(ti)
+print tempdir
+"'''
+
+def copy_to_remote_temporary_directory(host, files):
+    p = subprocess.Popen(
+        ['ssh', host, 'python', '-c', unzip_code],
+        stdout=subprocess.PIPE, stdin=subprocess.PIPE
+        )
+    tf = tarfile.open(fileobj=p.stdin, mode='w|gz')
+    for name in files:
+        tf.add(name, os.path.basename(name))
+    tf.close()
+    p.stdin.close()
+    return p.stdout.read().rstrip()
+
+#
+# Code which runs a host manager
+#
+
+def main():
+    # get data from parent over stdin
+    data = pickle.load(sys.stdin)
+    sys.stdin.close()
+
+    # set some stuff
+    _logger.setLevel(data['dist_log_level'])
+    forking.prepare(data)
+
+    # create server for a `HostManager` object
+    server = managers.Server(HostManager._registry, ('', 0), data['authkey'])
+    current_process()._server = server
+
+    # report server address and number of cpus back to parent
+    conn = connection.Client(data['parent_address'], authkey=data['authkey'])
+    conn.send((data['index'], server.address, slot_count))
+    conn.close()
+
+    # set name etc
+    current_process().set_name('Host-%s:%s' % server.address)
+    util._run_after_forkers()
+
+    # register a cleanup function
+    def cleanup(directory):
+        debug('removing directory %s', directory)
+        shutil.rmtree(directory)
+        debug('shutting down host manager')
+    util.Finalize(None, cleanup, args=[data['dir']], exitpriority=0)
+
+    # start host manager
+    debug('remote host manager starting in %s', data['dir'])
+    server.serve_forever()

Modified: python/branches/py3k/Doc/library/someos.rst
==============================================================================
--- python/branches/py3k/Doc/library/someos.rst	(original)
+++ python/branches/py3k/Doc/library/someos.rst	Wed Jun 11 18:44:04 2008
@@ -15,9 +15,9 @@
 
    select.rst
    threading.rst
-   dummy_threading.rst
    _thread.rst
    _dummy_thread.rst
+   multiprocessing.rst
    mmap.rst
    readline.rst
    rlcompleter.rst

Modified: python/branches/py3k/Lib/multiprocessing/__init__.py
==============================================================================
--- /python/trunk/Lib/multiprocessing/__init__.py	(original)
+++ python/branches/py3k/Lib/multiprocessing/__init__.py	Wed Jun 11 18:44:04 2008
@@ -1,269 +1,270 @@
-#
-# Package analogous to 'threading.py' but using processes
-#
-# multiprocessing/__init__.py
-#
-# This package is intended to duplicate the functionality (and much of
-# the API) of threading.py but uses processes instead of threads.  A
-# subpackage 'multiprocessing.dummy' has the same API but is a simple
-# wrapper for 'threading'.
-#
-# Try calling `multiprocessing.doc.main()` to read the html
-# documentation in in a webbrowser.
-#
-#
-# Copyright (c) 2006-2008, R Oudkerk
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-#
-# 1. Redistributions of source code must retain the above copyright
-#    notice, this list of conditions and the following disclaimer.
-# 2. Redistributions in binary form must reproduce the above copyright
-#    notice, this list of conditions and the following disclaimer in the
-#    documentation and/or other materials provided with the distribution.
-# 3. Neither the name of author nor the names of any contributors may be
-#    used to endorse or promote products derived from this software
-#    without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
-# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-#
-
-__version__ = '0.70a1'
-
-__all__ = [
-    'Process', 'current_process', 'active_children', 'freeze_support',
-    'Manager', 'Pipe', 'cpu_count', 'log_to_stderr', 'get_logger',
-    'allow_connection_pickling', 'BufferTooShort', 'TimeoutError',
-    'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Condition',
-    'Event', 'Queue', 'JoinableQueue', 'Pool', 'Value', 'Array',
-    'RawValue', 'RawArray'
-    ]
-
-__author__ = 'R. Oudkerk (r.m.oudkerk at gmail.com)'
-
-#
-# Imports
-#
-
-import os
-import sys
-
-import _multiprocessing
-from multiprocessing.process import Process, current_process, active_children
-
-#
-# Exceptions
-#
-
-class ProcessError(Exception):
-    pass
-    
-class BufferTooShort(ProcessError):
-    pass
-    
-class TimeoutError(ProcessError):
-    pass
-
-class AuthenticationError(ProcessError):
-    pass
-
-#
-# Definitions not depending on native semaphores
-#
-
-def Manager():
-    '''
-    Returns a manager associated with a running server process
-
-    The managers methods such as `Lock()`, `Condition()` and `Queue()`
-    can be used to create shared objects.
-    '''
-    from multiprocessing.managers import SyncManager
-    m = SyncManager()
-    m.start()
-    return m
-
-def Pipe(duplex=True):
-    '''
-    Returns two connection object connected by a pipe
-    '''
-    from multiprocessing.connection import Pipe
-    return Pipe(duplex)
-
-def cpu_count():
-    '''
-    Returns the number of CPUs in the system
-    '''
-    if sys.platform == 'win32':
-        try:
-            num = int(os.environ['NUMBER_OF_PROCESSORS'])
-        except (ValueError, KeyError):
-            num = 0
-    elif sys.platform == 'darwin':
-        try:
-            num = int(os.popen('sysctl -n hw.ncpu').read())
-        except ValueError:
-            num = 0
-    else:
-        try:
-            num = os.sysconf('SC_NPROCESSORS_ONLN')
-        except (ValueError, OSError, AttributeError):
-            num = 0
-        
-    if num >= 1:
-        return num
-    else:
-        raise NotImplementedError('cannot determine number of cpus')
-
-def freeze_support():
-    '''
-    Check whether this is a fake forked process in a frozen executable.
-    If so then run code specified by commandline and exit.
-    '''
-    if sys.platform == 'win32' and getattr(sys, 'frozen', False):
-        from multiprocessing.forking import freeze_support
-        freeze_support()
-
-def get_logger():
-    '''
-    Return package logger -- if it does not already exist then it is created
-    '''
-    from multiprocessing.util import get_logger
-    return get_logger()
-
-def log_to_stderr(level=None):
-    '''
-    Turn on logging and add a handler which prints to stderr
-    '''
-    from multiprocessing.util import log_to_stderr
-    return log_to_stderr(level)
-    
-def allow_connection_pickling():
-    '''
-    Install support for sending connections and sockets between processes
-    '''
-    from multiprocessing import reduction
-    
-#
-# Definitions depending on native semaphores
-#
-
-def Lock():
-    '''
-    Returns a non-recursive lock object
-    '''
-    from multiprocessing.synchronize import Lock
-    return Lock()
-
-def RLock():
-    '''
-    Returns a recursive lock object
-    '''
-    from multiprocessing.synchronize import RLock
-    return RLock()
-
-def Condition(lock=None):
-    '''
-    Returns a condition object
-    '''
-    from multiprocessing.synchronize import Condition
-    return Condition(lock)
-
-def Semaphore(value=1):
-    '''
-    Returns a semaphore object
-    '''
-    from multiprocessing.synchronize import Semaphore
-    return Semaphore(value)
-
-def BoundedSemaphore(value=1):
-    '''
-    Returns a bounded semaphore object
-    '''
-    from multiprocessing.synchronize import BoundedSemaphore
-    return BoundedSemaphore(value)
-
-def Event():
-    '''
-    Returns an event object
-    '''
-    from multiprocessing.synchronize import Event
-    return Event()
-
-def Queue(maxsize=0):
-    '''
-    Returns a queue object
-    '''
-    from multiprocessing.queues import Queue
-    return Queue(maxsize)
-
-def JoinableQueue(maxsize=0):
-    '''
-    Returns a queue object
-    '''
-    from multiprocessing.queues import JoinableQueue
-    return JoinableQueue(maxsize)
-
-def Pool(processes=None, initializer=None, initargs=()):
-    '''
-    Returns a process pool object
-    '''
-    from multiprocessing.pool import Pool
-    return Pool(processes, initializer, initargs)
-
-def RawValue(typecode_or_type, *args):
-    '''
-    Returns a shared object
-    '''
-    from multiprocessing.sharedctypes import RawValue
-    return RawValue(typecode_or_type, *args)
-
-def RawArray(typecode_or_type, size_or_initializer):
-    '''
-    Returns a shared array
-    '''
-    from multiprocessing.sharedctypes import RawArray
-    return RawArray(typecode_or_type, size_or_initializer)
-
-def Value(typecode_or_type, *args, **kwds):
-    '''
-    Returns a synchronized shared object
-    '''
-    from multiprocessing.sharedctypes import Value
-    return Value(typecode_or_type, *args, **kwds)
-
-def Array(typecode_or_type, size_or_initializer, **kwds):
-    '''
-    Returns a synchronized shared array
-    '''
-    from multiprocessing.sharedctypes import Array
-    return Array(typecode_or_type, size_or_initializer, **kwds)
-
-#
-#
-#
-
-if sys.platform == 'win32':
-
-    def set_executable(executable):
-        '''
-        Sets the path to a python.exe or pythonw.exe binary used to run
-        child processes on Windows instead of sys.executable.
-        Useful for people embedding Python. 
-        '''
-        from multiprocessing.forking import set_executable
-        set_executable(executable)
-
-    __all__ += ['set_executable']
+#
+# Package analogous to 'threading.py' but using processes
+#
+# multiprocessing/__init__.py
+#
+# This package is intended to duplicate the functionality (and much of
+# the API) of threading.py but uses processes instead of threads.  A
+# subpackage 'multiprocessing.dummy' has the same API but is a simple
+# wrapper for 'threading'.
+#
+# Try calling `multiprocessing.doc.main()` to read the html
+# documentation in in a webbrowser.
+#
+#
+# Copyright (c) 2006-2008, R Oudkerk
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. Neither the name of author nor the names of any contributors may be
+#    used to endorse or promote products derived from this software
+#    without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+#
+
+__version__ = '0.70a1'
+
+__all__ = [
+    'Process', 'current_process', 'active_children', 'freeze_support',
+    'Manager', 'Pipe', 'cpu_count', 'log_to_stderr', 'get_logger',
+    'allow_connection_pickling', 'BufferTooShort', 'TimeoutError',
+    'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Condition',
+    'Event', 'Queue', 'JoinableQueue', 'Pool', 'Value', 'Array',
+    'RawValue', 'RawArray'
+    ]
+
+__author__ = 'R. Oudkerk (r.m.oudkerk at gmail.com)'
+
+#
+# Imports
+#
+
+import os
+import sys
+
+from multiprocessing.process import Process, current_process, active_children
+
+#
+# Exceptions
+#
+
+class ProcessError(Exception):
+    pass
+
+class BufferTooShort(ProcessError):
+    pass
+
+class TimeoutError(ProcessError):
+    pass
+
+class AuthenticationError(ProcessError):
+    pass
+
+import _multiprocessing
+
+#
+# Definitions not depending on native semaphores
+#
+
+def Manager():
+    '''
+    Returns a manager associated with a running server process
+
+    The managers methods such as `Lock()`, `Condition()` and `Queue()`
+    can be used to create shared objects.
+    '''
+    from multiprocessing.managers import SyncManager
+    m = SyncManager()
+    m.start()
+    return m
+
+def Pipe(duplex=True):
+    '''
+    Returns two connection object connected by a pipe
+    '''
+    from multiprocessing.connection import Pipe
+    return Pipe(duplex)
+
+def cpu_count():
+    '''
+    Returns the number of CPUs in the system
+    '''
+    if sys.platform == 'win32':
+        try:
+            num = int(os.environ['NUMBER_OF_PROCESSORS'])
+        except (ValueError, KeyError):
+            num = 0
+    elif sys.platform == 'darwin':
+        try:
+            num = int(os.popen('sysctl -n hw.ncpu').read())
+        except ValueError:
+            num = 0
+    else:
+        try:
+            num = os.sysconf('SC_NPROCESSORS_ONLN')
+        except (ValueError, OSError, AttributeError):
+            num = 0
+
+    if num >= 1:
+        return num
+    else:
+        raise NotImplementedError('cannot determine number of cpus')
+
+def freeze_support():
+    '''
+    Check whether this is a fake forked process in a frozen executable.
+    If so then run code specified by commandline and exit.
+    '''
+    if sys.platform == 'win32' and getattr(sys, 'frozen', False):
+        from multiprocessing.forking import freeze_support
+        freeze_support()
+
+def get_logger():
+    '''
+    Return package logger -- if it does not already exist then it is created
+    '''
+    from multiprocessing.util import get_logger
+    return get_logger()
+
+def log_to_stderr(level=None):
+    '''
+    Turn on logging and add a handler which prints to stderr
+    '''
+    from multiprocessing.util import log_to_stderr
+    return log_to_stderr(level)
+
+def allow_connection_pickling():
+    '''
+    Install support for sending connections and sockets between processes
+    '''
+    from multiprocessing import reduction
+
+#
+# Definitions depending on native semaphores
+#
+
+def Lock():
+    '''
+    Returns a non-recursive lock object
+    '''
+    from multiprocessing.synchronize import Lock
+    return Lock()
+
+def RLock():
+    '''
+    Returns a recursive lock object
+    '''
+    from multiprocessing.synchronize import RLock
+    return RLock()
+
+def Condition(lock=None):
+    '''
+    Returns a condition object
+    '''
+    from multiprocessing.synchronize import Condition
+    return Condition(lock)
+
+def Semaphore(value=1):
+    '''
+    Returns a semaphore object
+    '''
+    from multiprocessing.synchronize import Semaphore
+    return Semaphore(value)
+
+def BoundedSemaphore(value=1):
+    '''
+    Returns a bounded semaphore object
+    '''
+    from multiprocessing.synchronize import BoundedSemaphore
+    return BoundedSemaphore(value)
+
+def Event():
+    '''
+    Returns an event object
+    '''
+    from multiprocessing.synchronize import Event
+    return Event()
+
+def Queue(maxsize=0):
+    '''
+    Returns a queue object
+    '''
+    from multiprocessing.queues import Queue
+    return Queue(maxsize)
+
+def JoinableQueue(maxsize=0):
+    '''
+    Returns a queue object
+    '''
+    from multiprocessing.queues import JoinableQueue
+    return JoinableQueue(maxsize)
+
+def Pool(processes=None, initializer=None, initargs=()):
+    '''
+    Returns a process pool object
+    '''
+    from multiprocessing.pool import Pool
+    return Pool(processes, initializer, initargs)
+
+def RawValue(typecode_or_type, *args):
+    '''
+    Returns a shared object
+    '''
+    from multiprocessing.sharedctypes import RawValue
+    return RawValue(typecode_or_type, *args)
+
+def RawArray(typecode_or_type, size_or_initializer):
+    '''
+    Returns a shared array
+    '''
+    from multiprocessing.sharedctypes import RawArray
+    return RawArray(typecode_or_type, size_or_initializer)
+
+def Value(typecode_or_type, *args, **kwds):
+    '''
+    Returns a synchronized shared object
+    '''
+    from multiprocessing.sharedctypes import Value
+    return Value(typecode_or_type, *args, **kwds)
+
+def Array(typecode_or_type, size_or_initializer, **kwds):
+    '''
+    Returns a synchronized shared array
+    '''
+    from multiprocessing.sharedctypes import Array
+    return Array(typecode_or_type, size_or_initializer, **kwds)
+
+#
+#
+#
+
+if sys.platform == 'win32':
+
+    def set_executable(executable):
+        '''
+        Sets the path to a python.exe or pythonw.exe binary used to run
+        child processes on Windows instead of sys.executable.
+        Useful for people embedding Python.
+        '''
+        from multiprocessing.forking import set_executable
+        set_executable(executable)
+
+    __all__ += ['set_executable']

Modified: python/branches/py3k/Lib/multiprocessing/connection.py
==============================================================================
--- /python/trunk/Lib/multiprocessing/connection.py	(original)
+++ python/branches/py3k/Lib/multiprocessing/connection.py	Wed Jun 11 18:44:04 2008
@@ -1,425 +1,425 @@
-#
-# A higher level module for using sockets (or Windows named pipes)
-#
-# multiprocessing/connection.py
-#
-# Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
-#
-
-__all__ = [ 'Client', 'Listener', 'Pipe' ]
-
-import os
-import sys
-import socket
-import time
-import tempfile
-import itertools
-
-import _multiprocessing
-from multiprocessing import current_process
-from multiprocessing.util import get_temp_dir, Finalize, sub_debug, debug
-from multiprocessing.forking import duplicate, close
-
-
-#
-#
-#
-
-BUFSIZE = 8192
-
-_mmap_counter = itertools.count()
-
-default_family = 'AF_INET'
-families = ['AF_INET']
-
-if hasattr(socket, 'AF_UNIX'):
-    default_family = 'AF_UNIX'
-    families += ['AF_UNIX']
-
-if sys.platform == 'win32':
-    default_family = 'AF_PIPE'
-    families += ['AF_PIPE']
-
-#
-#
-#
-
-def arbitrary_address(family):
-    '''
-    Return an arbitrary free address for the given family
-    '''
-    if family == 'AF_INET':
-        return ('localhost', 0)
-    elif family == 'AF_UNIX':        
-        return tempfile.mktemp(prefix='listener-', dir=get_temp_dir())
-    elif family == 'AF_PIPE':
-        return tempfile.mktemp(prefix=r'\\.\pipe\pyc-%d-%d-' %
-                               (os.getpid(), _mmap_counter.next()))
-    else:
-        raise ValueError('unrecognized family')
-
-
-def address_type(address):
-    '''
-    Return the types of the address
-
-    This can be 'AF_INET', 'AF_UNIX', or 'AF_PIPE'
-    '''
-    if type(address) == tuple:
-        return 'AF_INET'
-    elif type(address) is str and address.startswith('\\\\'):
-        return 'AF_PIPE'
-    elif type(address) is str:
-        return 'AF_UNIX'
-    else:
-        raise ValueError('address type of %r unrecognized' % address)
-
-#
-# Public functions
-#
-
-class Listener(object):
-    '''
-    Returns a listener object.
-
-    This is a wrapper for a bound socket which is 'listening' for
-    connections, or for a Windows named pipe.
-    '''
-    def __init__(self, address=None, family=None, backlog=1, authkey=None):
-        family = family or (address and address_type(address)) \
-                 or default_family
-        address = address or arbitrary_address(family)
-
-        if family == 'AF_PIPE':
-            self._listener = PipeListener(address, backlog)
-        else:
-            self._listener = SocketListener(address, family, backlog)
-
-        if authkey is not None and not isinstance(authkey, bytes):
-            raise TypeError, 'authkey should be a byte string'
-
-        self._authkey = authkey
-
-    def accept(self):
-        '''
-        Accept a connection on the bound socket or named pipe of `self`.
-
-        Returns a `Connection` object.
-        '''
-        c = self._listener.accept()
-        if self._authkey:
-            deliver_challenge(c, self._authkey)
-            answer_challenge(c, self._authkey)
-        return c
-
-    def close(self):
-        '''
-        Close the bound socket or named pipe of `self`.
-        '''
-        return self._listener.close()
-
-    address = property(lambda self: self._listener._address)
-    last_accepted = property(lambda self: self._listener._last_accepted)
-
-
-def Client(address, family=None, authkey=None):
-    '''
-    Returns a connection to the address of a `Listener`
-    '''
-    family = family or address_type(address)
-    if family == 'AF_PIPE':
-        c = PipeClient(address)
-    else:
-        c = SocketClient(address)
-
-    if authkey is not None and not isinstance(authkey, bytes):
-        raise TypeError, 'authkey should be a byte string'
-
-    if authkey is not None:
-        answer_challenge(c, authkey)
-        deliver_challenge(c, authkey)
-
-    return c
-
-
-if sys.platform != 'win32':
-
-    def Pipe(duplex=True):
-        '''
-        Returns pair of connection objects at either end of a pipe
-        '''
-        if duplex:
-            s1, s2 = socket.socketpair()
-            c1 = _multiprocessing.Connection(os.dup(s1.fileno()))
-            c2 = _multiprocessing.Connection(os.dup(s2.fileno()))
-            s1.close()
-            s2.close()
-        else:
-            fd1, fd2 = os.pipe()
-            c1 = _multiprocessing.Connection(fd1, writable=False)
-            c2 = _multiprocessing.Connection(fd2, readable=False)
-
-        return c1, c2
-    
-else:
-
-    from ._multiprocessing import win32
-
-    def Pipe(duplex=True):
-        '''
-        Returns pair of connection objects at either end of a pipe
-        '''
-        address = arbitrary_address('AF_PIPE')
-        if duplex:
-            openmode = win32.PIPE_ACCESS_DUPLEX
-            access = win32.GENERIC_READ | win32.GENERIC_WRITE
-            obsize, ibsize = BUFSIZE, BUFSIZE
-        else:
-            openmode = win32.PIPE_ACCESS_INBOUND
-            access = win32.GENERIC_WRITE
-            obsize, ibsize = 0, BUFSIZE
-
-        h1 = win32.CreateNamedPipe(
-            address, openmode,
-            win32.PIPE_TYPE_MESSAGE | win32.PIPE_READMODE_MESSAGE |
-            win32.PIPE_WAIT,
-            1, obsize, ibsize, win32.NMPWAIT_WAIT_FOREVER, win32.NULL
-            )
-        h2 = win32.CreateFile(
-            address, access, 0, win32.NULL, win32.OPEN_EXISTING, 0, win32.NULL
-            )
-        win32.SetNamedPipeHandleState(
-            h2, win32.PIPE_READMODE_MESSAGE, None, None
-            )
-
-        try:
-            win32.ConnectNamedPipe(h1, win32.NULL)
-        except WindowsError, e:
-            if e.args[0] != win32.ERROR_PIPE_CONNECTED:
-                raise
-
-        c1 = _multiprocessing.PipeConnection(h1, writable=duplex)
-        c2 = _multiprocessing.PipeConnection(h2, readable=duplex)
-        
-        return c1, c2
-
-#
-# Definitions for connections based on sockets
-#
-
-class SocketListener(object):
-    '''
-    Represtation of a socket which is bound to an address and listening
-    '''
-    def __init__(self, address, family, backlog=1):
-        self._socket = socket.socket(getattr(socket, family))
-        self._socket.bind(address)
-        self._socket.listen(backlog)
-        address = self._socket.getsockname()
-        if type(address) is tuple:
-            address = (socket.getfqdn(address[0]),) + address[1:]
-        self._address = address
-        self._family = family
-        self._last_accepted = None
-
-        sub_debug('listener bound to address %r', self._address)
-
-        if family == 'AF_UNIX':
-            self._unlink = Finalize(
-                self, os.unlink, args=(self._address,), exitpriority=0
-                )
-        else:
-            self._unlink = None
-
-    def accept(self):
-        s, self._last_accepted = self._socket.accept()
-        fd = duplicate(s.fileno())
-        conn = _multiprocessing.Connection(fd)
-        s.close()
-        return conn
-
-    def close(self):
-        self._socket.close()
-        if self._unlink is not None:
-            self._unlink()
-
-
-def SocketClient(address):
-    '''
-    Return a connection object connected to the socket given by `address`
-    '''
-    family = address_type(address)
-    s = socket.socket( getattr(socket, family) )
-
-    while 1:
-        try:
-            s.connect(address)
-        except socket.error, e:
-            if e.args[0] != 10061:    # 10061 => connection refused
-                debug('failed to connect to address %s', address)
-                raise
-            time.sleep(0.01)
-        else:
-            break
-    else:
-        raise
-
-    fd = duplicate(s.fileno())
-    conn = _multiprocessing.Connection(fd)
-    s.close()
-    return conn
-
-#
-# Definitions for connections based on named pipes
-#
-
-if sys.platform == 'win32':
-
-    class PipeListener(object):
-        '''
-        Representation of a named pipe
-        '''
-        def __init__(self, address, backlog=None):
-            self._address = address
-            handle = win32.CreateNamedPipe(
-                address, win32.PIPE_ACCESS_DUPLEX,
-                win32.PIPE_TYPE_MESSAGE | win32.PIPE_READMODE_MESSAGE |
-                win32.PIPE_WAIT,
-                win32.PIPE_UNLIMITED_INSTANCES, BUFSIZE, BUFSIZE,
-                win32.NMPWAIT_WAIT_FOREVER, win32.NULL
-                )
-            self._handle_queue = [handle]
-            self._last_accepted = None
-            
-            sub_debug('listener created with address=%r', self._address)
-
-            self.close = Finalize(
-                self, PipeListener._finalize_pipe_listener,
-                args=(self._handle_queue, self._address), exitpriority=0
-                )
-            
-        def accept(self):
-            newhandle = win32.CreateNamedPipe(
-                self._address, win32.PIPE_ACCESS_DUPLEX,
-                win32.PIPE_TYPE_MESSAGE | win32.PIPE_READMODE_MESSAGE |
-                win32.PIPE_WAIT,
-                win32.PIPE_UNLIMITED_INSTANCES, BUFSIZE, BUFSIZE,
-                win32.NMPWAIT_WAIT_FOREVER, win32.NULL
-                )
-            self._handle_queue.append(newhandle)
-            handle = self._handle_queue.pop(0)
-            try:
-                win32.ConnectNamedPipe(handle, win32.NULL)
-            except WindowsError, e:
-                if e.args[0] != win32.ERROR_PIPE_CONNECTED:
-                    raise
-            return _multiprocessing.PipeConnection(handle)
-
-        @staticmethod
-        def _finalize_pipe_listener(queue, address):
-            sub_debug('closing listener with address=%r', address)
-            for handle in queue:
-                close(handle)
-        
-    def PipeClient(address):
-        '''
-        Return a connection object connected to the pipe given by `address`
-        '''
-        while 1:
-            try:
-                win32.WaitNamedPipe(address, 1000)
-                h = win32.CreateFile(
-                    address, win32.GENERIC_READ | win32.GENERIC_WRITE,
-                    0, win32.NULL, win32.OPEN_EXISTING, 0, win32.NULL
-                    )
-            except WindowsError, e:
-                if e.args[0] not in (win32.ERROR_SEM_TIMEOUT,
-                                     win32.ERROR_PIPE_BUSY):
-                    raise
-            else:
-                break
-        else:
-            raise
-
-        win32.SetNamedPipeHandleState(
-            h, win32.PIPE_READMODE_MESSAGE, None, None
-            )
-        return _multiprocessing.PipeConnection(h)
-
-#
-# Authentication stuff
-#
-
-MESSAGE_LENGTH = 20
-
-CHALLENGE = '#CHALLENGE#'
-WELCOME = '#WELCOME#'
-FAILURE = '#FAILURE#'
-
-if sys.version_info >= (3, 0):         # XXX can use bytes literals in 2.6/3.0
-    CHALLENGE = CHALLENGE.encode('ascii')
-    WELCOME = WELCOME.encode('ascii')
-    FAILURE = FAILURE.encode('ascii')
-
-def deliver_challenge(connection, authkey):
-    import hmac
-    assert isinstance(authkey, bytes)
-    message = os.urandom(MESSAGE_LENGTH)
-    connection.send_bytes(CHALLENGE + message)
-    digest = hmac.new(authkey, message).digest()
-    response = connection.recv_bytes(256)        # reject large message
-    if response == digest:
-        connection.send_bytes(WELCOME)
-    else:
-        connection.send_bytes(FAILURE)
-        raise AuthenticationError('digest received was wrong')
-
-def answer_challenge(connection, authkey):
-    import hmac
-    assert isinstance(authkey, bytes)
-    message = connection.recv_bytes(256)         # reject large message
-    assert message[:len(CHALLENGE)] == CHALLENGE, 'message = %r' % message
-    message = message[len(CHALLENGE):]
-    digest = hmac.new(authkey, message).digest()
-    connection.send_bytes(digest)
-    response = connection.recv_bytes(256)        # reject large message
-    if response != WELCOME:
-        raise AuthenticationError('digest sent was rejected')
-
-#
-# Support for using xmlrpclib for serialization
-#
-
-class ConnectionWrapper(object):
-    def __init__(self, conn, dumps, loads):
-        self._conn = conn
-        self._dumps = dumps
-        self._loads = loads
-        for attr in ('fileno', 'close', 'poll', 'recv_bytes', 'send_bytes'):
-            obj = getattr(conn, attr)
-            setattr(self, attr, obj)            
-    def send(self, obj):
-        s = self._dumps(obj)
-        self._conn.send_bytes(s)
-    def recv(self):
-        s = self._conn.recv_bytes()
-        return self._loads(s)
-
-def _xml_dumps(obj):
-    return xmlrpclib.dumps((obj,), None, None, None, 1).encode('utf8')
-
-def _xml_loads(s):
-    (obj,), method = xmlrpclib.loads(s.decode('utf8'))
-    return obj
-
-class XmlListener(Listener):
-    def accept(self):
-        global xmlrpclib
-        import xmlrpclib
-        obj = Listener.accept(self)
-        return ConnectionWrapper(obj, _xml_dumps, _xml_loads)
-
-def XmlClient(*args, **kwds):
-    global xmlrpclib
-    import xmlrpclib
-    return ConnectionWrapper(Client(*args, **kwds), _xml_dumps, _xml_loads)
+#
+# A higher level module for using sockets (or Windows named pipes)
+#
+# multiprocessing/connection.py
+#
+# Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
+#
+
+__all__ = [ 'Client', 'Listener', 'Pipe' ]
+
+import os
+import sys
+import socket
+import time
+import tempfile
+import itertools
+
+import _multiprocessing
+from multiprocessing import current_process
+from multiprocessing.util import get_temp_dir, Finalize, sub_debug, debug
+from multiprocessing.forking import duplicate, close
+
+
+#
+#
+#
+
+BUFSIZE = 8192
+
+_mmap_counter = itertools.count()
+
+default_family = 'AF_INET'
+families = ['AF_INET']
+
+if hasattr(socket, 'AF_UNIX'):
+    default_family = 'AF_UNIX'
+    families += ['AF_UNIX']
+
+if sys.platform == 'win32':
+    default_family = 'AF_PIPE'
+    families += ['AF_PIPE']
+
+#
+#
+#
+
+def arbitrary_address(family):
+    '''
+    Return an arbitrary free address for the given family
+    '''
+    if family == 'AF_INET':
+        return ('localhost', 0)
+    elif family == 'AF_UNIX':
+        return tempfile.mktemp(prefix='listener-', dir=get_temp_dir())
+    elif family == 'AF_PIPE':
+        return tempfile.mktemp(prefix=r'\\.\pipe\pyc-%d-%d-' %
+                               (os.getpid(), next(_mmap_counter)))
+    else:
+        raise ValueError('unrecognized family')
+
+
+def address_type(address):
+    '''
+    Return the types of the address
+
+    This can be 'AF_INET', 'AF_UNIX', or 'AF_PIPE'
+    '''
+    if type(address) == tuple:
+        return 'AF_INET'
+    elif type(address) is str and address.startswith('\\\\'):
+        return 'AF_PIPE'
+    elif type(address) is str:
+        return 'AF_UNIX'
+    else:
+        raise ValueError('address type of %r unrecognized' % address)
+
+#
+# Public functions
+#
+
+class Listener(object):
+    '''
+    Returns a listener object.
+
+    This is a wrapper for a bound socket which is 'listening' for
+    connections, or for a Windows named pipe.
+    '''
+    def __init__(self, address=None, family=None, backlog=1, authkey=None):
+        family = family or (address and address_type(address)) \
+                 or default_family
+        address = address or arbitrary_address(family)
+
+        if family == 'AF_PIPE':
+            self._listener = PipeListener(address, backlog)
+        else:
+            self._listener = SocketListener(address, family, backlog)
+
+        if authkey is not None and not isinstance(authkey, bytes):
+            raise TypeError('authkey should be a byte string')
+
+        self._authkey = authkey
+
+    def accept(self):
+        '''
+        Accept a connection on the bound socket or named pipe of `self`.
+
+        Returns a `Connection` object.
+        '''
+        c = self._listener.accept()
+        if self._authkey:
+            deliver_challenge(c, self._authkey)
+            answer_challenge(c, self._authkey)
+        return c
+
+    def close(self):
+        '''
+        Close the bound socket or named pipe of `self`.
+        '''
+        return self._listener.close()
+
+    address = property(lambda self: self._listener._address)
+    last_accepted = property(lambda self: self._listener._last_accepted)
+
+
+def Client(address, family=None, authkey=None):
+    '''
+    Returns a connection to the address of a `Listener`
+    '''
+    family = family or address_type(address)
+    if family == 'AF_PIPE':
+        c = PipeClient(address)
+    else:
+        c = SocketClient(address)
+
+    if authkey is not None and not isinstance(authkey, bytes):
+        raise TypeError('authkey should be a byte string')
+
+    if authkey is not None:
+        answer_challenge(c, authkey)
+        deliver_challenge(c, authkey)
+
+    return c
+
+
+if sys.platform != 'win32':
+
+    def Pipe(duplex=True):
+        '''
+        Returns pair of connection objects at either end of a pipe
+        '''
+        if duplex:
+            s1, s2 = socket.socketpair()
+            c1 = _multiprocessing.Connection(os.dup(s1.fileno()))
+            c2 = _multiprocessing.Connection(os.dup(s2.fileno()))
+            s1.close()
+            s2.close()
+        else:
+            fd1, fd2 = os.pipe()
+            c1 = _multiprocessing.Connection(fd1, writable=False)
+            c2 = _multiprocessing.Connection(fd2, readable=False)
+
+        return c1, c2
+
+else:
+
+    from ._multiprocessing import win32
+
+    def Pipe(duplex=True):
+        '''
+        Returns pair of connection objects at either end of a pipe
+        '''
+        address = arbitrary_address('AF_PIPE')
+        if duplex:
+            openmode = win32.PIPE_ACCESS_DUPLEX
+            access = win32.GENERIC_READ | win32.GENERIC_WRITE
+            obsize, ibsize = BUFSIZE, BUFSIZE
+        else:
+            openmode = win32.PIPE_ACCESS_INBOUND
+            access = win32.GENERIC_WRITE
+            obsize, ibsize = 0, BUFSIZE
+
+        h1 = win32.CreateNamedPipe(
+            address, openmode,
+            win32.PIPE_TYPE_MESSAGE | win32.PIPE_READMODE_MESSAGE |
+            win32.PIPE_WAIT,
+            1, obsize, ibsize, win32.NMPWAIT_WAIT_FOREVER, win32.NULL
+            )
+        h2 = win32.CreateFile(
+            address, access, 0, win32.NULL, win32.OPEN_EXISTING, 0, win32.NULL
+            )
+        win32.SetNamedPipeHandleState(
+            h2, win32.PIPE_READMODE_MESSAGE, None, None
+            )
+
+        try:
+            win32.ConnectNamedPipe(h1, win32.NULL)
+        except WindowsError as e:
+            if e.args[0] != win32.ERROR_PIPE_CONNECTED:
+                raise
+
+        c1 = _multiprocessing.PipeConnection(h1, writable=duplex)
+        c2 = _multiprocessing.PipeConnection(h2, readable=duplex)
+
+        return c1, c2
+
+#
+# Definitions for connections based on sockets
+#
+
+class SocketListener(object):
+    '''
+    Represtation of a socket which is bound to an address and listening
+    '''
+    def __init__(self, address, family, backlog=1):
+        self._socket = socket.socket(getattr(socket, family))
+        self._socket.bind(address)
+        self._socket.listen(backlog)
+        address = self._socket.getsockname()
+        if type(address) is tuple:
+            address = (socket.getfqdn(address[0]),) + address[1:]
+        self._address = address
+        self._family = family
+        self._last_accepted = None
+
+        sub_debug('listener bound to address %r', self._address)
+
+        if family == 'AF_UNIX':
+            self._unlink = Finalize(
+                self, os.unlink, args=(self._address,), exitpriority=0
+                )
+        else:
+            self._unlink = None
+
+    def accept(self):
+        s, self._last_accepted = self._socket.accept()
+        fd = duplicate(s.fileno())
+        conn = _multiprocessing.Connection(fd)
+        s.close()
+        return conn
+
+    def close(self):
+        self._socket.close()
+        if self._unlink is not None:
+            self._unlink()
+
+
+def SocketClient(address):
+    '''
+    Return a connection object connected to the socket given by `address`
+    '''
+    family = address_type(address)
+    s = socket.socket( getattr(socket, family) )
+
+    while 1:
+        try:
+            s.connect(address)
+        except socket.error as e:
+            if e.args[0] != 10061:    # 10061 => connection refused
+                debug('failed to connect to address %s', address)
+                raise
+            time.sleep(0.01)
+        else:
+            break
+    else:
+        raise
+
+    fd = duplicate(s.fileno())
+    conn = _multiprocessing.Connection(fd)
+    s.close()
+    return conn
+
+#
+# Definitions for connections based on named pipes
+#
+
+if sys.platform == 'win32':
+
+    class PipeListener(object):
+        '''
+        Representation of a named pipe
+        '''
+        def __init__(self, address, backlog=None):
+            self._address = address
+            handle = win32.CreateNamedPipe(
+                address, win32.PIPE_ACCESS_DUPLEX,
+                win32.PIPE_TYPE_MESSAGE | win32.PIPE_READMODE_MESSAGE |
+                win32.PIPE_WAIT,
+                win32.PIPE_UNLIMITED_INSTANCES, BUFSIZE, BUFSIZE,
+                win32.NMPWAIT_WAIT_FOREVER, win32.NULL
+                )
+            self._handle_queue = [handle]
+            self._last_accepted = None
+
+            sub_debug('listener created with address=%r', self._address)
+
+            self.close = Finalize(
+                self, PipeListener._finalize_pipe_listener,
+                args=(self._handle_queue, self._address), exitpriority=0
+                )
+
+        def accept(self):
+            newhandle = win32.CreateNamedPipe(
+                self._address, win32.PIPE_ACCESS_DUPLEX,
+                win32.PIPE_TYPE_MESSAGE | win32.PIPE_READMODE_MESSAGE |
+                win32.PIPE_WAIT,
+                win32.PIPE_UNLIMITED_INSTANCES, BUFSIZE, BUFSIZE,
+                win32.NMPWAIT_WAIT_FOREVER, win32.NULL
+                )
+            self._handle_queue.append(newhandle)
+            handle = self._handle_queue.pop(0)
+            try:
+                win32.ConnectNamedPipe(handle, win32.NULL)
+            except WindowsError as e:
+                if e.args[0] != win32.ERROR_PIPE_CONNECTED:
+                    raise
+            return _multiprocessing.PipeConnection(handle)
+
+        @staticmethod
+        def _finalize_pipe_listener(queue, address):
+            sub_debug('closing listener with address=%r', address)
+            for handle in queue:
+                close(handle)
+
+    def PipeClient(address):
+        '''
+        Return a connection object connected to the pipe given by `address`
+        '''
+        while 1:
+            try:
+                win32.WaitNamedPipe(address, 1000)
+                h = win32.CreateFile(
+                    address, win32.GENERIC_READ | win32.GENERIC_WRITE,
+                    0, win32.NULL, win32.OPEN_EXISTING, 0, win32.NULL
+                    )
+            except WindowsError as e:
+                if e.args[0] not in (win32.ERROR_SEM_TIMEOUT,
+                                     win32.ERROR_PIPE_BUSY):
+                    raise
+            else:
+                break
+        else:
+            raise
+
+        win32.SetNamedPipeHandleState(
+            h, win32.PIPE_READMODE_MESSAGE, None, None
+            )
+        return _multiprocessing.PipeConnection(h)
+
+#
+# Authentication stuff
+#
+
+MESSAGE_LENGTH = 20
+
+CHALLENGE = '#CHALLENGE#'
+WELCOME = '#WELCOME#'
+FAILURE = '#FAILURE#'
+
+if sys.version_info >= (3, 0):         # XXX can use bytes literals in 2.6/3.0
+    CHALLENGE = CHALLENGE.encode('ascii')
+    WELCOME = WELCOME.encode('ascii')
+    FAILURE = FAILURE.encode('ascii')
+
+def deliver_challenge(connection, authkey):
+    import hmac
+    assert isinstance(authkey, bytes)
+    message = os.urandom(MESSAGE_LENGTH)
+    connection.send_bytes(CHALLENGE + message)
+    digest = hmac.new(authkey, message).digest()
+    response = connection.recv_bytes(256)        # reject large message
+    if response == digest:
+        connection.send_bytes(WELCOME)
+    else:
+        connection.send_bytes(FAILURE)
+        raise AuthenticationError('digest received was wrong')
+
+def answer_challenge(connection, authkey):
+    import hmac
+    assert isinstance(authkey, bytes)
+    message = connection.recv_bytes(256)         # reject large message
+    assert message[:len(CHALLENGE)] == CHALLENGE, 'message = %r' % message
+    message = message[len(CHALLENGE):]
+    digest = hmac.new(authkey, message).digest()
+    connection.send_bytes(digest)
+    response = connection.recv_bytes(256)        # reject large message
+    if response != WELCOME:
+        raise AuthenticationError('digest sent was rejected')
+
+#
+# Support for using xmlrpclib for serialization
+#
+
+class ConnectionWrapper(object):
+    def __init__(self, conn, dumps, loads):
+        self._conn = conn
+        self._dumps = dumps
+        self._loads = loads
+        for attr in ('fileno', 'close', 'poll', 'recv_bytes', 'send_bytes'):
+            obj = getattr(conn, attr)
+            setattr(self, attr, obj)
+    def send(self, obj):
+        s = self._dumps(obj)
+        self._conn.send_bytes(s)
+    def recv(self):
+        s = self._conn.recv_bytes()
+        return self._loads(s)
+
+def _xml_dumps(obj):
+    return xmlrpclib.dumps((obj,), None, None, None, 1).encode('utf8')
+
+def _xml_loads(s):
+    (obj,), method = xmlrpclib.loads(s.decode('utf8'))
+    return obj
+
+class XmlListener(Listener):
+    def accept(self):
+        global xmlrpclib
+        import xmlrpc.client as xmlrpclib
+        obj = Listener.accept(self)
+        return ConnectionWrapper(obj, _xml_dumps, _xml_loads)
+
+def XmlClient(*args, **kwds):
+    global xmlrpclib
+    import xmlrpc.client as xmlrpclib
+    return ConnectionWrapper(Client(*args, **kwds), _xml_dumps, _xml_loads)

Modified: python/branches/py3k/Lib/multiprocessing/dummy/__init__.py
==============================================================================
--- /python/trunk/Lib/multiprocessing/dummy/__init__.py	(original)
+++ python/branches/py3k/Lib/multiprocessing/dummy/__init__.py	Wed Jun 11 18:44:04 2008
@@ -1,143 +1,143 @@
-#
-# Support for the API of the multiprocessing package using threads
-#
-# multiprocessing/dummy/__init__.py
-#
-# Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
-#
-
-__all__ = [
-    'Process', 'current_process', 'active_children', 'freeze_support',
-    'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Condition',
-    'Event', 'Queue', 'Manager', 'Pipe', 'Pool', 'JoinableQueue'
-    ]
-
-#
-# Imports
-#
-
-import threading
-import sys
-import weakref
-import array
-import itertools
-
-from multiprocessing import TimeoutError, cpu_count
-from multiprocessing.dummy.connection import Pipe
-from threading import Lock, RLock, Semaphore, BoundedSemaphore
-from threading import Event
-from Queue import Queue
-
-#
-#
-#
-
-class DummyProcess(threading.Thread):
-
-    def __init__(self, group=None, target=None, name=None, args=(), kwargs={}):
-        threading.Thread.__init__(self, group, target, name, args, kwargs)
-        self._pid = None
-        self._children = weakref.WeakKeyDictionary()
-        self._start_called = False
-        self._parent = current_process()
-
-    def start(self):
-        assert self._parent is current_process()
-        self._start_called = True
-        self._parent._children[self] = None
-        threading.Thread.start(self)
-
-    def get_exitcode(self):
-        if self._start_called and not self.isAlive():
-            return 0
-        else:
-            return None
-
-    # XXX
-    if sys.version_info < (3, 0):
-        is_alive = threading.Thread.isAlive.im_func
-        get_name = threading.Thread.getName.im_func
-        set_name = threading.Thread.setName.im_func
-        is_daemon = threading.Thread.isDaemon.im_func
-        set_daemon = threading.Thread.setDaemon.im_func
-    else:
-        is_alive = threading.Thread.isAlive
-        get_name = threading.Thread.getName
-        set_name = threading.Thread.setName
-        is_daemon = threading.Thread.isDaemon
-        set_daemon = threading.Thread.setDaemon
-
-#
-#
-#
-        
-class Condition(threading._Condition):
-    # XXX
-    if sys.version_info < (3, 0):
-        notify_all = threading._Condition.notifyAll.im_func
-    else:
-        notify_all = threading._Condition.notifyAll
-
-#
-#
-#
-
-Process = DummyProcess
-current_process = threading.currentThread
-current_process()._children = weakref.WeakKeyDictionary()
-
-def active_children():
-    children = current_process()._children
-    for p in list(children):
-        if not p.isAlive():
-            children.pop(p, None)
-    return list(children)
-
-def freeze_support():
-    pass
-
-#
-#
-#
-
-class Namespace(object):
-    def __init__(self, **kwds):
-        self.__dict__.update(kwds)
-    def __repr__(self):
-        items = self.__dict__.items()
-        temp = []
-        for name, value in items:
-            if not name.startswith('_'):
-                temp.append('%s=%r' % (name, value))
-        temp.sort()
-        return 'Namespace(%s)' % str.join(', ', temp)
-
-dict = dict
-list = list
-
-def Array(typecode, sequence, lock=True):
-    return array.array(typecode, sequence)
-
-class Value(object):
-    def __init__(self, typecode, value, lock=True):
-        self._typecode = typecode
-        self._value = value
-    def _get(self):
-        return self._value
-    def _set(self, value):
-        self._value = value
-    value = property(_get, _set)
-    def __repr__(self):
-        return '<%r(%r, %r)>'%(type(self).__name__,self._typecode,self._value)
-
-def Manager():
-    return sys.modules[__name__]
-
-def shutdown():
-    pass
-
-def Pool(processes=None, initializer=None, initargs=()):
-    from multiprocessing.pool import ThreadPool
-    return ThreadPool(processes, initializer, initargs)
-
-JoinableQueue = Queue
+#
+# Support for the API of the multiprocessing package using threads
+#
+# multiprocessing/dummy/__init__.py
+#
+# Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
+#
+
+__all__ = [
+    'Process', 'current_process', 'active_children', 'freeze_support',
+    'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Condition',
+    'Event', 'Queue', 'Manager', 'Pipe', 'Pool', 'JoinableQueue'
+    ]
+
+#
+# Imports
+#
+
+import threading
+import sys
+import weakref
+import array
+import itertools
+
+from multiprocessing import TimeoutError, cpu_count
+from multiprocessing.dummy.connection import Pipe
+from threading import Lock, RLock, Semaphore, BoundedSemaphore
+from threading import Event
+from queue import Queue
+
+#
+#
+#
+
+class DummyProcess(threading.Thread):
+
+    def __init__(self, group=None, target=None, name=None, args=(), kwargs={}):
+        threading.Thread.__init__(self, group, target, name, args, kwargs)
+        self._pid = None
+        self._children = weakref.WeakKeyDictionary()
+        self._start_called = False
+        self._parent = current_process()
+
+    def start(self):
+        assert self._parent is current_process()
+        self._start_called = True
+        self._parent._children[self] = None
+        threading.Thread.start(self)
+
+    def get_exitcode(self):
+        if self._start_called and not self.isAlive():
+            return 0
+        else:
+            return None
+
+    # XXX
+    if sys.version_info < (3, 0):
+        is_alive = threading.Thread.isAlive.__func__
+        get_name = threading.Thread.getName.__func__
+        set_name = threading.Thread.setName.__func__
+        is_daemon = threading.Thread.isDaemon.__func__
+        set_daemon = threading.Thread.setDaemon.__func__
+    else:
+        is_alive = threading.Thread.isAlive
+        get_name = threading.Thread.getName
+        set_name = threading.Thread.setName
+        is_daemon = threading.Thread.isDaemon
+        set_daemon = threading.Thread.setDaemon
+
+#
+#
+#
+
+class Condition(threading._Condition):
+    # XXX
+    if sys.version_info < (3, 0):
+        notify_all = threading._Condition.notifyAll.__func__
+    else:
+        notify_all = threading._Condition.notifyAll
+
+#
+#
+#
+
+Process = DummyProcess
+current_process = threading.currentThread
+current_process()._children = weakref.WeakKeyDictionary()
+
+def active_children():
+    children = current_process()._children
+    for p in list(children):
+        if not p.isAlive():
+            children.pop(p, None)
+    return list(children)
+
+def freeze_support():
+    pass
+
+#
+#
+#
+
+class Namespace(object):
+    def __init__(self, **kwds):
+        self.__dict__.update(kwds)
+    def __repr__(self):
+        items = list(self.__dict__.items())
+        temp = []
+        for name, value in items:
+            if not name.startswith('_'):
+                temp.append('%s=%r' % (name, value))
+        temp.sort()
+        return 'Namespace(%s)' % str.join(', ', temp)
+
+dict = dict
+list = list
+
+def Array(typecode, sequence, lock=True):
+    return array.array(typecode, sequence)
+
+class Value(object):
+    def __init__(self, typecode, value, lock=True):
+        self._typecode = typecode
+        self._value = value
+    def _get(self):
+        return self._value
+    def _set(self, value):
+        self._value = value
+    value = property(_get, _set)
+    def __repr__(self):
+        return '<%r(%r, %r)>'%(type(self).__name__,self._typecode,self._value)
+
+def Manager():
+    return sys.modules[__name__]
+
+def shutdown():
+    pass
+
+def Pool(processes=None, initializer=None, initargs=()):
+    from multiprocessing.pool import ThreadPool
+    return ThreadPool(processes, initializer, initargs)
+
+JoinableQueue = Queue

Modified: python/branches/py3k/Lib/multiprocessing/dummy/connection.py
==============================================================================
--- /python/trunk/Lib/multiprocessing/dummy/connection.py	(original)
+++ python/branches/py3k/Lib/multiprocessing/dummy/connection.py	Wed Jun 11 18:44:04 2008
@@ -1,61 +1,61 @@
-#
-# Analogue of `multiprocessing.connection` which uses queues instead of sockets
-#
-# multiprocessing/dummy/connection.py
-#
-# Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
-#
-
-__all__ = [ 'Client', 'Listener', 'Pipe' ]
-
-from Queue import Queue
-
-
-families = [None]
-
-
-class Listener(object):
-
-    def __init__(self, address=None, family=None, backlog=1):
-        self._backlog_queue = Queue(backlog)
-
-    def accept(self):
-        return Connection(*self._backlog_queue.get())
-
-    def close(self):
-        self._backlog_queue = None
-
-    address = property(lambda self: self._backlog_queue)
-
-
-def Client(address):
-    _in, _out = Queue(), Queue()
-    address.put((_out, _in))
-    return Connection(_in, _out)
-
-
-def Pipe(duplex=True):
-    a, b = Queue(), Queue()
-    return Connection(a, b), Connection(b, a)
-
-
-class Connection(object):
-
-    def __init__(self, _in, _out):
-        self._out = _out
-        self._in = _in
-        self.send = self.send_bytes = _out.put
-        self.recv = self.recv_bytes = _in.get
-
-    def poll(self, timeout=0.0):
-        if self._in.qsize() > 0:
-            return True
-        if timeout <= 0.0:
-            return False
-        self._in.not_empty.acquire()
-        self._in.not_empty.wait(timeout)
-        self._in.not_empty.release()
-        return self._in.qsize() > 0
-
-    def close(self):
-        pass
+#
+# Analogue of `multiprocessing.connection` which uses queues instead of sockets
+#
+# multiprocessing/dummy/connection.py
+#
+# Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
+#
+
+__all__ = [ 'Client', 'Listener', 'Pipe' ]
+
+from queue import Queue
+
+
+families = [None]
+
+
+class Listener(object):
+
+    def __init__(self, address=None, family=None, backlog=1):
+        self._backlog_queue = Queue(backlog)
+
+    def accept(self):
+        return Connection(*self._backlog_queue.get())
+
+    def close(self):
+        self._backlog_queue = None
+
+    address = property(lambda self: self._backlog_queue)
+
+
+def Client(address):
+    _in, _out = Queue(), Queue()
+    address.put((_out, _in))
+    return Connection(_in, _out)
+
+
+def Pipe(duplex=True):
+    a, b = Queue(), Queue()
+    return Connection(a, b), Connection(b, a)
+
+
+class Connection(object):
+
+    def __init__(self, _in, _out):
+        self._out = _out
+        self._in = _in
+        self.send = self.send_bytes = _out.put
+        self.recv = self.recv_bytes = _in.get
+
+    def poll(self, timeout=0.0):
+        if self._in.qsize() > 0:
+            return True
+        if timeout <= 0.0:
+            return False
+        self._in.not_empty.acquire()
+        self._in.not_empty.wait(timeout)
+        self._in.not_empty.release()
+        return self._in.qsize() > 0
+
+    def close(self):
+        pass

Modified: python/branches/py3k/Lib/multiprocessing/forking.py
==============================================================================
--- /python/trunk/Lib/multiprocessing/forking.py	(original)
+++ python/branches/py3k/Lib/multiprocessing/forking.py	Wed Jun 11 18:44:04 2008
@@ -1,429 +1,429 @@
-#
-# Module for starting a process object using os.fork() or CreateProcess()
-#
-# multiprocessing/forking.py
-#
-# Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
-#
-
-import os
-import sys
-import signal
-
-from multiprocessing import util, process
-
-__all__ = ['Popen', 'assert_spawning', 'exit', 'duplicate', 'close']
-
-#
-# Check that the current thread is spawning a child process
-#
-
-def assert_spawning(self):
-    if not Popen.thread_is_spawning():
-        raise RuntimeError(
-            '%s objects should only be shared between processes'
-            ' through inheritance' % type(self).__name__
-            )
-
-#
-# Unix
-#
-
-if sys.platform != 'win32':
-    import time
-
-    exit = os._exit
-    duplicate = os.dup
-    close = os.close
-
-    #
-    # We define a Popen class similar to the one from subprocess, but
-    # whose constructor takes a process object as its argument.
-    #
-
-    class Popen(object):
-
-        def __init__(self, process_obj):
-            sys.stdout.flush()
-            sys.stderr.flush()
-            self.returncode = None
-
-            self.pid = os.fork()
-            if self.pid == 0:
-                if 'random' in sys.modules:
-                    import random
-                    random.seed()
-                code = process_obj._bootstrap()
-                sys.stdout.flush()
-                sys.stderr.flush()
-                os._exit(code)
-
-        def poll(self, flag=os.WNOHANG):
-            if self.returncode is None:
-                pid, sts = os.waitpid(self.pid, flag)
-                if pid == self.pid:
-                    if os.WIFSIGNALED(sts):
-                        self.returncode = -os.WTERMSIG(sts)
-                    else:
-                        assert os.WIFEXITED(sts)
-                        self.returncode = os.WEXITSTATUS(sts)
-            return self.returncode
-
-        def wait(self, timeout=None):
-            if timeout is None:
-                return self.poll(0)
-            deadline = time.time() + timeout
-            delay = 0.0005
-            while 1:
-                res = self.poll()
-                if res is not None:
-                    break
-                remaining = deadline - time.time()
-                if remaining <= 0:
-                    break
-                delay = min(delay * 2, remaining, 0.05)
-                time.sleep(delay)
-            return res
-
-        def terminate(self):
-            if self.returncode is None:
-                try:
-                    os.kill(self.pid, signal.SIGTERM)
-                except OSError, e:
-                    if self.wait(timeout=0.1) is None:
-                        raise
-                    
-        @staticmethod
-        def thread_is_spawning():
-            return False
-
-#
-# Windows
-#
-
-else:
-    import thread
-    import msvcrt
-    import _subprocess
-    import copy_reg
-    import time
-    
-    from ._multiprocessing import win32, Connection, PipeConnection
-    from .util import Finalize
-    
-    try:
-        from cPickle import dump, load, HIGHEST_PROTOCOL
-    except ImportError:
-        from pickle import dump, load, HIGHEST_PROTOCOL
-
-    #
-    #
-    #
-
-    TERMINATE = 0x10000
-    WINEXE = (sys.platform == 'win32' and getattr(sys, 'frozen', False))
-
-    exit = win32.ExitProcess
-    close = win32.CloseHandle
-
-    #
-    # _python_exe is the assumed path to the python executable.
-    # People embedding Python want to modify it.
-    #
-
-    if sys.executable.lower().endswith('pythonservice.exe'):
-        _python_exe = os.path.join(sys.exec_prefix, 'python.exe')
-    else:
-        _python_exe = sys.executable
-
-    def set_executable(exe):
-        global _python_exe
-        _python_exe = exe
-
-    #
-    #
-    #
-
-    def duplicate(handle, target_process=None, inheritable=False):
-        if target_process is None:
-            target_process = _subprocess.GetCurrentProcess()
-        return _subprocess.DuplicateHandle(
-            _subprocess.GetCurrentProcess(), handle, target_process,
-            0, inheritable, _subprocess.DUPLICATE_SAME_ACCESS
-            ).Detach()
-
-    #
-    # We define a Popen class similar to the one from subprocess, but
-    # whose constructor takes a process object as its argument.
-    #
-
-    class Popen(object):
-        '''
-        Start a subprocess to run the code of a process object
-        '''
-        _tls = thread._local()
-
-        def __init__(self, process_obj):
-            # create pipe for communication with child
-            rfd, wfd = os.pipe()
-
-            # get handle for read end of the pipe and make it inheritable
-            rhandle = duplicate(msvcrt.get_osfhandle(rfd), inheritable=True)
-            os.close(rfd)
-
-            # start process
-            cmd = get_command_line() + [rhandle]
-            cmd = ' '.join('"%s"' % x for x in cmd)
-            hp, ht, pid, tid = _subprocess.CreateProcess(
-                _python_exe, cmd, None, None, 1, 0, None, None, None
-                )
-            ht.Close()
-            close(rhandle)
-
-            # set attributes of self
-            self.pid = pid
-            self.returncode = None
-            self._handle = hp
-
-            # send information to child
-            prep_data = get_preparation_data(process_obj._name)
-            to_child = os.fdopen(wfd, 'wb')
-            Popen._tls.process_handle = int(hp)
-            try:
-                dump(prep_data, to_child, HIGHEST_PROTOCOL)
-                dump(process_obj, to_child, HIGHEST_PROTOCOL)
-            finally:
-                del Popen._tls.process_handle
-                to_child.close()
-
-        @staticmethod
-        def thread_is_spawning():
-            return getattr(Popen._tls, 'process_handle', None) is not None
-
-        @staticmethod
-        def duplicate_for_child(handle):
-            return duplicate(handle, Popen._tls.process_handle)
-
-        def wait(self, timeout=None):
-            if self.returncode is None:
-                if timeout is None:
-                    msecs = _subprocess.INFINITE
-                else:
-                    msecs = max(0, int(timeout * 1000 + 0.5))
-
-                res = _subprocess.WaitForSingleObject(int(self._handle), msecs)
-                if res == _subprocess.WAIT_OBJECT_0:
-                    code = _subprocess.GetExitCodeProcess(self._handle)
-                    if code == TERMINATE:
-                        code = -signal.SIGTERM
-                    self.returncode = code
-                    
-            return self.returncode
-
-        def poll(self):
-            return self.wait(timeout=0)
-
-        def terminate(self):
-            if self.returncode is None:
-                try:
-                    _subprocess.TerminateProcess(int(self._handle), TERMINATE)
-                except WindowsError:
-                    if self.wait(timeout=0.1) is None:
-                        raise
-        
-    #
-    #
-    #
-
-    def is_forking(argv):
-        '''
-        Return whether commandline indicates we are forking
-        '''
-        if len(argv) >= 2 and argv[1] == '--multiprocessing-fork':
-            assert len(argv) == 3
-            return True
-        else:
-            return False
-
-
-    def freeze_support():
-        '''
-        Run code for process object if this in not the main process
-        '''
-        if is_forking(sys.argv):
-            main()
-            sys.exit()
-
-
-    def get_command_line():
-        '''
-        Returns prefix of command line used for spawning a child process
-        '''
-        if process.current_process()._identity==() and is_forking(sys.argv):
-            raise RuntimeError('''
-            Attempt to start a new process before the current process
-            has finished its bootstrapping phase.
-
-            This probably means that you are on Windows and you have
-            forgotten to use the proper idiom in the main module:
-
-                if __name__ == '__main__':
-                    freeze_support()
-                    ...
-
-            The "freeze_support()" line can be omitted if the program
-            is not going to be frozen to produce a Windows executable.''')
-
-        if getattr(sys, 'frozen', False):
-            return [sys.executable, '--multiprocessing-fork']
-        else:
-            prog = 'from multiprocessing.forking import main; main()'
-            return [_python_exe, '-c', prog, '--multiprocessing-fork']
-
-
-    def main():
-        '''
-        Run code specifed by data received over pipe
-        '''
-        assert is_forking(sys.argv)
-
-        handle = int(sys.argv[-1])
-        fd = msvcrt.open_osfhandle(handle, os.O_RDONLY)
-        from_parent = os.fdopen(fd, 'rb')
-
-        process.current_process()._inheriting = True
-        preparation_data = load(from_parent)
-        prepare(preparation_data)
-        self = load(from_parent)
-        process.current_process()._inheriting = False
-
-        from_parent.close()
-
-        exitcode = self._bootstrap()
-        exit(exitcode)
-
-
-    def get_preparation_data(name):
-        '''
-        Return info about parent needed by child to unpickle process object
-        '''
-        from .util import _logger, _log_to_stderr
-        
-        d = dict(
-            name=name,
-            sys_path=sys.path,
-            sys_argv=sys.argv,
-            log_to_stderr=_log_to_stderr,
-            orig_dir=process.ORIGINAL_DIR,
-            authkey=process.current_process().get_authkey(),
-            )
-        
-        if _logger is not None:
-            d['log_level'] = _logger.getEffectiveLevel()
-
-        if not WINEXE:
-            main_path = getattr(sys.modules['__main__'], '__file__', None)
-            if not main_path and sys.argv[0] not in ('', '-c'):
-                main_path = sys.argv[0]
-            if main_path is not None:
-                if not os.path.isabs(main_path) and \
-                                          process.ORIGINAL_DIR is not None:
-                    main_path = os.path.join(process.ORIGINAL_DIR, main_path)
-                d['main_path'] = os.path.normpath(main_path)
-
-        return d
-
-    #
-    # Make (Pipe)Connection picklable
-    #
-    
-    def reduce_connection(conn):
-        if not Popen.thread_is_spawning():
-            raise RuntimeError(
-                'By default %s objects can only be shared between processes\n'
-                'using inheritance' % type(conn).__name__
-                )
-        return type(conn), (Popen.duplicate_for_child(conn.fileno()),
-                            conn.readable, conn.writable)
-    
-    copy_reg.pickle(Connection, reduce_connection)
-    copy_reg.pickle(PipeConnection, reduce_connection)
-
-
-#
-# Prepare current process
-#
-
-old_main_modules = []
-
-def prepare(data):
-    '''
-    Try to get current process ready to unpickle process object
-    '''
-    old_main_modules.append(sys.modules['__main__'])
-
-    if 'name' in data:
-        process.current_process().set_name(data['name'])
-
-    if 'authkey' in data:
-        process.current_process()._authkey = data['authkey']
-    
-    if 'log_to_stderr' in data and data['log_to_stderr']:
-        util.log_to_stderr()
-
-    if 'log_level' in data:
-        util.get_logger().setLevel(data['log_level'])
-
-    if 'sys_path' in data:
-        sys.path = data['sys_path']
-
-    if 'sys_argv' in data:
-        sys.argv = data['sys_argv']
-
-    if 'dir' in data:
-        os.chdir(data['dir'])
-
-    if 'orig_dir' in data:
-        process.ORIGINAL_DIR = data['orig_dir']
-
-    if 'main_path' in data:
-        main_path = data['main_path']
-        main_name = os.path.splitext(os.path.basename(main_path))[0]
-        if main_name == '__init__':
-            main_name = os.path.basename(os.path.dirname(main_path))
-
-        if main_name != 'ipython':
-            import imp
-
-            if main_path is None:
-                dirs = None
-            elif os.path.basename(main_path).startswith('__init__.py'):
-                dirs = [os.path.dirname(os.path.dirname(main_path))]
-            else:
-                dirs = [os.path.dirname(main_path)]
-
-            assert main_name not in sys.modules, main_name
-            file, path_name, etc = imp.find_module(main_name, dirs)
-            try:
-                # We would like to do "imp.load_module('__main__', ...)"
-                # here.  However, that would cause 'if __name__ ==
-                # "__main__"' clauses to be executed.
-                main_module = imp.load_module(
-                    '__parents_main__', file, path_name, etc
-                    )
-            finally:
-                if file:
-                    file.close()
-
-            sys.modules['__main__'] = main_module
-            main_module.__name__ = '__main__'
-
-            # Try to make the potentially picklable objects in
-            # sys.modules['__main__'] realize they are in the main
-            # module -- somewhat ugly.
-            for obj in main_module.__dict__.values():
-                try:
-                    if obj.__module__ == '__parents_main__':
-                        obj.__module__ = '__main__'
-                except Exception:
-                    pass
+#
+# Module for starting a process object using os.fork() or CreateProcess()
+#
+# multiprocessing/forking.py
+#
+# Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
+#
+
+import os
+import sys
+import signal
+
+from multiprocessing import util, process
+
+__all__ = ['Popen', 'assert_spawning', 'exit', 'duplicate', 'close']
+
+#
+# Check that the current thread is spawning a child process
+#
+
+def assert_spawning(self):
+    if not Popen.thread_is_spawning():
+        raise RuntimeError(
+            '%s objects should only be shared between processes'
+            ' through inheritance' % type(self).__name__
+            )
+
+#
+# Unix
+#
+
+if sys.platform != 'win32':
+    import time
+
+    exit = os._exit
+    duplicate = os.dup
+    close = os.close
+
+    #
+    # We define a Popen class similar to the one from subprocess, but
+    # whose constructor takes a process object as its argument.
+    #
+
+    class Popen(object):
+
+        def __init__(self, process_obj):
+            sys.stdout.flush()
+            sys.stderr.flush()
+            self.returncode = None
+
+            self.pid = os.fork()
+            if self.pid == 0:
+                if 'random' in sys.modules:
+                    import random
+                    random.seed()
+                code = process_obj._bootstrap()
+                sys.stdout.flush()
+                sys.stderr.flush()
+                os._exit(code)
+
+        def poll(self, flag=os.WNOHANG):
+            if self.returncode is None:
+                pid, sts = os.waitpid(self.pid, flag)
+                if pid == self.pid:
+                    if os.WIFSIGNALED(sts):
+                        self.returncode = -os.WTERMSIG(sts)
+                    else:
+                        assert os.WIFEXITED(sts)
+                        self.returncode = os.WEXITSTATUS(sts)
+            return self.returncode
+
+        def wait(self, timeout=None):
+            if timeout is None:
+                return self.poll(0)
+            deadline = time.time() + timeout
+            delay = 0.0005
+            while 1:
+                res = self.poll()
+                if res is not None:
+                    break
+                remaining = deadline - time.time()
+                if remaining <= 0:
+                    break
+                delay = min(delay * 2, remaining, 0.05)
+                time.sleep(delay)
+            return res
+
+        def terminate(self):
+            if self.returncode is None:
+                try:
+                    os.kill(self.pid, signal.SIGTERM)
+                except OSError as e:
+                    if self.wait(timeout=0.1) is None:
+                        raise
+
+        @staticmethod
+        def thread_is_spawning():
+            return False
+
+#
+# Windows
+#
+
+else:
+    import _thread
+    import msvcrt
+    import _subprocess
+    import copyreg
+    import time
+
+    from ._multiprocessing import win32, Connection, PipeConnection
+    from .util import Finalize
+
+    try:
+        from cPickle import dump, load, HIGHEST_PROTOCOL
+    except ImportError:
+        from pickle import dump, load, HIGHEST_PROTOCOL
+
+    #
+    #
+    #
+
+    TERMINATE = 0x10000
+    WINEXE = (sys.platform == 'win32' and getattr(sys, 'frozen', False))
+
+    exit = win32.ExitProcess
+    close = win32.CloseHandle
+
+    #
+    # _python_exe is the assumed path to the python executable.
+    # People embedding Python want to modify it.
+    #
+
+    if sys.executable.lower().endswith('pythonservice.exe'):
+        _python_exe = os.path.join(sys.exec_prefix, 'python.exe')
+    else:
+        _python_exe = sys.executable
+
+    def set_executable(exe):
+        global _python_exe
+        _python_exe = exe
+
+    #
+    #
+    #
+
+    def duplicate(handle, target_process=None, inheritable=False):
+        if target_process is None:
+            target_process = _subprocess.GetCurrentProcess()
+        return _subprocess.DuplicateHandle(
+            _subprocess.GetCurrentProcess(), handle, target_process,
+            0, inheritable, _subprocess.DUPLICATE_SAME_ACCESS
+            ).Detach()
+
+    #
+    # We define a Popen class similar to the one from subprocess, but
+    # whose constructor takes a process object as its argument.
+    #
+
+    class Popen(object):
+        '''
+        Start a subprocess to run the code of a process object
+        '''
+        _tls = _thread._local()
+
+        def __init__(self, process_obj):
+            # create pipe for communication with child
+            rfd, wfd = os.pipe()
+
+            # get handle for read end of the pipe and make it inheritable
+            rhandle = duplicate(msvcrt.get_osfhandle(rfd), inheritable=True)
+            os.close(rfd)
+
+            # start process
+            cmd = get_command_line() + [rhandle]
+            cmd = ' '.join('"%s"' % x for x in cmd)
+            hp, ht, pid, tid = _subprocess.CreateProcess(
+                _python_exe, cmd, None, None, 1, 0, None, None, None
+                )
+            ht.Close()
+            close(rhandle)
+
+            # set attributes of self
+            self.pid = pid
+            self.returncode = None
+            self._handle = hp
+
+            # send information to child
+            prep_data = get_preparation_data(process_obj._name)
+            to_child = os.fdopen(wfd, 'wb')
+            Popen._tls.process_handle = int(hp)
+            try:
+                dump(prep_data, to_child, HIGHEST_PROTOCOL)
+                dump(process_obj, to_child, HIGHEST_PROTOCOL)
+            finally:
+                del Popen._tls.process_handle
+                to_child.close()
+
+        @staticmethod
+        def thread_is_spawning():
+            return getattr(Popen._tls, 'process_handle', None) is not None
+
+        @staticmethod
+        def duplicate_for_child(handle):
+            return duplicate(handle, Popen._tls.process_handle)
+
+        def wait(self, timeout=None):
+            if self.returncode is None:
+                if timeout is None:
+                    msecs = _subprocess.INFINITE
+                else:
+                    msecs = max(0, int(timeout * 1000 + 0.5))
+
+                res = _subprocess.WaitForSingleObject(int(self._handle), msecs)
+                if res == _subprocess.WAIT_OBJECT_0:
+                    code = _subprocess.GetExitCodeProcess(self._handle)
+                    if code == TERMINATE:
+                        code = -signal.SIGTERM
+                    self.returncode = code
+
+            return self.returncode
+
+        def poll(self):
+            return self.wait(timeout=0)
+
+        def terminate(self):
+            if self.returncode is None:
+                try:
+                    _subprocess.TerminateProcess(int(self._handle), TERMINATE)
+                except WindowsError:
+                    if self.wait(timeout=0.1) is None:
+                        raise
+
+    #
+    #
+    #
+
+    def is_forking(argv):
+        '''
+        Return whether commandline indicates we are forking
+        '''
+        if len(argv) >= 2 and argv[1] == '--multiprocessing-fork':
+            assert len(argv) == 3
+            return True
+        else:
+            return False
+
+
+    def freeze_support():
+        '''
+        Run code for process object if this in not the main process
+        '''
+        if is_forking(sys.argv):
+            main()
+            sys.exit()
+
+
+    def get_command_line():
+        '''
+        Returns prefix of command line used for spawning a child process
+        '''
+        if process.current_process()._identity==() and is_forking(sys.argv):
+            raise RuntimeError('''
+            Attempt to start a new process before the current process
+            has finished its bootstrapping phase.
+
+            This probably means that you are on Windows and you have
+            forgotten to use the proper idiom in the main module:
+
+                if __name__ == '__main__':
+                    freeze_support()
+                    ...
+
+            The "freeze_support()" line can be omitted if the program
+            is not going to be frozen to produce a Windows executable.''')
+
+        if getattr(sys, 'frozen', False):
+            return [sys.executable, '--multiprocessing-fork']
+        else:
+            prog = 'from multiprocessing.forking import main; main()'
+            return [_python_exe, '-c', prog, '--multiprocessing-fork']
+
+
+    def main():
+        '''
+        Run code specifed by data received over pipe
+        '''
+        assert is_forking(sys.argv)
+
+        handle = int(sys.argv[-1])
+        fd = msvcrt.open_osfhandle(handle, os.O_RDONLY)
+        from_parent = os.fdopen(fd, 'rb')
+
+        process.current_process()._inheriting = True
+        preparation_data = load(from_parent)
+        prepare(preparation_data)
+        self = load(from_parent)
+        process.current_process()._inheriting = False
+
+        from_parent.close()
+
+        exitcode = self._bootstrap()
+        exit(exitcode)
+
+
+    def get_preparation_data(name):
+        '''
+        Return info about parent needed by child to unpickle process object
+        '''
+        from .util import _logger, _log_to_stderr
+
+        d = dict(
+            name=name,
+            sys_path=sys.path,
+            sys_argv=sys.argv,
+            log_to_stderr=_log_to_stderr,
+            orig_dir=process.ORIGINAL_DIR,
+            authkey=process.current_process().get_authkey(),
+            )
+
+        if _logger is not None:
+            d['log_level'] = _logger.getEffectiveLevel()
+
+        if not WINEXE:
+            main_path = getattr(sys.modules['__main__'], '__file__', None)
+            if not main_path and sys.argv[0] not in ('', '-c'):
+                main_path = sys.argv[0]
+            if main_path is not None:
+                if not os.path.isabs(main_path) and \
+                                          process.ORIGINAL_DIR is not None:
+                    main_path = os.path.join(process.ORIGINAL_DIR, main_path)
+                d['main_path'] = os.path.normpath(main_path)
+
+        return d
+
+    #
+    # Make (Pipe)Connection picklable
+    #
+
+    def reduce_connection(conn):
+        if not Popen.thread_is_spawning():
+            raise RuntimeError(
+                'By default %s objects can only be shared between processes\n'
+                'using inheritance' % type(conn).__name__
+                )
+        return type(conn), (Popen.duplicate_for_child(conn.fileno()),
+                            conn.readable, conn.writable)
+
+    copyreg.pickle(Connection, reduce_connection)
+    copyreg.pickle(PipeConnection, reduce_connection)
+
+
+#
+# Prepare current process
+#
+
+old_main_modules = []
+
+def prepare(data):
+    '''
+    Try to get current process ready to unpickle process object
+    '''
+    old_main_modules.append(sys.modules['__main__'])
+
+    if 'name' in data:
+        process.current_process().set_name(data['name'])
+
+    if 'authkey' in data:
+        process.current_process()._authkey = data['authkey']
+
+    if 'log_to_stderr' in data and data['log_to_stderr']:
+        util.log_to_stderr()
+
+    if 'log_level' in data:
+        util.get_logger().setLevel(data['log_level'])
+
+    if 'sys_path' in data:
+        sys.path = data['sys_path']
+
+    if 'sys_argv' in data:
+        sys.argv = data['sys_argv']
+
+    if 'dir' in data:
+        os.chdir(data['dir'])
+
+    if 'orig_dir' in data:
+        process.ORIGINAL_DIR = data['orig_dir']
+
+    if 'main_path' in data:
+        main_path = data['main_path']
+        main_name = os.path.splitext(os.path.basename(main_path))[0]
+        if main_name == '__init__':
+            main_name = os.path.basename(os.path.dirname(main_path))
+
+        if main_name != 'ipython':
+            import imp
+
+            if main_path is None:
+                dirs = None
+            elif os.path.basename(main_path).startswith('__init__.py'):
+                dirs = [os.path.dirname(os.path.dirname(main_path))]
+            else:
+                dirs = [os.path.dirname(main_path)]
+
+            assert main_name not in sys.modules, main_name
+            file, path_name, etc = imp.find_module(main_name, dirs)
+            try:
+                # We would like to do "imp.load_module('__main__', ...)"
+                # here.  However, that would cause 'if __name__ ==
+                # "__main__"' clauses to be executed.
+                main_module = imp.load_module(
+                    '__parents_main__', file, path_name, etc
+                    )
+            finally:
+                if file:
+                    file.close()
+
+            sys.modules['__main__'] = main_module
+            main_module.__name__ = '__main__'
+
+            # Try to make the potentially picklable objects in
+            # sys.modules['__main__'] realize they are in the main
+            # module -- somewhat ugly.
+            for obj in list(main_module.__dict__.values()):
+                try:
+                    if obj.__module__ == '__parents_main__':
+                        obj.__module__ = '__main__'
+                except Exception:
+                    pass

Modified: python/branches/py3k/Lib/multiprocessing/heap.py
==============================================================================
--- /python/trunk/Lib/multiprocessing/heap.py	(original)
+++ python/branches/py3k/Lib/multiprocessing/heap.py	Wed Jun 11 18:44:04 2008
@@ -34,7 +34,7 @@
 
         def __init__(self, size):
             self.size = size
-            self.name = 'pym-%d-%d' % (os.getpid(), Arena._counter.next())
+            self.name = 'pym-%d-%d' % (os.getpid(), next(Arena._counter))
             self.buffer = mmap.mmap(-1, self.size, tagname=self.name)
             assert win32.GetLastError() == 0, 'tagname already in use'
             self._state = (self.size, self.name)
@@ -161,7 +161,7 @@
 
     def malloc(self, size):
         # return a block of right size (possibly rounded up)
-        assert 0 <= size < sys.maxint
+        assert 0 <= size < sys.maxsize
         if os.getpid() != self._lastpid:
             self.__init__()                     # reinitialize after fork
         self._lock.acquire()
@@ -186,7 +186,7 @@
     _heap = Heap()
 
     def __init__(self, size):
-        assert 0 <= size < sys.maxint
+        assert 0 <= size < sys.maxsize
         block = BufferWrapper._heap.malloc(size)
         self._state = (block, size)
         Finalize(self, BufferWrapper._heap.free, args=(block,))

Modified: python/branches/py3k/Lib/multiprocessing/managers.py
==============================================================================
--- /python/trunk/Lib/multiprocessing/managers.py	(original)
+++ python/branches/py3k/Lib/multiprocessing/managers.py	Wed Jun 11 18:44:04 2008
@@ -1,1092 +1,1092 @@
-#
-# Module providing the `SyncManager` class for dealing
-# with shared objects
-#
-# multiprocessing/managers.py
-#
-# Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
-#
-
-__all__ = [ 'BaseManager', 'SyncManager', 'BaseProxy', 'Token' ]
-
-#
-# Imports
-#
-
-import os
-import sys
-import weakref
-import threading
-import array
-import copy_reg
-import Queue
-
-from traceback import format_exc
-from multiprocessing import Process, current_process, active_children, Pool, util, connection
-from multiprocessing.process import AuthenticationString
-from multiprocessing.forking import exit, Popen, assert_spawning
-from multiprocessing.util import Finalize, info
-
-try:
-    from cPickle import PicklingError
-except ImportError:
-    from pickle import PicklingError
-
-#
-#
-#
-
-try:
-    bytes
-except NameError:
-    bytes = str                  # XXX not needed in Py2.6 and Py3.0
-    
-#
-# Register some things for pickling
-#
-
-def reduce_array(a):
-    return array.array, (a.typecode, a.tostring())
-copy_reg.pickle(array.array, reduce_array)
-
-view_types = [type(getattr({}, name)()) for name in ('items','keys','values')]
-if view_types[0] is not list:       # XXX only needed in Py3.0
-    def rebuild_as_list(obj):
-        return list, (list(obj),)
-    for view_type in view_types:
-        copy_reg.pickle(view_type, rebuild_as_list)
-    
-#
-# Type for identifying shared objects
-#
-
-class Token(object):
-    '''
-    Type to uniquely indentify a shared object
-    '''
-    __slots__ = ('typeid', 'address', 'id')
-
-    def __init__(self, typeid, address, id):
-        (self.typeid, self.address, self.id) = (typeid, address, id)
-
-    def __getstate__(self):
-        return (self.typeid, self.address, self.id)
-
-    def __setstate__(self, state):
-        (self.typeid, self.address, self.id) = state
-
-    def __repr__(self):
-        return 'Token(typeid=%r, address=%r, id=%r)' % \
-               (self.typeid, self.address, self.id)
-
-#
-# Function for communication with a manager's server process
-#
-
-def dispatch(c, id, methodname, args=(), kwds={}):
-    '''
-    Send a message to manager using connection `c` and return response
-    '''
-    c.send((id, methodname, args, kwds))
-    kind, result = c.recv()
-    if kind == '#RETURN':
-        return result
-    raise convert_to_error(kind, result)
-
-def convert_to_error(kind, result):
-    if kind == '#ERROR':
-        return result
-    elif kind == '#TRACEBACK':
-        assert type(result) is str
-        return  RemoteError(result)
-    elif kind == '#UNSERIALIZABLE':
-        assert type(result) is str
-        return RemoteError('Unserializable message: %s\n' % result)
-    else:
-        return ValueError('Unrecognized message type')
-        
-class RemoteError(Exception):
-    def __str__(self):
-        return ('\n' + '-'*75 + '\n' + str(self.args[0]) + '-'*75)
-
-#
-# Functions for finding the method names of an object
-#
-
-def all_methods(obj):
-    '''
-    Return a list of names of methods of `obj`
-    '''
-    temp = []
-    for name in dir(obj):
-        func = getattr(obj, name)
-        if hasattr(func, '__call__'):
-            temp.append(name)
-    return temp
-
-def public_methods(obj):
-    '''
-    Return a list of names of methods of `obj` which do not start with '_'
-    '''
-    return [name for name in all_methods(obj) if name[0] != '_']
-
-#
-# Server which is run in a process controlled by a manager
-#
-
-class Server(object):
-    '''
-    Server class which runs in a process controlled by a manager object
-    '''
-    public = ['shutdown', 'create', 'accept_connection', 'get_methods',
-              'debug_info', 'number_of_objects', 'dummy', 'incref', 'decref']
-
-    def __init__(self, registry, address, authkey, serializer):
-        assert isinstance(authkey, bytes)
-        self.registry = registry
-        self.authkey = AuthenticationString(authkey)
-        Listener, Client = listener_client[serializer]
-
-        # do authentication later
-        self.listener = Listener(address=address, backlog=5)
-        self.address = self.listener.address
-
-        self.id_to_obj = {0: (None, ())}
-        self.id_to_refcount = {}
-        self.mutex = threading.RLock()
-        self.stop = 0
-
-    def serve_forever(self):
-        '''
-        Run the server forever
-        '''
-        current_process()._manager_server = self
-        try:
-            try:
-                while 1:
-                    try:
-                        c = self.listener.accept()
-                    except (OSError, IOError):
-                        continue
-                    t = threading.Thread(target=self.handle_request, args=(c,))
-                    t.setDaemon(True)
-                    t.start()
-            except (KeyboardInterrupt, SystemExit):
-                pass
-        finally:
-            self.stop = 999
-            self.listener.close()
-
-    def handle_request(self, c):
-        '''
-        Handle a new connection
-        '''
-        funcname = result = request = None
-        try:
-            connection.deliver_challenge(c, self.authkey)
-            connection.answer_challenge(c, self.authkey)
-            request = c.recv()
-            ignore, funcname, args, kwds = request
-            assert funcname in self.public, '%r unrecognized' % funcname
-            func = getattr(self, funcname)
-        except Exception:
-            msg = ('#TRACEBACK', format_exc())
-        else:
-            try:
-                result = func(c, *args, **kwds)
-            except Exception:
-                msg = ('#TRACEBACK', format_exc())
-            else:
-                msg = ('#RETURN', result)
-        try:
-            c.send(msg)
-        except Exception, e:
-            try:
-                c.send(('#TRACEBACK', format_exc()))
-            except Exception:
-                pass
-            util.info('Failure to send message: %r', msg)
-            util.info(' ... request was %r', request)
-            util.info(' ... exception was %r', e)
-
-        c.close()
-
-    def serve_client(self, conn):
-        '''
-        Handle requests from the proxies in a particular process/thread
-        '''
-        util.debug('starting server thread to service %r',
-                   threading.currentThread().getName())
-
-        recv = conn.recv
-        send = conn.send
-        id_to_obj = self.id_to_obj
-
-        while not self.stop:
-
-            try:
-                methodname = obj = None
-                request = recv()
-                ident, methodname, args, kwds = request
-                obj, exposed, gettypeid = id_to_obj[ident]
-
-                if methodname not in exposed:
-                    raise AttributeError(
-                        'method %r of %r object is not in exposed=%r' %
-                        (methodname, type(obj), exposed)
-                        )
-
-                function = getattr(obj, methodname)
-
-                try:
-                    res = function(*args, **kwds)
-                except Exception, e:
-                    msg = ('#ERROR', e)
-                else:
-                    typeid = gettypeid and gettypeid.get(methodname, None)
-                    if typeid:
-                        rident, rexposed = self.create(conn, typeid, res)
-                        token = Token(typeid, self.address, rident)
-                        msg = ('#PROXY', (rexposed, token))
-                    else:
-                        msg = ('#RETURN', res)
-
-            except AttributeError:
-                if methodname is None:
-                    msg = ('#TRACEBACK', format_exc())
-                else:
-                    try:
-                        fallback_func = self.fallback_mapping[methodname]
-                        result = fallback_func(
-                            self, conn, ident, obj, *args, **kwds
-                            )
-                        msg = ('#RETURN', result)
-                    except Exception:
-                        msg = ('#TRACEBACK', format_exc())
-
-            except EOFError:
-                util.debug('got EOF -- exiting thread serving %r',
-                           threading.currentThread().getName())
-                sys.exit(0)
-
-            except Exception:
-                msg = ('#TRACEBACK', format_exc())
-
-            try:
-                try:
-                    send(msg)
-                except Exception, e:
-                    send(('#UNSERIALIZABLE', repr(msg)))
-            except Exception, e:
-                util.info('exception in thread serving %r',
-                        threading.currentThread().getName())
-                util.info(' ... message was %r', msg)
-                util.info(' ... exception was %r', e)
-                conn.close()
-                sys.exit(1)
-
-    def fallback_getvalue(self, conn, ident, obj):
-        return obj
-
-    def fallback_str(self, conn, ident, obj):
-        return str(obj)
-
-    def fallback_repr(self, conn, ident, obj):
-        return repr(obj)
-
-    fallback_mapping = {
-        '__str__':fallback_str,
-        '__repr__':fallback_repr,
-        '#GETVALUE':fallback_getvalue
-        }
-
-    def dummy(self, c):
-        pass
-
-    def debug_info(self, c):
-        '''
-        Return some info --- useful to spot problems with refcounting
-        '''
-        self.mutex.acquire()
-        try:
-            result = []
-            keys = self.id_to_obj.keys()
-            keys.sort()
-            for ident in keys:
-                if ident != 0:
-                    result.append('  %s:       refcount=%s\n    %s' %
-                                  (ident, self.id_to_refcount[ident],
-                                   str(self.id_to_obj[ident][0])[:75]))
-            return '\n'.join(result)
-        finally:
-            self.mutex.release()
-
-    def number_of_objects(self, c):
-        '''
-        Number of shared objects
-        '''
-        return len(self.id_to_obj) - 1      # don't count ident=0
-
-    def shutdown(self, c):
-        '''
-        Shutdown this process
-        '''
-        try:
-            try:
-                util.debug('manager received shutdown message')
-                c.send(('#RETURN', None))
-
-                if sys.stdout != sys.__stdout__:
-                    util.debug('resetting stdout, stderr')
-                    sys.stdout = sys.__stdout__
-                    sys.stderr = sys.__stderr__
-                    
-                util._run_finalizers(0)
-
-                for p in active_children():
-                    util.debug('terminating a child process of manager')
-                    p.terminate()
-
-                for p in active_children():
-                    util.debug('terminating a child process of manager')
-                    p.join()
-
-                util._run_finalizers()
-                util.info('manager exiting with exitcode 0')
-            except:
-                import traceback
-                traceback.print_exc()
-        finally:
-            exit(0)
-            
-    def create(self, c, typeid, *args, **kwds):
-        '''
-        Create a new shared object and return its id
-        '''
-        self.mutex.acquire()
-        try:
-            callable, exposed, method_to_typeid, proxytype = \
-                      self.registry[typeid]
-            
-            if callable is None:
-                assert len(args) == 1 and not kwds
-                obj = args[0]
-            else:
-                obj = callable(*args, **kwds)
-
-            if exposed is None:
-                exposed = public_methods(obj)
-            if method_to_typeid is not None:
-                assert type(method_to_typeid) is dict
-                exposed = list(exposed) + list(method_to_typeid)
-
-            ident = '%x' % id(obj)  # convert to string because xmlrpclib
-                                    # only has 32 bit signed integers
-            util.debug('%r callable returned object with id %r', typeid, ident)
-
-            self.id_to_obj[ident] = (obj, set(exposed), method_to_typeid)
-            if ident not in self.id_to_refcount:
-                self.id_to_refcount[ident] = None
-            return ident, tuple(exposed)
-        finally:
-            self.mutex.release()
-
-    def get_methods(self, c, token):
-        '''
-        Return the methods of the shared object indicated by token
-        '''
-        return tuple(self.id_to_obj[token.id][1])
-
-    def accept_connection(self, c, name):
-        '''
-        Spawn a new thread to serve this connection
-        '''
-        threading.currentThread().setName(name)
-        c.send(('#RETURN', None))
-        self.serve_client(c)
-
-    def incref(self, c, ident):
-        self.mutex.acquire()
-        try:
-            try:
-                self.id_to_refcount[ident] += 1
-            except TypeError:
-                assert self.id_to_refcount[ident] is None
-                self.id_to_refcount[ident] = 1
-        finally:
-            self.mutex.release()
-
-    def decref(self, c, ident):
-        self.mutex.acquire()
-        try:
-            assert self.id_to_refcount[ident] >= 1
-            self.id_to_refcount[ident] -= 1
-            if self.id_to_refcount[ident] == 0:
-                del self.id_to_obj[ident], self.id_to_refcount[ident]
-                util.debug('disposing of obj with id %d', ident)
-        finally:
-            self.mutex.release()
-
-#
-# Class to represent state of a manager
-#
-
-class State(object):
-    __slots__ = ['value']
-    INITIAL = 0
-    STARTED = 1
-    SHUTDOWN = 2
-
-#
-# Mapping from serializer name to Listener and Client types
-#
-
-listener_client = {
-    'pickle' : (connection.Listener, connection.Client),
-    'xmlrpclib' : (connection.XmlListener, connection.XmlClient)
-    }
-
-#
-# Definition of BaseManager
-#
-
-class BaseManager(object):
-    '''
-    Base class for managers
-    '''
-    _registry = {}
-    _Server = Server
-    
-    def __init__(self, address=None, authkey=None, serializer='pickle'):
-        if authkey is None:
-            authkey = current_process().get_authkey()
-        self._address = address     # XXX not final address if eg ('', 0)
-        self._authkey = AuthenticationString(authkey)
-        self._state = State()
-        self._state.value = State.INITIAL
-        self._serializer = serializer
-        self._Listener, self._Client = listener_client[serializer]
-
-    def __reduce__(self):
-        return type(self).from_address, \
-               (self._address, self._authkey, self._serializer)
-
-    def get_server(self):
-        '''
-        Return server object with serve_forever() method and address attribute
-        '''
-        assert self._state.value == State.INITIAL
-        return Server(self._registry, self._address,
-                      self._authkey, self._serializer)
-
-    def connect(self):
-        '''
-        Connect manager object to the server process
-        '''
-        Listener, Client = listener_client[self._serializer]
-        conn = Client(self._address, authkey=self._authkey)
-        dispatch(conn, None, 'dummy')
-        self._state.value = State.STARTED
-        
-    def start(self):
-        '''
-        Spawn a server process for this manager object
-        '''
-        assert self._state.value == State.INITIAL
-
-        # pipe over which we will retrieve address of server
-        reader, writer = connection.Pipe(duplex=False)
-
-        # spawn process which runs a server
-        self._process = Process(
-            target=type(self)._run_server,
-            args=(self._registry, self._address, self._authkey,
-                  self._serializer, writer),
-            )
-        ident = ':'.join(str(i) for i in self._process._identity)
-        self._process.set_name(type(self).__name__  + '-' + ident)
-        self._process.start()
-
-        # get address of server
-        writer.close()
-        self._address = reader.recv()
-        reader.close()
-
-        # register a finalizer
-        self._state.value = State.STARTED
-        self.shutdown = util.Finalize(
-            self, type(self)._finalize_manager,
-            args=(self._process, self._address, self._authkey,
-                  self._state, self._Client),
-            exitpriority=0
-            )
-
-    @classmethod
-    def _run_server(cls, registry, address, authkey, serializer, writer):
-        '''
-        Create a server, report its address and run it
-        '''
-        # create server
-        server = cls._Server(registry, address, authkey, serializer)
-
-        # inform parent process of the server's address
-        writer.send(server.address)
-        writer.close()
-
-        # run the manager
-        util.info('manager serving at %r', server.address)
-        server.serve_forever()
-
-    def _create(self, typeid, *args, **kwds):
-        '''
-        Create a new shared object; return the token and exposed tuple
-        '''
-        assert self._state.value == State.STARTED, 'server not yet started'
-        conn = self._Client(self._address, authkey=self._authkey)
-        try:
-            id, exposed = dispatch(conn, None, 'create', (typeid,)+args, kwds)
-        finally:
-            conn.close()
-        return Token(typeid, self._address, id), exposed
-
-    def join(self, timeout=None):
-        '''
-        Join the manager process (if it has been spawned)
-        '''
-        self._process.join(timeout)
-
-    def _debug_info(self):
-        '''
-        Return some info about the servers shared objects and connections
-        '''
-        conn = self._Client(self._address, authkey=self._authkey)
-        try:
-            return dispatch(conn, None, 'debug_info')
-        finally:
-            conn.close()
-
-    def _number_of_objects(self):
-        '''
-        Return the number of shared objects
-        '''
-        conn = self._Client(self._address, authkey=self._authkey)
-        try:        
-            return dispatch(conn, None, 'number_of_objects')
-        finally:
-            conn.close()        
-
-    def __enter__(self):
-        return self
-
-    def __exit__(self, exc_type, exc_val, exc_tb):
-        self.shutdown()
-
-    @staticmethod
-    def _finalize_manager(process, address, authkey, state, _Client):
-        '''
-        Shutdown the manager process; will be registered as a finalizer
-        '''
-        if process.is_alive():
-            util.info('sending shutdown message to manager')
-            try:
-                conn = _Client(address, authkey=authkey)
-                try:
-                    dispatch(conn, None, 'shutdown')
-                finally:
-                    conn.close()
-            except Exception:
-                pass
-
-            process.join(timeout=0.2)
-            if process.is_alive():
-                util.info('manager still alive')
-                if hasattr(process, 'terminate'):
-                    util.info('trying to `terminate()` manager process')
-                    process.terminate()
-                    process.join(timeout=0.1)
-                    if process.is_alive():
-                        util.info('manager still alive after terminate')
-
-        state.value = State.SHUTDOWN
-        try:
-            del BaseProxy._address_to_local[address]
-        except KeyError:
-            pass
-        
-    address = property(lambda self: self._address)
-
-    @classmethod
-    def register(cls, typeid, callable=None, proxytype=None, exposed=None,
-                 method_to_typeid=None, create_method=True):
-        '''
-        Register a typeid with the manager type
-        '''
-        if '_registry' not in cls.__dict__:
-            cls._registry = cls._registry.copy()
-
-        if proxytype is None:
-            proxytype = AutoProxy
-
-        exposed = exposed or getattr(proxytype, '_exposed_', None)
-
-        method_to_typeid = method_to_typeid or \
-                           getattr(proxytype, '_method_to_typeid_', None)
-
-        if method_to_typeid:
-            for key, value in method_to_typeid.items():
-                assert type(key) is str, '%r is not a string' % key
-                assert type(value) is str, '%r is not a string' % value
-
-        cls._registry[typeid] = (
-            callable, exposed, method_to_typeid, proxytype
-            )
-        
-        if create_method:
-            def temp(self, *args, **kwds):
-                util.debug('requesting creation of a shared %r object', typeid)
-                token, exp = self._create(typeid, *args, **kwds)
-                proxy = proxytype(
-                    token, self._serializer, manager=self,
-                    authkey=self._authkey, exposed=exp
-                    )
-                return proxy
-            temp.__name__ = typeid
-            setattr(cls, typeid, temp)
-
-#
-# Subclass of set which get cleared after a fork
-#
-
-class ProcessLocalSet(set):
-    def __init__(self):
-        util.register_after_fork(self, lambda obj: obj.clear())
-    def __reduce__(self):
-        return type(self), ()
-
-#
-# Definition of BaseProxy
-#
-
-class BaseProxy(object):
-    '''
-    A base for proxies of shared objects
-    '''
-    _address_to_local = {}
-    _mutex = util.ForkAwareThreadLock()
-
-    def __init__(self, token, serializer, manager=None,
-                 authkey=None, exposed=None, incref=True):
-        BaseProxy._mutex.acquire()
-        try:
-            tls_idset = BaseProxy._address_to_local.get(token.address, None)
-            if tls_idset is None:
-                tls_idset = util.ForkAwareLocal(), ProcessLocalSet()
-                BaseProxy._address_to_local[token.address] = tls_idset
-        finally:
-            BaseProxy._mutex.release()
-
-        # self._tls is used to record the connection used by this
-        # thread to communicate with the manager at token.address
-        self._tls = tls_idset[0]
-
-        # self._idset is used to record the identities of all shared
-        # objects for which the current process owns references and
-        # which are in the manager at token.address
-        self._idset = tls_idset[1]
-
-        self._token = token
-        self._id = self._token.id
-        self._manager = manager
-        self._serializer = serializer
-        self._Client = listener_client[serializer][1]
-
-        if authkey is not None:
-            self._authkey = AuthenticationString(authkey)
-        elif self._manager is not None:
-            self._authkey = self._manager._authkey
-        else:
-            self._authkey = current_process().get_authkey()
-
-        if incref:
-            self._incref()
-            
-        util.register_after_fork(self, BaseProxy._after_fork)
-        
-    def _connect(self):
-        util.debug('making connection to manager')
-        name = current_process().get_name()
-        if threading.currentThread().getName() != 'MainThread':
-            name += '|' + threading.currentThread().getName()
-        conn = self._Client(self._token.address, authkey=self._authkey)
-        dispatch(conn, None, 'accept_connection', (name,))
-        self._tls.connection = conn
-        
-    def _callmethod(self, methodname, args=(), kwds={}):
-        '''
-        Try to call a method of the referrent and return a copy of the result
-        '''
-        try:
-            conn = self._tls.connection
-        except AttributeError:
-            util.debug('thread %r does not own a connection',
-                       threading.currentThread().getName())
-            self._connect()
-            conn = self._tls.connection
-
-        conn.send((self._id, methodname, args, kwds))
-        kind, result = conn.recv()
-        
-        if kind == '#RETURN':
-            return result
-        elif kind == '#PROXY':
-            exposed, token = result
-            proxytype = self._manager._registry[token.typeid][-1]
-            return proxytype(
-                token, self._serializer, manager=self._manager,
-                authkey=self._authkey, exposed=exposed
-                )
-        raise convert_to_error(kind, result)
-
-    def _getvalue(self):
-        '''
-        Get a copy of the value of the referent
-        '''
-        return self._callmethod('#GETVALUE')
-
-    def _incref(self):
-        conn = self._Client(self._token.address, authkey=self._authkey)
-        dispatch(conn, None, 'incref', (self._id,))
-        util.debug('INCREF %r', self._token.id)
-
-        self._idset.add(self._id)
-
-        state = self._manager and self._manager._state
-
-        self._close = util.Finalize(
-            self, BaseProxy._decref,
-            args=(self._token, self._authkey, state,
-                  self._tls, self._idset, self._Client),
-            exitpriority=10
-            )
-
-    @staticmethod
-    def _decref(token, authkey, state, tls, idset, _Client):
-        idset.discard(token.id)
-
-        # check whether manager is still alive
-        if state is None or state.value == State.STARTED:
-            # tell manager this process no longer cares about referent
-            try:
-                util.debug('DECREF %r', token.id)
-                conn = _Client(token.address, authkey=authkey)
-                dispatch(conn, None, 'decref', (token.id,))
-            except Exception, e:
-                util.debug('... decref failed %s', e)
-
-        else:
-            util.debug('DECREF %r -- manager already shutdown', token.id)
-
-        # check whether we can close this thread's connection because
-        # the process owns no more references to objects for this manager
-        if not idset and hasattr(tls, 'connection'):
-            util.debug('thread %r has no more proxies so closing conn',
-                       threading.currentThread().getName())
-            tls.connection.close()
-            del tls.connection
-            
-    def _after_fork(self):
-        self._manager = None
-        try:
-            self._incref()
-        except Exception, e:
-            # the proxy may just be for a manager which has shutdown
-            util.info('incref failed: %s' % e)
-
-    def __reduce__(self):
-        kwds = {}
-        if Popen.thread_is_spawning():
-            kwds['authkey'] = self._authkey
-        
-        if getattr(self, '_isauto', False):
-            kwds['exposed'] = self._exposed_
-            return (RebuildProxy,
-                    (AutoProxy, self._token, self._serializer, kwds))
-        else:
-            return (RebuildProxy,
-                    (type(self), self._token, self._serializer, kwds))
-
-    def __deepcopy__(self, memo):
-        return self._getvalue()
-    
-    def __repr__(self):
-        return '<%s object, typeid %r at %s>' % \
-               (type(self).__name__, self._token.typeid, '0x%x' % id(self))
-
-    def __str__(self):
-        '''
-        Return representation of the referent (or a fall-back if that fails)
-        '''
-        try:
-            return self._callmethod('__repr__')
-        except Exception:
-            return repr(self)[:-1] + "; '__str__()' failed>"
-
-#
-# Function used for unpickling
-#
-
-def RebuildProxy(func, token, serializer, kwds):
-    '''
-    Function used for unpickling proxy objects.
-
-    If possible the shared object is returned, or otherwise a proxy for it.
-    '''
-    server = getattr(current_process(), '_manager_server', None)
-    
-    if server and server.address == token.address:
-        return server.id_to_obj[token.id][0]
-    else:
-        incref = (
-            kwds.pop('incref', True) and
-            not getattr(current_process(), '_inheriting', False)
-            )
-        return func(token, serializer, incref=incref, **kwds)
-
-#
-# Functions to create proxies and proxy types
-#
-
-def MakeProxyType(name, exposed, _cache={}):
-    '''
-    Return an proxy type whose methods are given by `exposed`
-    '''
-    exposed = tuple(exposed)
-    try:
-        return _cache[(name, exposed)]
-    except KeyError:
-        pass
-
-    dic = {}
-
-    for meth in exposed:
-        exec '''def %s(self, *args, **kwds):
-        return self._callmethod(%r, args, kwds)''' % (meth, meth) in dic
-
-    ProxyType = type(name, (BaseProxy,), dic)
-    ProxyType._exposed_ = exposed
-    _cache[(name, exposed)] = ProxyType
-    return ProxyType
-
-
-def AutoProxy(token, serializer, manager=None, authkey=None,
-              exposed=None, incref=True):
-    '''
-    Return an auto-proxy for `token`
-    '''
-    _Client = listener_client[serializer][1]
-    
-    if exposed is None:
-        conn = _Client(token.address, authkey=authkey)
-        try:
-            exposed = dispatch(conn, None, 'get_methods', (token,))
-        finally:
-            conn.close()
-
-    if authkey is None and manager is not None:
-        authkey = manager._authkey
-    if authkey is None:
-        authkey = current_process().get_authkey()
-
-    ProxyType = MakeProxyType('AutoProxy[%s]' % token.typeid, exposed)
-    proxy = ProxyType(token, serializer, manager=manager, authkey=authkey,
-                      incref=incref)
-    proxy._isauto = True
-    return proxy
-
-#
-# Types/callables which we will register with SyncManager
-#
-
-class Namespace(object):
-    def __init__(self, **kwds):
-        self.__dict__.update(kwds)
-    def __repr__(self):
-        items = self.__dict__.items()
-        temp = []
-        for name, value in items:
-            if not name.startswith('_'):
-                temp.append('%s=%r' % (name, value))
-        temp.sort()
-        return 'Namespace(%s)' % str.join(', ', temp)
-
-class Value(object):
-    def __init__(self, typecode, value, lock=True):
-        self._typecode = typecode
-        self._value = value
-    def get(self):
-        return self._value
-    def set(self, value):
-        self._value = value
-    def __repr__(self):
-        return '%s(%r, %r)'%(type(self).__name__, self._typecode, self._value)
-    value = property(get, set)
-
-def Array(typecode, sequence, lock=True):
-    return array.array(typecode, sequence)
-
-#
-# Proxy types used by SyncManager
-#
-
-class IteratorProxy(BaseProxy):
-    # XXX remove methods for Py3.0 and Py2.6
-    _exposed_ = ('__next__', 'next', 'send', 'throw', 'close')
-    def __iter__(self):
-        return self
-    def __next__(self, *args):
-        return self._callmethod('__next__', args)
-    def next(self, *args):
-        return self._callmethod('next', args)
-    def send(self, *args):
-        return self._callmethod('send', args)
-    def throw(self, *args):
-        return self._callmethod('throw', args)
-    def close(self, *args):
-        return self._callmethod('close', args)
-
-
-class AcquirerProxy(BaseProxy):
-    _exposed_ = ('acquire', 'release')
-    def acquire(self, blocking=True):
-        return self._callmethod('acquire', (blocking,))
-    def release(self):
-        return self._callmethod('release')
-    def __enter__(self):
-        return self._callmethod('acquire')
-    def __exit__(self, exc_type, exc_val, exc_tb):
-        return self._callmethod('release')
-
-
-class ConditionProxy(AcquirerProxy):
-    # XXX will Condition.notfyAll() name be available in Py3.0?
-    _exposed_ = ('acquire', 'release', 'wait', 'notify', 'notifyAll')
-    def wait(self, timeout=None):
-        return self._callmethod('wait', (timeout,))
-    def notify(self):
-        return self._callmethod('notify')
-    def notify_all(self):
-        return self._callmethod('notifyAll')
-
-class EventProxy(BaseProxy):
-    # XXX will Event.isSet name be available in Py3.0?
-    _exposed_ = ('isSet', 'set', 'clear', 'wait')
-    def is_set(self):
-        return self._callmethod('isSet')
-    def set(self):
-        return self._callmethod('set')
-    def clear(self):
-        return self._callmethod('clear')
-    def wait(self, timeout=None):
-        return self._callmethod('wait', (timeout,))
-
-class NamespaceProxy(BaseProxy):
-    _exposed_ = ('__getattribute__', '__setattr__', '__delattr__')
-    def __getattr__(self, key):
-        if key[0] == '_':
-            return object.__getattribute__(self, key)
-        callmethod = object.__getattribute__(self, '_callmethod')
-        return callmethod('__getattribute__', (key,))    
-    def __setattr__(self, key, value):
-        if key[0] == '_':
-            return object.__setattr__(self, key, value)
-        callmethod = object.__getattribute__(self, '_callmethod')
-        return callmethod('__setattr__', (key, value))
-    def __delattr__(self, key):
-        if key[0] == '_':
-            return object.__delattr__(self, key)
-        callmethod = object.__getattribute__(self, '_callmethod')
-        return callmethod('__delattr__', (key,))
-
-    
-class ValueProxy(BaseProxy):
-    _exposed_ = ('get', 'set')
-    def get(self):
-        return self._callmethod('get')
-    def set(self, value):
-        return self._callmethod('set', (value,))
-    value = property(get, set)
-
-
-BaseListProxy = MakeProxyType('BaseListProxy', (
-    '__add__', '__contains__', '__delitem__', '__delslice__',
-    '__getitem__', '__getslice__', '__len__', '__mul__',
-    '__reversed__', '__rmul__', '__setitem__', '__setslice__',
-    'append', 'count', 'extend', 'index', 'insert', 'pop', 'remove',
-    'reverse', 'sort', '__imul__'
-    ))                  # XXX __getslice__ and __setslice__ unneeded in Py3.0
-class ListProxy(BaseListProxy):
-    def __iadd__(self, value):
-        self._callmethod('extend', (value,))
-        return self
-    def __imul__(self, value):
-        self._callmethod('__imul__', (value,))
-        return self
-
-
-DictProxy = MakeProxyType('DictProxy', (
-    '__contains__', '__delitem__', '__getitem__', '__len__',
-    '__setitem__', 'clear', 'copy', 'get', 'has_key', 'items',
-    'keys', 'pop', 'popitem', 'setdefault', 'update', 'values'
-    ))
-
-
-ArrayProxy = MakeProxyType('ArrayProxy', (
-    '__len__', '__getitem__', '__setitem__', '__getslice__', '__setslice__'
-    ))                  # XXX __getslice__ and __setslice__ unneeded in Py3.0
-
-
-PoolProxy = MakeProxyType('PoolProxy', (
-    'apply', 'apply_async', 'close', 'imap', 'imap_unordered', 'join',
-    'map', 'map_async', 'terminate'
-    ))
-PoolProxy._method_to_typeid_ = {
-    'apply_async': 'AsyncResult',
-    'map_async': 'AsyncResult',
-    'imap': 'Iterator',
-    'imap_unordered': 'Iterator'
-    }
-
-#
-# Definition of SyncManager
-#
-
-class SyncManager(BaseManager):
-    '''
-    Subclass of `BaseManager` which supports a number of shared object types.
-    
-    The types registered are those intended for the synchronization
-    of threads, plus `dict`, `list` and `Namespace`.
-    
-    The `multiprocessing.Manager()` function creates started instances of
-    this class.
-    '''
-
-SyncManager.register('Queue', Queue.Queue)
-SyncManager.register('JoinableQueue', Queue.Queue)
-SyncManager.register('Event', threading.Event, EventProxy)
-SyncManager.register('Lock', threading.Lock, AcquirerProxy)
-SyncManager.register('RLock', threading.RLock, AcquirerProxy)
-SyncManager.register('Semaphore', threading.Semaphore, AcquirerProxy)
-SyncManager.register('BoundedSemaphore', threading.BoundedSemaphore,
-                     AcquirerProxy)
-SyncManager.register('Condition', threading.Condition, ConditionProxy)
-SyncManager.register('Pool', Pool, PoolProxy)
-SyncManager.register('list', list, ListProxy)
-SyncManager.register('dict', dict, DictProxy)
-SyncManager.register('Value', Value, ValueProxy)
-SyncManager.register('Array', Array, ArrayProxy)
-SyncManager.register('Namespace', Namespace, NamespaceProxy)
-
-# types returned by methods of PoolProxy
-SyncManager.register('Iterator', proxytype=IteratorProxy, create_method=False)
-SyncManager.register('AsyncResult', create_method=False)
+#
+# Module providing the `SyncManager` class for dealing
+# with shared objects
+#
+# multiprocessing/managers.py
+#
+# Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
+#
+
+__all__ = [ 'BaseManager', 'SyncManager', 'BaseProxy', 'Token' ]
+
+#
+# Imports
+#
+
+import os
+import sys
+import weakref
+import threading
+import array
+import copyreg
+import queue
+
+from traceback import format_exc
+from multiprocessing import Process, current_process, active_children, Pool, util, connection
+from multiprocessing.process import AuthenticationString
+from multiprocessing.forking import exit, Popen, assert_spawning
+from multiprocessing.util import Finalize, info
+
+try:
+    from cPickle import PicklingError
+except ImportError:
+    from pickle import PicklingError
+
+#
+#
+#
+
+try:
+    bytes
+except NameError:
+    bytes = str                  # XXX not needed in Py2.6 and Py3.0
+
+#
+# Register some things for pickling
+#
+
+def reduce_array(a):
+    return array.array, (a.typecode, a.tostring())
+copyreg.pickle(array.array, reduce_array)
+
+view_types = [type(getattr({}, name)()) for name in ('items','keys','values')]
+if view_types[0] is not list:       # XXX only needed in Py3.0
+    def rebuild_as_list(obj):
+        return list, (list(obj),)
+    for view_type in view_types:
+        copyreg.pickle(view_type, rebuild_as_list)
+
+#
+# Type for identifying shared objects
+#
+
+class Token(object):
+    '''
+    Type to uniquely indentify a shared object
+    '''
+    __slots__ = ('typeid', 'address', 'id')
+
+    def __init__(self, typeid, address, id):
+        (self.typeid, self.address, self.id) = (typeid, address, id)
+
+    def __getstate__(self):
+        return (self.typeid, self.address, self.id)
+
+    def __setstate__(self, state):
+        (self.typeid, self.address, self.id) = state
+
+    def __repr__(self):
+        return 'Token(typeid=%r, address=%r, id=%r)' % \
+               (self.typeid, self.address, self.id)
+
+#
+# Function for communication with a manager's server process
+#
+
+def dispatch(c, id, methodname, args=(), kwds={}):
+    '''
+    Send a message to manager using connection `c` and return response
+    '''
+    c.send((id, methodname, args, kwds))
+    kind, result = c.recv()
+    if kind == '#RETURN':
+        return result
+    raise convert_to_error(kind, result)
+
+def convert_to_error(kind, result):
+    if kind == '#ERROR':
+        return result
+    elif kind == '#TRACEBACK':
+        assert type(result) is str
+        return  RemoteError(result)
+    elif kind == '#UNSERIALIZABLE':
+        assert type(result) is str
+        return RemoteError('Unserializable message: %s\n' % result)
+    else:
+        return ValueError('Unrecognized message type')
+
+class RemoteError(Exception):
+    def __str__(self):
+        return ('\n' + '-'*75 + '\n' + str(self.args[0]) + '-'*75)
+
+#
+# Functions for finding the method names of an object
+#
+
+def all_methods(obj):
+    '''
+    Return a list of names of methods of `obj`
+    '''
+    temp = []
+    for name in dir(obj):
+        func = getattr(obj, name)
+        if hasattr(func, '__call__'):
+            temp.append(name)
+    return temp
+
+def public_methods(obj):
+    '''
+    Return a list of names of methods of `obj` which do not start with '_'
+    '''
+    return [name for name in all_methods(obj) if name[0] != '_']
+
+#
+# Server which is run in a process controlled by a manager
+#
+
+class Server(object):
+    '''
+    Server class which runs in a process controlled by a manager object
+    '''
+    public = ['shutdown', 'create', 'accept_connection', 'get_methods',
+              'debug_info', 'number_of_objects', 'dummy', 'incref', 'decref']
+
+    def __init__(self, registry, address, authkey, serializer):
+        assert isinstance(authkey, bytes)
+        self.registry = registry
+        self.authkey = AuthenticationString(authkey)
+        Listener, Client = listener_client[serializer]
+
+        # do authentication later
+        self.listener = Listener(address=address, backlog=5)
+        self.address = self.listener.address
+
+        self.id_to_obj = {0: (None, ())}
+        self.id_to_refcount = {}
+        self.mutex = threading.RLock()
+        self.stop = 0
+
+    def serve_forever(self):
+        '''
+        Run the server forever
+        '''
+        current_process()._manager_server = self
+        try:
+            try:
+                while 1:
+                    try:
+                        c = self.listener.accept()
+                    except (OSError, IOError):
+                        continue
+                    t = threading.Thread(target=self.handle_request, args=(c,))
+                    t.setDaemon(True)
+                    t.start()
+            except (KeyboardInterrupt, SystemExit):
+                pass
+        finally:
+            self.stop = 999
+            self.listener.close()
+
+    def handle_request(self, c):
+        '''
+        Handle a new connection
+        '''
+        funcname = result = request = None
+        try:
+            connection.deliver_challenge(c, self.authkey)
+            connection.answer_challenge(c, self.authkey)
+            request = c.recv()
+            ignore, funcname, args, kwds = request
+            assert funcname in self.public, '%r unrecognized' % funcname
+            func = getattr(self, funcname)
+        except Exception:
+            msg = ('#TRACEBACK', format_exc())
+        else:
+            try:
+                result = func(c, *args, **kwds)
+            except Exception:
+                msg = ('#TRACEBACK', format_exc())
+            else:
+                msg = ('#RETURN', result)
+        try:
+            c.send(msg)
+        except Exception as e:
+            try:
+                c.send(('#TRACEBACK', format_exc()))
+            except Exception:
+                pass
+            util.info('Failure to send message: %r', msg)
+            util.info(' ... request was %r', request)
+            util.info(' ... exception was %r', e)
+
+        c.close()
+
+    def serve_client(self, conn):
+        '''
+        Handle requests from the proxies in a particular process/thread
+        '''
+        util.debug('starting server thread to service %r',
+                   threading.currentThread().getName())
+
+        recv = conn.recv
+        send = conn.send
+        id_to_obj = self.id_to_obj
+
+        while not self.stop:
+
+            try:
+                methodname = obj = None
+                request = recv()
+                ident, methodname, args, kwds = request
+                obj, exposed, gettypeid = id_to_obj[ident]
+
+                if methodname not in exposed:
+                    raise AttributeError(
+                        'method %r of %r object is not in exposed=%r' %
+                        (methodname, type(obj), exposed)
+                        )
+
+                function = getattr(obj, methodname)
+
+                try:
+                    res = function(*args, **kwds)
+                except Exception as e:
+                    msg = ('#ERROR', e)
+                else:
+                    typeid = gettypeid and gettypeid.get(methodname, None)
+                    if typeid:
+                        rident, rexposed = self.create(conn, typeid, res)
+                        token = Token(typeid, self.address, rident)
+                        msg = ('#PROXY', (rexposed, token))
+                    else:
+                        msg = ('#RETURN', res)
+
+            except AttributeError:
+                if methodname is None:
+                    msg = ('#TRACEBACK', format_exc())
+                else:
+                    try:
+                        fallback_func = self.fallback_mapping[methodname]
+                        result = fallback_func(
+                            self, conn, ident, obj, *args, **kwds
+                            )
+                        msg = ('#RETURN', result)
+                    except Exception:
+                        msg = ('#TRACEBACK', format_exc())
+
+            except EOFError:
+                util.debug('got EOF -- exiting thread serving %r',
+                           threading.currentThread().getName())
+                sys.exit(0)
+
+            except Exception:
+                msg = ('#TRACEBACK', format_exc())
+
+            try:
+                try:
+                    send(msg)
+                except Exception as e:
+                    send(('#UNSERIALIZABLE', repr(msg)))
+            except Exception as e:
+                util.info('exception in thread serving %r',
+                        threading.currentThread().getName())
+                util.info(' ... message was %r', msg)
+                util.info(' ... exception was %r', e)
+                conn.close()
+                sys.exit(1)
+
+    def fallback_getvalue(self, conn, ident, obj):
+        return obj
+
+    def fallback_str(self, conn, ident, obj):
+        return str(obj)
+
+    def fallback_repr(self, conn, ident, obj):
+        return repr(obj)
+
+    fallback_mapping = {
+        '__str__':fallback_str,
+        '__repr__':fallback_repr,
+        '#GETVALUE':fallback_getvalue
+        }
+
+    def dummy(self, c):
+        pass
+
+    def debug_info(self, c):
+        '''
+        Return some info --- useful to spot problems with refcounting
+        '''
+        self.mutex.acquire()
+        try:
+            result = []
+            keys = list(self.id_to_obj.keys())
+            keys.sort()
+            for ident in keys:
+                if ident != 0:
+                    result.append('  %s:       refcount=%s\n    %s' %
+                                  (ident, self.id_to_refcount[ident],
+                                   str(self.id_to_obj[ident][0])[:75]))
+            return '\n'.join(result)
+        finally:
+            self.mutex.release()
+
+    def number_of_objects(self, c):
+        '''
+        Number of shared objects
+        '''
+        return len(self.id_to_obj) - 1      # don't count ident=0
+
+    def shutdown(self, c):
+        '''
+        Shutdown this process
+        '''
+        try:
+            try:
+                util.debug('manager received shutdown message')
+                c.send(('#RETURN', None))
+
+                if sys.stdout != sys.__stdout__:
+                    util.debug('resetting stdout, stderr')
+                    sys.stdout = sys.__stdout__
+                    sys.stderr = sys.__stderr__
+
+                util._run_finalizers(0)
+
+                for p in active_children():
+                    util.debug('terminating a child process of manager')
+                    p.terminate()
+
+                for p in active_children():
+                    util.debug('terminating a child process of manager')
+                    p.join()
+
+                util._run_finalizers()
+                util.info('manager exiting with exitcode 0')
+            except:
+                import traceback
+                traceback.print_exc()
+        finally:
+            exit(0)
+
+    def create(self, c, typeid, *args, **kwds):
+        '''
+        Create a new shared object and return its id
+        '''
+        self.mutex.acquire()
+        try:
+            callable, exposed, method_to_typeid, proxytype = \
+                      self.registry[typeid]
+
+            if callable is None:
+                assert len(args) == 1 and not kwds
+                obj = args[0]
+            else:
+                obj = callable(*args, **kwds)
+
+            if exposed is None:
+                exposed = public_methods(obj)
+            if method_to_typeid is not None:
+                assert type(method_to_typeid) is dict
+                exposed = list(exposed) + list(method_to_typeid)
+
+            ident = '%x' % id(obj)  # convert to string because xmlrpclib
+                                    # only has 32 bit signed integers
+            util.debug('%r callable returned object with id %r', typeid, ident)
+
+            self.id_to_obj[ident] = (obj, set(exposed), method_to_typeid)
+            if ident not in self.id_to_refcount:
+                self.id_to_refcount[ident] = None
+            return ident, tuple(exposed)
+        finally:
+            self.mutex.release()
+
+    def get_methods(self, c, token):
+        '''
+        Return the methods of the shared object indicated by token
+        '''
+        return tuple(self.id_to_obj[token.id][1])
+
+    def accept_connection(self, c, name):
+        '''
+        Spawn a new thread to serve this connection
+        '''
+        threading.currentThread().setName(name)
+        c.send(('#RETURN', None))
+        self.serve_client(c)
+
+    def incref(self, c, ident):
+        self.mutex.acquire()
+        try:
+            try:
+                self.id_to_refcount[ident] += 1
+            except TypeError:
+                assert self.id_to_refcount[ident] is None
+                self.id_to_refcount[ident] = 1
+        finally:
+            self.mutex.release()
+
+    def decref(self, c, ident):
+        self.mutex.acquire()
+        try:
+            assert self.id_to_refcount[ident] >= 1
+            self.id_to_refcount[ident] -= 1
+            if self.id_to_refcount[ident] == 0:
+                del self.id_to_obj[ident], self.id_to_refcount[ident]
+                util.debug('disposing of obj with id %d', ident)
+        finally:
+            self.mutex.release()
+
+#
+# Class to represent state of a manager
+#
+
+class State(object):
+    __slots__ = ['value']
+    INITIAL = 0
+    STARTED = 1
+    SHUTDOWN = 2
+
+#
+# Mapping from serializer name to Listener and Client types
+#
+
+listener_client = {
+    'pickle' : (connection.Listener, connection.Client),
+    'xmlrpclib' : (connection.XmlListener, connection.XmlClient)
+    }
+
+#
+# Definition of BaseManager
+#
+
+class BaseManager(object):
+    '''
+    Base class for managers
+    '''
+    _registry = {}
+    _Server = Server
+
+    def __init__(self, address=None, authkey=None, serializer='pickle'):
+        if authkey is None:
+            authkey = current_process().get_authkey()
+        self._address = address     # XXX not final address if eg ('', 0)
+        self._authkey = AuthenticationString(authkey)
+        self._state = State()
+        self._state.value = State.INITIAL
+        self._serializer = serializer
+        self._Listener, self._Client = listener_client[serializer]
+
+    def __reduce__(self):
+        return type(self).from_address, \
+               (self._address, self._authkey, self._serializer)
+
+    def get_server(self):
+        '''
+        Return server object with serve_forever() method and address attribute
+        '''
+        assert self._state.value == State.INITIAL
+        return Server(self._registry, self._address,
+                      self._authkey, self._serializer)
+
+    def connect(self):
+        '''
+        Connect manager object to the server process
+        '''
+        Listener, Client = listener_client[self._serializer]
+        conn = Client(self._address, authkey=self._authkey)
+        dispatch(conn, None, 'dummy')
+        self._state.value = State.STARTED
+
+    def start(self):
+        '''
+        Spawn a server process for this manager object
+        '''
+        assert self._state.value == State.INITIAL
+
+        # pipe over which we will retrieve address of server
+        reader, writer = connection.Pipe(duplex=False)
+
+        # spawn process which runs a server
+        self._process = Process(
+            target=type(self)._run_server,
+            args=(self._registry, self._address, self._authkey,
+                  self._serializer, writer),
+            )
+        ident = ':'.join(str(i) for i in self._process._identity)
+        self._process.set_name(type(self).__name__  + '-' + ident)
+        self._process.start()
+
+        # get address of server
+        writer.close()
+        self._address = reader.recv()
+        reader.close()
+
+        # register a finalizer
+        self._state.value = State.STARTED
+        self.shutdown = util.Finalize(
+            self, type(self)._finalize_manager,
+            args=(self._process, self._address, self._authkey,
+                  self._state, self._Client),
+            exitpriority=0
+            )
+
+    @classmethod
+    def _run_server(cls, registry, address, authkey, serializer, writer):
+        '''
+        Create a server, report its address and run it
+        '''
+        # create server
+        server = cls._Server(registry, address, authkey, serializer)
+
+        # inform parent process of the server's address
+        writer.send(server.address)
+        writer.close()
+
+        # run the manager
+        util.info('manager serving at %r', server.address)
+        server.serve_forever()
+
+    def _create(self, typeid, *args, **kwds):
+        '''
+        Create a new shared object; return the token and exposed tuple
+        '''
+        assert self._state.value == State.STARTED, 'server not yet started'
+        conn = self._Client(self._address, authkey=self._authkey)
+        try:
+            id, exposed = dispatch(conn, None, 'create', (typeid,)+args, kwds)
+        finally:
+            conn.close()
+        return Token(typeid, self._address, id), exposed
+
+    def join(self, timeout=None):
+        '''
+        Join the manager process (if it has been spawned)
+        '''
+        self._process.join(timeout)
+
+    def _debug_info(self):
+        '''
+        Return some info about the servers shared objects and connections
+        '''
+        conn = self._Client(self._address, authkey=self._authkey)
+        try:
+            return dispatch(conn, None, 'debug_info')
+        finally:
+            conn.close()
+
+    def _number_of_objects(self):
+        '''
+        Return the number of shared objects
+        '''
+        conn = self._Client(self._address, authkey=self._authkey)
+        try:
+            return dispatch(conn, None, 'number_of_objects')
+        finally:
+            conn.close()
+
+    def __enter__(self):
+        return self
+
+    def __exit__(self, exc_type, exc_val, exc_tb):
+        self.shutdown()
+
+    @staticmethod
+    def _finalize_manager(process, address, authkey, state, _Client):
+        '''
+        Shutdown the manager process; will be registered as a finalizer
+        '''
+        if process.is_alive():
+            util.info('sending shutdown message to manager')
+            try:
+                conn = _Client(address, authkey=authkey)
+                try:
+                    dispatch(conn, None, 'shutdown')
+                finally:
+                    conn.close()
+            except Exception:
+                pass
+
+            process.join(timeout=0.2)
+            if process.is_alive():
+                util.info('manager still alive')
+                if hasattr(process, 'terminate'):
+                    util.info('trying to `terminate()` manager process')
+                    process.terminate()
+                    process.join(timeout=0.1)
+                    if process.is_alive():
+                        util.info('manager still alive after terminate')
+
+        state.value = State.SHUTDOWN
+        try:
+            del BaseProxy._address_to_local[address]
+        except KeyError:
+            pass
+
+    address = property(lambda self: self._address)
+
+    @classmethod
+    def register(cls, typeid, callable=None, proxytype=None, exposed=None,
+                 method_to_typeid=None, create_method=True):
+        '''
+        Register a typeid with the manager type
+        '''
+        if '_registry' not in cls.__dict__:
+            cls._registry = cls._registry.copy()
+
+        if proxytype is None:
+            proxytype = AutoProxy
+
+        exposed = exposed or getattr(proxytype, '_exposed_', None)
+
+        method_to_typeid = method_to_typeid or \
+                           getattr(proxytype, '_method_to_typeid_', None)
+
+        if method_to_typeid:
+            for key, value in list(method_to_typeid.items()):
+                assert type(key) is str, '%r is not a string' % key
+                assert type(value) is str, '%r is not a string' % value
+
+        cls._registry[typeid] = (
+            callable, exposed, method_to_typeid, proxytype
+            )
+
+        if create_method:
+            def temp(self, *args, **kwds):
+                util.debug('requesting creation of a shared %r object', typeid)
+                token, exp = self._create(typeid, *args, **kwds)
+                proxy = proxytype(
+                    token, self._serializer, manager=self,
+                    authkey=self._authkey, exposed=exp
+                    )
+                return proxy
+            temp.__name__ = typeid
+            setattr(cls, typeid, temp)
+
+#
+# Subclass of set which get cleared after a fork
+#
+
+class ProcessLocalSet(set):
+    def __init__(self):
+        util.register_after_fork(self, lambda obj: obj.clear())
+    def __reduce__(self):
+        return type(self), ()
+
+#
+# Definition of BaseProxy
+#
+
+class BaseProxy(object):
+    '''
+    A base for proxies of shared objects
+    '''
+    _address_to_local = {}
+    _mutex = util.ForkAwareThreadLock()
+
+    def __init__(self, token, serializer, manager=None,
+                 authkey=None, exposed=None, incref=True):
+        BaseProxy._mutex.acquire()
+        try:
+            tls_idset = BaseProxy._address_to_local.get(token.address, None)
+            if tls_idset is None:
+                tls_idset = util.ForkAwareLocal(), ProcessLocalSet()
+                BaseProxy._address_to_local[token.address] = tls_idset
+        finally:
+            BaseProxy._mutex.release()
+
+        # self._tls is used to record the connection used by this
+        # thread to communicate with the manager at token.address
+        self._tls = tls_idset[0]
+
+        # self._idset is used to record the identities of all shared
+        # objects for which the current process owns references and
+        # which are in the manager at token.address
+        self._idset = tls_idset[1]
+
+        self._token = token
+        self._id = self._token.id
+        self._manager = manager
+        self._serializer = serializer
+        self._Client = listener_client[serializer][1]
+
+        if authkey is not None:
+            self._authkey = AuthenticationString(authkey)
+        elif self._manager is not None:
+            self._authkey = self._manager._authkey
+        else:
+            self._authkey = current_process().get_authkey()
+
+        if incref:
+            self._incref()
+
+        util.register_after_fork(self, BaseProxy._after_fork)
+
+    def _connect(self):
+        util.debug('making connection to manager')
+        name = current_process().get_name()
+        if threading.currentThread().getName() != 'MainThread':
+            name += '|' + threading.currentThread().getName()
+        conn = self._Client(self._token.address, authkey=self._authkey)
+        dispatch(conn, None, 'accept_connection', (name,))
+        self._tls.connection = conn
+
+    def _callmethod(self, methodname, args=(), kwds={}):
+        '''
+        Try to call a method of the referrent and return a copy of the result
+        '''
+        try:
+            conn = self._tls.connection
+        except AttributeError:
+            util.debug('thread %r does not own a connection',
+                       threading.currentThread().getName())
+            self._connect()
+            conn = self._tls.connection
+
+        conn.send((self._id, methodname, args, kwds))
+        kind, result = conn.recv()
+
+        if kind == '#RETURN':
+            return result
+        elif kind == '#PROXY':
+            exposed, token = result
+            proxytype = self._manager._registry[token.typeid][-1]
+            return proxytype(
+                token, self._serializer, manager=self._manager,
+                authkey=self._authkey, exposed=exposed
+                )
+        raise convert_to_error(kind, result)
+
+    def _getvalue(self):
+        '''
+        Get a copy of the value of the referent
+        '''
+        return self._callmethod('#GETVALUE')
+
+    def _incref(self):
+        conn = self._Client(self._token.address, authkey=self._authkey)
+        dispatch(conn, None, 'incref', (self._id,))
+        util.debug('INCREF %r', self._token.id)
+
+        self._idset.add(self._id)
+
+        state = self._manager and self._manager._state
+
+        self._close = util.Finalize(
+            self, BaseProxy._decref,
+            args=(self._token, self._authkey, state,
+                  self._tls, self._idset, self._Client),
+            exitpriority=10
+            )
+
+    @staticmethod
+    def _decref(token, authkey, state, tls, idset, _Client):
+        idset.discard(token.id)
+
+        # check whether manager is still alive
+        if state is None or state.value == State.STARTED:
+            # tell manager this process no longer cares about referent
+            try:
+                util.debug('DECREF %r', token.id)
+                conn = _Client(token.address, authkey=authkey)
+                dispatch(conn, None, 'decref', (token.id,))
+            except Exception as e:
+                util.debug('... decref failed %s', e)
+
+        else:
+            util.debug('DECREF %r -- manager already shutdown', token.id)
+
+        # check whether we can close this thread's connection because
+        # the process owns no more references to objects for this manager
+        if not idset and hasattr(tls, 'connection'):
+            util.debug('thread %r has no more proxies so closing conn',
+                       threading.currentThread().getName())
+            tls.connection.close()
+            del tls.connection
+
+    def _after_fork(self):
+        self._manager = None
+        try:
+            self._incref()
+        except Exception as e:
+            # the proxy may just be for a manager which has shutdown
+            util.info('incref failed: %s' % e)
+
+    def __reduce__(self):
+        kwds = {}
+        if Popen.thread_is_spawning():
+            kwds['authkey'] = self._authkey
+
+        if getattr(self, '_isauto', False):
+            kwds['exposed'] = self._exposed_
+            return (RebuildProxy,
+                    (AutoProxy, self._token, self._serializer, kwds))
+        else:
+            return (RebuildProxy,
+                    (type(self), self._token, self._serializer, kwds))
+
+    def __deepcopy__(self, memo):
+        return self._getvalue()
+
+    def __repr__(self):
+        return '<%s object, typeid %r at %s>' % \
+               (type(self).__name__, self._token.typeid, '0x%x' % id(self))
+
+    def __str__(self):
+        '''
+        Return representation of the referent (or a fall-back if that fails)
+        '''
+        try:
+            return self._callmethod('__repr__')
+        except Exception:
+            return repr(self)[:-1] + "; '__str__()' failed>"
+
+#
+# Function used for unpickling
+#
+
+def RebuildProxy(func, token, serializer, kwds):
+    '''
+    Function used for unpickling proxy objects.
+
+    If possible the shared object is returned, or otherwise a proxy for it.
+    '''
+    server = getattr(current_process(), '_manager_server', None)
+
+    if server and server.address == token.address:
+        return server.id_to_obj[token.id][0]
+    else:
+        incref = (
+            kwds.pop('incref', True) and
+            not getattr(current_process(), '_inheriting', False)
+            )
+        return func(token, serializer, incref=incref, **kwds)
+
+#
+# Functions to create proxies and proxy types
+#
+
+def MakeProxyType(name, exposed, _cache={}):
+    '''
+    Return an proxy type whose methods are given by `exposed`
+    '''
+    exposed = tuple(exposed)
+    try:
+        return _cache[(name, exposed)]
+    except KeyError:
+        pass
+
+    dic = {}
+
+    for meth in exposed:
+        exec('''def %s(self, *args, **kwds):
+        return self._callmethod(%r, args, kwds)''' % (meth, meth), dic)
+
+    ProxyType = type(name, (BaseProxy,), dic)
+    ProxyType._exposed_ = exposed
+    _cache[(name, exposed)] = ProxyType
+    return ProxyType
+
+
+def AutoProxy(token, serializer, manager=None, authkey=None,
+              exposed=None, incref=True):
+    '''
+    Return an auto-proxy for `token`
+    '''
+    _Client = listener_client[serializer][1]
+
+    if exposed is None:
+        conn = _Client(token.address, authkey=authkey)
+        try:
+            exposed = dispatch(conn, None, 'get_methods', (token,))
+        finally:
+            conn.close()
+
+    if authkey is None and manager is not None:
+        authkey = manager._authkey
+    if authkey is None:
+        authkey = current_process().get_authkey()
+
+    ProxyType = MakeProxyType('AutoProxy[%s]' % token.typeid, exposed)
+    proxy = ProxyType(token, serializer, manager=manager, authkey=authkey,
+                      incref=incref)
+    proxy._isauto = True
+    return proxy
+
+#
+# Types/callables which we will register with SyncManager
+#
+
+class Namespace(object):
+    def __init__(self, **kwds):
+        self.__dict__.update(kwds)
+    def __repr__(self):
+        items = list(self.__dict__.items())
+        temp = []
+        for name, value in items:
+            if not name.startswith('_'):
+                temp.append('%s=%r' % (name, value))
+        temp.sort()
+        return 'Namespace(%s)' % str.join(', ', temp)
+
+class Value(object):
+    def __init__(self, typecode, value, lock=True):
+        self._typecode = typecode
+        self._value = value
+    def get(self):
+        return self._value
+    def set(self, value):
+        self._value = value
+    def __repr__(self):
+        return '%s(%r, %r)'%(type(self).__name__, self._typecode, self._value)
+    value = property(get, set)
+
+def Array(typecode, sequence, lock=True):
+    return array.array(typecode, sequence)
+
+#
+# Proxy types used by SyncManager
+#
+
+class IteratorProxy(BaseProxy):
+    # XXX remove methods for Py3.0 and Py2.6
+    _exposed_ = ('__next__', 'next', 'send', 'throw', 'close')
+    def __iter__(self):
+        return self
+    def __next__(self, *args):
+        return self._callmethod('__next__', args)
+    def next(self, *args):
+        return self._callmethod('next', args)
+    def send(self, *args):
+        return self._callmethod('send', args)
+    def throw(self, *args):
+        return self._callmethod('throw', args)
+    def close(self, *args):
+        return self._callmethod('close', args)
+
+
+class AcquirerProxy(BaseProxy):
+    _exposed_ = ('acquire', 'release')
+    def acquire(self, blocking=True):
+        return self._callmethod('acquire', (blocking,))
+    def release(self):
+        return self._callmethod('release')
+    def __enter__(self):
+        return self._callmethod('acquire')
+    def __exit__(self, exc_type, exc_val, exc_tb):
+        return self._callmethod('release')
+
+
+class ConditionProxy(AcquirerProxy):
+    # XXX will Condition.notfyAll() name be available in Py3.0?
+    _exposed_ = ('acquire', 'release', 'wait', 'notify', 'notifyAll')
+    def wait(self, timeout=None):
+        return self._callmethod('wait', (timeout,))
+    def notify(self):
+        return self._callmethod('notify')
+    def notify_all(self):
+        return self._callmethod('notifyAll')
+
+class EventProxy(BaseProxy):
+    # XXX will Event.isSet name be available in Py3.0?
+    _exposed_ = ('isSet', 'set', 'clear', 'wait')
+    def is_set(self):
+        return self._callmethod('isSet')
+    def set(self):
+        return self._callmethod('set')
+    def clear(self):
+        return self._callmethod('clear')
+    def wait(self, timeout=None):
+        return self._callmethod('wait', (timeout,))
+
+class NamespaceProxy(BaseProxy):
+    _exposed_ = ('__getattribute__', '__setattr__', '__delattr__')
+    def __getattr__(self, key):
+        if key[0] == '_':
+            return object.__getattribute__(self, key)
+        callmethod = object.__getattribute__(self, '_callmethod')
+        return callmethod('__getattribute__', (key,))
+    def __setattr__(self, key, value):
+        if key[0] == '_':
+            return object.__setattr__(self, key, value)
+        callmethod = object.__getattribute__(self, '_callmethod')
+        return callmethod('__setattr__', (key, value))
+    def __delattr__(self, key):
+        if key[0] == '_':
+            return object.__delattr__(self, key)
+        callmethod = object.__getattribute__(self, '_callmethod')
+        return callmethod('__delattr__', (key,))
+
+
+class ValueProxy(BaseProxy):
+    _exposed_ = ('get', 'set')
+    def get(self):
+        return self._callmethod('get')
+    def set(self, value):
+        return self._callmethod('set', (value,))
+    value = property(get, set)
+
+
+BaseListProxy = MakeProxyType('BaseListProxy', (
+    '__add__', '__contains__', '__delitem__', '__delslice__',
+    '__getitem__', '__getslice__', '__len__', '__mul__',
+    '__reversed__', '__rmul__', '__setitem__', '__setslice__',
+    'append', 'count', 'extend', 'index', 'insert', 'pop', 'remove',
+    'reverse', 'sort', '__imul__'
+    ))                  # XXX __getslice__ and __setslice__ unneeded in Py3.0
+class ListProxy(BaseListProxy):
+    def __iadd__(self, value):
+        self._callmethod('extend', (value,))
+        return self
+    def __imul__(self, value):
+        self._callmethod('__imul__', (value,))
+        return self
+
+
+DictProxy = MakeProxyType('DictProxy', (
+    '__contains__', '__delitem__', '__getitem__', '__len__',
+    '__setitem__', 'clear', 'copy', 'get', 'has_key', 'items',
+    'keys', 'pop', 'popitem', 'setdefault', 'update', 'values'
+    ))
+
+
+ArrayProxy = MakeProxyType('ArrayProxy', (
+    '__len__', '__getitem__', '__setitem__', '__getslice__', '__setslice__'
+    ))                  # XXX __getslice__ and __setslice__ unneeded in Py3.0
+
+
+PoolProxy = MakeProxyType('PoolProxy', (
+    'apply', 'apply_async', 'close', 'imap', 'imap_unordered', 'join',
+    'map', 'map_async', 'terminate'
+    ))
+PoolProxy._method_to_typeid_ = {
+    'apply_async': 'AsyncResult',
+    'map_async': 'AsyncResult',
+    'imap': 'Iterator',
+    'imap_unordered': 'Iterator'
+    }
+
+#
+# Definition of SyncManager
+#
+
+class SyncManager(BaseManager):
+    '''
+    Subclass of `BaseManager` which supports a number of shared object types.
+
+    The types registered are those intended for the synchronization
+    of threads, plus `dict`, `list` and `Namespace`.
+
+    The `multiprocessing.Manager()` function creates started instances of
+    this class.
+    '''
+
+SyncManager.register('Queue', queue.Queue)
+SyncManager.register('JoinableQueue', queue.Queue)
+SyncManager.register('Event', threading.Event, EventProxy)
+SyncManager.register('Lock', threading.Lock, AcquirerProxy)
+SyncManager.register('RLock', threading.RLock, AcquirerProxy)
+SyncManager.register('Semaphore', threading.Semaphore, AcquirerProxy)
+SyncManager.register('BoundedSemaphore', threading.BoundedSemaphore,
+                     AcquirerProxy)
+SyncManager.register('Condition', threading.Condition, ConditionProxy)
+SyncManager.register('Pool', Pool, PoolProxy)
+SyncManager.register('list', list, ListProxy)
+SyncManager.register('dict', dict, DictProxy)
+SyncManager.register('Value', Value, ValueProxy)
+SyncManager.register('Array', Array, ArrayProxy)
+SyncManager.register('Namespace', Namespace, NamespaceProxy)
+
+# types returned by methods of PoolProxy
+SyncManager.register('Iterator', proxytype=IteratorProxy, create_method=False)
+SyncManager.register('AsyncResult', create_method=False)

Modified: python/branches/py3k/Lib/multiprocessing/pool.py
==============================================================================
--- /python/trunk/Lib/multiprocessing/pool.py	(original)
+++ python/branches/py3k/Lib/multiprocessing/pool.py	Wed Jun 11 18:44:04 2008
@@ -1,596 +1,596 @@
-#
-# Module providing the `Pool` class for managing a process pool
-#
-# multiprocessing/pool.py
-#
-# Copyright (c) 2007-2008, R Oudkerk --- see COPYING.txt
-#
-
-__all__ = ['Pool']
-
-#
-# Imports
-#
-
-import threading
-import Queue
-import itertools
-import collections
-import time
-
-from multiprocessing import Process, cpu_count, TimeoutError
-from multiprocessing.util import Finalize, debug
-
-#
-# Constants representing the state of a pool
-#
-
-RUN = 0
-CLOSE = 1
-TERMINATE = 2
-
-#
-# Miscellaneous
-#
-
-job_counter = itertools.count()
-
-def mapstar(args):
-    return map(*args)
-
-#
-# Code run by worker processes
-#
-
-def worker(inqueue, outqueue, initializer=None, initargs=()):
-    put = outqueue.put
-    get = inqueue.get
-    if hasattr(inqueue, '_writer'):
-        inqueue._writer.close()
-        outqueue._reader.close()
-
-    if initializer is not None:
-        initializer(*initargs)
-
-    while 1:
-        try:
-            task = get()
-        except (EOFError, IOError):
-            debug('worker got EOFError or IOError -- exiting')
-            break
-        
-        if task is None:
-            debug('worker got sentinel -- exiting')
-            break
-            
-        job, i, func, args, kwds = task
-        try:
-            result = (True, func(*args, **kwds))
-        except Exception, e:
-            result = (False, e)
-        put((job, i, result))
-    
-#
-# Class representing a process pool
-#
-
-class Pool(object):
-    '''
-    Class which supports an async version of the `apply()` builtin
-    '''
-    Process = Process
-
-    def __init__(self, processes=None, initializer=None, initargs=()):
-        self._setup_queues()
-        self._taskqueue = Queue.Queue()
-        self._cache = {}
-        self._state = RUN
-
-        if processes is None:
-            try:
-                processes = cpu_count()
-            except NotImplementedError:
-                processes = 1
-            
-        self._pool = []
-        for i in range(processes):
-            w = self.Process(
-                target=worker,
-                args=(self._inqueue, self._outqueue, initializer, initargs)
-                )
-            self._pool.append(w)
-            w.set_name(w.get_name().replace('Process', 'PoolWorker'))
-            w.set_daemon(True)
-            w.start()
-            
-        self._task_handler = threading.Thread(
-            target=Pool._handle_tasks,
-            args=(self._taskqueue, self._quick_put, self._outqueue, self._pool)
-            )
-        self._task_handler.setDaemon(True)
-        self._task_handler._state = RUN
-        self._task_handler.start()
-
-        self._result_handler = threading.Thread(
-            target=Pool._handle_results,
-            args=(self._outqueue, self._quick_get, self._cache)
-            )
-        self._result_handler.setDaemon(True)
-        self._result_handler._state = RUN
-        self._result_handler.start()
-
-        self._terminate = Finalize(
-            self, self._terminate_pool,
-            args=(self._taskqueue, self._inqueue, self._outqueue, self._pool,
-                  self._task_handler, self._result_handler, self._cache),
-            exitpriority=15
-            )
-
-    def _setup_queues(self):
-        from .queues import SimpleQueue
-        self._inqueue = SimpleQueue()
-        self._outqueue = SimpleQueue()
-        self._quick_put = self._inqueue._writer.send
-        self._quick_get = self._outqueue._reader.recv
-        
-    def apply(self, func, args=(), kwds={}):
-        '''
-        Equivalent of `apply()` builtin
-        '''
-        assert self._state == RUN
-        return self.apply_async(func, args, kwds).get()
-
-    def map(self, func, iterable, chunksize=None):
-        '''
-        Equivalent of `map()` builtin
-        '''
-        assert self._state == RUN
-        return self.map_async(func, iterable, chunksize).get()
-
-    def imap(self, func, iterable, chunksize=1):
-        '''
-        Equivalent of `itertool.imap()` -- can be MUCH slower than `Pool.map()`
-        '''
-        assert self._state == RUN
-        if chunksize == 1:
-            result = IMapIterator(self._cache)
-            self._taskqueue.put((((result._job, i, func, (x,), {})
-                         for i, x in enumerate(iterable)), result._set_length))
-            return result
-        else:
-            assert chunksize > 1
-            task_batches = Pool._get_tasks(func, iterable, chunksize)
-            result = IMapIterator(self._cache)
-            self._taskqueue.put((((result._job, i, mapstar, (x,), {})
-                     for i, x in enumerate(task_batches)), result._set_length))
-            return (item for chunk in result for item in chunk)
-
-    def imap_unordered(self, func, iterable, chunksize=1):
-        '''
-        Like `imap()` method but ordering of results is arbitrary
-        '''
-        assert self._state == RUN
-        if chunksize == 1:
-            result = IMapUnorderedIterator(self._cache)
-            self._taskqueue.put((((result._job, i, func, (x,), {})
-                         for i, x in enumerate(iterable)), result._set_length))
-            return result
-        else:
-            assert chunksize > 1
-            task_batches = Pool._get_tasks(func, iterable, chunksize)
-            result = IMapUnorderedIterator(self._cache)
-            self._taskqueue.put((((result._job, i, mapstar, (x,), {})
-                     for i, x in enumerate(task_batches)), result._set_length))
-            return (item for chunk in result for item in chunk)
-            
-    def apply_async(self, func, args=(), kwds={}, callback=None):
-        '''
-        Asynchronous equivalent of `apply()` builtin
-        '''
-        assert self._state == RUN
-        result = ApplyResult(self._cache, callback)
-        self._taskqueue.put(([(result._job, None, func, args, kwds)], None))
-        return result
-
-    def map_async(self, func, iterable, chunksize=None, callback=None):
-        '''
-        Asynchronous equivalent of `map()` builtin
-        '''
-        assert self._state == RUN
-        if not hasattr(iterable, '__len__'):
-            iterable = list(iterable)
-        
-        if chunksize is None:
-            chunksize, extra = divmod(len(iterable), len(self._pool) * 4)
-            if extra:
-                chunksize += 1
-                
-        task_batches = Pool._get_tasks(func, iterable, chunksize)
-        result = MapResult(self._cache, chunksize, len(iterable), callback)
-        self._taskqueue.put((((result._job, i, mapstar, (x,), {})
-                              for i, x in enumerate(task_batches)), None))
-        return result
-
-    @staticmethod
-    def _handle_tasks(taskqueue, put, outqueue, pool):
-        thread = threading.currentThread()
-
-        for taskseq, set_length in iter(taskqueue.get, None):
-            i = -1
-            for i, task in enumerate(taskseq):
-                if thread._state:
-                    debug('task handler found thread._state != RUN')
-                    break
-                try:
-                    put(task)
-                except IOError:
-                    debug('could not put task on queue')
-                    break
-            else:
-                if set_length:
-                    debug('doing set_length()')
-                    set_length(i+1)
-                continue
-            break
-        else:
-            debug('task handler got sentinel')
-            
-
-        try:
-            # tell result handler to finish when cache is empty
-            debug('task handler sending sentinel to result handler')
-            outqueue.put(None)
-            
-            # tell workers there is no more work
-            debug('task handler sending sentinel to workers')
-            for p in pool:
-                put(None)
-        except IOError:
-            debug('task handler got IOError when sending sentinels')
-
-        debug('task handler exiting')
-
-    @staticmethod
-    def _handle_results(outqueue, get, cache):
-        thread = threading.currentThread()
-
-        while 1:
-            try:
-                task = get()
-            except (IOError, EOFError):
-                debug('result handler got EOFError/IOError -- exiting')
-                return
-            
-            if thread._state:
-                assert thread._state == TERMINATE
-                debug('result handler found thread._state=TERMINATE')
-                break
-            
-            if task is None:
-                debug('result handler got sentinel')
-                break
-
-            job, i, obj = task
-            try:
-                cache[job]._set(i, obj)
-            except KeyError:
-                pass
-
-        while cache and thread._state != TERMINATE:
-            try:
-                task = get()
-            except (IOError, EOFError):
-                debug('result handler got EOFError/IOError -- exiting')
-                return
-
-            if task is None:
-                debug('result handler ignoring extra sentinel')
-                continue
-            job, i, obj = task
-            try:
-                cache[job]._set(i, obj)
-            except KeyError:
-                pass
-
-        if hasattr(outqueue, '_reader'):
-            debug('ensuring that outqueue is not full')
-            # If we don't make room available in outqueue then
-            # attempts to add the sentinel (None) to outqueue may
-            # block.  There is guaranteed to be no more than 2 sentinels.
-            try:
-                for i in range(10):
-                    if not outqueue._reader.poll():
-                        break
-                    get()
-            except (IOError, EOFError):
-                pass
-
-        debug('result handler exiting: len(cache)=%s, thread._state=%s',
-              len(cache), thread._state)
-
-    @staticmethod
-    def _get_tasks(func, it, size):
-        it = iter(it)
-        while 1:
-            x = tuple(itertools.islice(it, size))
-            if not x:
-                return
-            yield (func, x)
-
-    def __reduce__(self):
-        raise NotImplementedError(
-              'pool objects cannot be passed between processes or pickled'
-              )
-    
-    def close(self):
-        debug('closing pool')
-        if self._state == RUN:
-            self._state = CLOSE
-            self._taskqueue.put(None)
-
-    def terminate(self):
-        debug('terminating pool')
-        self._state = TERMINATE
-        self._terminate()
-
-    def join(self):
-        debug('joining pool')
-        assert self._state in (CLOSE, TERMINATE)
-        self._task_handler.join()
-        self._result_handler.join()
-        for p in self._pool:
-            p.join()
-
-    @staticmethod
-    def _help_stuff_finish(inqueue, task_handler, size):
-        # task_handler may be blocked trying to put items on inqueue
-        debug('removing tasks from inqueue until task handler finished')
-        inqueue._rlock.acquire()
-        while task_handler.isAlive() and inqueue._reader.poll():
-            inqueue._reader.recv()
-            time.sleep(0)
-
-    @classmethod
-    def _terminate_pool(cls, taskqueue, inqueue, outqueue, pool,
-                        task_handler, result_handler, cache):
-        # this is guaranteed to only be called once
-        debug('finalizing pool')
-        
-        task_handler._state = TERMINATE
-        taskqueue.put(None)                 # sentinel
-
-        debug('helping task handler/workers to finish')
-        cls._help_stuff_finish(inqueue, task_handler, len(pool))
-
-        assert result_handler.isAlive() or len(cache) == 0
-        
-        result_handler._state = TERMINATE
-        outqueue.put(None)                  # sentinel
-
-        if pool and hasattr(pool[0], 'terminate'):
-            debug('terminating workers')
-            for p in pool:
-                p.terminate()
-
-        debug('joining task handler')
-        task_handler.join(1e100)
-
-        debug('joining result handler')
-        result_handler.join(1e100)
-
-        if pool and hasattr(pool[0], 'terminate'):
-            debug('joining pool workers')
-            for p in pool:
-                p.join()
-
-#
-# Class whose instances are returned by `Pool.apply_async()`
-#
-
-class ApplyResult(object):
-
-    def __init__(self, cache, callback):
-        self._cond = threading.Condition(threading.Lock())
-        self._job = job_counter.next()
-        self._cache = cache
-        self._ready = False
-        self._callback = callback
-        cache[self._job] = self
-        
-    def ready(self):
-        return self._ready
-    
-    def successful(self):
-        assert self._ready
-        return self._success
-    
-    def wait(self, timeout=None):
-        self._cond.acquire()
-        try:
-            if not self._ready:
-                self._cond.wait(timeout)
-        finally:
-            self._cond.release()
-
-    def get(self, timeout=None):
-        self.wait(timeout)
-        if not self._ready:
-            raise TimeoutError
-        if self._success:
-            return self._value
-        else:
-            raise self._value
-
-    def _set(self, i, obj):
-        self._success, self._value = obj
-        if self._callback and self._success:
-            self._callback(self._value)
-        self._cond.acquire()
-        try:
-            self._ready = True
-            self._cond.notify()
-        finally:
-            self._cond.release()
-        del self._cache[self._job]
-
-#
-# Class whose instances are returned by `Pool.map_async()`
-#
-
-class MapResult(ApplyResult):
-    
-    def __init__(self, cache, chunksize, length, callback):
-        ApplyResult.__init__(self, cache, callback)
-        self._success = True
-        self._value = [None] * length
-        self._chunksize = chunksize
-        if chunksize <= 0:
-            self._number_left = 0
-            self._ready = True
-        else:
-            self._number_left = length//chunksize + bool(length % chunksize)
-        
-    def _set(self, i, success_result):
-        success, result = success_result
-        if success:
-            self._value[i*self._chunksize:(i+1)*self._chunksize] = result
-            self._number_left -= 1
-            if self._number_left == 0:
-                if self._callback:
-                    self._callback(self._value)
-                del self._cache[self._job]
-                self._cond.acquire()
-                try:
-                    self._ready = True
-                    self._cond.notify()
-                finally:
-                    self._cond.release()
-
-        else:
-            self._success = False
-            self._value = result
-            del self._cache[self._job]
-            self._cond.acquire()
-            try:
-                self._ready = True
-                self._cond.notify()
-            finally:
-                self._cond.release()
-
-#
-# Class whose instances are returned by `Pool.imap()`
-#
-
-class IMapIterator(object):
-
-    def __init__(self, cache):
-        self._cond = threading.Condition(threading.Lock())
-        self._job = job_counter.next()
-        self._cache = cache
-        self._items = collections.deque()
-        self._index = 0
-        self._length = None
-        self._unsorted = {}
-        cache[self._job] = self
-        
-    def __iter__(self):
-        return self
-    
-    def next(self, timeout=None):
-        self._cond.acquire()
-        try:
-            try:
-                item = self._items.popleft()
-            except IndexError:
-                if self._index == self._length:
-                    raise StopIteration
-                self._cond.wait(timeout)
-                try:
-                    item = self._items.popleft()
-                except IndexError:
-                    if self._index == self._length:
-                        raise StopIteration
-                    raise TimeoutError
-        finally:
-            self._cond.release()
-
-        success, value = item
-        if success:
-            return value
-        raise value
-
-    __next__ = next                    # XXX
-    
-    def _set(self, i, obj):
-        self._cond.acquire()
-        try:
-            if self._index == i:
-                self._items.append(obj)
-                self._index += 1
-                while self._index in self._unsorted:
-                    obj = self._unsorted.pop(self._index)
-                    self._items.append(obj)
-                    self._index += 1
-                self._cond.notify()
-            else:
-                self._unsorted[i] = obj
-                
-            if self._index == self._length:
-                del self._cache[self._job]
-        finally:
-            self._cond.release()
-            
-    def _set_length(self, length):
-        self._cond.acquire()
-        try:
-            self._length = length
-            if self._index == self._length:
-                self._cond.notify()
-                del self._cache[self._job]
-        finally:
-            self._cond.release()
-
-#
-# Class whose instances are returned by `Pool.imap_unordered()`
-#
-
-class IMapUnorderedIterator(IMapIterator):
-
-    def _set(self, i, obj):
-        self._cond.acquire()
-        try:
-            self._items.append(obj)
-            self._index += 1
-            self._cond.notify()
-            if self._index == self._length:
-                del self._cache[self._job]
-        finally:
-            self._cond.release()
-
-#
-#
-#
-
-class ThreadPool(Pool):
-    
-    from .dummy import Process
-    
-    def __init__(self, processes=None, initializer=None, initargs=()):
-        Pool.__init__(self, processes, initializer, initargs)
-        
-    def _setup_queues(self):
-        self._inqueue = Queue.Queue()
-        self._outqueue = Queue.Queue()
-        self._quick_put = self._inqueue.put
-        self._quick_get = self._outqueue.get
-        
-    @staticmethod
-    def _help_stuff_finish(inqueue, task_handler, size):
-        # put sentinels at head of inqueue to make workers finish
-        inqueue.not_empty.acquire()
-        try:
-            inqueue.queue.clear()
-            inqueue.queue.extend([None] * size)
-            inqueue.not_empty.notifyAll()
-        finally:
-            inqueue.not_empty.release()
+#
+# Module providing the `Pool` class for managing a process pool
+#
+# multiprocessing/pool.py
+#
+# Copyright (c) 2007-2008, R Oudkerk --- see COPYING.txt
+#
+
+__all__ = ['Pool']
+
+#
+# Imports
+#
+
+import threading
+import queue
+import itertools
+import collections
+import time
+
+from multiprocessing import Process, cpu_count, TimeoutError
+from multiprocessing.util import Finalize, debug
+
+#
+# Constants representing the state of a pool
+#
+
+RUN = 0
+CLOSE = 1
+TERMINATE = 2
+
+#
+# Miscellaneous
+#
+
+job_counter = itertools.count()
+
+def mapstar(args):
+    return list(map(*args))
+
+#
+# Code run by worker processes
+#
+
+def worker(inqueue, outqueue, initializer=None, initargs=()):
+    put = outqueue.put
+    get = inqueue.get
+    if hasattr(inqueue, '_writer'):
+        inqueue._writer.close()
+        outqueue._reader.close()
+
+    if initializer is not None:
+        initializer(*initargs)
+
+    while 1:
+        try:
+            task = get()
+        except (EOFError, IOError):
+            debug('worker got EOFError or IOError -- exiting')
+            break
+
+        if task is None:
+            debug('worker got sentinel -- exiting')
+            break
+
+        job, i, func, args, kwds = task
+        try:
+            result = (True, func(*args, **kwds))
+        except Exception as e:
+            result = (False, e)
+        put((job, i, result))
+
+#
+# Class representing a process pool
+#
+
+class Pool(object):
+    '''
+    Class which supports an async version of the `apply()` builtin
+    '''
+    Process = Process
+
+    def __init__(self, processes=None, initializer=None, initargs=()):
+        self._setup_queues()
+        self._taskqueue = queue.Queue()
+        self._cache = {}
+        self._state = RUN
+
+        if processes is None:
+            try:
+                processes = cpu_count()
+            except NotImplementedError:
+                processes = 1
+
+        self._pool = []
+        for i in range(processes):
+            w = self.Process(
+                target=worker,
+                args=(self._inqueue, self._outqueue, initializer, initargs)
+                )
+            self._pool.append(w)
+            w.set_name(w.get_name().replace('Process', 'PoolWorker'))
+            w.set_daemon(True)
+            w.start()
+
+        self._task_handler = threading.Thread(
+            target=Pool._handle_tasks,
+            args=(self._taskqueue, self._quick_put, self._outqueue, self._pool)
+            )
+        self._task_handler.setDaemon(True)
+        self._task_handler._state = RUN
+        self._task_handler.start()
+
+        self._result_handler = threading.Thread(
+            target=Pool._handle_results,
+            args=(self._outqueue, self._quick_get, self._cache)
+            )
+        self._result_handler.setDaemon(True)
+        self._result_handler._state = RUN
+        self._result_handler.start()
+
+        self._terminate = Finalize(
+            self, self._terminate_pool,
+            args=(self._taskqueue, self._inqueue, self._outqueue, self._pool,
+                  self._task_handler, self._result_handler, self._cache),
+            exitpriority=15
+            )
+
+    def _setup_queues(self):
+        from .queues import SimpleQueue
+        self._inqueue = SimpleQueue()
+        self._outqueue = SimpleQueue()
+        self._quick_put = self._inqueue._writer.send
+        self._quick_get = self._outqueue._reader.recv
+
+    def apply(self, func, args=(), kwds={}):
+        '''
+        Equivalent of `apply()` builtin
+        '''
+        assert self._state == RUN
+        return self.apply_async(func, args, kwds).get()
+
+    def map(self, func, iterable, chunksize=None):
+        '''
+        Equivalent of `map()` builtin
+        '''
+        assert self._state == RUN
+        return self.map_async(func, iterable, chunksize).get()
+
+    def imap(self, func, iterable, chunksize=1):
+        '''
+        Equivalent of `itertool.imap()` -- can be MUCH slower than `Pool.map()`
+        '''
+        assert self._state == RUN
+        if chunksize == 1:
+            result = IMapIterator(self._cache)
+            self._taskqueue.put((((result._job, i, func, (x,), {})
+                         for i, x in enumerate(iterable)), result._set_length))
+            return result
+        else:
+            assert chunksize > 1
+            task_batches = Pool._get_tasks(func, iterable, chunksize)
+            result = IMapIterator(self._cache)
+            self._taskqueue.put((((result._job, i, mapstar, (x,), {})
+                     for i, x in enumerate(task_batches)), result._set_length))
+            return (item for chunk in result for item in chunk)
+
+    def imap_unordered(self, func, iterable, chunksize=1):
+        '''
+        Like `imap()` method but ordering of results is arbitrary
+        '''
+        assert self._state == RUN
+        if chunksize == 1:
+            result = IMapUnorderedIterator(self._cache)
+            self._taskqueue.put((((result._job, i, func, (x,), {})
+                         for i, x in enumerate(iterable)), result._set_length))
+            return result
+        else:
+            assert chunksize > 1
+            task_batches = Pool._get_tasks(func, iterable, chunksize)
+            result = IMapUnorderedIterator(self._cache)
+            self._taskqueue.put((((result._job, i, mapstar, (x,), {})
+                     for i, x in enumerate(task_batches)), result._set_length))
+            return (item for chunk in result for item in chunk)
+
+    def apply_async(self, func, args=(), kwds={}, callback=None):
+        '''
+        Asynchronous equivalent of `apply()` builtin
+        '''
+        assert self._state == RUN
+        result = ApplyResult(self._cache, callback)
+        self._taskqueue.put(([(result._job, None, func, args, kwds)], None))
+        return result
+
+    def map_async(self, func, iterable, chunksize=None, callback=None):
+        '''
+        Asynchronous equivalent of `map()` builtin
+        '''
+        assert self._state == RUN
+        if not hasattr(iterable, '__len__'):
+            iterable = list(iterable)
+
+        if chunksize is None:
+            chunksize, extra = divmod(len(iterable), len(self._pool) * 4)
+            if extra:
+                chunksize += 1
+
+        task_batches = Pool._get_tasks(func, iterable, chunksize)
+        result = MapResult(self._cache, chunksize, len(iterable), callback)
+        self._taskqueue.put((((result._job, i, mapstar, (x,), {})
+                              for i, x in enumerate(task_batches)), None))
+        return result
+
+    @staticmethod
+    def _handle_tasks(taskqueue, put, outqueue, pool):
+        thread = threading.currentThread()
+
+        for taskseq, set_length in iter(taskqueue.get, None):
+            i = -1
+            for i, task in enumerate(taskseq):
+                if thread._state:
+                    debug('task handler found thread._state != RUN')
+                    break
+                try:
+                    put(task)
+                except IOError:
+                    debug('could not put task on queue')
+                    break
+            else:
+                if set_length:
+                    debug('doing set_length()')
+                    set_length(i+1)
+                continue
+            break
+        else:
+            debug('task handler got sentinel')
+
+
+        try:
+            # tell result handler to finish when cache is empty
+            debug('task handler sending sentinel to result handler')
+            outqueue.put(None)
+
+            # tell workers there is no more work
+            debug('task handler sending sentinel to workers')
+            for p in pool:
+                put(None)
+        except IOError:
+            debug('task handler got IOError when sending sentinels')
+
+        debug('task handler exiting')
+
+    @staticmethod
+    def _handle_results(outqueue, get, cache):
+        thread = threading.currentThread()
+
+        while 1:
+            try:
+                task = get()
+            except (IOError, EOFError):
+                debug('result handler got EOFError/IOError -- exiting')
+                return
+
+            if thread._state:
+                assert thread._state == TERMINATE
+                debug('result handler found thread._state=TERMINATE')
+                break
+
+            if task is None:
+                debug('result handler got sentinel')
+                break
+
+            job, i, obj = task
+            try:
+                cache[job]._set(i, obj)
+            except KeyError:
+                pass
+
+        while cache and thread._state != TERMINATE:
+            try:
+                task = get()
+            except (IOError, EOFError):
+                debug('result handler got EOFError/IOError -- exiting')
+                return
+
+            if task is None:
+                debug('result handler ignoring extra sentinel')
+                continue
+            job, i, obj = task
+            try:
+                cache[job]._set(i, obj)
+            except KeyError:
+                pass
+
+        if hasattr(outqueue, '_reader'):
+            debug('ensuring that outqueue is not full')
+            # If we don't make room available in outqueue then
+            # attempts to add the sentinel (None) to outqueue may
+            # block.  There is guaranteed to be no more than 2 sentinels.
+            try:
+                for i in range(10):
+                    if not outqueue._reader.poll():
+                        break
+                    get()
+            except (IOError, EOFError):
+                pass
+
+        debug('result handler exiting: len(cache)=%s, thread._state=%s',
+              len(cache), thread._state)
+
+    @staticmethod
+    def _get_tasks(func, it, size):
+        it = iter(it)
+        while 1:
+            x = tuple(itertools.islice(it, size))
+            if not x:
+                return
+            yield (func, x)
+
+    def __reduce__(self):
+        raise NotImplementedError(
+              'pool objects cannot be passed between processes or pickled'
+              )
+
+    def close(self):
+        debug('closing pool')
+        if self._state == RUN:
+            self._state = CLOSE
+            self._taskqueue.put(None)
+
+    def terminate(self):
+        debug('terminating pool')
+        self._state = TERMINATE
+        self._terminate()
+
+    def join(self):
+        debug('joining pool')
+        assert self._state in (CLOSE, TERMINATE)
+        self._task_handler.join()
+        self._result_handler.join()
+        for p in self._pool:
+            p.join()
+
+    @staticmethod
+    def _help_stuff_finish(inqueue, task_handler, size):
+        # task_handler may be blocked trying to put items on inqueue
+        debug('removing tasks from inqueue until task handler finished')
+        inqueue._rlock.acquire()
+        while task_handler.isAlive() and inqueue._reader.poll():
+            inqueue._reader.recv()
+            time.sleep(0)
+
+    @classmethod
+    def _terminate_pool(cls, taskqueue, inqueue, outqueue, pool,
+                        task_handler, result_handler, cache):
+        # this is guaranteed to only be called once
+        debug('finalizing pool')
+
+        task_handler._state = TERMINATE
+        taskqueue.put(None)                 # sentinel
+
+        debug('helping task handler/workers to finish')
+        cls._help_stuff_finish(inqueue, task_handler, len(pool))
+
+        assert result_handler.isAlive() or len(cache) == 0
+
+        result_handler._state = TERMINATE
+        outqueue.put(None)                  # sentinel
+
+        if pool and hasattr(pool[0], 'terminate'):
+            debug('terminating workers')
+            for p in pool:
+                p.terminate()
+
+        debug('joining task handler')
+        task_handler.join(1e100)
+
+        debug('joining result handler')
+        result_handler.join(1e100)
+
+        if pool and hasattr(pool[0], 'terminate'):
+            debug('joining pool workers')
+            for p in pool:
+                p.join()
+
+#
+# Class whose instances are returned by `Pool.apply_async()`
+#
+
+class ApplyResult(object):
+
+    def __init__(self, cache, callback):
+        self._cond = threading.Condition(threading.Lock())
+        self._job = next(job_counter)
+        self._cache = cache
+        self._ready = False
+        self._callback = callback
+        cache[self._job] = self
+
+    def ready(self):
+        return self._ready
+
+    def successful(self):
+        assert self._ready
+        return self._success
+
+    def wait(self, timeout=None):
+        self._cond.acquire()
+        try:
+            if not self._ready:
+                self._cond.wait(timeout)
+        finally:
+            self._cond.release()
+
+    def get(self, timeout=None):
+        self.wait(timeout)
+        if not self._ready:
+            raise TimeoutError
+        if self._success:
+            return self._value
+        else:
+            raise self._value
+
+    def _set(self, i, obj):
+        self._success, self._value = obj
+        if self._callback and self._success:
+            self._callback(self._value)
+        self._cond.acquire()
+        try:
+            self._ready = True
+            self._cond.notify()
+        finally:
+            self._cond.release()
+        del self._cache[self._job]
+
+#
+# Class whose instances are returned by `Pool.map_async()`
+#
+
+class MapResult(ApplyResult):
+
+    def __init__(self, cache, chunksize, length, callback):
+        ApplyResult.__init__(self, cache, callback)
+        self._success = True
+        self._value = [None] * length
+        self._chunksize = chunksize
+        if chunksize <= 0:
+            self._number_left = 0
+            self._ready = True
+        else:
+            self._number_left = length//chunksize + bool(length % chunksize)
+
+    def _set(self, i, success_result):
+        success, result = success_result
+        if success:
+            self._value[i*self._chunksize:(i+1)*self._chunksize] = result
+            self._number_left -= 1
+            if self._number_left == 0:
+                if self._callback:
+                    self._callback(self._value)
+                del self._cache[self._job]
+                self._cond.acquire()
+                try:
+                    self._ready = True
+                    self._cond.notify()
+                finally:
+                    self._cond.release()
+
+        else:
+            self._success = False
+            self._value = result
+            del self._cache[self._job]
+            self._cond.acquire()
+            try:
+                self._ready = True
+                self._cond.notify()
+            finally:
+                self._cond.release()
+
+#
+# Class whose instances are returned by `Pool.imap()`
+#
+
+class IMapIterator(object):
+
+    def __init__(self, cache):
+        self._cond = threading.Condition(threading.Lock())
+        self._job = next(job_counter)
+        self._cache = cache
+        self._items = collections.deque()
+        self._index = 0
+        self._length = None
+        self._unsorted = {}
+        cache[self._job] = self
+
+    def __iter__(self):
+        return self
+
+    def next(self, timeout=None):
+        self._cond.acquire()
+        try:
+            try:
+                item = self._items.popleft()
+            except IndexError:
+                if self._index == self._length:
+                    raise StopIteration
+                self._cond.wait(timeout)
+                try:
+                    item = self._items.popleft()
+                except IndexError:
+                    if self._index == self._length:
+                        raise StopIteration
+                    raise TimeoutError
+        finally:
+            self._cond.release()
+
+        success, value = item
+        if success:
+            return value
+        raise value
+
+    __next__ = next                    # XXX
+
+    def _set(self, i, obj):
+        self._cond.acquire()
+        try:
+            if self._index == i:
+                self._items.append(obj)
+                self._index += 1
+                while self._index in self._unsorted:
+                    obj = self._unsorted.pop(self._index)
+                    self._items.append(obj)
+                    self._index += 1
+                self._cond.notify()
+            else:
+                self._unsorted[i] = obj
+
+            if self._index == self._length:
+                del self._cache[self._job]
+        finally:
+            self._cond.release()
+
+    def _set_length(self, length):
+        self._cond.acquire()
+        try:
+            self._length = length
+            if self._index == self._length:
+                self._cond.notify()
+                del self._cache[self._job]
+        finally:
+            self._cond.release()
+
+#
+# Class whose instances are returned by `Pool.imap_unordered()`
+#
+
+class IMapUnorderedIterator(IMapIterator):
+
+    def _set(self, i, obj):
+        self._cond.acquire()
+        try:
+            self._items.append(obj)
+            self._index += 1
+            self._cond.notify()
+            if self._index == self._length:
+                del self._cache[self._job]
+        finally:
+            self._cond.release()
+
+#
+#
+#
+
+class ThreadPool(Pool):
+
+    from .dummy import Process
+
+    def __init__(self, processes=None, initializer=None, initargs=()):
+        Pool.__init__(self, processes, initializer, initargs)
+
+    def _setup_queues(self):
+        self._inqueue = queue.Queue()
+        self._outqueue = queue.Queue()
+        self._quick_put = self._inqueue.put
+        self._quick_get = self._outqueue.get
+
+    @staticmethod
+    def _help_stuff_finish(inqueue, task_handler, size):
+        # put sentinels at head of inqueue to make workers finish
+        inqueue.not_empty.acquire()
+        try:
+            inqueue.queue.clear()
+            inqueue.queue.extend([None] * size)
+            inqueue.not_empty.notifyAll()
+        finally:
+            inqueue.not_empty.release()

Modified: python/branches/py3k/Lib/multiprocessing/process.py
==============================================================================
--- /python/trunk/Lib/multiprocessing/process.py	(original)
+++ python/branches/py3k/Lib/multiprocessing/process.py	Wed Jun 11 18:44:04 2008
@@ -1,302 +1,302 @@
-#
-# Module providing the `Process` class which emulates `threading.Thread`
-#
-# multiprocessing/process.py
-#
-# Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
-#
-
-__all__ = ['Process', 'current_process', 'active_children']
-
-#
-# Imports
-#
-
-import os
-import sys
-import signal
-import itertools
-
-#
-#
-#
-
-try:
-    ORIGINAL_DIR = os.path.abspath(os.getcwd())
-except OSError:
-    ORIGINAL_DIR = None
-
-try:
-    bytes
-except NameError:
-    bytes = str                  # XXX not needed in Py2.6 and Py3.0
-
-#
-# Public functions
-#
-
-def current_process():
-    '''
-    Return process object representing the current process
-    '''
-    return _current_process
-
-def active_children():
-    '''
-    Return list of process objects corresponding to live child processes
-    '''
-    _cleanup()
-    return list(_current_process._children)
-    
-#
-#
-#
-
-def _cleanup():
-    # check for processes which have finished
-    for p in list(_current_process._children):
-        if p._popen.poll() is not None:
-            _current_process._children.discard(p)
-
-#
-# The `Process` class
-#
-
-class Process(object):
-    '''
-    Process objects represent activity that is run in a separate process
-
-    The class is analagous to `threading.Thread`
-    '''
-    _Popen = None
-    
-    def __init__(self, group=None, target=None, name=None, args=(), kwargs={}):
-        assert group is None, 'group argument must be None for now'
-        count = _current_process._counter.next()
-        self._identity = _current_process._identity + (count,)
-        self._authkey = _current_process._authkey
-        self._daemonic = _current_process._daemonic
-        self._tempdir = _current_process._tempdir
-        self._parent_pid = os.getpid()
-        self._popen = None
-        self._target = target
-        self._args = tuple(args)
-        self._kwargs = dict(kwargs)
-        self._name = name or type(self).__name__ + '-' + \
-                     ':'.join(str(i) for i in self._identity)
-
-    def run(self):
-        '''
-        Method to be run in sub-process; can be overridden in sub-class
-        '''
-        if self._target:
-            self._target(*self._args, **self._kwargs)
-            
-    def start(self):
-        '''
-        Start child process
-        '''
-        assert self._popen is None, 'cannot start a process twice'
-        assert self._parent_pid == os.getpid(), \
-               'can only start a process object created by current process'
-        assert not _current_process._daemonic, \
-               'daemonic processes are not allowed to have children'
-        _cleanup()
-        if self._Popen is not None:
-            Popen = self._Popen
-        else:
-            from .forking import Popen
-        self._popen = Popen(self)
-        _current_process._children.add(self)
-
-    def terminate(self):
-        '''
-        Terminate process; sends SIGTERM signal or uses TerminateProcess()
-        '''
-        self._popen.terminate()
-        
-    def join(self, timeout=None):
-        '''
-        Wait until child process terminates
-        '''
-        assert self._parent_pid == os.getpid(), 'can only join a child process'
-        assert self._popen is not None, 'can only join a started process'
-        res = self._popen.wait(timeout)
-        if res is not None:
-            _current_process._children.discard(self)
-
-    def is_alive(self):
-        '''
-        Return whether process is alive
-        '''
-        if self is _current_process:
-            return True
-        assert self._parent_pid == os.getpid(), 'can only test a child process'
-        if self._popen is None:
-            return False
-        self._popen.poll()
-        return self._popen.returncode is None
-
-    def get_name(self):
-        '''
-        Return name of process
-        '''
-        return self._name
-
-    def set_name(self, name):
-        '''
-        Set name of process
-        '''
-        assert isinstance(name, str), 'name must be a string'
-        self._name = name
-
-    def is_daemon(self):
-        '''
-        Return whether process is a daemon
-        '''
-        return self._daemonic
-
-    def set_daemon(self, daemonic):
-        '''
-        Set whether process is a daemon
-        '''
-        assert self._popen is None, 'process has already started'
-        self._daemonic = daemonic
-
-    def get_authkey(self):
-        '''
-        Return authorization key of process
-        '''
-        return self._authkey
-
-    def set_authkey(self, authkey):
-        '''
-        Set authorization key of process
-        '''
-        self._authkey = AuthenticationString(authkey)
-
-    def get_exitcode(self):
-        '''
-        Return exit code of process or `None` if it has yet to stop
-        '''
-        if self._popen is None:
-            return self._popen
-        return self._popen.poll()
-
-    def get_ident(self):
-        '''
-        Return indentifier (PID) of process or `None` if it has yet to start
-        '''
-        if self is _current_process:
-            return os.getpid()
-        else:
-            return self._popen and self._popen.pid
-
-    pid = property(get_ident)
-
-    def __repr__(self):
-        if self is _current_process:
-            status = 'started'
-        elif self._parent_pid != os.getpid():
-            status = 'unknown'
-        elif self._popen is None:
-            status = 'initial'
-        else:
-            if self._popen.poll() is not None:
-                status = self.get_exitcode()
-            else:
-                status = 'started'
-
-        if type(status) is int:
-            if status == 0:
-                status = 'stopped'
-            else:
-                status = 'stopped[%s]' % _exitcode_to_name.get(status, status)
-
-        return '<%s(%s, %s%s)>' % (type(self).__name__, self._name,
-                                   status, self._daemonic and ' daemon' or '')
-
-    ##
-        
-    def _bootstrap(self):
-        from . import util
-        global _current_process
-        
-        try:
-            self._children = set()
-            self._counter = itertools.count(1)
-            try:
-                os.close(sys.stdin.fileno())
-            except (OSError, ValueError):
-                pass
-            _current_process = self
-            util._finalizer_registry.clear()
-            util._run_after_forkers()
-            util.info('child process calling self.run()')
-            try:
-                self.run()
-                exitcode = 0
-            finally:
-                util._exit_function()
-        except SystemExit, e:
-            if not e.args:
-                exitcode = 1
-            elif type(e.args[0]) is int:
-                exitcode = e.args[0]
-            else:
-                sys.stderr.write(e.args[0] + '\n')
-                sys.stderr.flush()
-                exitcode = 1
-        except:
-            exitcode = 1
-            import traceback
-            sys.stderr.write('Process %s:\n' % self.get_name())
-            sys.stderr.flush()
-            traceback.print_exc()
-
-        util.info('process exiting with exitcode %d' % exitcode)
-        return exitcode
-
-#
-# We subclass bytes to avoid accidental transmission of auth keys over network
-#
-
-class AuthenticationString(bytes):
-    def __reduce__(self):
-        from .forking import Popen
-        if not Popen.thread_is_spawning():
-            raise TypeError(
-                'Pickling an AuthenticationString object is '
-                'disallowed for security reasons'
-                )
-        return AuthenticationString, (bytes(self),)
-
-#
-# Create object representing the main process
-#
-
-class _MainProcess(Process):
-
-    def __init__(self):
-        self._identity = ()
-        self._daemonic = False
-        self._name = 'MainProcess'
-        self._parent_pid = None
-        self._popen = None
-        self._counter = itertools.count(1)
-        self._children = set()
-        self._authkey = AuthenticationString(os.urandom(32))
-        self._tempdir = None
-
-_current_process = _MainProcess()
-del _MainProcess
-
-#
-# Give names to some return codes
-#
-
-_exitcode_to_name = {}
-
-for name, signum in signal.__dict__.items():
-    if name[:3]=='SIG' and '_' not in name:
-        _exitcode_to_name[-signum] = name
+#
+# Module providing the `Process` class which emulates `threading.Thread`
+#
+# multiprocessing/process.py
+#
+# Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
+#
+
+__all__ = ['Process', 'current_process', 'active_children']
+
+#
+# Imports
+#
+
+import os
+import sys
+import signal
+import itertools
+
+#
+#
+#
+
+try:
+    ORIGINAL_DIR = os.path.abspath(os.getcwd())
+except OSError:
+    ORIGINAL_DIR = None
+
+try:
+    bytes
+except NameError:
+    bytes = str                  # XXX not needed in Py2.6 and Py3.0
+
+#
+# Public functions
+#
+
+def current_process():
+    '''
+    Return process object representing the current process
+    '''
+    return _current_process
+
+def active_children():
+    '''
+    Return list of process objects corresponding to live child processes
+    '''
+    _cleanup()
+    return list(_current_process._children)
+
+#
+#
+#
+
+def _cleanup():
+    # check for processes which have finished
+    for p in list(_current_process._children):
+        if p._popen.poll() is not None:
+            _current_process._children.discard(p)
+
+#
+# The `Process` class
+#
+
+class Process(object):
+    '''
+    Process objects represent activity that is run in a separate process
+
+    The class is analagous to `threading.Thread`
+    '''
+    _Popen = None
+
+    def __init__(self, group=None, target=None, name=None, args=(), kwargs={}):
+        assert group is None, 'group argument must be None for now'
+        count = next(_current_process._counter)
+        self._identity = _current_process._identity + (count,)
+        self._authkey = _current_process._authkey
+        self._daemonic = _current_process._daemonic
+        self._tempdir = _current_process._tempdir
+        self._parent_pid = os.getpid()
+        self._popen = None
+        self._target = target
+        self._args = tuple(args)
+        self._kwargs = dict(kwargs)
+        self._name = name or type(self).__name__ + '-' + \
+                     ':'.join(str(i) for i in self._identity)
+
+    def run(self):
+        '''
+        Method to be run in sub-process; can be overridden in sub-class
+        '''
+        if self._target:
+            self._target(*self._args, **self._kwargs)
+
+    def start(self):
+        '''
+        Start child process
+        '''
+        assert self._popen is None, 'cannot start a process twice'
+        assert self._parent_pid == os.getpid(), \
+               'can only start a process object created by current process'
+        assert not _current_process._daemonic, \
+               'daemonic processes are not allowed to have children'
+        _cleanup()
+        if self._Popen is not None:
+            Popen = self._Popen
+        else:
+            from .forking import Popen
+        self._popen = Popen(self)
+        _current_process._children.add(self)
+
+    def terminate(self):
+        '''
+        Terminate process; sends SIGTERM signal or uses TerminateProcess()
+        '''
+        self._popen.terminate()
+
+    def join(self, timeout=None):
+        '''
+        Wait until child process terminates
+        '''
+        assert self._parent_pid == os.getpid(), 'can only join a child process'
+        assert self._popen is not None, 'can only join a started process'
+        res = self._popen.wait(timeout)
+        if res is not None:
+            _current_process._children.discard(self)
+
+    def is_alive(self):
+        '''
+        Return whether process is alive
+        '''
+        if self is _current_process:
+            return True
+        assert self._parent_pid == os.getpid(), 'can only test a child process'
+        if self._popen is None:
+            return False
+        self._popen.poll()
+        return self._popen.returncode is None
+
+    def get_name(self):
+        '''
+        Return name of process
+        '''
+        return self._name
+
+    def set_name(self, name):
+        '''
+        Set name of process
+        '''
+        assert isinstance(name, str), 'name must be a string'
+        self._name = name
+
+    def is_daemon(self):
+        '''
+        Return whether process is a daemon
+        '''
+        return self._daemonic
+
+    def set_daemon(self, daemonic):
+        '''
+        Set whether process is a daemon
+        '''
+        assert self._popen is None, 'process has already started'
+        self._daemonic = daemonic
+
+    def get_authkey(self):
+        '''
+        Return authorization key of process
+        '''
+        return self._authkey
+
+    def set_authkey(self, authkey):
+        '''
+        Set authorization key of process
+        '''
+        self._authkey = AuthenticationString(authkey)
+
+    def get_exitcode(self):
+        '''
+        Return exit code of process or `None` if it has yet to stop
+        '''
+        if self._popen is None:
+            return self._popen
+        return self._popen.poll()
+
+    def get_ident(self):
+        '''
+        Return indentifier (PID) of process or `None` if it has yet to start
+        '''
+        if self is _current_process:
+            return os.getpid()
+        else:
+            return self._popen and self._popen.pid
+
+    pid = property(get_ident)
+
+    def __repr__(self):
+        if self is _current_process:
+            status = 'started'
+        elif self._parent_pid != os.getpid():
+            status = 'unknown'
+        elif self._popen is None:
+            status = 'initial'
+        else:
+            if self._popen.poll() is not None:
+                status = self.get_exitcode()
+            else:
+                status = 'started'
+
+        if type(status) is int:
+            if status == 0:
+                status = 'stopped'
+            else:
+                status = 'stopped[%s]' % _exitcode_to_name.get(status, status)
+
+        return '<%s(%s, %s%s)>' % (type(self).__name__, self._name,
+                                   status, self._daemonic and ' daemon' or '')
+
+    ##
+
+    def _bootstrap(self):
+        from . import util
+        global _current_process
+
+        try:
+            self._children = set()
+            self._counter = itertools.count(1)
+            try:
+                os.close(sys.stdin.fileno())
+            except (OSError, ValueError):
+                pass
+            _current_process = self
+            util._finalizer_registry.clear()
+            util._run_after_forkers()
+            util.info('child process calling self.run()')
+            try:
+                self.run()
+                exitcode = 0
+            finally:
+                util._exit_function()
+        except SystemExit as e:
+            if not e.args:
+                exitcode = 1
+            elif type(e.args[0]) is int:
+                exitcode = e.args[0]
+            else:
+                sys.stderr.write(e.args[0] + '\n')
+                sys.stderr.flush()
+                exitcode = 1
+        except:
+            exitcode = 1
+            import traceback
+            sys.stderr.write('Process %s:\n' % self.get_name())
+            sys.stderr.flush()
+            traceback.print_exc()
+
+        util.info('process exiting with exitcode %d' % exitcode)
+        return exitcode
+
+#
+# We subclass bytes to avoid accidental transmission of auth keys over network
+#
+
+class AuthenticationString(bytes):
+    def __reduce__(self):
+        from .forking import Popen
+        if not Popen.thread_is_spawning():
+            raise TypeError(
+                'Pickling an AuthenticationString object is '
+                'disallowed for security reasons'
+                )
+        return AuthenticationString, (bytes(self),)
+
+#
+# Create object representing the main process
+#
+
+class _MainProcess(Process):
+
+    def __init__(self):
+        self._identity = ()
+        self._daemonic = False
+        self._name = 'MainProcess'
+        self._parent_pid = None
+        self._popen = None
+        self._counter = itertools.count(1)
+        self._children = set()
+        self._authkey = AuthenticationString(os.urandom(32))
+        self._tempdir = None
+
+_current_process = _MainProcess()
+del _MainProcess
+
+#
+# Give names to some return codes
+#
+
+_exitcode_to_name = {}
+
+for name, signum in list(signal.__dict__.items()):
+    if name[:3]=='SIG' and '_' not in name:
+        _exitcode_to_name[-signum] = name

Modified: python/branches/py3k/Lib/multiprocessing/queues.py
==============================================================================
--- /python/trunk/Lib/multiprocessing/queues.py	(original)
+++ python/branches/py3k/Lib/multiprocessing/queues.py	Wed Jun 11 18:44:04 2008
@@ -1,356 +1,356 @@
-#
-# Module implementing queues
-#
-# multiprocessing/queues.py
-#
-# Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
-#
-
-__all__ = ['Queue', 'SimpleQueue']
-
-import sys
-import os
-import threading
-import collections
-import time
-import atexit
-import weakref
-
-from Queue import Empty, Full
-import _multiprocessing
-from multiprocessing import Pipe
-from multiprocessing.synchronize import Lock, BoundedSemaphore, Semaphore, Condition
-from multiprocessing.util import debug, info, Finalize, register_after_fork
-from multiprocessing.forking import assert_spawning
-
-#
-# Queue type using a pipe, buffer and thread
-#
-
-class Queue(object):
-
-    def __init__(self, maxsize=0):
-        if maxsize <= 0:
-            maxsize = _multiprocessing.SemLock.SEM_VALUE_MAX
-        self._maxsize = maxsize
-        self._reader, self._writer = Pipe(duplex=False)
-        self._rlock = Lock()
-        self._opid = os.getpid()
-        if sys.platform == 'win32':
-            self._wlock = None
-        else:
-            self._wlock = Lock()
-        self._sem = BoundedSemaphore(maxsize)
-            
-        self._after_fork()
-        
-        if sys.platform != 'win32':
-            register_after_fork(self, Queue._after_fork)
-
-    def __getstate__(self):
-        assert_spawning(self)
-        return (self._maxsize, self._reader, self._writer,
-                self._rlock, self._wlock, self._sem, self._opid)
-    
-    def __setstate__(self, state):
-        (self._maxsize, self._reader, self._writer,
-         self._rlock, self._wlock, self._sem, self._opid) = state
-        self._after_fork()
-        
-    def _after_fork(self):
-        debug('Queue._after_fork()')
-        self._notempty = threading.Condition(threading.Lock())
-        self._buffer = collections.deque()
-        self._thread = None
-        self._jointhread = None
-        self._joincancelled = False
-        self._closed = False
-        self._close = None
-        self._send = self._writer.send
-        self._recv = self._reader.recv
-        self._poll = self._reader.poll
-        
-    def put(self, obj, block=True, timeout=None):
-        assert not self._closed
-        if not self._sem.acquire(block, timeout):
-            raise Full
-
-        self._notempty.acquire()
-        try:
-            if self._thread is None:
-                self._start_thread()
-            self._buffer.append(obj)
-            self._notempty.notify()
-        finally:
-            self._notempty.release()
-
-    def get(self, block=True, timeout=None):
-        if block and timeout is None:
-            self._rlock.acquire()
-            try:
-                res = self._recv()
-                self._sem.release()
-                return res
-            finally:
-                self._rlock.release()
-                
-        else:
-            if block:
-                deadline = time.time() + timeout
-            if not self._rlock.acquire(block, timeout):
-                raise Empty
-            try:
-                if not self._poll(block and (deadline-time.time()) or 0.0):
-                    raise Empty
-                res = self._recv()
-                self._sem.release()
-                return res
-            finally:
-                self._rlock.release()
-
-    def qsize(self):
-        # Raises NotImplementError on Mac OSX because of broken sem_getvalue()
-        return self._maxsize - self._sem._semlock._get_value()
-
-    def empty(self):
-        return not self._poll()
-
-    def full(self):
-        return self._sem._semlock._is_zero()
-
-    def get_nowait(self):
-        return self.get(False)
-
-    def put_nowait(self, obj):
-        return self.put(obj, False)
-
-    def close(self):
-        self._closed = True
-        self._reader.close()
-        if self._close:
-            self._close()
-
-    def join_thread(self):
-        debug('Queue.join_thread()')
-        assert self._closed
-        if self._jointhread:
-            self._jointhread()
-    
-    def cancel_join_thread(self):
-        debug('Queue.cancel_join_thread()')
-        self._joincancelled = True
-        try:
-            self._jointhread.cancel()
-        except AttributeError:
-            pass
-
-    def _start_thread(self):
-        debug('Queue._start_thread()')
-        
-        # Start thread which transfers data from buffer to pipe
-        self._buffer.clear()
-        self._thread = threading.Thread(
-            target=Queue._feed,
-            args=(self._buffer, self._notempty, self._send,
-                  self._wlock, self._writer.close),
-            name='QueueFeederThread'
-            )
-        self._thread.setDaemon(True)
-
-        debug('doing self._thread.start()')
-        self._thread.start()
-        debug('... done self._thread.start()')
-
-        # On process exit we will wait for data to be flushed to pipe.
-        #
-        # However, if this process created the queue then all
-        # processes which use the queue will be descendants of this
-        # process.  Therefore waiting for the queue to be flushed
-        # is pointless once all the child processes have been joined.
-        created_by_this_process = (self._opid == os.getpid())
-        if not self._joincancelled and not created_by_this_process:
-            self._jointhread = Finalize(
-                self._thread, Queue._finalize_join,
-                [weakref.ref(self._thread)],
-                exitpriority=-5
-                )
-            
-        # Send sentinel to the thread queue object when garbage collected
-        self._close = Finalize(
-            self, Queue._finalize_close,
-            [self._buffer, self._notempty],
-            exitpriority=10
-            )
-        
-    @staticmethod
-    def _finalize_join(twr):
-        debug('joining queue thread')
-        thread = twr()
-        if thread is not None:
-            thread.join()
-            debug('... queue thread joined')
-        else:
-            debug('... queue thread already dead')
-            
-    @staticmethod
-    def _finalize_close(buffer, notempty):
-        debug('telling queue thread to quit')
-        notempty.acquire()
-        try:
-            buffer.append(_sentinel)
-            notempty.notify()
-        finally:
-            notempty.release()
-
-    @staticmethod
-    def _feed(buffer, notempty, send, writelock, close):
-        debug('starting thread to feed data to pipe')
-        from .util import is_exiting
-        
-        nacquire = notempty.acquire
-        nrelease = notempty.release
-        nwait = notempty.wait
-        bpopleft = buffer.popleft
-        sentinel = _sentinel
-        if sys.platform != 'win32':
-            wacquire = writelock.acquire
-            wrelease = writelock.release
-        else:
-            wacquire = None
-        
-        try:
-            while 1:
-                nacquire()
-                try:
-                    if not buffer:
-                        nwait()
-                finally:
-                    nrelease()
-                try:
-                    while 1:
-                        obj = bpopleft()
-                        if obj is sentinel:
-                            debug('feeder thread got sentinel -- exiting')
-                            close()
-                            return
-
-                        if wacquire is None:
-                            send(obj)
-                        else:
-                            wacquire()
-                            try:
-                                send(obj)
-                            finally:
-                                wrelease()
-                except IndexError:
-                    pass
-        except Exception, e:
-            # Since this runs in a daemon thread the resources it uses
-            # may be become unusable while the process is cleaning up.
-            # We ignore errors which happen after the process has
-            # started to cleanup.
-            try:
-                if is_exiting():
-                    info('error in queue thread: %s', e)
-                else:
-                    import traceback
-                    traceback.print_exc()
-            except Exception:
-                pass
-            
-_sentinel = object()
-
-#
-# A queue type which also supports join() and task_done() methods
-#
-# Note that if you do not call task_done() for each finished task then
-# eventually the counter's semaphore may overflow causing Bad Things
-# to happen.
-#
-
-class JoinableQueue(Queue):
-
-    def __init__(self, maxsize=0):
-        Queue.__init__(self, maxsize)
-        self._unfinished_tasks = Semaphore(0)
-        self._cond = Condition()
-        
-    def __getstate__(self):
-        return Queue.__getstate__(self) + (self._cond, self._unfinished_tasks)
-
-    def __setstate__(self, state):
-        Queue.__setstate__(self, state[:-2])
-        self._cond, self._unfinished_tasks = state[-2:]
-
-    def put(self, item, block=True, timeout=None):
-        Queue.put(self, item, block, timeout)
-        self._unfinished_tasks.release()
-        
-    def task_done(self):
-        self._cond.acquire()
-        try:
-            if not self._unfinished_tasks.acquire(False):
-                raise ValueError('task_done() called too many times')
-            if self._unfinished_tasks._semlock._is_zero():
-                self._cond.notify_all()
-        finally:
-            self._cond.release()
-            
-    def join(self):
-        self._cond.acquire()
-        try:
-            if not self._unfinished_tasks._semlock._is_zero():
-                self._cond.wait()
-        finally:
-            self._cond.release()
-
-#
-# Simplified Queue type -- really just a locked pipe
-#
-
-class SimpleQueue(object):
-
-    def __init__(self):
-        self._reader, self._writer = Pipe(duplex=False)
-        self._rlock = Lock()
-        if sys.platform == 'win32':
-            self._wlock = None
-        else:
-            self._wlock = Lock()
-        self._make_methods()
-
-    def empty(self):
-        return not self._reader.poll()
-
-    def __getstate__(self):
-        assert_spawning(self)
-        return (self._reader, self._writer, self._rlock, self._wlock)
-
-    def __setstate__(self, state):
-        (self._reader, self._writer, self._rlock, self._wlock) = state
-        self._make_methods()
-
-    def _make_methods(self):
-        recv = self._reader.recv
-        racquire, rrelease = self._rlock.acquire, self._rlock.release
-        def get():
-            racquire()
-            try:
-                return recv()
-            finally:
-                rrelease()
-        self.get = get
-
-        if self._wlock is None:
-            # writes to a message oriented win32 pipe are atomic
-            self.put = self._writer.send
-        else:
-            send = self._writer.send
-            wacquire, wrelease = self._wlock.acquire, self._wlock.release
-            def put(obj):
-                wacquire()
-                try:
-                    return send(obj)
-                finally:
-                    wrelease()
-            self.put = put
+#
+# Module implementing queues
+#
+# multiprocessing/queues.py
+#
+# Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
+#
+
+__all__ = ['Queue', 'SimpleQueue']
+
+import sys
+import os
+import threading
+import collections
+import time
+import atexit
+import weakref
+
+from queue import Empty, Full
+import _multiprocessing
+from multiprocessing import Pipe
+from multiprocessing.synchronize import Lock, BoundedSemaphore, Semaphore, Condition
+from multiprocessing.util import debug, info, Finalize, register_after_fork
+from multiprocessing.forking import assert_spawning
+
+#
+# Queue type using a pipe, buffer and thread
+#
+
+class Queue(object):
+
+    def __init__(self, maxsize=0):
+        if maxsize <= 0:
+            maxsize = _multiprocessing.SemLock.SEM_VALUE_MAX
+        self._maxsize = maxsize
+        self._reader, self._writer = Pipe(duplex=False)
+        self._rlock = Lock()
+        self._opid = os.getpid()
+        if sys.platform == 'win32':
+            self._wlock = None
+        else:
+            self._wlock = Lock()
+        self._sem = BoundedSemaphore(maxsize)
+
+        self._after_fork()
+
+        if sys.platform != 'win32':
+            register_after_fork(self, Queue._after_fork)
+
+    def __getstate__(self):
+        assert_spawning(self)
+        return (self._maxsize, self._reader, self._writer,
+                self._rlock, self._wlock, self._sem, self._opid)
+
+    def __setstate__(self, state):
+        (self._maxsize, self._reader, self._writer,
+         self._rlock, self._wlock, self._sem, self._opid) = state
+        self._after_fork()
+
+    def _after_fork(self):
+        debug('Queue._after_fork()')
+        self._notempty = threading.Condition(threading.Lock())
+        self._buffer = collections.deque()
+        self._thread = None
+        self._jointhread = None
+        self._joincancelled = False
+        self._closed = False
+        self._close = None
+        self._send = self._writer.send
+        self._recv = self._reader.recv
+        self._poll = self._reader.poll
+
+    def put(self, obj, block=True, timeout=None):
+        assert not self._closed
+        if not self._sem.acquire(block, timeout):
+            raise Full
+
+        self._notempty.acquire()
+        try:
+            if self._thread is None:
+                self._start_thread()
+            self._buffer.append(obj)
+            self._notempty.notify()
+        finally:
+            self._notempty.release()
+
+    def get(self, block=True, timeout=None):
+        if block and timeout is None:
+            self._rlock.acquire()
+            try:
+                res = self._recv()
+                self._sem.release()
+                return res
+            finally:
+                self._rlock.release()
+
+        else:
+            if block:
+                deadline = time.time() + timeout
+            if not self._rlock.acquire(block, timeout):
+                raise Empty
+            try:
+                if not self._poll(block and (deadline-time.time()) or 0.0):
+                    raise Empty
+                res = self._recv()
+                self._sem.release()
+                return res
+            finally:
+                self._rlock.release()
+
+    def qsize(self):
+        # Raises NotImplementError on Mac OSX because of broken sem_getvalue()
+        return self._maxsize - self._sem._semlock._get_value()
+
+    def empty(self):
+        return not self._poll()
+
+    def full(self):
+        return self._sem._semlock._is_zero()
+
+    def get_nowait(self):
+        return self.get(False)
+
+    def put_nowait(self, obj):
+        return self.put(obj, False)
+
+    def close(self):
+        self._closed = True
+        self._reader.close()
+        if self._close:
+            self._close()
+
+    def join_thread(self):
+        debug('Queue.join_thread()')
+        assert self._closed
+        if self._jointhread:
+            self._jointhread()
+
+    def cancel_join_thread(self):
+        debug('Queue.cancel_join_thread()')
+        self._joincancelled = True
+        try:
+            self._jointhread.cancel()
+        except AttributeError:
+            pass
+
+    def _start_thread(self):
+        debug('Queue._start_thread()')
+
+        # Start thread which transfers data from buffer to pipe
+        self._buffer.clear()
+        self._thread = threading.Thread(
+            target=Queue._feed,
+            args=(self._buffer, self._notempty, self._send,
+                  self._wlock, self._writer.close),
+            name='QueueFeederThread'
+            )
+        self._thread.setDaemon(True)
+
+        debug('doing self._thread.start()')
+        self._thread.start()
+        debug('... done self._thread.start()')
+
+        # On process exit we will wait for data to be flushed to pipe.
+        #
+        # However, if this process created the queue then all
+        # processes which use the queue will be descendants of this
+        # process.  Therefore waiting for the queue to be flushed
+        # is pointless once all the child processes have been joined.
+        created_by_this_process = (self._opid == os.getpid())
+        if not self._joincancelled and not created_by_this_process:
+            self._jointhread = Finalize(
+                self._thread, Queue._finalize_join,
+                [weakref.ref(self._thread)],
+                exitpriority=-5
+                )
+
+        # Send sentinel to the thread queue object when garbage collected
+        self._close = Finalize(
+            self, Queue._finalize_close,
+            [self._buffer, self._notempty],
+            exitpriority=10
+            )
+
+    @staticmethod
+    def _finalize_join(twr):
+        debug('joining queue thread')
+        thread = twr()
+        if thread is not None:
+            thread.join()
+            debug('... queue thread joined')
+        else:
+            debug('... queue thread already dead')
+
+    @staticmethod
+    def _finalize_close(buffer, notempty):
+        debug('telling queue thread to quit')
+        notempty.acquire()
+        try:
+            buffer.append(_sentinel)
+            notempty.notify()
+        finally:
+            notempty.release()
+
+    @staticmethod
+    def _feed(buffer, notempty, send, writelock, close):
+        debug('starting thread to feed data to pipe')
+        from .util import is_exiting
+
+        nacquire = notempty.acquire
+        nrelease = notempty.release
+        nwait = notempty.wait
+        bpopleft = buffer.popleft
+        sentinel = _sentinel
+        if sys.platform != 'win32':
+            wacquire = writelock.acquire
+            wrelease = writelock.release
+        else:
+            wacquire = None
+
+        try:
+            while 1:
+                nacquire()
+                try:
+                    if not buffer:
+                        nwait()
+                finally:
+                    nrelease()
+                try:
+                    while 1:
+                        obj = bpopleft()
+                        if obj is sentinel:
+                            debug('feeder thread got sentinel -- exiting')
+                            close()
+                            return
+
+                        if wacquire is None:
+                            send(obj)
+                        else:
+                            wacquire()
+                            try:
+                                send(obj)
+                            finally:
+                                wrelease()
+                except IndexError:
+                    pass
+        except Exception as e:
+            # Since this runs in a daemon thread the resources it uses
+            # may be become unusable while the process is cleaning up.
+            # We ignore errors which happen after the process has
+            # started to cleanup.
+            try:
+                if is_exiting():
+                    info('error in queue thread: %s', e)
+                else:
+                    import traceback
+                    traceback.print_exc()
+            except Exception:
+                pass
+
+_sentinel = object()
+
+#
+# A queue type which also supports join() and task_done() methods
+#
+# Note that if you do not call task_done() for each finished task then
+# eventually the counter's semaphore may overflow causing Bad Things
+# to happen.
+#
+
+class JoinableQueue(Queue):
+
+    def __init__(self, maxsize=0):
+        Queue.__init__(self, maxsize)
+        self._unfinished_tasks = Semaphore(0)
+        self._cond = Condition()
+
+    def __getstate__(self):
+        return Queue.__getstate__(self) + (self._cond, self._unfinished_tasks)
+
+    def __setstate__(self, state):
+        Queue.__setstate__(self, state[:-2])
+        self._cond, self._unfinished_tasks = state[-2:]
+
+    def put(self, item, block=True, timeout=None):
+        Queue.put(self, item, block, timeout)
+        self._unfinished_tasks.release()
+
+    def task_done(self):
+        self._cond.acquire()
+        try:
+            if not self._unfinished_tasks.acquire(False):
+                raise ValueError('task_done() called too many times')
+            if self._unfinished_tasks._semlock._is_zero():
+                self._cond.notify_all()
+        finally:
+            self._cond.release()
+
+    def join(self):
+        self._cond.acquire()
+        try:
+            if not self._unfinished_tasks._semlock._is_zero():
+                self._cond.wait()
+        finally:
+            self._cond.release()
+
+#
+# Simplified Queue type -- really just a locked pipe
+#
+
+class SimpleQueue(object):
+
+    def __init__(self):
+        self._reader, self._writer = Pipe(duplex=False)
+        self._rlock = Lock()
+        if sys.platform == 'win32':
+            self._wlock = None
+        else:
+            self._wlock = Lock()
+        self._make_methods()
+
+    def empty(self):
+        return not self._reader.poll()
+
+    def __getstate__(self):
+        assert_spawning(self)
+        return (self._reader, self._writer, self._rlock, self._wlock)
+
+    def __setstate__(self, state):
+        (self._reader, self._writer, self._rlock, self._wlock) = state
+        self._make_methods()
+
+    def _make_methods(self):
+        recv = self._reader.recv
+        racquire, rrelease = self._rlock.acquire, self._rlock.release
+        def get():
+            racquire()
+            try:
+                return recv()
+            finally:
+                rrelease()
+        self.get = get
+
+        if self._wlock is None:
+            # writes to a message oriented win32 pipe are atomic
+            self.put = self._writer.send
+        else:
+            send = self._writer.send
+            wacquire, wrelease = self._wlock.acquire, self._wlock.release
+            def put(obj):
+                wacquire()
+                try:
+                    return send(obj)
+                finally:
+                    wrelease()
+            self.put = put

Modified: python/branches/py3k/Lib/multiprocessing/reduction.py
==============================================================================
--- /python/trunk/Lib/multiprocessing/reduction.py	(original)
+++ python/branches/py3k/Lib/multiprocessing/reduction.py	Wed Jun 11 18:44:04 2008
@@ -1,190 +1,190 @@
-#
-# Module to allow connection and socket objects to be transferred
-# between processes
-#
-# multiprocessing/reduction.py
-#
-# Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
-#
-
-__all__ = []
-
-import os
-import sys
-import socket
-import threading
-import copy_reg
-
-import _multiprocessing
-from multiprocessing import current_process
-from multiprocessing.forking import Popen, duplicate, close
-from multiprocessing.util import register_after_fork, debug, sub_debug
-from multiprocessing.connection import Client, Listener
-
-
-#
-#
-#
-
-if not(sys.platform == 'win32' or hasattr(_multiprocessing, 'recvfd')):
-    raise ImportError('pickling of connections not supported')
-
-#
-# Platform specific definitions
-#
-
-if sys.platform == 'win32':
-    import _subprocess
-    from ._multiprocessing import win32
-    
-    def send_handle(conn, handle, destination_pid):
-        process_handle = win32.OpenProcess(
-            win32.PROCESS_ALL_ACCESS, False, destination_pid
-            )
-        try:
-            new_handle = duplicate(handle, process_handle)
-            conn.send(new_handle)
-        finally:
-            close(process_handle)
-            
-    def recv_handle(conn):
-        return conn.recv()
-
-else:
-    def send_handle(conn, handle, destination_pid):
-        _multiprocessing.sendfd(conn.fileno(), handle)
-        
-    def recv_handle(conn):
-        return _multiprocessing.recvfd(conn.fileno())
-
-#
-# Support for a per-process server thread which caches pickled handles
-#
-
-_cache = set()
-
-def _reset(obj):
-    global _lock, _listener, _cache
-    for h in _cache:
-        close(h)
-    _cache.clear()
-    _lock = threading.Lock()
-    _listener = None
-
-_reset(None)
-register_after_fork(_reset, _reset)
-
-def _get_listener():
-    global _listener
-
-    if _listener is None:
-        _lock.acquire()
-        try:
-            if _listener is None:
-                debug('starting listener and thread for sending handles')
-                _listener = Listener(authkey=current_process().get_authkey())
-                t = threading.Thread(target=_serve)
-                t.setDaemon(True)
-                t.start()
-        finally:
-            _lock.release()
-
-    return _listener
-
-def _serve():
-    from .util import is_exiting, sub_warning
-    
-    while 1:
-        try:
-            conn = _listener.accept()
-            handle_wanted, destination_pid = conn.recv()
-            _cache.remove(handle_wanted)
-            send_handle(conn, handle_wanted, destination_pid)
-            close(handle_wanted)
-            conn.close()
-        except:
-            if not is_exiting():
-                import traceback
-                sub_warning(
-                    'thread for sharing handles raised exception :\n' +
-                    '-'*79 + '\n' + traceback.format_exc() + '-'*79
-                    )
-    
-#
-# Functions to be used for pickling/unpickling objects with handles
-#
-
-def reduce_handle(handle):
-    if Popen.thread_is_spawning():
-        return (None, Popen.duplicate_for_child(handle), True)
-    dup_handle = duplicate(handle)
-    _cache.add(dup_handle)
-    sub_debug('reducing handle %d', handle)
-    return (_get_listener().address, dup_handle, False)
-
-def rebuild_handle(pickled_data):
-    address, handle, inherited = pickled_data
-    if inherited:
-        return handle
-    sub_debug('rebuilding handle %d', handle)
-    conn = Client(address, authkey=current_process().get_authkey())
-    conn.send((handle, os.getpid()))
-    new_handle = recv_handle(conn)
-    conn.close()
-    return new_handle
-
-#
-# Register `_multiprocessing.Connection` with `copy_reg`
-#
-
-def reduce_connection(conn):
-    rh = reduce_handle(conn.fileno())
-    return rebuild_connection, (rh, conn.readable, conn.writable)
-
-def rebuild_connection(reduced_handle, readable, writable):
-    handle = rebuild_handle(reduced_handle)
-    return _multiprocessing.Connection(
-        handle, readable=readable, writable=writable
-        )
-
-copy_reg.pickle(_multiprocessing.Connection, reduce_connection)
-
-#
-# Register `socket.socket` with `copy_reg`
-#
-
-def fromfd(fd, family, type_, proto=0):
-    s = socket.fromfd(fd, family, type_, proto)
-    if s.__class__ is not socket.socket:
-        s = socket.socket(_sock=s)
-    return s
-
-def reduce_socket(s):
-    reduced_handle = reduce_handle(s.fileno())
-    return rebuild_socket, (reduced_handle, s.family, s.type, s.proto)
-
-def rebuild_socket(reduced_handle, family, type_, proto):
-    fd = rebuild_handle(reduced_handle)
-    _sock = fromfd(fd, family, type_, proto)
-    close(fd)
-    return _sock
-
-copy_reg.pickle(socket.socket, reduce_socket)
-
-#
-# Register `_multiprocessing.PipeConnection` with `copy_reg`
-#
-
-if sys.platform == 'win32':
-    
-    def reduce_pipe_connection(conn):
-        rh = reduce_handle(conn.fileno())
-        return rebuild_pipe_connection, (rh, conn.readable, conn.writable)
-    
-    def rebuild_pipe_connection(reduced_handle, readable, writable):
-        handle = rebuild_handle(reduced_handle)
-        return _multiprocessing.PipeConnection(
-            handle, readable=readable, writable=writable
-            )
-    
-    copy_reg.pickle(_multiprocessing.PipeConnection, reduce_pipe_connection)
+#
+# Module to allow connection and socket objects to be transferred
+# between processes
+#
+# multiprocessing/reduction.py
+#
+# Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
+#
+
+__all__ = []
+
+import os
+import sys
+import socket
+import threading
+import copyreg
+
+import _multiprocessing
+from multiprocessing import current_process
+from multiprocessing.forking import Popen, duplicate, close
+from multiprocessing.util import register_after_fork, debug, sub_debug
+from multiprocessing.connection import Client, Listener
+
+
+#
+#
+#
+
+if not(sys.platform == 'win32' or hasattr(_multiprocessing, 'recvfd')):
+    raise ImportError('pickling of connections not supported')
+
+#
+# Platform specific definitions
+#
+
+if sys.platform == 'win32':
+    import _subprocess
+    from ._multiprocessing import win32
+
+    def send_handle(conn, handle, destination_pid):
+        process_handle = win32.OpenProcess(
+            win32.PROCESS_ALL_ACCESS, False, destination_pid
+            )
+        try:
+            new_handle = duplicate(handle, process_handle)
+            conn.send(new_handle)
+        finally:
+            close(process_handle)
+
+    def recv_handle(conn):
+        return conn.recv()
+
+else:
+    def send_handle(conn, handle, destination_pid):
+        _multiprocessing.sendfd(conn.fileno(), handle)
+
+    def recv_handle(conn):
+        return _multiprocessing.recvfd(conn.fileno())
+
+#
+# Support for a per-process server thread which caches pickled handles
+#
+
+_cache = set()
+
+def _reset(obj):
+    global _lock, _listener, _cache
+    for h in _cache:
+        close(h)
+    _cache.clear()
+    _lock = threading.Lock()
+    _listener = None
+
+_reset(None)
+register_after_fork(_reset, _reset)
+
+def _get_listener():
+    global _listener
+
+    if _listener is None:
+        _lock.acquire()
+        try:
+            if _listener is None:
+                debug('starting listener and thread for sending handles')
+                _listener = Listener(authkey=current_process().get_authkey())
+                t = threading.Thread(target=_serve)
+                t.setDaemon(True)
+                t.start()
+        finally:
+            _lock.release()
+
+    return _listener
+
+def _serve():
+    from .util import is_exiting, sub_warning
+
+    while 1:
+        try:
+            conn = _listener.accept()
+            handle_wanted, destination_pid = conn.recv()
+            _cache.remove(handle_wanted)
+            send_handle(conn, handle_wanted, destination_pid)
+            close(handle_wanted)
+            conn.close()
+        except:
+            if not is_exiting():
+                import traceback
+                sub_warning(
+                    'thread for sharing handles raised exception :\n' +
+                    '-'*79 + '\n' + traceback.format_exc() + '-'*79
+                    )
+
+#
+# Functions to be used for pickling/unpickling objects with handles
+#
+
+def reduce_handle(handle):
+    if Popen.thread_is_spawning():
+        return (None, Popen.duplicate_for_child(handle), True)
+    dup_handle = duplicate(handle)
+    _cache.add(dup_handle)
+    sub_debug('reducing handle %d', handle)
+    return (_get_listener().address, dup_handle, False)
+
+def rebuild_handle(pickled_data):
+    address, handle, inherited = pickled_data
+    if inherited:
+        return handle
+    sub_debug('rebuilding handle %d', handle)
+    conn = Client(address, authkey=current_process().get_authkey())
+    conn.send((handle, os.getpid()))
+    new_handle = recv_handle(conn)
+    conn.close()
+    return new_handle
+
+#
+# Register `_multiprocessing.Connection` with `copy_reg`
+#
+
+def reduce_connection(conn):
+    rh = reduce_handle(conn.fileno())
+    return rebuild_connection, (rh, conn.readable, conn.writable)
+
+def rebuild_connection(reduced_handle, readable, writable):
+    handle = rebuild_handle(reduced_handle)
+    return _multiprocessing.Connection(
+        handle, readable=readable, writable=writable
+        )
+
+copyreg.pickle(_multiprocessing.Connection, reduce_connection)
+
+#
+# Register `socket.socket` with `copy_reg`
+#
+
+def fromfd(fd, family, type_, proto=0):
+    s = socket.fromfd(fd, family, type_, proto)
+    if s.__class__ is not socket.socket:
+        s = socket.socket(_sock=s)
+    return s
+
+def reduce_socket(s):
+    reduced_handle = reduce_handle(s.fileno())
+    return rebuild_socket, (reduced_handle, s.family, s.type, s.proto)
+
+def rebuild_socket(reduced_handle, family, type_, proto):
+    fd = rebuild_handle(reduced_handle)
+    _sock = fromfd(fd, family, type_, proto)
+    close(fd)
+    return _sock
+
+copyreg.pickle(socket.socket, reduce_socket)
+
+#
+# Register `_multiprocessing.PipeConnection` with `copy_reg`
+#
+
+if sys.platform == 'win32':
+
+    def reduce_pipe_connection(conn):
+        rh = reduce_handle(conn.fileno())
+        return rebuild_pipe_connection, (rh, conn.readable, conn.writable)
+
+    def rebuild_pipe_connection(reduced_handle, readable, writable):
+        handle = rebuild_handle(reduced_handle)
+        return _multiprocessing.PipeConnection(
+            handle, readable=readable, writable=writable
+            )
+
+    copyreg.pickle(_multiprocessing.PipeConnection, reduce_pipe_connection)

Modified: python/branches/py3k/Lib/multiprocessing/sharedctypes.py
==============================================================================
--- /python/trunk/Lib/multiprocessing/sharedctypes.py	(original)
+++ python/branches/py3k/Lib/multiprocessing/sharedctypes.py	Wed Jun 11 18:44:04 2008
@@ -1,234 +1,234 @@
-#
-# Module which supports allocation of ctypes objects from shared memory
-#
-# multiprocessing/sharedctypes.py
-#
-# Copyright (c) 2007-2008, R Oudkerk --- see COPYING.txt
-#
-
-import sys
-import ctypes
-import weakref
-import copy_reg
-
-from multiprocessing import heap, RLock
-from multiprocessing.forking import assert_spawning
-
-__all__ = ['RawValue', 'RawArray', 'Value', 'Array', 'copy', 'synchronized']
-
-#
-#
-#
-
-typecode_to_type = {
-    'c': ctypes.c_char,  'u': ctypes.c_wchar,
-    'b': ctypes.c_byte,  'B': ctypes.c_ubyte,
-    'h': ctypes.c_short, 'H': ctypes.c_ushort,
-    'i': ctypes.c_int,   'I': ctypes.c_uint,
-    'l': ctypes.c_long,  'L': ctypes.c_ulong,
-    'f': ctypes.c_float, 'd': ctypes.c_double
-    }
-
-#
-#
-#
-
-def _new_value(type_):
-    size = ctypes.sizeof(type_)
-    wrapper = heap.BufferWrapper(size)
-    return rebuild_ctype(type_, wrapper, None)
-
-def RawValue(typecode_or_type, *args):
-    '''
-    Returns a ctypes object allocated from shared memory
-    '''
-    type_ = typecode_to_type.get(typecode_or_type, typecode_or_type)
-    obj = _new_value(type_)
-    ctypes.memset(ctypes.addressof(obj), 0, ctypes.sizeof(obj))
-    obj.__init__(*args)
-    return obj
-
-def RawArray(typecode_or_type, size_or_initializer):
-    '''
-    Returns a ctypes array allocated from shared memory
-    '''
-    type_ = typecode_to_type.get(typecode_or_type, typecode_or_type)
-    if isinstance(size_or_initializer, int):
-        type_ = type_ * size_or_initializer
-        return _new_value(type_)
-    else:
-        type_ = type_ * len(size_or_initializer)
-        result = _new_value(type_)
-        result.__init__(*size_or_initializer)
-        return result
-
-def Value(typecode_or_type, *args, **kwds):
-    '''
-    Return a synchronization wrapper for a Value
-    '''
-    lock = kwds.pop('lock', None)
-    if kwds:
-        raise ValueError('unrecognized keyword argument(s): %s' % kwds.keys())
-    obj = RawValue(typecode_or_type, *args)
-    if lock is None:
-        lock = RLock()
-    assert hasattr(lock, 'acquire')
-    return synchronized(obj, lock)
-
-def Array(typecode_or_type, size_or_initializer, **kwds):
-    '''
-    Return a synchronization wrapper for a RawArray
-    '''
-    lock = kwds.pop('lock', None)
-    if kwds:
-        raise ValueError('unrecognized keyword argument(s): %s' % kwds.keys())
-    obj = RawArray(typecode_or_type, size_or_initializer)
-    if lock is None:
-        lock = RLock()
-    assert hasattr(lock, 'acquire')
-    return synchronized(obj, lock)
-
-def copy(obj):
-    new_obj = _new_value(type(obj))
-    ctypes.pointer(new_obj)[0] = obj
-    return new_obj
-    
-def synchronized(obj, lock=None):
-    assert not isinstance(obj, SynchronizedBase), 'object already synchronized'
-    
-    if isinstance(obj, ctypes._SimpleCData):
-        return Synchronized(obj, lock)
-    elif isinstance(obj, ctypes.Array):
-        if obj._type_ is ctypes.c_char:
-            return SynchronizedString(obj, lock)
-        return SynchronizedArray(obj, lock)
-    else:
-        cls = type(obj)
-        try:
-            scls = class_cache[cls]
-        except KeyError:
-            names = [field[0] for field in cls._fields_]
-            d = dict((name, make_property(name)) for name in names)
-            classname = 'Synchronized' + cls.__name__
-            scls = class_cache[cls] = type(classname, (SynchronizedBase,), d)
-        return scls(obj, lock)
-
-#
-# Functions for pickling/unpickling
-#
-
-def reduce_ctype(obj):
-    assert_spawning(obj)
-    if isinstance(obj, ctypes.Array):
-        return rebuild_ctype, (obj._type_, obj._wrapper, obj._length_)
-    else:
-        return rebuild_ctype, (type(obj), obj._wrapper, None)
-    
-def rebuild_ctype(type_, wrapper, length):
-    if length is not None:
-        type_ = type_ * length
-    if sys.platform == 'win32' and type_ not in copy_reg.dispatch_table:
-        copy_reg.pickle(type_, reduce_ctype)
-    obj = type_.from_address(wrapper.get_address())
-    obj._wrapper = wrapper
-    return obj
-
-#
-# Function to create properties
-#
-
-def make_property(name):
-    try:
-        return prop_cache[name]
-    except KeyError:
-        d = {}
-        exec template % ((name,)*7) in d
-        prop_cache[name] = d[name]
-        return d[name]
-
-template = '''
-def get%s(self):
-    self.acquire()
-    try:
-        return self._obj.%s
-    finally:
-        self.release()
-def set%s(self, value):
-    self.acquire()
-    try:
-        self._obj.%s = value
-    finally:
-        self.release()
-%s = property(get%s, set%s)
-'''
-
-prop_cache = {}
-class_cache = weakref.WeakKeyDictionary()
-
-#
-# Synchronized wrappers
-#
-
-class SynchronizedBase(object):
-    
-    def __init__(self, obj, lock=None):
-        self._obj = obj
-        self._lock = lock or RLock()
-        self.acquire = self._lock.acquire
-        self.release = self._lock.release
-
-    def __reduce__(self):
-        assert_spawning(self)
-        return synchronized, (self._obj, self._lock)
-    
-    def get_obj(self):
-        return self._obj
-    
-    def get_lock(self):
-        return self._lock
-    
-    def __repr__(self):
-        return '<%s wrapper for %s>' % (type(self).__name__, self._obj)
-    
-    
-class Synchronized(SynchronizedBase):
-    value = make_property('value')
-    
-    
-class SynchronizedArray(SynchronizedBase):
-    
-    def __len__(self):
-        return len(self._obj)
-    
-    def __getitem__(self, i):
-        self.acquire()
-        try:
-            return self._obj[i]
-        finally:
-            self.release()
-            
-    def __setitem__(self, i, value):
-        self.acquire()
-        try:
-            self._obj[i] = value
-        finally:
-            self.release()
-            
-    def __getslice__(self, start, stop):
-        self.acquire()
-        try:
-            return self._obj[start:stop]
-        finally:
-            self.release()
-            
-    def __setslice__(self, start, stop, values):
-        self.acquire()
-        try:
-            self._obj[start:stop] = values
-        finally:
-            self.release()
-            
-            
-class SynchronizedString(SynchronizedArray):
-    value = make_property('value')
-    raw = make_property('raw')
+#
+# Module which supports allocation of ctypes objects from shared memory
+#
+# multiprocessing/sharedctypes.py
+#
+# Copyright (c) 2007-2008, R Oudkerk --- see COPYING.txt
+#
+
+import sys
+import ctypes
+import weakref
+import copyreg
+
+from multiprocessing import heap, RLock
+from multiprocessing.forking import assert_spawning
+
+__all__ = ['RawValue', 'RawArray', 'Value', 'Array', 'copy', 'synchronized']
+
+#
+#
+#
+
+typecode_to_type = {
+    'c': ctypes.c_char,  'u': ctypes.c_wchar,
+    'b': ctypes.c_byte,  'B': ctypes.c_ubyte,
+    'h': ctypes.c_short, 'H': ctypes.c_ushort,
+    'i': ctypes.c_int,   'I': ctypes.c_uint,
+    'l': ctypes.c_long,  'L': ctypes.c_ulong,
+    'f': ctypes.c_float, 'd': ctypes.c_double
+    }
+
+#
+#
+#
+
+def _new_value(type_):
+    size = ctypes.sizeof(type_)
+    wrapper = heap.BufferWrapper(size)
+    return rebuild_ctype(type_, wrapper, None)
+
+def RawValue(typecode_or_type, *args):
+    '''
+    Returns a ctypes object allocated from shared memory
+    '''
+    type_ = typecode_to_type.get(typecode_or_type, typecode_or_type)
+    obj = _new_value(type_)
+    ctypes.memset(ctypes.addressof(obj), 0, ctypes.sizeof(obj))
+    obj.__init__(*args)
+    return obj
+
+def RawArray(typecode_or_type, size_or_initializer):
+    '''
+    Returns a ctypes array allocated from shared memory
+    '''
+    type_ = typecode_to_type.get(typecode_or_type, typecode_or_type)
+    if isinstance(size_or_initializer, int):
+        type_ = type_ * size_or_initializer
+        return _new_value(type_)
+    else:
+        type_ = type_ * len(size_or_initializer)
+        result = _new_value(type_)
+        result.__init__(*size_or_initializer)
+        return result
+
+def Value(typecode_or_type, *args, **kwds):
+    '''
+    Return a synchronization wrapper for a Value
+    '''
+    lock = kwds.pop('lock', None)
+    if kwds:
+        raise ValueError('unrecognized keyword argument(s): %s' % list(kwds.keys()))
+    obj = RawValue(typecode_or_type, *args)
+    if lock is None:
+        lock = RLock()
+    assert hasattr(lock, 'acquire')
+    return synchronized(obj, lock)
+
+def Array(typecode_or_type, size_or_initializer, **kwds):
+    '''
+    Return a synchronization wrapper for a RawArray
+    '''
+    lock = kwds.pop('lock', None)
+    if kwds:
+        raise ValueError('unrecognized keyword argument(s): %s' % list(kwds.keys()))
+    obj = RawArray(typecode_or_type, size_or_initializer)
+    if lock is None:
+        lock = RLock()
+    assert hasattr(lock, 'acquire')
+    return synchronized(obj, lock)
+
+def copy(obj):
+    new_obj = _new_value(type(obj))
+    ctypes.pointer(new_obj)[0] = obj
+    return new_obj
+
+def synchronized(obj, lock=None):
+    assert not isinstance(obj, SynchronizedBase), 'object already synchronized'
+
+    if isinstance(obj, ctypes._SimpleCData):
+        return Synchronized(obj, lock)
+    elif isinstance(obj, ctypes.Array):
+        if obj._type_ is ctypes.c_char:
+            return SynchronizedString(obj, lock)
+        return SynchronizedArray(obj, lock)
+    else:
+        cls = type(obj)
+        try:
+            scls = class_cache[cls]
+        except KeyError:
+            names = [field[0] for field in cls._fields_]
+            d = dict((name, make_property(name)) for name in names)
+            classname = 'Synchronized' + cls.__name__
+            scls = class_cache[cls] = type(classname, (SynchronizedBase,), d)
+        return scls(obj, lock)
+
+#
+# Functions for pickling/unpickling
+#
+
+def reduce_ctype(obj):
+    assert_spawning(obj)
+    if isinstance(obj, ctypes.Array):
+        return rebuild_ctype, (obj._type_, obj._wrapper, obj._length_)
+    else:
+        return rebuild_ctype, (type(obj), obj._wrapper, None)
+
+def rebuild_ctype(type_, wrapper, length):
+    if length is not None:
+        type_ = type_ * length
+    if sys.platform == 'win32' and type_ not in copyreg.dispatch_table:
+        copyreg.pickle(type_, reduce_ctype)
+    obj = type_.from_address(wrapper.get_address())
+    obj._wrapper = wrapper
+    return obj
+
+#
+# Function to create properties
+#
+
+def make_property(name):
+    try:
+        return prop_cache[name]
+    except KeyError:
+        d = {}
+        exec(template % ((name,)*7), d)
+        prop_cache[name] = d[name]
+        return d[name]
+
+template = '''
+def get%s(self):
+    self.acquire()
+    try:
+        return self._obj.%s
+    finally:
+        self.release()
+def set%s(self, value):
+    self.acquire()
+    try:
+        self._obj.%s = value
+    finally:
+        self.release()
+%s = property(get%s, set%s)
+'''
+
+prop_cache = {}
+class_cache = weakref.WeakKeyDictionary()
+
+#
+# Synchronized wrappers
+#
+
+class SynchronizedBase(object):
+
+    def __init__(self, obj, lock=None):
+        self._obj = obj
+        self._lock = lock or RLock()
+        self.acquire = self._lock.acquire
+        self.release = self._lock.release
+
+    def __reduce__(self):
+        assert_spawning(self)
+        return synchronized, (self._obj, self._lock)
+
+    def get_obj(self):
+        return self._obj
+
+    def get_lock(self):
+        return self._lock
+
+    def __repr__(self):
+        return '<%s wrapper for %s>' % (type(self).__name__, self._obj)
+
+
+class Synchronized(SynchronizedBase):
+    value = make_property('value')
+
+
+class SynchronizedArray(SynchronizedBase):
+
+    def __len__(self):
+        return len(self._obj)
+
+    def __getitem__(self, i):
+        self.acquire()
+        try:
+            return self._obj[i]
+        finally:
+            self.release()
+
+    def __setitem__(self, i, value):
+        self.acquire()
+        try:
+            self._obj[i] = value
+        finally:
+            self.release()
+
+    def __getslice__(self, start, stop):
+        self.acquire()
+        try:
+            return self._obj[start:stop]
+        finally:
+            self.release()
+
+    def __setslice__(self, start, stop, values):
+        self.acquire()
+        try:
+            self._obj[start:stop] = values
+        finally:
+            self.release()
+
+
+class SynchronizedString(SynchronizedArray):
+    value = make_property('value')
+    raw = make_property('raw')

Modified: python/branches/py3k/Lib/multiprocessing/synchronize.py
==============================================================================
--- /python/trunk/Lib/multiprocessing/synchronize.py	(original)
+++ python/branches/py3k/Lib/multiprocessing/synchronize.py	Wed Jun 11 18:44:04 2008
@@ -1,294 +1,294 @@
-#
-# Module implementing synchronization primitives
-#
-# multiprocessing/synchronize.py
-#
-# Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
-#
-
-__all__ = [
-    'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Condition', 'Event'
-    ]
-
-import threading
-import os
-import sys
-
-from time import time as _time, sleep as _sleep
-
-import _multiprocessing
-from multiprocessing.process import current_process
-from multiprocessing.util import Finalize, register_after_fork, debug
-from multiprocessing.forking import assert_spawning, Popen
-
-#
-# Constants
-#
-
-RECURSIVE_MUTEX, SEMAPHORE = range(2)
-SEM_VALUE_MAX = _multiprocessing.SemLock.SEM_VALUE_MAX
-
-#
-# Base class for semaphores and mutexes; wraps `_multiprocessing.SemLock`
-#
-
-class SemLock(object):
-
-    def __init__(self, kind, value, maxvalue):
-        sl = self._semlock = _multiprocessing.SemLock(kind, value, maxvalue)
-        debug('created semlock with handle %s' % sl.handle)
-        self._make_methods()
-        
-        if sys.platform != 'win32':
-            def _after_fork(obj):
-                obj._semlock._after_fork()
-            register_after_fork(self, _after_fork)
-
-    def _make_methods(self):
-        self.acquire = self._semlock.acquire
-        self.release = self._semlock.release
-        self.__enter__ = self._semlock.__enter__
-        self.__exit__ = self._semlock.__exit__
-
-    def __getstate__(self):
-        assert_spawning(self)
-        sl = self._semlock
-        return (Popen.duplicate_for_child(sl.handle), sl.kind, sl.maxvalue)
-
-    def __setstate__(self, state):
-        self._semlock = _multiprocessing.SemLock._rebuild(*state)
-        debug('recreated blocker with handle %r' % state[0])
-        self._make_methods()
-
-#
-# Semaphore
-#
-
-class Semaphore(SemLock):
-
-    def __init__(self, value=1):
-        SemLock.__init__(self, SEMAPHORE, value, SEM_VALUE_MAX)
-
-    def get_value(self):
-        return self._semlock._get_value()
-
-    def __repr__(self):
-        try:
-            value = self._semlock._get_value()
-        except Exception:
-            value = 'unknown'
-        return '<Semaphore(value=%s)>' % value
-
-#
-# Bounded semaphore
-#
-
-class BoundedSemaphore(Semaphore):
-
-    def __init__(self, value=1):
-        SemLock.__init__(self, SEMAPHORE, value, value)
-
-    def __repr__(self):
-        try:
-            value = self._semlock._get_value()
-        except Exception:
-            value = 'unknown'
-        return '<BoundedSemaphore(value=%s, maxvalue=%s)>' % \
-               (value, self._semlock.maxvalue)
-
-#
-# Non-recursive lock
-#
-
-class Lock(SemLock):
-
-    def __init__(self):
-        SemLock.__init__(self, SEMAPHORE, 1, 1)
-
-    def __repr__(self):
-        try:
-            if self._semlock._is_mine():
-                name = current_process().get_name()
-                if threading.currentThread().getName() != 'MainThread':
-                    name += '|' + threading.currentThread().getName()
-            elif self._semlock._get_value() == 1:
-                name = 'None'
-            elif self._semlock._count() > 0:
-                name = 'SomeOtherThread'
-            else:
-                name = 'SomeOtherProcess'
-        except Exception:
-            name = 'unknown'
-        return '<Lock(owner=%s)>' % name
-
-#
-# Recursive lock
-#
-
-class RLock(SemLock):
-
-    def __init__(self):
-        SemLock.__init__(self, RECURSIVE_MUTEX, 1, 1)
-        
-    def __repr__(self):
-        try:
-            if self._semlock._is_mine():
-                name = current_process().get_name()
-                if threading.currentThread().getName() != 'MainThread':
-                    name += '|' + threading.currentThread().getName()
-                count = self._semlock._count()
-            elif self._semlock._get_value() == 1:
-                name, count = 'None', 0
-            elif self._semlock._count() > 0:
-                name, count = 'SomeOtherThread', 'nonzero'
-            else:
-                name, count = 'SomeOtherProcess', 'nonzero'
-        except Exception:
-            name, count = 'unknown', 'unknown'
-        return '<RLock(%s, %s)>' % (name, count)
-
-#
-# Condition variable
-#
-
-class Condition(object):
-
-    def __init__(self, lock=None):
-        self._lock = lock or RLock()
-        self._sleeping_count = Semaphore(0)
-        self._woken_count = Semaphore(0)
-        self._wait_semaphore = Semaphore(0)
-        self._make_methods()
-
-    def __getstate__(self):
-        assert_spawning(self)
-        return (self._lock, self._sleeping_count,
-                self._woken_count, self._wait_semaphore)
-
-    def __setstate__(self, state):
-        (self._lock, self._sleeping_count,
-         self._woken_count, self._wait_semaphore) = state
-        self._make_methods()
-
-    def _make_methods(self):
-        self.acquire = self._lock.acquire
-        self.release = self._lock.release
-        self.__enter__ = self._lock.__enter__
-        self.__exit__ = self._lock.__exit__
-
-    def __repr__(self):
-        try:
-            num_waiters = (self._sleeping_count._semlock._get_value() -
-                           self._woken_count._semlock._get_value())
-        except Exception:
-            num_waiters = 'unkown'
-        return '<Condition(%s, %s)>' % (self._lock, num_waiters)
-
-    def wait(self, timeout=None):
-        assert self._lock._semlock._is_mine(), \
-               'must acquire() condition before using wait()'
-
-        # indicate that this thread is going to sleep
-        self._sleeping_count.release()
-
-        # release lock
-        count = self._lock._semlock._count()
-        for i in xrange(count):
-            self._lock.release()
-
-        try:
-            # wait for notification or timeout
-            self._wait_semaphore.acquire(True, timeout)
-        finally:
-            # indicate that this thread has woken
-            self._woken_count.release()
-
-            # reacquire lock
-            for i in xrange(count):
-                self._lock.acquire()
-
-    def notify(self):
-        assert self._lock._semlock._is_mine(), 'lock is not owned'
-        assert not self._wait_semaphore.acquire(False)
-        
-        # to take account of timeouts since last notify() we subtract
-        # woken_count from sleeping_count and rezero woken_count
-        while self._woken_count.acquire(False):
-            res = self._sleeping_count.acquire(False)
-            assert res
-            
-        if self._sleeping_count.acquire(False): # try grabbing a sleeper
-            self._wait_semaphore.release()      # wake up one sleeper
-            self._woken_count.acquire()         # wait for the sleeper to wake
-            
-            # rezero _wait_semaphore in case a timeout just happened
-            self._wait_semaphore.acquire(False)
-
-    def notify_all(self):
-        assert self._lock._semlock._is_mine(), 'lock is not owned'
-        assert not self._wait_semaphore.acquire(False)
-
-        # to take account of timeouts since last notify*() we subtract
-        # woken_count from sleeping_count and rezero woken_count
-        while self._woken_count.acquire(False):
-            res = self._sleeping_count.acquire(False)
-            assert res
-            
-        sleepers = 0
-        while self._sleeping_count.acquire(False):
-            self._wait_semaphore.release()        # wake up one sleeper
-            sleepers += 1
-
-        if sleepers:
-            for i in xrange(sleepers):
-                self._woken_count.acquire()       # wait for a sleeper to wake
-
-            # rezero wait_semaphore in case some timeouts just happened
-            while self._wait_semaphore.acquire(False):
-                pass
-
-#
-# Event
-#
-
-class Event(object):
-
-    def __init__(self):
-        self._cond = Condition(Lock())
-        self._flag = Semaphore(0)
-
-    def is_set(self):
-        self._cond.acquire()
-        try:
-            if self._flag.acquire(False):
-                self._flag.release()
-                return True
-            return False
-        finally:
-            self._cond.release()
-    
-    def set(self):
-        self._cond.acquire()
-        try:
-            self._flag.acquire(False)
-            self._flag.release()
-            self._cond.notify_all()
-        finally:
-            self._cond.release()
-
-    def clear(self):
-        self._cond.acquire()
-        try:
-            self._flag.acquire(False)
-        finally:
-            self._cond.release()
-
-    def wait(self, timeout=None):
-        self._cond.acquire()
-        try:
-            if self._flag.acquire(False):
-                self._flag.release()
-            else:
-                self._cond.wait(timeout)
-        finally:
-            self._cond.release()
+#
+# Module implementing synchronization primitives
+#
+# multiprocessing/synchronize.py
+#
+# Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
+#
+
+__all__ = [
+    'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Condition', 'Event'
+    ]
+
+import threading
+import os
+import sys
+
+from time import time as _time, sleep as _sleep
+
+import _multiprocessing
+from multiprocessing.process import current_process
+from multiprocessing.util import Finalize, register_after_fork, debug
+from multiprocessing.forking import assert_spawning, Popen
+
+#
+# Constants
+#
+
+RECURSIVE_MUTEX, SEMAPHORE = list(range(2))
+SEM_VALUE_MAX = _multiprocessing.SemLock.SEM_VALUE_MAX
+
+#
+# Base class for semaphores and mutexes; wraps `_multiprocessing.SemLock`
+#
+
+class SemLock(object):
+
+    def __init__(self, kind, value, maxvalue):
+        sl = self._semlock = _multiprocessing.SemLock(kind, value, maxvalue)
+        debug('created semlock with handle %s' % sl.handle)
+        self._make_methods()
+
+        if sys.platform != 'win32':
+            def _after_fork(obj):
+                obj._semlock._after_fork()
+            register_after_fork(self, _after_fork)
+
+    def _make_methods(self):
+        self.acquire = self._semlock.acquire
+        self.release = self._semlock.release
+        self.__enter__ = self._semlock.__enter__
+        self.__exit__ = self._semlock.__exit__
+
+    def __getstate__(self):
+        assert_spawning(self)
+        sl = self._semlock
+        return (Popen.duplicate_for_child(sl.handle), sl.kind, sl.maxvalue)
+
+    def __setstate__(self, state):
+        self._semlock = _multiprocessing.SemLock._rebuild(*state)
+        debug('recreated blocker with handle %r' % state[0])
+        self._make_methods()
+
+#
+# Semaphore
+#
+
+class Semaphore(SemLock):
+
+    def __init__(self, value=1):
+        SemLock.__init__(self, SEMAPHORE, value, SEM_VALUE_MAX)
+
+    def get_value(self):
+        return self._semlock._get_value()
+
+    def __repr__(self):
+        try:
+            value = self._semlock._get_value()
+        except Exception:
+            value = 'unknown'
+        return '<Semaphore(value=%s)>' % value
+
+#
+# Bounded semaphore
+#
+
+class BoundedSemaphore(Semaphore):
+
+    def __init__(self, value=1):
+        SemLock.__init__(self, SEMAPHORE, value, value)
+
+    def __repr__(self):
+        try:
+            value = self._semlock._get_value()
+        except Exception:
+            value = 'unknown'
+        return '<BoundedSemaphore(value=%s, maxvalue=%s)>' % \
+               (value, self._semlock.maxvalue)
+
+#
+# Non-recursive lock
+#
+
+class Lock(SemLock):
+
+    def __init__(self):
+        SemLock.__init__(self, SEMAPHORE, 1, 1)
+
+    def __repr__(self):
+        try:
+            if self._semlock._is_mine():
+                name = current_process().get_name()
+                if threading.currentThread().getName() != 'MainThread':
+                    name += '|' + threading.currentThread().getName()
+            elif self._semlock._get_value() == 1:
+                name = 'None'
+            elif self._semlock._count() > 0:
+                name = 'SomeOtherThread'
+            else:
+                name = 'SomeOtherProcess'
+        except Exception:
+            name = 'unknown'
+        return '<Lock(owner=%s)>' % name
+
+#
+# Recursive lock
+#
+
+class RLock(SemLock):
+
+    def __init__(self):
+        SemLock.__init__(self, RECURSIVE_MUTEX, 1, 1)
+
+    def __repr__(self):
+        try:
+            if self._semlock._is_mine():
+                name = current_process().get_name()
+                if threading.currentThread().getName() != 'MainThread':
+                    name += '|' + threading.currentThread().getName()
+                count = self._semlock._count()
+            elif self._semlock._get_value() == 1:
+                name, count = 'None', 0
+            elif self._semlock._count() > 0:
+                name, count = 'SomeOtherThread', 'nonzero'
+            else:
+                name, count = 'SomeOtherProcess', 'nonzero'
+        except Exception:
+            name, count = 'unknown', 'unknown'
+        return '<RLock(%s, %s)>' % (name, count)
+
+#
+# Condition variable
+#
+
+class Condition(object):
+
+    def __init__(self, lock=None):
+        self._lock = lock or RLock()
+        self._sleeping_count = Semaphore(0)
+        self._woken_count = Semaphore(0)
+        self._wait_semaphore = Semaphore(0)
+        self._make_methods()
+
+    def __getstate__(self):
+        assert_spawning(self)
+        return (self._lock, self._sleeping_count,
+                self._woken_count, self._wait_semaphore)
+
+    def __setstate__(self, state):
+        (self._lock, self._sleeping_count,
+         self._woken_count, self._wait_semaphore) = state
+        self._make_methods()
+
+    def _make_methods(self):
+        self.acquire = self._lock.acquire
+        self.release = self._lock.release
+        self.__enter__ = self._lock.__enter__
+        self.__exit__ = self._lock.__exit__
+
+    def __repr__(self):
+        try:
+            num_waiters = (self._sleeping_count._semlock._get_value() -
+                           self._woken_count._semlock._get_value())
+        except Exception:
+            num_waiters = 'unkown'
+        return '<Condition(%s, %s)>' % (self._lock, num_waiters)
+
+    def wait(self, timeout=None):
+        assert self._lock._semlock._is_mine(), \
+               'must acquire() condition before using wait()'
+
+        # indicate that this thread is going to sleep
+        self._sleeping_count.release()
+
+        # release lock
+        count = self._lock._semlock._count()
+        for i in range(count):
+            self._lock.release()
+
+        try:
+            # wait for notification or timeout
+            self._wait_semaphore.acquire(True, timeout)
+        finally:
+            # indicate that this thread has woken
+            self._woken_count.release()
+
+            # reacquire lock
+            for i in range(count):
+                self._lock.acquire()
+
+    def notify(self):
+        assert self._lock._semlock._is_mine(), 'lock is not owned'
+        assert not self._wait_semaphore.acquire(False)
+
+        # to take account of timeouts since last notify() we subtract
+        # woken_count from sleeping_count and rezero woken_count
+        while self._woken_count.acquire(False):
+            res = self._sleeping_count.acquire(False)
+            assert res
+
+        if self._sleeping_count.acquire(False): # try grabbing a sleeper
+            self._wait_semaphore.release()      # wake up one sleeper
+            self._woken_count.acquire()         # wait for the sleeper to wake
+
+            # rezero _wait_semaphore in case a timeout just happened
+            self._wait_semaphore.acquire(False)
+
+    def notify_all(self):
+        assert self._lock._semlock._is_mine(), 'lock is not owned'
+        assert not self._wait_semaphore.acquire(False)
+
+        # to take account of timeouts since last notify*() we subtract
+        # woken_count from sleeping_count and rezero woken_count
+        while self._woken_count.acquire(False):
+            res = self._sleeping_count.acquire(False)
+            assert res
+
+        sleepers = 0
+        while self._sleeping_count.acquire(False):
+            self._wait_semaphore.release()        # wake up one sleeper
+            sleepers += 1
+
+        if sleepers:
+            for i in range(sleepers):
+                self._woken_count.acquire()       # wait for a sleeper to wake
+
+            # rezero wait_semaphore in case some timeouts just happened
+            while self._wait_semaphore.acquire(False):
+                pass
+
+#
+# Event
+#
+
+class Event(object):
+
+    def __init__(self):
+        self._cond = Condition(Lock())
+        self._flag = Semaphore(0)
+
+    def is_set(self):
+        self._cond.acquire()
+        try:
+            if self._flag.acquire(False):
+                self._flag.release()
+                return True
+            return False
+        finally:
+            self._cond.release()
+
+    def set(self):
+        self._cond.acquire()
+        try:
+            self._flag.acquire(False)
+            self._flag.release()
+            self._cond.notify_all()
+        finally:
+            self._cond.release()
+
+    def clear(self):
+        self._cond.acquire()
+        try:
+            self._flag.acquire(False)
+        finally:
+            self._cond.release()
+
+    def wait(self, timeout=None):
+        self._cond.acquire()
+        try:
+            if self._flag.acquire(False):
+                self._flag.release()
+            else:
+                self._cond.wait(timeout)
+        finally:
+            self._cond.release()

Modified: python/branches/py3k/Lib/multiprocessing/util.py
==============================================================================
--- /python/trunk/Lib/multiprocessing/util.py	(original)
+++ python/branches/py3k/Lib/multiprocessing/util.py	Wed Jun 11 18:44:04 2008
@@ -1,336 +1,336 @@
-#
-# Module providing various facilities to other parts of the package
-#
-# multiprocessing/util.py
-#
-# Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
-#
-
-import itertools
-import weakref
-import copy_reg
-import atexit
-import threading        # we want threading to install it's
-                        # cleanup function before multiprocessing does
-
-from multiprocessing.process import current_process, active_children
-
-__all__ = [
-    'sub_debug', 'debug', 'info', 'sub_warning', 'get_logger',
-    'log_to_stderr', 'get_temp_dir', 'register_after_fork',
-    'is_exiting', 'Finalize', 'ForkAwareThreadLock', 'ForkAwareLocal'
-    ]
-
-#
-# Logging
-#
-
-NOTSET = 0
-SUBDEBUG = 5
-DEBUG = 10
-INFO = 20
-SUBWARNING = 25
-
-LOGGER_NAME = 'multiprocessing'
-DEFAULT_LOGGING_FORMAT = '[%(levelname)s/%(processName)s] %(message)s'
-
-_logger = None
-_log_to_stderr = False
-
-def sub_debug(msg, *args):
-    if _logger:
-        _logger.log(SUBDEBUG, msg, *args)
-
-def debug(msg, *args):
-    if _logger:
-        _logger.log(DEBUG, msg, *args)
-
-def info(msg, *args):
-    if _logger:
-        _logger.log(INFO, msg, *args)
-
-def sub_warning(msg, *args):
-    if _logger:
-        _logger.log(SUBWARNING, msg, *args)
-
-def get_logger():
-    '''
-    Returns logger used by multiprocessing
-    '''
-    global _logger
-
-    if not _logger:
-        import logging, atexit
-
-        # XXX multiprocessing should cleanup before logging
-        if hasattr(atexit, 'unregister'):
-            atexit.unregister(_exit_function)
-            atexit.register(_exit_function)
-        else:
-            atexit._exithandlers.remove((_exit_function, (), {}))
-            atexit._exithandlers.append((_exit_function, (), {}))
-
-        _check_logger_class()
-        _logger = logging.getLogger(LOGGER_NAME)
-
-    return _logger
-
-def _check_logger_class():
-    '''
-    Make sure process name is recorded when loggers are used
-    '''
-    # XXX This function is unnecessary once logging is patched
-    import logging
-    if hasattr(logging, 'multiprocessing'):
-        return
-    
-    logging._acquireLock()
-    try:
-        OldLoggerClass = logging.getLoggerClass()
-        if not getattr(OldLoggerClass, '_process_aware', False):
-            class ProcessAwareLogger(OldLoggerClass):
-                _process_aware = True
-                def makeRecord(self, *args, **kwds):
-                    record = OldLoggerClass.makeRecord(self, *args, **kwds)
-                    record.processName = current_process()._name
-                    return record
-            logging.setLoggerClass(ProcessAwareLogger)
-    finally:
-        logging._releaseLock()
-
-def log_to_stderr(level=None):
-    '''
-    Turn on logging and add a handler which prints to stderr
-    '''
-    global _log_to_stderr
-    import logging
-    logger = get_logger()
-    formatter = logging.Formatter(DEFAULT_LOGGING_FORMAT)
-    handler = logging.StreamHandler()
-    handler.setFormatter(formatter)
-    logger.addHandler(handler)
-    if level is not None:
-        logger.setLevel(level)
-    _log_to_stderr = True
-
-#
-# Function returning a temp directory which will be removed on exit
-#
-
-def get_temp_dir():
-    # get name of a temp directory which will be automatically cleaned up
-    if current_process()._tempdir is None:
-        import shutil, tempfile
-        tempdir = tempfile.mkdtemp(prefix='pymp-')
-        info('created temp directory %s', tempdir)
-        Finalize(None, shutil.rmtree, args=[tempdir], exitpriority=-100)
-        current_process()._tempdir = tempdir
-    return current_process()._tempdir
-
-#
-# Support for reinitialization of objects when bootstrapping a child process
-#
-
-_afterfork_registry = weakref.WeakValueDictionary()
-_afterfork_counter = itertools.count()
-
-def _run_after_forkers():
-    items = list(_afterfork_registry.items())
-    items.sort()
-    for (index, ident, func), obj in items:
-        try:
-            func(obj)
-        except Exception, e:
-            info('after forker raised exception %s', e)
-
-def register_after_fork(obj, func):
-    _afterfork_registry[(_afterfork_counter.next(), id(obj), func)] = obj
-
-#
-# Finalization using weakrefs
-#
-
-_finalizer_registry = {}
-_finalizer_counter = itertools.count()
-
-
-class Finalize(object):
-    '''
-    Class which supports object finalization using weakrefs
-    '''
-    def __init__(self, obj, callback, args=(), kwargs=None, exitpriority=None):
-        assert exitpriority is None or type(exitpriority) is int
-
-        if obj is not None:
-            self._weakref = weakref.ref(obj, self)
-        else:
-            assert exitpriority is not None
-
-        self._callback = callback
-        self._args = args
-        self._kwargs = kwargs or {}
-        self._key = (exitpriority, _finalizer_counter.next())
-
-        _finalizer_registry[self._key] = self
-
-    def __call__(self, wr=None):
-        '''
-        Run the callback unless it has already been called or cancelled
-        '''
-        try:
-            del _finalizer_registry[self._key]
-        except KeyError:
-            sub_debug('finalizer no longer registered')
-        else:
-            sub_debug('finalizer calling %s with args %s and kwargs %s',
-                     self._callback, self._args, self._kwargs)
-            res = self._callback(*self._args, **self._kwargs)
-            self._weakref = self._callback = self._args = \
-                            self._kwargs = self._key = None
-            return res
-
-    def cancel(self):
-        '''
-        Cancel finalization of the object
-        '''
-        try:
-            del _finalizer_registry[self._key]
-        except KeyError:
-            pass
-        else:
-            self._weakref = self._callback = self._args = \
-                            self._kwargs = self._key = None
-
-    def still_active(self):
-        '''
-        Return whether this finalizer is still waiting to invoke callback
-        '''
-        return self._key in _finalizer_registry
-
-    def __repr__(self):
-        try:
-            obj = self._weakref()
-        except (AttributeError, TypeError):
-            obj = None
-
-        if obj is None:
-            return '<Finalize object, dead>'
-
-        x = '<Finalize object, callback=%s' % \
-            getattr(self._callback, '__name__', self._callback)
-        if self._args:
-            x += ', args=' + str(self._args)
-        if self._kwargs:
-            x += ', kwargs=' + str(self._kwargs)
-        if self._key[0] is not None:
-            x += ', exitprority=' + str(self._key[0])
-        return x + '>'
-
-
-def _run_finalizers(minpriority=None):
-    '''
-    Run all finalizers whose exit priority is not None and at least minpriority
-
-    Finalizers with highest priority are called first; finalizers with
-    the same priority will be called in reverse order of creation.
-    '''
-    if minpriority is None:
-        f = lambda p : p[0][0] is not None
-    else:
-        f = lambda p : p[0][0] is not None and p[0][0] >= minpriority
-
-    items = [x for x in _finalizer_registry.items() if f(x)]
-    items.sort(reverse=True)
-
-    for key, finalizer in items:
-        sub_debug('calling %s', finalizer)
-        try:
-            finalizer()
-        except Exception:
-            import traceback
-            traceback.print_exc()
-
-    if minpriority is None:
-        _finalizer_registry.clear()
-
-#
-# Clean up on exit
-#
-
-def is_exiting():
-    '''
-    Returns true if the process is shutting down
-    '''
-    return _exiting or _exiting is None
-
-_exiting = False
-
-def _exit_function():
-    global _exiting
-
-    info('process shutting down')
-    debug('running all "atexit" finalizers with priority >= 0')
-    _run_finalizers(0)
-
-    for p in active_children():
-        if p._daemonic:
-            info('calling terminate() for daemon %s', p.get_name())
-            p._popen.terminate()
-
-    for p in active_children():
-        info('calling join() for process %s', p.get_name())
-        p.join()
-
-    debug('running the remaining "atexit" finalizers')
-    _run_finalizers()
-
-atexit.register(_exit_function)
-
-#
-# Some fork aware types
-#
-
-class ForkAwareThreadLock(object):
-    def __init__(self):
-        self._lock = threading.Lock()
-        self.acquire = self._lock.acquire
-        self.release = self._lock.release
-        register_after_fork(self, ForkAwareThreadLock.__init__)
-
-class ForkAwareLocal(threading.local):
-    def __init__(self):
-        register_after_fork(self, lambda obj : obj.__dict__.clear())
-    def __reduce__(self):
-        return type(self), ()
-
-#
-# Try making some callable types picklable
-#
-
-def _reduce_method(m):
-    if m.im_self is None:
-        return getattr, (m.im_class, m.im_func.func_name)
-    else:
-        return getattr, (m.im_self, m.im_func.func_name)
-copy_reg.pickle(type(Finalize.__init__), _reduce_method)
-
-def _reduce_method_descriptor(m):
-    return getattr, (m.__objclass__, m.__name__)
-copy_reg.pickle(type(list.append), _reduce_method_descriptor)
-copy_reg.pickle(type(int.__add__), _reduce_method_descriptor)
-
-def _reduce_builtin_function_or_method(m):
-    return getattr, (m.__self__, m.__name__)
-copy_reg.pickle(type(list().append), _reduce_builtin_function_or_method)
-copy_reg.pickle(type(int().__add__), _reduce_builtin_function_or_method)
-
-try:
-    from functools import partial
-except ImportError:
-    pass
-else:
-    def _reduce_partial(p):
-        return _rebuild_partial, (p.func, p.args, p.keywords or {})
-    def _rebuild_partial(func, args, keywords):
-        return partial(func, *args, **keywords)
-    copy_reg.pickle(partial, _reduce_partial)
+#
+# Module providing various facilities to other parts of the package
+#
+# multiprocessing/util.py
+#
+# Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
+#
+
+import itertools
+import weakref
+import copyreg
+import atexit
+import threading        # we want threading to install it's
+                        # cleanup function before multiprocessing does
+
+from multiprocessing.process import current_process, active_children
+
+__all__ = [
+    'sub_debug', 'debug', 'info', 'sub_warning', 'get_logger',
+    'log_to_stderr', 'get_temp_dir', 'register_after_fork',
+    'is_exiting', 'Finalize', 'ForkAwareThreadLock', 'ForkAwareLocal'
+    ]
+
+#
+# Logging
+#
+
+NOTSET = 0
+SUBDEBUG = 5
+DEBUG = 10
+INFO = 20
+SUBWARNING = 25
+
+LOGGER_NAME = 'multiprocessing'
+DEFAULT_LOGGING_FORMAT = '[%(levelname)s/%(processName)s] %(message)s'
+
+_logger = None
+_log_to_stderr = False
+
+def sub_debug(msg, *args):
+    if _logger:
+        _logger.log(SUBDEBUG, msg, *args)
+
+def debug(msg, *args):
+    if _logger:
+        _logger.log(DEBUG, msg, *args)
+
+def info(msg, *args):
+    if _logger:
+        _logger.log(INFO, msg, *args)
+
+def sub_warning(msg, *args):
+    if _logger:
+        _logger.log(SUBWARNING, msg, *args)
+
+def get_logger():
+    '''
+    Returns logger used by multiprocessing
+    '''
+    global _logger
+
+    if not _logger:
+        import logging, atexit
+
+        # XXX multiprocessing should cleanup before logging
+        if hasattr(atexit, 'unregister'):
+            atexit.unregister(_exit_function)
+            atexit.register(_exit_function)
+        else:
+            atexit._exithandlers.remove((_exit_function, (), {}))
+            atexit._exithandlers.append((_exit_function, (), {}))
+
+        _check_logger_class()
+        _logger = logging.getLogger(LOGGER_NAME)
+
+    return _logger
+
+def _check_logger_class():
+    '''
+    Make sure process name is recorded when loggers are used
+    '''
+    # XXX This function is unnecessary once logging is patched
+    import logging
+    if hasattr(logging, 'multiprocessing'):
+        return
+
+    logging._acquireLock()
+    try:
+        OldLoggerClass = logging.getLoggerClass()
+        if not getattr(OldLoggerClass, '_process_aware', False):
+            class ProcessAwareLogger(OldLoggerClass):
+                _process_aware = True
+                def makeRecord(self, *args, **kwds):
+                    record = OldLoggerClass.makeRecord(self, *args, **kwds)
+                    record.processName = current_process()._name
+                    return record
+            logging.setLoggerClass(ProcessAwareLogger)
+    finally:
+        logging._releaseLock()
+
+def log_to_stderr(level=None):
+    '''
+    Turn on logging and add a handler which prints to stderr
+    '''
+    global _log_to_stderr
+    import logging
+    logger = get_logger()
+    formatter = logging.Formatter(DEFAULT_LOGGING_FORMAT)
+    handler = logging.StreamHandler()
+    handler.setFormatter(formatter)
+    logger.addHandler(handler)
+    if level is not None:
+        logger.setLevel(level)
+    _log_to_stderr = True
+
+#
+# Function returning a temp directory which will be removed on exit
+#
+
+def get_temp_dir():
+    # get name of a temp directory which will be automatically cleaned up
+    if current_process()._tempdir is None:
+        import shutil, tempfile
+        tempdir = tempfile.mkdtemp(prefix='pymp-')
+        info('created temp directory %s', tempdir)
+        Finalize(None, shutil.rmtree, args=[tempdir], exitpriority=-100)
+        current_process()._tempdir = tempdir
+    return current_process()._tempdir
+
+#
+# Support for reinitialization of objects when bootstrapping a child process
+#
+
+_afterfork_registry = weakref.WeakValueDictionary()
+_afterfork_counter = itertools.count()
+
+def _run_after_forkers():
+    items = list(_afterfork_registry.items())
+    items.sort()
+    for (index, ident, func), obj in items:
+        try:
+            func(obj)
+        except Exception as e:
+            info('after forker raised exception %s', e)
+
+def register_after_fork(obj, func):
+    _afterfork_registry[(next(_afterfork_counter), id(obj), func)] = obj
+
+#
+# Finalization using weakrefs
+#
+
+_finalizer_registry = {}
+_finalizer_counter = itertools.count()
+
+
+class Finalize(object):
+    '''
+    Class which supports object finalization using weakrefs
+    '''
+    def __init__(self, obj, callback, args=(), kwargs=None, exitpriority=None):
+        assert exitpriority is None or type(exitpriority) is int
+
+        if obj is not None:
+            self._weakref = weakref.ref(obj, self)
+        else:
+            assert exitpriority is not None
+
+        self._callback = callback
+        self._args = args
+        self._kwargs = kwargs or {}
+        self._key = (exitpriority, next(_finalizer_counter))
+
+        _finalizer_registry[self._key] = self
+
+    def __call__(self, wr=None):
+        '''
+        Run the callback unless it has already been called or cancelled
+        '''
+        try:
+            del _finalizer_registry[self._key]
+        except KeyError:
+            sub_debug('finalizer no longer registered')
+        else:
+            sub_debug('finalizer calling %s with args %s and kwargs %s',
+                     self._callback, self._args, self._kwargs)
+            res = self._callback(*self._args, **self._kwargs)
+            self._weakref = self._callback = self._args = \
+                            self._kwargs = self._key = None
+            return res
+
+    def cancel(self):
+        '''
+        Cancel finalization of the object
+        '''
+        try:
+            del _finalizer_registry[self._key]
+        except KeyError:
+            pass
+        else:
+            self._weakref = self._callback = self._args = \
+                            self._kwargs = self._key = None
+
+    def still_active(self):
+        '''
+        Return whether this finalizer is still waiting to invoke callback
+        '''
+        return self._key in _finalizer_registry
+
+    def __repr__(self):
+        try:
+            obj = self._weakref()
+        except (AttributeError, TypeError):
+            obj = None
+
+        if obj is None:
+            return '<Finalize object, dead>'
+
+        x = '<Finalize object, callback=%s' % \
+            getattr(self._callback, '__name__', self._callback)
+        if self._args:
+            x += ', args=' + str(self._args)
+        if self._kwargs:
+            x += ', kwargs=' + str(self._kwargs)
+        if self._key[0] is not None:
+            x += ', exitprority=' + str(self._key[0])
+        return x + '>'
+
+
+def _run_finalizers(minpriority=None):
+    '''
+    Run all finalizers whose exit priority is not None and at least minpriority
+
+    Finalizers with highest priority are called first; finalizers with
+    the same priority will be called in reverse order of creation.
+    '''
+    if minpriority is None:
+        f = lambda p : p[0][0] is not None
+    else:
+        f = lambda p : p[0][0] is not None and p[0][0] >= minpriority
+
+    items = [x for x in list(_finalizer_registry.items()) if f(x)]
+    items.sort(reverse=True)
+
+    for key, finalizer in items:
+        sub_debug('calling %s', finalizer)
+        try:
+            finalizer()
+        except Exception:
+            import traceback
+            traceback.print_exc()
+
+    if minpriority is None:
+        _finalizer_registry.clear()
+
+#
+# Clean up on exit
+#
+
+def is_exiting():
+    '''
+    Returns true if the process is shutting down
+    '''
+    return _exiting or _exiting is None
+
+_exiting = False
+
+def _exit_function():
+    global _exiting
+
+    info('process shutting down')
+    debug('running all "atexit" finalizers with priority >= 0')
+    _run_finalizers(0)
+
+    for p in active_children():
+        if p._daemonic:
+            info('calling terminate() for daemon %s', p.get_name())
+            p._popen.terminate()
+
+    for p in active_children():
+        info('calling join() for process %s', p.get_name())
+        p.join()
+
+    debug('running the remaining "atexit" finalizers')
+    _run_finalizers()
+
+atexit.register(_exit_function)
+
+#
+# Some fork aware types
+#
+
+class ForkAwareThreadLock(object):
+    def __init__(self):
+        self._lock = threading.Lock()
+        self.acquire = self._lock.acquire
+        self.release = self._lock.release
+        register_after_fork(self, ForkAwareThreadLock.__init__)
+
+class ForkAwareLocal(threading.local):
+    def __init__(self):
+        register_after_fork(self, lambda obj : obj.__dict__.clear())
+    def __reduce__(self):
+        return type(self), ()
+
+#
+# Try making some callable types picklable
+#
+
+def _reduce_method(m):
+    if m.__self__ is None:
+        return getattr, (m.__self__.__class__, m.__func__.__name__)
+    else:
+        return getattr, (m.__self__, m.__func__.__name__)
+copyreg.pickle(type(Finalize.__init__), _reduce_method)
+
+def _reduce_method_descriptor(m):
+    return getattr, (m.__objclass__, m.__name__)
+copyreg.pickle(type(list.append), _reduce_method_descriptor)
+copyreg.pickle(type(int.__add__), _reduce_method_descriptor)
+
+def _reduce_builtin_function_or_method(m):
+    return getattr, (m.__self__, m.__name__)
+copyreg.pickle(type(list().append), _reduce_builtin_function_or_method)
+copyreg.pickle(type(int().__add__), _reduce_builtin_function_or_method)
+
+try:
+    from functools import partial
+except ImportError:
+    pass
+else:
+    def _reduce_partial(p):
+        return _rebuild_partial, (p.func, p.args, p.keywords or {})
+    def _rebuild_partial(func, args, keywords):
+        return partial(func, *args, **keywords)
+    copyreg.pickle(partial, _reduce_partial)

Copied: python/branches/py3k/Lib/test/test_multiprocessing.py (from r64104, /python/trunk/Lib/test/test_multiprocessing.py)
==============================================================================
--- /python/trunk/Lib/test/test_multiprocessing.py	(original)
+++ python/branches/py3k/Lib/test/test_multiprocessing.py	Wed Jun 11 18:44:04 2008
@@ -1,1791 +1,1791 @@
-#
-# Unit tests for the multiprocessing package
-#
-
-import unittest
-import threading
-import Queue
-import time
-import sys
-import os
-import gc
-import signal
-import array
-import copy
-import socket
-import random
-import logging
-
-import _multiprocessing
-import multiprocessing.dummy
-import multiprocessing.connection
-import multiprocessing.managers
-import multiprocessing.heap
-import multiprocessing.managers
-import multiprocessing.pool
-
-from multiprocessing import util
-
-#
-#
-#
-
-if sys.version_info >= (3, 0):
-    def latin(s):
-        return s.encode('latin')
-else:
-    latin = str
-
-try:
-    bytes
-except NameError:
-    bytes = str
-    def bytearray(seq):
-        return array.array('c', seq)
-
-#
-# Constants
-#
-
-LOG_LEVEL = util.SUBWARNING
-#LOG_LEVEL = logging.WARNING
-
-DELTA = 0.1
-CHECK_TIMINGS = False     # making true makes tests take a lot longer
-                          # and can sometimes cause some non-serious
-                          # failures because some calls block a bit
-                          # longer than expected
-if CHECK_TIMINGS:
-    TIMEOUT1, TIMEOUT2, TIMEOUT3 = 0.82, 0.35, 1.4
-else:
-    TIMEOUT1, TIMEOUT2, TIMEOUT3 = 0.1, 0.1, 0.1
-
-HAVE_GETVALUE = not getattr(_multiprocessing,
-                            'HAVE_BROKEN_SEM_GETVALUE', False)
-
-#
-# Creates a wrapper for a function which records the time it takes to finish
-#
-
-class TimingWrapper(object):
-
-    def __init__(self, func):
-        self.func = func
-        self.elapsed = None
-
-    def __call__(self, *args, **kwds):
-        t = time.time()
-        try:
-            return self.func(*args, **kwds)
-        finally:
-            self.elapsed = time.time() - t
-        
-#
-# Base class for test cases
-#
-
-class BaseTestCase(object):
-    
-    ALLOWED_TYPES = ('processes', 'manager', 'threads')
-
-    def assertTimingAlmostEqual(self, a, b):
-        if CHECK_TIMINGS:
-            self.assertAlmostEqual(a, b, 1)
-
-    def assertReturnsIfImplemented(self, value, func, *args):
-        try:
-            res = func(*args)
-        except NotImplementedError:
-            pass
-        else:
-            return self.assertEqual(value, res)
-
-#
-# Return the value of a semaphore
-#
-
-def get_value(self):
-    try:
-        return self.get_value()
-    except AttributeError:
-        try:
-            return self._Semaphore__value
-        except AttributeError:
-            try:
-                return self._value
-            except AttributeError:
-                raise NotImplementedError
-
-#
-# Testcases
-#
-
-class _TestProcess(BaseTestCase):
-    
-    ALLOWED_TYPES = ('processes', 'threads')
-    
-    def test_current(self):
-        if self.TYPE == 'threads':
-            return
-
-        current = self.current_process()
-        authkey = current.get_authkey()
-        
-        self.assertTrue(current.is_alive())
-        self.assertTrue(not current.is_daemon())        
-        self.assertTrue(isinstance(authkey, bytes))
-        self.assertTrue(len(authkey) > 0)
-        self.assertEqual(current.get_ident(), os.getpid())
-        self.assertEqual(current.get_exitcode(), None)
-
-    def _test(self, q, *args, **kwds):
-        current = self.current_process()
-        q.put(args)
-        q.put(kwds)
-        q.put(current.get_name())
-        if self.TYPE != 'threads':
-            q.put(bytes(current.get_authkey()))
-            q.put(current.pid)
-
-    def test_process(self):
-        q = self.Queue(1)
-        e = self.Event()
-        args = (q, 1, 2)
-        kwargs = {'hello':23, 'bye':2.54}
-        name = 'SomeProcess'
-        p = self.Process(
-            target=self._test, args=args, kwargs=kwargs, name=name
-            )
-        p.set_daemon(True)
-        current = self.current_process()
-
-        if self.TYPE != 'threads':
-            self.assertEquals(p.get_authkey(), current.get_authkey())
-        self.assertEquals(p.is_alive(), False)
-        self.assertEquals(p.is_daemon(), True)
-        self.assertTrue(p not in self.active_children())
-        self.assertTrue(type(self.active_children()) is list)
-        self.assertEqual(p.get_exitcode(), None)
-        
-        p.start()
-        
-        self.assertEquals(p.get_exitcode(), None)
-        self.assertEquals(p.is_alive(), True)
-        self.assertTrue(p in self.active_children())
-        
-        self.assertEquals(q.get(), args[1:])
-        self.assertEquals(q.get(), kwargs)
-        self.assertEquals(q.get(), p.get_name())
-        if self.TYPE != 'threads':
-            self.assertEquals(q.get(), current.get_authkey())
-            self.assertEquals(q.get(), p.pid)
-
-        p.join()
-
-        self.assertEquals(p.get_exitcode(), 0)
-        self.assertEquals(p.is_alive(), False)
-        self.assertTrue(p not in self.active_children())        
-
-    def _test_terminate(self):
-        time.sleep(1000)
-
-    def test_terminate(self):
-        if self.TYPE == 'threads':
-            return
-        
-        p = self.Process(target=self._test_terminate)
-        p.set_daemon(True)
-        p.start()
-
-        self.assertEqual(p.is_alive(), True)
-        self.assertTrue(p in self.active_children())
-        self.assertEqual(p.get_exitcode(), None)
-
-        p.terminate()
-
-        join = TimingWrapper(p.join)
-        self.assertEqual(join(), None)
-        self.assertTimingAlmostEqual(join.elapsed, 0.0)
-        
-        self.assertEqual(p.is_alive(), False)
-        self.assertTrue(p not in self.active_children())
-
-        p.join()
-
-        # XXX sometimes get p.get_exitcode() == 0 on Windows ...
-        #self.assertEqual(p.get_exitcode(), -signal.SIGTERM)
-
-    def test_cpu_count(self):
-        try:
-            cpus = multiprocessing.cpu_count()
-        except NotImplementedError:
-            cpus = 1
-        self.assertTrue(type(cpus) is int)
-        self.assertTrue(cpus >= 1)
-
-    def test_active_children(self):
-        self.assertEqual(type(self.active_children()), list)
-
-        p = self.Process(target=time.sleep, args=(DELTA,))
-        self.assertTrue(p not in self.active_children())
-        
-        p.start()
-        self.assertTrue(p in self.active_children())
-
-        p.join()
-        self.assertTrue(p not in self.active_children())
-
-    def _test_recursion(self, wconn, id):
-        from multiprocessing import forking
-        wconn.send(id)
-        if len(id) < 2:
-            for i in range(2):
-                p = self.Process(
-                    target=self._test_recursion, args=(wconn, id+[i])
-                    )
-                p.start()
-                p.join()
-
-    def test_recursion(self):
-        rconn, wconn = self.Pipe(duplex=False)
-        self._test_recursion(wconn, [])
-        
-        time.sleep(DELTA)
-        result = []
-        while rconn.poll():
-            result.append(rconn.recv())
-            
-        expected = [
-            [],
-              [0],
-                [0, 0],
-                [0, 1],
-              [1],
-                [1, 0],
-                [1, 1]
-            ]
-        self.assertEqual(result, expected)
-
-#
-#
-#
-
-class _UpperCaser(multiprocessing.Process):
-
-    def __init__(self):
-        multiprocessing.Process.__init__(self)
-        self.child_conn, self.parent_conn = multiprocessing.Pipe()
-
-    def run(self):
-        self.parent_conn.close()
-        for s in iter(self.child_conn.recv, None):
-            self.child_conn.send(s.upper())
-        self.child_conn.close()
-
-    def submit(self, s):
-        assert type(s) is str
-        self.parent_conn.send(s)
-        return self.parent_conn.recv()
-
-    def stop(self):
-        self.parent_conn.send(None)
-        self.parent_conn.close()
-        self.child_conn.close()
-
-class _TestSubclassingProcess(BaseTestCase):
-
-    ALLOWED_TYPES = ('processes',)
-
-    def test_subclassing(self):
-        uppercaser = _UpperCaser()
-        uppercaser.start()
-        self.assertEqual(uppercaser.submit('hello'), 'HELLO')
-        self.assertEqual(uppercaser.submit('world'), 'WORLD')
-        uppercaser.stop()
-        uppercaser.join()
-        
-#
-#
-#
-
-def queue_empty(q):
-    if hasattr(q, 'empty'):
-        return q.empty()
-    else:
-        return q.qsize() == 0
-
-def queue_full(q, maxsize):
-    if hasattr(q, 'full'):
-        return q.full()
-    else:
-        return q.qsize() == maxsize
-
-
-class _TestQueue(BaseTestCase):
-
-
-    def _test_put(self, queue, child_can_start, parent_can_continue):
-        child_can_start.wait()
-        for i in range(6):
-            queue.get()
-        parent_can_continue.set()
-
-    def test_put(self):
-        MAXSIZE = 6
-        queue = self.Queue(maxsize=MAXSIZE)
-        child_can_start = self.Event()
-        parent_can_continue = self.Event()
-
-        proc = self.Process(
-            target=self._test_put,
-            args=(queue, child_can_start, parent_can_continue)
-            )
-        proc.set_daemon(True)
-        proc.start()
-        
-        self.assertEqual(queue_empty(queue), True)
-        self.assertEqual(queue_full(queue, MAXSIZE), False)
-
-        queue.put(1)
-        queue.put(2, True)
-        queue.put(3, True, None)
-        queue.put(4, False)
-        queue.put(5, False, None)
-        queue.put_nowait(6)
-
-        # the values may be in buffer but not yet in pipe so sleep a bit
-        time.sleep(DELTA)     
-
-        self.assertEqual(queue_empty(queue), False)
-        self.assertEqual(queue_full(queue, MAXSIZE), True)
-
-        put = TimingWrapper(queue.put)
-        put_nowait = TimingWrapper(queue.put_nowait)
-
-        self.assertRaises(Queue.Full, put, 7, False)
-        self.assertTimingAlmostEqual(put.elapsed, 0)
-
-        self.assertRaises(Queue.Full, put, 7, False, None)
-        self.assertTimingAlmostEqual(put.elapsed, 0)
-
-        self.assertRaises(Queue.Full, put_nowait, 7)
-        self.assertTimingAlmostEqual(put_nowait.elapsed, 0)
-
-        self.assertRaises(Queue.Full, put, 7, True, TIMEOUT1)
-        self.assertTimingAlmostEqual(put.elapsed, TIMEOUT1)
-
-        self.assertRaises(Queue.Full, put, 7, False, TIMEOUT2)
-        self.assertTimingAlmostEqual(put.elapsed, 0)
-
-        self.assertRaises(Queue.Full, put, 7, True, timeout=TIMEOUT3)
-        self.assertTimingAlmostEqual(put.elapsed, TIMEOUT3)
-
-        child_can_start.set()
-        parent_can_continue.wait()
-
-        self.assertEqual(queue_empty(queue), True)
-        self.assertEqual(queue_full(queue, MAXSIZE), False)
-
-        proc.join()
-
-    def _test_get(self, queue, child_can_start, parent_can_continue):
-        child_can_start.wait()
-        queue.put(1)
-        queue.put(2)
-        queue.put(3)
-        queue.put(4)
-        queue.put(5)
-        parent_can_continue.set()
-        
-    def test_get(self):
-        queue = self.Queue()
-        child_can_start = self.Event()
-        parent_can_continue = self.Event()
-        
-        proc = self.Process(
-            target=self._test_get,
-            args=(queue, child_can_start, parent_can_continue)
-            )
-        proc.set_daemon(True)
-        proc.start()
-        
-        self.assertEqual(queue_empty(queue), True)
-        
-        child_can_start.set()
-        parent_can_continue.wait()
-
-        time.sleep(DELTA)
-        self.assertEqual(queue_empty(queue), False)
-
-        self.assertEqual(queue.get(), 1)
-        self.assertEqual(queue.get(True, None), 2)
-        self.assertEqual(queue.get(True), 3)
-        self.assertEqual(queue.get(timeout=1), 4)
-        self.assertEqual(queue.get_nowait(), 5)
-        
-        self.assertEqual(queue_empty(queue), True)
-
-        get = TimingWrapper(queue.get)
-        get_nowait = TimingWrapper(queue.get_nowait)
-        
-        self.assertRaises(Queue.Empty, get, False)
-        self.assertTimingAlmostEqual(get.elapsed, 0)
-
-        self.assertRaises(Queue.Empty, get, False, None)
-        self.assertTimingAlmostEqual(get.elapsed, 0)
-
-        self.assertRaises(Queue.Empty, get_nowait)
-        self.assertTimingAlmostEqual(get_nowait.elapsed, 0)
-
-        self.assertRaises(Queue.Empty, get, True, TIMEOUT1)
-        self.assertTimingAlmostEqual(get.elapsed, TIMEOUT1)
-
-        self.assertRaises(Queue.Empty, get, False, TIMEOUT2)
-        self.assertTimingAlmostEqual(get.elapsed, 0)
-
-        self.assertRaises(Queue.Empty, get, timeout=TIMEOUT3)
-        self.assertTimingAlmostEqual(get.elapsed, TIMEOUT3)
-
-        proc.join()
-        
-    def _test_fork(self, queue):
-        for i in range(10, 20):
-            queue.put(i)
-        # note that at this point the items may only be buffered, so the
-        # process cannot shutdown until the feeder thread has finished
-        # pushing items onto the pipe.
-
-    def test_fork(self):
-        # Old versions of Queue would fail to create a new feeder
-        # thread for a forked process if the original process had its
-        # own feeder thread.  This test checks that this no longer
-        # happens.
-
-        queue = self.Queue()
-
-        # put items on queue so that main process starts a feeder thread
-        for i in range(10):
-            queue.put(i)
-
-        # wait to make sure thread starts before we fork a new process
-        time.sleep(DELTA)
-
-        # fork process
-        p = self.Process(target=self._test_fork, args=(queue,))
-        p.start()
-
-        # check that all expected items are in the queue
-        for i in range(20):
-            self.assertEqual(queue.get(), i)
-        self.assertRaises(Queue.Empty, queue.get, False)
-
-        p.join()
-
-    def test_qsize(self):
-        q = self.Queue()
-        try:
-            self.assertEqual(q.qsize(), 0)
-        except NotImplementedError:
-            return
-        q.put(1)
-        self.assertEqual(q.qsize(), 1)
-        q.put(5)
-        self.assertEqual(q.qsize(), 2)
-        q.get()
-        self.assertEqual(q.qsize(), 1)
-        q.get()
-        self.assertEqual(q.qsize(), 0)
-
-    def _test_task_done(self, q):
-        for obj in iter(q.get, None):
-            time.sleep(DELTA)
-            q.task_done()
-
-    def test_task_done(self):
-        queue = self.JoinableQueue()
-
-        if sys.version_info < (2, 5) and not hasattr(queue, 'task_done'):
-            return
-
-        workers = [self.Process(target=self._test_task_done, args=(queue,))
-                   for i in xrange(4)]
-        
-        for p in workers:
-            p.start()
-
-        for i in xrange(10):
-            queue.put(i)
-
-        queue.join()
-
-        for p in workers:
-            queue.put(None)
-        
-        for p in workers:
-            p.join()
-
-#
-#
-#
-
-class _TestLock(BaseTestCase):
-
-    def test_lock(self):
-        lock = self.Lock()
-        self.assertEqual(lock.acquire(), True)
-        self.assertEqual(lock.acquire(False), False)
-        self.assertEqual(lock.release(), None)
-        self.assertRaises((ValueError, threading.ThreadError), lock.release)
-
-    def test_rlock(self):
-        lock = self.RLock()
-        self.assertEqual(lock.acquire(), True)
-        self.assertEqual(lock.acquire(), True)
-        self.assertEqual(lock.acquire(), True)
-        self.assertEqual(lock.release(), None)
-        self.assertEqual(lock.release(), None)
-        self.assertEqual(lock.release(), None)
-        self.assertRaises((AssertionError, RuntimeError), lock.release)
-        
-        
-class _TestSemaphore(BaseTestCase):
-
-    def _test_semaphore(self, sem):
-        self.assertReturnsIfImplemented(2, get_value, sem)
-        self.assertEqual(sem.acquire(), True)
-        self.assertReturnsIfImplemented(1, get_value, sem)
-        self.assertEqual(sem.acquire(), True)
-        self.assertReturnsIfImplemented(0, get_value, sem)
-        self.assertEqual(sem.acquire(False), False)
-        self.assertReturnsIfImplemented(0, get_value, sem)
-        self.assertEqual(sem.release(), None)
-        self.assertReturnsIfImplemented(1, get_value, sem)
-        self.assertEqual(sem.release(), None)
-        self.assertReturnsIfImplemented(2, get_value, sem)
-        
-    def test_semaphore(self):
-        sem = self.Semaphore(2)
-        self._test_semaphore(sem)
-        self.assertEqual(sem.release(), None)
-        self.assertReturnsIfImplemented(3, get_value, sem)
-        self.assertEqual(sem.release(), None)
-        self.assertReturnsIfImplemented(4, get_value, sem)
-
-    def test_bounded_semaphore(self):
-        sem = self.BoundedSemaphore(2)
-        self._test_semaphore(sem)
-        # Currently fails on OS/X
-        #if HAVE_GETVALUE:
-        #    self.assertRaises(ValueError, sem.release)
-        #    self.assertReturnsIfImplemented(2, get_value, sem)
-
-    def test_timeout(self):
-        if self.TYPE != 'processes':
-            return
-
-        sem = self.Semaphore(0)
-        acquire = TimingWrapper(sem.acquire)
-
-        self.assertEqual(acquire(False), False)
-        self.assertTimingAlmostEqual(acquire.elapsed, 0.0)
-
-        self.assertEqual(acquire(False, None), False)
-        self.assertTimingAlmostEqual(acquire.elapsed, 0.0)
-
-        self.assertEqual(acquire(False, TIMEOUT1), False)
-        self.assertTimingAlmostEqual(acquire.elapsed, 0)
-
-        self.assertEqual(acquire(True, TIMEOUT2), False)
-        self.assertTimingAlmostEqual(acquire.elapsed, TIMEOUT2)
-
-        self.assertEqual(acquire(timeout=TIMEOUT3), False)
-        self.assertTimingAlmostEqual(acquire.elapsed, TIMEOUT3)
-
-
-class _TestCondition(BaseTestCase):
-    
-    def f(self, cond, sleeping, woken, timeout=None):
-        cond.acquire()
-        sleeping.release()
-        cond.wait(timeout)
-        woken.release()
-        cond.release()
-    
-    def check_invariant(self, cond):
-        # this is only supposed to succeed when there are no sleepers
-        if self.TYPE == 'processes':
-            try:
-                sleepers = (cond._sleeping_count.get_value() -
-                            cond._woken_count.get_value())
-                self.assertEqual(sleepers, 0)
-                self.assertEqual(cond._wait_semaphore.get_value(), 0)
-            except NotImplementedError:
-                pass
-            
-    def test_notify(self):
-        cond = self.Condition()
-        sleeping = self.Semaphore(0)
-        woken = self.Semaphore(0)
-        
-        p = self.Process(target=self.f, args=(cond, sleeping, woken))
-        p.set_daemon(True)
-        p.start()
-
-        p = threading.Thread(target=self.f, args=(cond, sleeping, woken))
-        p.setDaemon(True)
-        p.start()
-        
-        # wait for both children to start sleeping
-        sleeping.acquire()
-        sleeping.acquire()
-        
-        # check no process/thread has woken up
-        time.sleep(DELTA)
-        self.assertReturnsIfImplemented(0, get_value, woken)
-
-        # wake up one process/thread
-        cond.acquire()
-        cond.notify()
-        cond.release()
-        
-        # check one process/thread has woken up
-        time.sleep(DELTA)
-        self.assertReturnsIfImplemented(1, get_value, woken)
-
-        # wake up another
-        cond.acquire()
-        cond.notify()
-        cond.release()
-        
-        # check other has woken up
-        time.sleep(DELTA)
-        self.assertReturnsIfImplemented(2, get_value, woken)
-        
-        # check state is not mucked up
-        self.check_invariant(cond)
-        p.join()
-        
-    def test_notify_all(self):
-        cond = self.Condition()
-        sleeping = self.Semaphore(0)
-        woken = self.Semaphore(0)
-
-        # start some threads/processes which will timeout
-        for i in range(3):
-            p = self.Process(target=self.f,
-                             args=(cond, sleeping, woken, TIMEOUT1))
-            p.set_daemon(True)
-            p.start()
-
-            t = threading.Thread(target=self.f,
-                                 args=(cond, sleeping, woken, TIMEOUT1))
-            t.setDaemon(True)
-            t.start()
-
-        # wait for them all to sleep
-        for i in xrange(6):
-            sleeping.acquire()
-
-        # check they have all timed out
-        for i in xrange(6):
-            woken.acquire()
-        self.assertReturnsIfImplemented(0, get_value, woken)
-
-        # check state is not mucked up
-        self.check_invariant(cond)
-
-        # start some more threads/processes
-        for i in range(3):
-            p = self.Process(target=self.f, args=(cond, sleeping, woken))
-            p.set_daemon(True)
-            p.start()
-            
-            t = threading.Thread(target=self.f, args=(cond, sleeping, woken))
-            t.setDaemon(True)
-            t.start()
-            
-        # wait for them to all sleep
-        for i in xrange(6):
-            sleeping.acquire()
-            
-        # check no process/thread has woken up
-        time.sleep(DELTA)
-        self.assertReturnsIfImplemented(0, get_value, woken)
-
-        # wake them all up
-        cond.acquire()
-        cond.notify_all()
-        cond.release()
-
-        # check they have all woken
-        time.sleep(DELTA)
-        self.assertReturnsIfImplemented(6, get_value, woken)
-
-        # check state is not mucked up
-        self.check_invariant(cond)
-
-    def test_timeout(self):
-        cond = self.Condition()
-        wait = TimingWrapper(cond.wait)
-        cond.acquire()
-        res = wait(TIMEOUT1)
-        cond.release()
-        self.assertEqual(res, None)
-        self.assertTimingAlmostEqual(wait.elapsed, TIMEOUT1)
-
-        
-class _TestEvent(BaseTestCase):
-
-    def _test_event(self, event):
-        time.sleep(TIMEOUT2)
-        event.set()
-
-    def test_event(self):
-        event = self.Event()
-        wait = TimingWrapper(event.wait)
-        
-        # Removed temporaily, due to API shear, this does not 
-        # work with threading._Event objects. is_set == isSet
-        #self.assertEqual(event.is_set(), False)
-        
-        self.assertEqual(wait(0.0), None)
-        self.assertTimingAlmostEqual(wait.elapsed, 0.0)
-        self.assertEqual(wait(TIMEOUT1), None)
-        self.assertTimingAlmostEqual(wait.elapsed, TIMEOUT1)
-
-        event.set()
-
-        # See note above on the API differences
-        # self.assertEqual(event.is_set(), True)
-        self.assertEqual(wait(), None)
-        self.assertTimingAlmostEqual(wait.elapsed, 0.0)
-        self.assertEqual(wait(TIMEOUT1), None)
-        self.assertTimingAlmostEqual(wait.elapsed, 0.0)
-        # self.assertEqual(event.is_set(), True)
-
-        event.clear()
-
-        #self.assertEqual(event.is_set(), False)
-
-        self.Process(target=self._test_event, args=(event,)).start()
-        self.assertEqual(wait(), None)
-
-#
-#
-#
-
-class _TestValue(BaseTestCase):
-
-    codes_values = [
-        ('i', 4343, 24234),
-        ('d', 3.625, -4.25),
-        ('h', -232, 234),
-        ('c', latin('x'), latin('y'))
-        ]
-
-    def _test(self, values):
-        for sv, cv in zip(values, self.codes_values):
-            sv.value = cv[2]
-            
-        
-    def test_value(self, raw=False):
-        if self.TYPE != 'processes':
-            return
-
-        if raw:
-            values = [self.RawValue(code, value)
-                      for code, value, _ in self.codes_values]
-        else:
-            values = [self.Value(code, value)
-                      for code, value, _ in self.codes_values]
-            
-        for sv, cv in zip(values, self.codes_values):
-            self.assertEqual(sv.value, cv[1])
-        
-        proc = self.Process(target=self._test, args=(values,))
-        proc.start()
-        proc.join()
-
-        for sv, cv in zip(values, self.codes_values):
-            self.assertEqual(sv.value, cv[2])
-
-    def test_rawvalue(self):
-        self.test_value(raw=True)
-
-    def test_getobj_getlock(self):
-        if self.TYPE != 'processes':
-            return
-
-        val1 = self.Value('i', 5)
-        lock1 = val1.get_lock()
-        obj1 = val1.get_obj()
-
-        val2 = self.Value('i', 5, lock=None)
-        lock2 = val2.get_lock()
-        obj2 = val2.get_obj()
-
-        lock = self.Lock()
-        val3 = self.Value('i', 5, lock=lock)
-        lock3 = val3.get_lock()
-        obj3 = val3.get_obj()
-        self.assertEqual(lock, lock3)
-        
-        arr4 = self.RawValue('i', 5)
-        self.assertFalse(hasattr(arr4, 'get_lock'))
-        self.assertFalse(hasattr(arr4, 'get_obj'))
-
-
-class _TestArray(BaseTestCase):
-
-    def f(self, seq):
-        for i in range(1, len(seq)):
-            seq[i] += seq[i-1]
-
-    def test_array(self, raw=False):
-        if self.TYPE != 'processes':
-            return
-
-        seq = [680, 626, 934, 821, 150, 233, 548, 982, 714, 831]
-        if raw:
-            arr = self.RawArray('i', seq)
-        else:
-            arr = self.Array('i', seq)
-        
-        self.assertEqual(len(arr), len(seq))
-        self.assertEqual(arr[3], seq[3])
-        self.assertEqual(list(arr[2:7]), list(seq[2:7]))
-        
-        arr[4:8] = seq[4:8] = array.array('i', [1, 2, 3, 4])
-        
-        self.assertEqual(list(arr[:]), seq)
-        
-        self.f(seq)
-        
-        p = self.Process(target=self.f, args=(arr,))
-        p.start()
-        p.join()
-        
-        self.assertEqual(list(arr[:]), seq)
-        
-    def test_rawarray(self):
-        self.test_array(raw=True)
-        
-    def test_getobj_getlock_obj(self):
-        if self.TYPE != 'processes':
-            return
-
-        arr1 = self.Array('i', range(10))
-        lock1 = arr1.get_lock()
-        obj1 = arr1.get_obj()
-
-        arr2 = self.Array('i', range(10), lock=None)
-        lock2 = arr2.get_lock()
-        obj2 = arr2.get_obj()
-
-        lock = self.Lock()
-        arr3 = self.Array('i', range(10), lock=lock)
-        lock3 = arr3.get_lock()
-        obj3 = arr3.get_obj()
-        self.assertEqual(lock, lock3)
-        
-        arr4 = self.RawArray('i', range(10))
-        self.assertFalse(hasattr(arr4, 'get_lock'))
-        self.assertFalse(hasattr(arr4, 'get_obj'))
-
-#
-#
-#
-
-class _TestContainers(BaseTestCase):
-
-    ALLOWED_TYPES = ('manager',)
-
-    def test_list(self):
-        a = self.list(range(10))
-        self.assertEqual(a[:], range(10))
-        
-        b = self.list()
-        self.assertEqual(b[:], [])
-        
-        b.extend(range(5))
-        self.assertEqual(b[:], range(5))
-        
-        self.assertEqual(b[2], 2)
-        self.assertEqual(b[2:10], [2,3,4])
-
-        b *= 2
-        self.assertEqual(b[:], [0, 1, 2, 3, 4, 0, 1, 2, 3, 4])
-
-        self.assertEqual(b + [5, 6], [0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 5, 6])
-
-        self.assertEqual(a[:], range(10))
-
-        d = [a, b]
-        e = self.list(d)
-        self.assertEqual(
-            e[:],
-            [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [0, 1, 2, 3, 4, 0, 1, 2, 3, 4]]
-            )
-        
-        f = self.list([a])
-        a.append('hello')
-        self.assertEqual(f[:], [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'hello']])
-
-    def test_dict(self):
-        d = self.dict()
-        indices = range(65, 70)
-        for i in indices:
-            d[i] = chr(i)
-        self.assertEqual(d.copy(), dict((i, chr(i)) for i in indices))
-        self.assertEqual(sorted(d.keys()), indices)
-        self.assertEqual(sorted(d.values()), [chr(i) for i in indices])
-        self.assertEqual(sorted(d.items()), [(i, chr(i)) for i in indices])
-        
-    def test_namespace(self):
-        n = self.Namespace()
-        n.name = 'Bob'
-        n.job = 'Builder'
-        n._hidden = 'hidden'
-        self.assertEqual((n.name, n.job), ('Bob', 'Builder'))
-        del n.job
-        self.assertEqual(str(n), "Namespace(name='Bob')")
-        self.assertTrue(hasattr(n, 'name'))
-        self.assertTrue(not hasattr(n, 'job'))
-
-#
-#
-#
-
-def sqr(x, wait=0.0):
-    time.sleep(wait)
-    return x*x
-
-class _TestPool(BaseTestCase):
-
-    def test_apply(self):
-        papply = self.pool.apply
-        self.assertEqual(papply(sqr, (5,)), sqr(5))
-        self.assertEqual(papply(sqr, (), {'x':3}), sqr(x=3))
-
-    def test_map(self):
-        pmap = self.pool.map
-        self.assertEqual(pmap(sqr, range(10)), map(sqr, range(10)))
-        self.assertEqual(pmap(sqr, range(100), chunksize=20),
-                         map(sqr, range(100)))
-        
-    def test_async(self):
-        res = self.pool.apply_async(sqr, (7, TIMEOUT1,))
-        get = TimingWrapper(res.get)
-        self.assertEqual(get(), 49)
-        self.assertTimingAlmostEqual(get.elapsed, TIMEOUT1)
-
-    def test_async_timeout(self):
-        res = self.pool.apply_async(sqr, (6, TIMEOUT2 + 0.2))
-        get = TimingWrapper(res.get)
-        self.assertRaises(multiprocessing.TimeoutError, get, timeout=TIMEOUT2)
-        self.assertTimingAlmostEqual(get.elapsed, TIMEOUT2)
-
-    def test_imap(self):
-        it = self.pool.imap(sqr, range(10))
-        self.assertEqual(list(it), map(sqr, range(10)))
-
-        it = self.pool.imap(sqr, range(10))
-        for i in range(10):
-            self.assertEqual(it.next(), i*i)
-        self.assertRaises(StopIteration, it.next)
-
-        it = self.pool.imap(sqr, range(1000), chunksize=100)
-        for i in range(1000):
-            self.assertEqual(it.next(), i*i)
-        self.assertRaises(StopIteration, it.next)
-
-    def test_imap_unordered(self):
-        it = self.pool.imap_unordered(sqr, range(1000))
-        self.assertEqual(sorted(it), map(sqr, range(1000)))
-
-        it = self.pool.imap_unordered(sqr, range(1000), chunksize=53)
-        self.assertEqual(sorted(it), map(sqr, range(1000)))
-
-    def test_make_pool(self):
-        p = multiprocessing.Pool(3)
-        self.assertEqual(3, len(p._pool))
-        p.close()
-        p.join()
-
-    def test_terminate(self):
-        if self.TYPE == 'manager':
-            # On Unix a forked process increfs each shared object to
-            # which its parent process held a reference.  If the
-            # forked process gets terminated then there is likely to
-            # be a reference leak.  So to prevent
-            # _TestZZZNumberOfObjects from failing we skip this test
-            # when using a manager.
-            return
-
-        result = self.pool.map_async(
-            time.sleep, [0.1 for i in range(10000)], chunksize=1
-            )
-        self.pool.terminate()
-        join = TimingWrapper(self.pool.join)
-        join()
-        self.assertTrue(join.elapsed < 0.2)
-
-#
-# Test that manager has expected number of shared objects left
-#
-
-class _TestZZZNumberOfObjects(BaseTestCase):
-    # Because test cases are sorted alphabetically, this one will get
-    # run after all the other tests for the manager.  It tests that
-    # there have been no "reference leaks" for the manager's shared
-    # objects.  Note the comment in _TestPool.test_terminate().
-    ALLOWED_TYPES = ('manager',)
-
-    def test_number_of_objects(self):
-        EXPECTED_NUMBER = 1                # the pool object is still alive
-        multiprocessing.active_children()  # discard dead process objs
-        gc.collect()                       # do garbage collection
-        refs = self.manager._number_of_objects()
-        if refs != EXPECTED_NUMBER:
-            print self.manager._debugInfo()
-
-        self.assertEqual(refs, EXPECTED_NUMBER)
-
-#
-# Test of creating a customized manager class
-#
-
-from multiprocessing.managers import BaseManager, BaseProxy, RemoteError
-    
-class FooBar(object):
-    def f(self):
-        return 'f()'
-    def g(self):
-        raise ValueError
-    def _h(self):
-        return '_h()'
-    
-def baz():
-    for i in xrange(10):
-        yield i*i
-
-class IteratorProxy(BaseProxy):
-    _exposed_ = ('next', '__next__')
-    def __iter__(self):
-        return self
-    def next(self):
-        return self._callmethod('next')
-    def __next__(self):
-        return self._callmethod('__next__')
-
-class MyManager(BaseManager):
-    pass
-
-MyManager.register('Foo', callable=FooBar)
-MyManager.register('Bar', callable=FooBar, exposed=('f', '_h'))
-MyManager.register('baz', callable=baz, proxytype=IteratorProxy)
-
-
-class _TestMyManager(BaseTestCase):
-    
-    ALLOWED_TYPES = ('manager',)
-
-    def test_mymanager(self):
-        manager = MyManager()
-        manager.start()
-        
-        foo = manager.Foo()
-        bar = manager.Bar()
-        baz = manager.baz()
-        
-        foo_methods = [name for name in ('f', 'g', '_h') if hasattr(foo, name)]
-        bar_methods = [name for name in ('f', 'g', '_h') if hasattr(bar, name)]
-        
-        self.assertEqual(foo_methods, ['f', 'g'])
-        self.assertEqual(bar_methods, ['f', '_h'])
-        
-        self.assertEqual(foo.f(), 'f()')
-        self.assertRaises(ValueError, foo.g)
-        self.assertEqual(foo._callmethod('f'), 'f()')
-        self.assertRaises(RemoteError, foo._callmethod, '_h')
-        
-        self.assertEqual(bar.f(), 'f()')
-        self.assertEqual(bar._h(), '_h()')
-        self.assertEqual(bar._callmethod('f'), 'f()')
-        self.assertEqual(bar._callmethod('_h'), '_h()')
-        
-        self.assertEqual(list(baz), [i*i for i in range(10)])
-        
-        manager.shutdown()
-        
-#
-# Test of connecting to a remote server and using xmlrpclib for serialization
-#
-
-_queue = Queue.Queue()
-def get_queue():
-    return _queue
-
-class QueueManager(BaseManager):
-    '''manager class used by server process'''
-QueueManager.register('get_queue', callable=get_queue)
-
-class QueueManager2(BaseManager):
-    '''manager class which specifies the same interface as QueueManager'''
-QueueManager2.register('get_queue')
-
-
-SERIALIZER = 'xmlrpclib'
-
-class _TestRemoteManager(BaseTestCase):
-
-    ALLOWED_TYPES = ('manager',)
-    
-    def _putter(self, address, authkey):
-        manager = QueueManager2(
-            address=address, authkey=authkey, serializer=SERIALIZER
-            )
-        manager.connect()
-        queue = manager.get_queue()
-        queue.put(('hello world', None, True, 2.25))
-
-    def test_remote(self):
-        authkey = os.urandom(32)
-
-        manager = QueueManager(
-            address=('localhost', 0), authkey=authkey, serializer=SERIALIZER
-            )
-        manager.start()
-
-        p = self.Process(target=self._putter, args=(manager.address, authkey))
-        p.start()
-        
-        manager2 = QueueManager2(
-            address=manager.address, authkey=authkey, serializer=SERIALIZER
-            )
-        manager2.connect()
-        queue = manager2.get_queue()
-        
-        # Note that xmlrpclib will deserialize object as a list not a tuple
-        self.assertEqual(queue.get(), ['hello world', None, True, 2.25])
-
-        # Because we are using xmlrpclib for serialization instead of
-        # pickle this will cause a serialization error.
-        self.assertRaises(Exception, queue.put, time.sleep)
-
-        # Make queue finalizer run before the server is stopped
-        del queue
-        manager.shutdown()
-
-#
-#
-#
-
-SENTINEL = latin('')
-
-class _TestConnection(BaseTestCase):
-
-    ALLOWED_TYPES = ('processes', 'threads')
-
-    def _echo(self, conn):
-        for msg in iter(conn.recv_bytes, SENTINEL):
-            conn.send_bytes(msg)
-        conn.close()
-
-    def test_connection(self):
-        conn, child_conn = self.Pipe()
-        
-        p = self.Process(target=self._echo, args=(child_conn,))
-        p.set_daemon(True)
-        p.start()
-
-        seq = [1, 2.25, None]
-        msg = latin('hello world')
-        longmsg = msg * 10
-        arr = array.array('i', range(4))
-
-        if self.TYPE == 'processes':
-            self.assertEqual(type(conn.fileno()), int)
-
-        self.assertEqual(conn.send(seq), None)
-        self.assertEqual(conn.recv(), seq)
-
-        self.assertEqual(conn.send_bytes(msg), None)
-        self.assertEqual(conn.recv_bytes(), msg)
-
-        if self.TYPE == 'processes':
-            buffer = array.array('i', [0]*10)
-            expected = list(arr) + [0] * (10 - len(arr))
-            self.assertEqual(conn.send_bytes(arr), None)
-            self.assertEqual(conn.recv_bytes_into(buffer),
-                             len(arr) * buffer.itemsize)
-            self.assertEqual(list(buffer), expected)
-
-            buffer = array.array('i', [0]*10)
-            expected = [0] * 3 + list(arr) + [0] * (10 - 3 - len(arr))
-            self.assertEqual(conn.send_bytes(arr), None)
-            self.assertEqual(conn.recv_bytes_into(buffer, 3 * buffer.itemsize),
-                             len(arr) * buffer.itemsize)
-            self.assertEqual(list(buffer), expected)
-
-            buffer = bytearray(latin(' ' * 40))
-            self.assertEqual(conn.send_bytes(longmsg), None)
-            try:
-                res = conn.recv_bytes_into(buffer)
-            except multiprocessing.BufferTooShort, e:
-                self.assertEqual(e.args, (longmsg,))
-            else:
-                self.fail('expected BufferTooShort, got %s' % res)
-
-        poll = TimingWrapper(conn.poll)
-
-        self.assertEqual(poll(), False)
-        self.assertTimingAlmostEqual(poll.elapsed, 0)
-
-        self.assertEqual(poll(TIMEOUT1), False)
-        self.assertTimingAlmostEqual(poll.elapsed, TIMEOUT1)
-
-        conn.send(None)
-
-        self.assertEqual(poll(TIMEOUT1), True)
-        self.assertTimingAlmostEqual(poll.elapsed, 0)
-        
-        self.assertEqual(conn.recv(), None)
-
-        really_big_msg = latin('X') * (1024 * 1024 * 16)   # 16Mb
-        conn.send_bytes(really_big_msg)
-        self.assertEqual(conn.recv_bytes(), really_big_msg)
-        
-        conn.send_bytes(SENTINEL)                          # tell child to quit
-        child_conn.close()
-
-        if self.TYPE == 'processes':
-            self.assertEqual(conn.readable, True)
-            self.assertEqual(conn.writable, True)
-            self.assertRaises(EOFError, conn.recv)
-            self.assertRaises(EOFError, conn.recv_bytes)
-
-        p.join()
-        
-    def test_duplex_false(self):
-        reader, writer = self.Pipe(duplex=False)
-        self.assertEqual(writer.send(1), None)
-        self.assertEqual(reader.recv(), 1)
-        if self.TYPE == 'processes':
-            self.assertEqual(reader.readable, True)
-            self.assertEqual(reader.writable, False)
-            self.assertEqual(writer.readable, False)
-            self.assertEqual(writer.writable, True)
-            self.assertRaises(IOError, reader.send, 2)
-            self.assertRaises(IOError, writer.recv)
-            self.assertRaises(IOError, writer.poll)
-
-    def test_spawn_close(self):
-        # We test that a pipe connection can be closed by parent
-        # process immediately after child is spawned.  On Windows this
-        # would have sometimes failed on old versions because
-        # child_conn would be closed before the child got a chance to
-        # duplicate it.
-        conn, child_conn = self.Pipe()
-        
-        p = self.Process(target=self._echo, args=(child_conn,))
-        p.start()
-        child_conn.close()    # this might complete before child initializes
-
-        msg = latin('hello')
-        conn.send_bytes(msg)
-        self.assertEqual(conn.recv_bytes(), msg)
-
-        conn.send_bytes(SENTINEL)
-        conn.close()
-        p.join()
-
-    def test_sendbytes(self):
-        if self.TYPE != 'processes':
-            return
-
-        msg = latin('abcdefghijklmnopqrstuvwxyz')
-        a, b = self.Pipe()
-        
-        a.send_bytes(msg)
-        self.assertEqual(b.recv_bytes(), msg)
-
-        a.send_bytes(msg, 5)
-        self.assertEqual(b.recv_bytes(), msg[5:])
-
-        a.send_bytes(msg, 7, 8)
-        self.assertEqual(b.recv_bytes(), msg[7:7+8])
-
-        a.send_bytes(msg, 26)
-        self.assertEqual(b.recv_bytes(), latin(''))
-
-        a.send_bytes(msg, 26, 0)
-        self.assertEqual(b.recv_bytes(), latin(''))
-
-        self.assertRaises(ValueError, a.send_bytes, msg, 27)
-        
-        self.assertRaises(ValueError, a.send_bytes, msg, 22, 5)
-        
-        self.assertRaises(ValueError, a.send_bytes, msg, 26, 1)
-
-        self.assertRaises(ValueError, a.send_bytes, msg, -1)
-
-        self.assertRaises(ValueError, a.send_bytes, msg, 4, -1)
-        
-
-class _TestListenerClient(BaseTestCase):
-
-    ALLOWED_TYPES = ('processes', 'threads')
-
-    def _test(self, address):
-        conn = self.connection.Client(address)
-        conn.send('hello')
-        conn.close()
-
-    def test_listener_client(self):        
-        for family in self.connection.families:
-            l = self.connection.Listener(family=family)
-            p = self.Process(target=self._test, args=(l.address,))
-            p.set_daemon(True)
-            p.start()
-            conn = l.accept()
-            self.assertEqual(conn.recv(), 'hello')
-            p.join()
-            l.close()
-
-#
-# Test of sending connection and socket objects between processes
-#
-
-class _TestPicklingConnections(BaseTestCase):
-
-    ALLOWED_TYPES = ('processes',)
-
-    def _listener(self, conn, families):
-        for fam in families:
-            l = self.connection.Listener(family=fam)
-            conn.send(l.address)
-            new_conn = l.accept()
-            conn.send(new_conn)
-
-        if self.TYPE == 'processes':
-            l = socket.socket()
-            l.bind(('localhost', 0))
-            conn.send(l.getsockname())
-            l.listen(1)
-            new_conn, addr = l.accept()
-            conn.send(new_conn)
-        
-        conn.recv()
-
-    def _remote(self, conn):
-        for (address, msg) in iter(conn.recv, None):
-            client = self.connection.Client(address)
-            client.send(msg.upper())
-            client.close()
-
-        if self.TYPE == 'processes':
-            address, msg = conn.recv()
-            client = socket.socket()
-            client.connect(address)
-            client.sendall(msg.upper())
-            client.close()
-
-        conn.close()
-
-    def test_pickling(self):
-        try:
-            multiprocessing.allow_connection_pickling()
-        except ImportError:
-            return
-        
-        families = self.connection.families
-
-        lconn, lconn0 = self.Pipe()
-        lp = self.Process(target=self._listener, args=(lconn0, families))
-        lp.start()
-        lconn0.close()
-
-        rconn, rconn0 = self.Pipe()
-        rp = self.Process(target=self._remote, args=(rconn0,))
-        rp.start()
-        rconn0.close()
-
-        for fam in families:
-            msg = ('This connection uses family %s' % fam).encode('ascii')
-            address = lconn.recv()
-            rconn.send((address, msg))
-            new_conn = lconn.recv()
-            self.assertEqual(new_conn.recv(), msg.upper())
-            
-        rconn.send(None)
-
-        if self.TYPE == 'processes':
-            msg = latin('This connection uses a normal socket')
-            address = lconn.recv()
-            rconn.send((address, msg))
-            if hasattr(socket, 'fromfd'):
-                new_conn = lconn.recv()
-                self.assertEqual(new_conn.recv(100), msg.upper())
-            else:
-                # XXX On Windows with Py2.6 need to backport fromfd()
-                discard = lconn.recv_bytes()
-                
-        lconn.send(None)
-        
-        rconn.close()
-        lconn.close()
-        
-        lp.join()
-        rp.join()
-
-#
-#
-#
-
-class _TestHeap(BaseTestCase):
-
-    ALLOWED_TYPES = ('processes',)
-
-    def test_heap(self):
-        iterations = 5000
-        maxblocks = 50
-        blocks = []
-
-        # create and destroy lots of blocks of different sizes
-        for i in xrange(iterations):
-            size = int(random.lognormvariate(0, 1) * 1000)
-            b = multiprocessing.heap.BufferWrapper(size)
-            blocks.append(b)
-            if len(blocks) > maxblocks:
-                i = random.randrange(maxblocks)
-                del blocks[i]
-
-        # get the heap object
-        heap = multiprocessing.heap.BufferWrapper._heap
-
-        # verify the state of the heap
-        all = []
-        occupied = 0
-        for L in heap._len_to_seq.values():
-            for arena, start, stop in L:
-                all.append((heap._arenas.index(arena), start, stop,
-                            stop-start, 'free'))
-        for arena, start, stop in heap._allocated_blocks:
-            all.append((heap._arenas.index(arena), start, stop,
-                        stop-start, 'occupied'))
-            occupied += (stop-start)
-
-        all.sort()
-
-        for i in range(len(all)-1):
-            (arena, start, stop) = all[i][:3]
-            (narena, nstart, nstop) = all[i+1][:3]
-            self.assertTrue((arena != narena and nstart == 0) or
-                            (stop == nstart))
-            
-#
-#
-#
-
-try:
-    from ctypes import Structure, Value, copy, c_int, c_double
-except ImportError:
-    Structure = object
-    c_int = c_double = None
-
-class _Foo(Structure):
-    _fields_ = [
-        ('x', c_int),
-        ('y', c_double)
-        ]
-
-class _TestSharedCTypes(BaseTestCase):
-
-    ALLOWED_TYPES = ('processes',)
-
-    def _double(self, x, y, foo, arr, string):
-        x.value *= 2
-        y.value *= 2
-        foo.x *= 2
-        foo.y *= 2
-        string.value *= 2
-        for i in range(len(arr)):
-            arr[i] *= 2
-
-    def test_sharedctypes(self, lock=False):
-        if c_int is None:
-            return
-        
-        x = Value('i', 7, lock=lock)
-        y = Value(ctypes.c_double, 1.0/3.0, lock=lock)
-        foo = Value(_Foo, 3, 2, lock=lock)
-        arr = Array('d', range(10), lock=lock)
-        string = Array('c', 20, lock=lock)
-        string.value = 'hello'
-
-        p = self.Process(target=self._double, args=(x, y, foo, arr, string))
-        p.start()
-        p.join()
-
-        self.assertEqual(x.value, 14)
-        self.assertAlmostEqual(y.value, 2.0/3.0)
-        self.assertEqual(foo.x, 6)
-        self.assertAlmostEqual(foo.y, 4.0)
-        for i in range(10):
-            self.assertAlmostEqual(arr[i], i*2)
-        self.assertEqual(string.value, latin('hellohello'))
-
-    def test_synchronize(self):
-        self.test_sharedctypes(lock=True)
-
-    def test_copy(self):
-        if c_int is None:
-            return
-
-        foo = _Foo(2, 5.0)
-        bar = copy(foo)
-        foo.x = 0
-        foo.y = 0
-        self.assertEqual(bar.x, 2)
-        self.assertAlmostEqual(bar.y, 5.0)
-
-#
-#
-#
-
-class _TestFinalize(BaseTestCase):
-
-    ALLOWED_TYPES = ('processes',)
-
-    def _test_finalize(self, conn):
-        class Foo(object):
-            pass
-
-        a = Foo()
-        util.Finalize(a, conn.send, args=('a',))
-        del a           # triggers callback for a
-
-        b = Foo()
-        close_b = util.Finalize(b, conn.send, args=('b',))    
-        close_b()       # triggers callback for b
-        close_b()       # does nothing because callback has already been called
-        del b           # does nothing because callback has already been called
-
-        c = Foo()
-        util.Finalize(c, conn.send, args=('c',))
-
-        d10 = Foo()
-        util.Finalize(d10, conn.send, args=('d10',), exitpriority=1)
-
-        d01 = Foo()
-        util.Finalize(d01, conn.send, args=('d01',), exitpriority=0)
-        d02 = Foo()
-        util.Finalize(d02, conn.send, args=('d02',), exitpriority=0)
-        d03 = Foo()
-        util.Finalize(d03, conn.send, args=('d03',), exitpriority=0)
-
-        util.Finalize(None, conn.send, args=('e',), exitpriority=-10)
-
-        util.Finalize(None, conn.send, args=('STOP',), exitpriority=-100)
-
-        # call mutliprocessing's cleanup function then exit process without
-        # garbage collecting locals
-        util._exit_function()
-        conn.close()
-        os._exit(0)
-
-    def test_finalize(self):
-        conn, child_conn = self.Pipe()
-        
-        p = self.Process(target=self._test_finalize, args=(child_conn,))
-        p.start()
-        p.join()
-
-        result = [obj for obj in iter(conn.recv, 'STOP')]
-        self.assertEqual(result, ['a', 'b', 'd10', 'd03', 'd02', 'd01', 'e'])
-
-#
-# Test that from ... import * works for each module
-#
-
-class _TestImportStar(BaseTestCase):
-
-    ALLOWED_TYPES = ('processes',)
-
-    def test_import(self):
-        modules = (
-            'multiprocessing', 'multiprocessing.connection',
-            'multiprocessing.heap', 'multiprocessing.managers',
-            'multiprocessing.pool', 'multiprocessing.process',
-            'multiprocessing.reduction', 'multiprocessing.sharedctypes',
-            'multiprocessing.synchronize', 'multiprocessing.util'
-            )
-        
-        for name in modules:
-            __import__(name)
-            mod = sys.modules[name]
-            
-            for attr in getattr(mod, '__all__', ()):
-                self.assertTrue(
-                    hasattr(mod, attr),
-                    '%r does not have attribute %r' % (mod, attr)
-                    )
-
-#
-# Quick test that logging works -- does not test logging output
-#
-
-class _TestLogging(BaseTestCase):
-
-    ALLOWED_TYPES = ('processes',)
-
-    def test_enable_logging(self):
-        logger = multiprocessing.get_logger()
-        logger.setLevel(util.SUBWARNING)
-        self.assertTrue(logger is not None)
-        logger.debug('this will not be printed')
-        logger.info('nor will this')
-        logger.setLevel(LOG_LEVEL)
-
-    def _test_level(self, conn):
-        logger = multiprocessing.get_logger()
-        conn.send(logger.getEffectiveLevel())
-
-    def test_level(self):
-        LEVEL1 = 32
-        LEVEL2 = 37
-        
-        logger = multiprocessing.get_logger()
-        root_logger = logging.getLogger()
-        root_level = root_logger.level
-
-        reader, writer = multiprocessing.Pipe(duplex=False)
-
-        logger.setLevel(LEVEL1)
-        self.Process(target=self._test_level, args=(writer,)).start()
-        self.assertEqual(LEVEL1, reader.recv())
-
-        logger.setLevel(logging.NOTSET)
-        root_logger.setLevel(LEVEL2)
-        self.Process(target=self._test_level, args=(writer,)).start()
-        self.assertEqual(LEVEL2, reader.recv())
-
-        root_logger.setLevel(root_level)
-        logger.setLevel(level=LOG_LEVEL)
-
-#
-# Functions used to create test cases from the base ones in this module
-#
-
-def get_attributes(Source, names):
-    d = {}
-    for name in names:
-        obj = getattr(Source, name)
-        if type(obj) == type(get_attributes):
-            obj = staticmethod(obj)
-        d[name] = obj
-    return d
-
-def create_test_cases(Mixin, type):
-    result = {}
-    glob = globals()
-    Type = type[0].upper() + type[1:]
-
-    for name in glob.keys():
-        if name.startswith('_Test'):
-            base = glob[name]
-            if type in base.ALLOWED_TYPES:
-                newname = 'With' + Type + name[1:]
-                class Temp(base, unittest.TestCase, Mixin):
-                    pass
-                result[newname] = Temp
-                Temp.__name__ = newname
-                Temp.__module__ = Mixin.__module__
-    return result
-
-#
-# Create test cases
-#
-
-class ProcessesMixin(object):
-    TYPE = 'processes'
-    Process = multiprocessing.Process
-    locals().update(get_attributes(multiprocessing, (
-        'Queue', 'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore',
-        'Condition', 'Event', 'Value', 'Array', 'RawValue',
-        'RawArray', 'current_process', 'active_children', 'Pipe',
-        'connection', 'JoinableQueue'
-        )))
-
-testcases_processes = create_test_cases(ProcessesMixin, type='processes')
-globals().update(testcases_processes)
-
-
-class ManagerMixin(object):
-    TYPE = 'manager'
-    Process = multiprocessing.Process
-    manager = object.__new__(multiprocessing.managers.SyncManager)
-    locals().update(get_attributes(manager, (
-        'Queue', 'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 
-       'Condition', 'Event', 'Value', 'Array', 'list', 'dict',
-        'Namespace', 'JoinableQueue'
-        )))
-
-testcases_manager = create_test_cases(ManagerMixin, type='manager')
-globals().update(testcases_manager)
-
-
-class ThreadsMixin(object):
-    TYPE = 'threads'
-    Process = multiprocessing.dummy.Process
-    locals().update(get_attributes(multiprocessing.dummy, (
-        'Queue', 'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore',
-        'Condition', 'Event', 'Value', 'Array', 'current_process',
-        'active_children', 'Pipe', 'connection', 'dict', 'list',
-        'Namespace', 'JoinableQueue'
-        )))
-
-testcases_threads = create_test_cases(ThreadsMixin, type='threads')
-globals().update(testcases_threads)
-
-#
-#
-#
-
-def test_main(run=None):
-    if run is None:
-        from test.test_support import run_unittest as run
-
-    util.get_temp_dir()     # creates temp directory for use by all processes
-    
-    multiprocessing.get_logger().setLevel(LOG_LEVEL)
-
-    ProcessesMixin.pool = multiprocessing.Pool(4)
-    ThreadsMixin.pool = multiprocessing.dummy.Pool(4)
-    ManagerMixin.manager.__init__()
-    ManagerMixin.manager.start()
-    ManagerMixin.pool = ManagerMixin.manager.Pool(4)
-
-    testcases = (
-        sorted(testcases_processes.values(), key=lambda tc:tc.__name__) +
-        sorted(testcases_threads.values(), key=lambda tc:tc.__name__) +
-        sorted(testcases_manager.values(), key=lambda tc:tc.__name__)
-        )
-
-    loadTestsFromTestCase = unittest.defaultTestLoader.loadTestsFromTestCase
-    suite = unittest.TestSuite(loadTestsFromTestCase(tc) for tc in testcases)
-    run(suite)
-
-    ThreadsMixin.pool.terminate()
-    ProcessesMixin.pool.terminate()
-    ManagerMixin.pool.terminate()
-    ManagerMixin.manager.shutdown()
-    
-    del ProcessesMixin.pool, ThreadsMixin.pool, ManagerMixin.pool
-
-def main():
-    test_main(unittest.TextTestRunner(verbosity=2).run)
-
-if __name__ == '__main__':
-    main()
+#
+# Unit tests for the multiprocessing package
+#
+
+import unittest
+import threading
+import queue as pyqueue
+import time
+import sys
+import os
+import gc
+import signal
+import array
+import copy
+import socket
+import random
+import logging
+
+import multiprocessing.dummy
+import multiprocessing.connection
+import multiprocessing.managers
+import multiprocessing.heap
+import multiprocessing.managers
+import multiprocessing.pool
+import _multiprocessing
+
+from multiprocessing import util
+
+#
+#
+#
+
+if sys.version_info >= (3, 0):
+    def latin(s):
+        return s.encode('latin')
+else:
+    latin = str
+
+try:
+    bytes
+except NameError:
+    bytes = str
+    def bytearray(seq):
+        return array.array('c', seq)
+
+#
+# Constants
+#
+
+LOG_LEVEL = util.SUBWARNING
+#LOG_LEVEL = logging.WARNING
+
+DELTA = 0.1
+CHECK_TIMINGS = False     # making true makes tests take a lot longer
+                          # and can sometimes cause some non-serious
+                          # failures because some calls block a bit
+                          # longer than expected
+if CHECK_TIMINGS:
+    TIMEOUT1, TIMEOUT2, TIMEOUT3 = 0.82, 0.35, 1.4
+else:
+    TIMEOUT1, TIMEOUT2, TIMEOUT3 = 0.1, 0.1, 0.1
+
+HAVE_GETVALUE = not getattr(_multiprocessing,
+                            'HAVE_BROKEN_SEM_GETVALUE', False)
+
+#
+# Creates a wrapper for a function which records the time it takes to finish
+#
+
+class TimingWrapper(object):
+
+    def __init__(self, func):
+        self.func = func
+        self.elapsed = None
+
+    def __call__(self, *args, **kwds):
+        t = time.time()
+        try:
+            return self.func(*args, **kwds)
+        finally:
+            self.elapsed = time.time() - t
+
+#
+# Base class for test cases
+#
+
+class BaseTestCase(object):
+
+    ALLOWED_TYPES = ('processes', 'manager', 'threads')
+
+    def assertTimingAlmostEqual(self, a, b):
+        if CHECK_TIMINGS:
+            self.assertAlmostEqual(a, b, 1)
+
+    def assertReturnsIfImplemented(self, value, func, *args):
+        try:
+            res = func(*args)
+        except NotImplementedError:
+            pass
+        else:
+            return self.assertEqual(value, res)
+
+#
+# Return the value of a semaphore
+#
+
+def get_value(self):
+    try:
+        return self.get_value()
+    except AttributeError:
+        try:
+            return self._Semaphore__value
+        except AttributeError:
+            try:
+                return self._value
+            except AttributeError:
+                raise NotImplementedError
+
+#
+# Testcases
+#
+
+class _TestProcess(BaseTestCase):
+
+    ALLOWED_TYPES = ('processes', 'threads')
+
+    def test_current(self):
+        if self.TYPE == 'threads':
+            return
+
+        current = self.current_process()
+        authkey = current.get_authkey()
+
+        self.assertTrue(current.is_alive())
+        self.assertTrue(not current.is_daemon())
+        self.assertTrue(isinstance(authkey, bytes))
+        self.assertTrue(len(authkey) > 0)
+        self.assertEqual(current.get_ident(), os.getpid())
+        self.assertEqual(current.get_exitcode(), None)
+
+    def _test(self, q, *args, **kwds):
+        current = self.current_process()
+        q.put(args)
+        q.put(kwds)
+        q.put(current.get_name())
+        if self.TYPE != 'threads':
+            q.put(bytes(current.get_authkey()))
+            q.put(current.pid)
+
+    def test_process(self):
+        q = self.Queue(1)
+        e = self.Event()
+        args = (q, 1, 2)
+        kwargs = {'hello':23, 'bye':2.54}
+        name = 'SomeProcess'
+        p = self.Process(
+            target=self._test, args=args, kwargs=kwargs, name=name
+            )
+        p.set_daemon(True)
+        current = self.current_process()
+
+        if self.TYPE != 'threads':
+            self.assertEquals(p.get_authkey(), current.get_authkey())
+        self.assertEquals(p.is_alive(), False)
+        self.assertEquals(p.is_daemon(), True)
+        self.assertTrue(p not in self.active_children())
+        self.assertTrue(type(self.active_children()) is list)
+        self.assertEqual(p.get_exitcode(), None)
+
+        p.start()
+
+        self.assertEquals(p.get_exitcode(), None)
+        self.assertEquals(p.is_alive(), True)
+        self.assertTrue(p in self.active_children())
+
+        self.assertEquals(q.get(), args[1:])
+        self.assertEquals(q.get(), kwargs)
+        self.assertEquals(q.get(), p.get_name())
+        if self.TYPE != 'threads':
+            self.assertEquals(q.get(), current.get_authkey())
+            self.assertEquals(q.get(), p.pid)
+
+        p.join()
+
+        self.assertEquals(p.get_exitcode(), 0)
+        self.assertEquals(p.is_alive(), False)
+        self.assertTrue(p not in self.active_children())
+
+    def _test_terminate(self):
+        time.sleep(1000)
+
+    def test_terminate(self):
+        if self.TYPE == 'threads':
+            return
+
+        p = self.Process(target=self._test_terminate)
+        p.set_daemon(True)
+        p.start()
+
+        self.assertEqual(p.is_alive(), True)
+        self.assertTrue(p in self.active_children())
+        self.assertEqual(p.get_exitcode(), None)
+
+        p.terminate()
+
+        join = TimingWrapper(p.join)
+        self.assertEqual(join(), None)
+        self.assertTimingAlmostEqual(join.elapsed, 0.0)
+
+        self.assertEqual(p.is_alive(), False)
+        self.assertTrue(p not in self.active_children())
+
+        p.join()
+
+        # XXX sometimes get p.get_exitcode() == 0 on Windows ...
+        #self.assertEqual(p.get_exitcode(), -signal.SIGTERM)
+
+    def test_cpu_count(self):
+        try:
+            cpus = multiprocessing.cpu_count()
+        except NotImplementedError:
+            cpus = 1
+        self.assertTrue(type(cpus) is int)
+        self.assertTrue(cpus >= 1)
+
+    def test_active_children(self):
+        self.assertEqual(type(self.active_children()), list)
+
+        p = self.Process(target=time.sleep, args=(DELTA,))
+        self.assertTrue(p not in self.active_children())
+
+        p.start()
+        self.assertTrue(p in self.active_children())
+
+        p.join()
+        self.assertTrue(p not in self.active_children())
+
+    def _test_recursion(self, wconn, id):
+        from multiprocessing import forking
+        wconn.send(id)
+        if len(id) < 2:
+            for i in range(2):
+                p = self.Process(
+                    target=self._test_recursion, args=(wconn, id+[i])
+                    )
+                p.start()
+                p.join()
+
+    def test_recursion(self):
+        rconn, wconn = self.Pipe(duplex=False)
+        self._test_recursion(wconn, [])
+
+        time.sleep(DELTA)
+        result = []
+        while rconn.poll():
+            result.append(rconn.recv())
+
+        expected = [
+            [],
+              [0],
+                [0, 0],
+                [0, 1],
+              [1],
+                [1, 0],
+                [1, 1]
+            ]
+        self.assertEqual(result, expected)
+
+#
+#
+#
+
+class _UpperCaser(multiprocessing.Process):
+
+    def __init__(self):
+        multiprocessing.Process.__init__(self)
+        self.child_conn, self.parent_conn = multiprocessing.Pipe()
+
+    def run(self):
+        self.parent_conn.close()
+        for s in iter(self.child_conn.recv, None):
+            self.child_conn.send(s.upper())
+        self.child_conn.close()
+
+    def submit(self, s):
+        assert type(s) is str
+        self.parent_conn.send(s)
+        return self.parent_conn.recv()
+
+    def stop(self):
+        self.parent_conn.send(None)
+        self.parent_conn.close()
+        self.child_conn.close()
+
+class _TestSubclassingProcess(BaseTestCase):
+
+    ALLOWED_TYPES = ('processes',)
+
+    def test_subclassing(self):
+        uppercaser = _UpperCaser()
+        uppercaser.start()
+        self.assertEqual(uppercaser.submit('hello'), 'HELLO')
+        self.assertEqual(uppercaser.submit('world'), 'WORLD')
+        uppercaser.stop()
+        uppercaser.join()
+
+#
+#
+#
+
+def queue_empty(q):
+    if hasattr(q, 'empty'):
+        return q.empty()
+    else:
+        return q.qsize() == 0
+
+def queue_full(q, maxsize):
+    if hasattr(q, 'full'):
+        return q.full()
+    else:
+        return q.qsize() == maxsize
+
+
+class _TestQueue(BaseTestCase):
+
+
+    def _test_put(self, queue, child_can_start, parent_can_continue):
+        child_can_start.wait()
+        for i in range(6):
+            queue.get()
+        parent_can_continue.set()
+
+    def test_put(self):
+        MAXSIZE = 6
+        queue = self.Queue(maxsize=MAXSIZE)
+        child_can_start = self.Event()
+        parent_can_continue = self.Event()
+
+        proc = self.Process(
+            target=self._test_put,
+            args=(queue, child_can_start, parent_can_continue)
+            )
+        proc.set_daemon(True)
+        proc.start()
+
+        self.assertEqual(queue_empty(queue), True)
+        self.assertEqual(queue_full(queue, MAXSIZE), False)
+
+        queue.put(1)
+        queue.put(2, True)
+        queue.put(3, True, None)
+        queue.put(4, False)
+        queue.put(5, False, None)
+        queue.put_nowait(6)
+
+        # the values may be in buffer but not yet in pipe so sleep a bit
+        time.sleep(DELTA)
+
+        self.assertEqual(queue_empty(queue), False)
+        self.assertEqual(queue_full(queue, MAXSIZE), True)
+
+        put = TimingWrapper(queue.put)
+        put_nowait = TimingWrapper(queue.put_nowait)
+
+        self.assertRaises(pyqueue.Full, put, 7, False)
+        self.assertTimingAlmostEqual(put.elapsed, 0)
+
+        self.assertRaises(pyqueue.Full, put, 7, False, None)
+        self.assertTimingAlmostEqual(put.elapsed, 0)
+
+        self.assertRaises(pyqueue.Full, put_nowait, 7)
+        self.assertTimingAlmostEqual(put_nowait.elapsed, 0)
+
+        self.assertRaises(pyqueue.Full, put, 7, True, TIMEOUT1)
+        self.assertTimingAlmostEqual(put.elapsed, TIMEOUT1)
+
+        self.assertRaises(pyqueue.Full, put, 7, False, TIMEOUT2)
+        self.assertTimingAlmostEqual(put.elapsed, 0)
+
+        self.assertRaises(pyqueue.Full, put, 7, True, timeout=TIMEOUT3)
+        self.assertTimingAlmostEqual(put.elapsed, TIMEOUT3)
+
+        child_can_start.set()
+        parent_can_continue.wait()
+
+        self.assertEqual(queue_empty(queue), True)
+        self.assertEqual(queue_full(queue, MAXSIZE), False)
+
+        proc.join()
+
+    def _test_get(self, queue, child_can_start, parent_can_continue):
+        child_can_start.wait()
+        queue.put(1)
+        queue.put(2)
+        queue.put(3)
+        queue.put(4)
+        queue.put(5)
+        parent_can_continue.set()
+
+    def test_get(self):
+        queue = self.Queue()
+        child_can_start = self.Event()
+        parent_can_continue = self.Event()
+
+        proc = self.Process(
+            target=self._test_get,
+            args=(queue, child_can_start, parent_can_continue)
+            )
+        proc.set_daemon(True)
+        proc.start()
+
+        self.assertEqual(queue_empty(queue), True)
+
+        child_can_start.set()
+        parent_can_continue.wait()
+
+        time.sleep(DELTA)
+        self.assertEqual(queue_empty(queue), False)
+
+        self.assertEqual(queue.get(), 1)
+        self.assertEqual(queue.get(True, None), 2)
+        self.assertEqual(queue.get(True), 3)
+        self.assertEqual(queue.get(timeout=1), 4)
+        self.assertEqual(queue.get_nowait(), 5)
+
+        self.assertEqual(queue_empty(queue), True)
+
+        get = TimingWrapper(queue.get)
+        get_nowait = TimingWrapper(queue.get_nowait)
+
+        self.assertRaises(pyqueue.Empty, get, False)
+        self.assertTimingAlmostEqual(get.elapsed, 0)
+
+        self.assertRaises(pyqueue.Empty, get, False, None)
+        self.assertTimingAlmostEqual(get.elapsed, 0)
+
+        self.assertRaises(pyqueue.Empty, get_nowait)
+        self.assertTimingAlmostEqual(get_nowait.elapsed, 0)
+
+        self.assertRaises(pyqueue.Empty, get, True, TIMEOUT1)
+        self.assertTimingAlmostEqual(get.elapsed, TIMEOUT1)
+
+        self.assertRaises(pyqueue.Empty, get, False, TIMEOUT2)
+        self.assertTimingAlmostEqual(get.elapsed, 0)
+
+        self.assertRaises(pyqueue.Empty, get, timeout=TIMEOUT3)
+        self.assertTimingAlmostEqual(get.elapsed, TIMEOUT3)
+
+        proc.join()
+
+    def _test_fork(self, queue):
+        for i in range(10, 20):
+            queue.put(i)
+        # note that at this point the items may only be buffered, so the
+        # process cannot shutdown until the feeder thread has finished
+        # pushing items onto the pipe.
+
+    def test_fork(self):
+        # Old versions of Queue would fail to create a new feeder
+        # thread for a forked process if the original process had its
+        # own feeder thread.  This test checks that this no longer
+        # happens.
+
+        queue = self.Queue()
+
+        # put items on queue so that main process starts a feeder thread
+        for i in range(10):
+            queue.put(i)
+
+        # wait to make sure thread starts before we fork a new process
+        time.sleep(DELTA)
+
+        # fork process
+        p = self.Process(target=self._test_fork, args=(queue,))
+        p.start()
+
+        # check that all expected items are in the queue
+        for i in range(20):
+            self.assertEqual(queue.get(), i)
+        self.assertRaises(pyqueue.Empty, queue.get, False)
+
+        p.join()
+
+    def test_qsize(self):
+        q = self.Queue()
+        try:
+            self.assertEqual(q.qsize(), 0)
+        except NotImplementedError:
+            return
+        q.put(1)
+        self.assertEqual(q.qsize(), 1)
+        q.put(5)
+        self.assertEqual(q.qsize(), 2)
+        q.get()
+        self.assertEqual(q.qsize(), 1)
+        q.get()
+        self.assertEqual(q.qsize(), 0)
+
+    def _test_task_done(self, q):
+        for obj in iter(q.get, None):
+            time.sleep(DELTA)
+            q.task_done()
+
+    def test_task_done(self):
+        queue = self.JoinableQueue()
+
+        if sys.version_info < (2, 5) and not hasattr(queue, 'task_done'):
+            return
+
+        workers = [self.Process(target=self._test_task_done, args=(queue,))
+                   for i in range(4)]
+
+        for p in workers:
+            p.start()
+
+        for i in range(10):
+            queue.put(i)
+
+        queue.join()
+
+        for p in workers:
+            queue.put(None)
+
+        for p in workers:
+            p.join()
+
+#
+#
+#
+
+class _TestLock(BaseTestCase):
+
+    def test_lock(self):
+        lock = self.Lock()
+        self.assertEqual(lock.acquire(), True)
+        self.assertEqual(lock.acquire(False), False)
+        self.assertEqual(lock.release(), None)
+        self.assertRaises((ValueError, threading.ThreadError), lock.release)
+
+    def test_rlock(self):
+        lock = self.RLock()
+        self.assertEqual(lock.acquire(), True)
+        self.assertEqual(lock.acquire(), True)
+        self.assertEqual(lock.acquire(), True)
+        self.assertEqual(lock.release(), None)
+        self.assertEqual(lock.release(), None)
+        self.assertEqual(lock.release(), None)
+        self.assertRaises((AssertionError, RuntimeError), lock.release)
+
+
+class _TestSemaphore(BaseTestCase):
+
+    def _test_semaphore(self, sem):
+        self.assertReturnsIfImplemented(2, get_value, sem)
+        self.assertEqual(sem.acquire(), True)
+        self.assertReturnsIfImplemented(1, get_value, sem)
+        self.assertEqual(sem.acquire(), True)
+        self.assertReturnsIfImplemented(0, get_value, sem)
+        self.assertEqual(sem.acquire(False), False)
+        self.assertReturnsIfImplemented(0, get_value, sem)
+        self.assertEqual(sem.release(), None)
+        self.assertReturnsIfImplemented(1, get_value, sem)
+        self.assertEqual(sem.release(), None)
+        self.assertReturnsIfImplemented(2, get_value, sem)
+
+    def test_semaphore(self):
+        sem = self.Semaphore(2)
+        self._test_semaphore(sem)
+        self.assertEqual(sem.release(), None)
+        self.assertReturnsIfImplemented(3, get_value, sem)
+        self.assertEqual(sem.release(), None)
+        self.assertReturnsIfImplemented(4, get_value, sem)
+
+    def test_bounded_semaphore(self):
+        sem = self.BoundedSemaphore(2)
+        self._test_semaphore(sem)
+        # Currently fails on OS/X
+        #if HAVE_GETVALUE:
+        #    self.assertRaises(ValueError, sem.release)
+        #    self.assertReturnsIfImplemented(2, get_value, sem)
+
+    def test_timeout(self):
+        if self.TYPE != 'processes':
+            return
+
+        sem = self.Semaphore(0)
+        acquire = TimingWrapper(sem.acquire)
+
+        self.assertEqual(acquire(False), False)
+        self.assertTimingAlmostEqual(acquire.elapsed, 0.0)
+
+        self.assertEqual(acquire(False, None), False)
+        self.assertTimingAlmostEqual(acquire.elapsed, 0.0)
+
+        self.assertEqual(acquire(False, TIMEOUT1), False)
+        self.assertTimingAlmostEqual(acquire.elapsed, 0)
+
+        self.assertEqual(acquire(True, TIMEOUT2), False)
+        self.assertTimingAlmostEqual(acquire.elapsed, TIMEOUT2)
+
+        self.assertEqual(acquire(timeout=TIMEOUT3), False)
+        self.assertTimingAlmostEqual(acquire.elapsed, TIMEOUT3)
+
+
+class _TestCondition(BaseTestCase):
+
+    def f(self, cond, sleeping, woken, timeout=None):
+        cond.acquire()
+        sleeping.release()
+        cond.wait(timeout)
+        woken.release()
+        cond.release()
+
+    def check_invariant(self, cond):
+        # this is only supposed to succeed when there are no sleepers
+        if self.TYPE == 'processes':
+            try:
+                sleepers = (cond._sleeping_count.get_value() -
+                            cond._woken_count.get_value())
+                self.assertEqual(sleepers, 0)
+                self.assertEqual(cond._wait_semaphore.get_value(), 0)
+            except NotImplementedError:
+                pass
+
+    def test_notify(self):
+        cond = self.Condition()
+        sleeping = self.Semaphore(0)
+        woken = self.Semaphore(0)
+
+        p = self.Process(target=self.f, args=(cond, sleeping, woken))
+        p.set_daemon(True)
+        p.start()
+
+        p = threading.Thread(target=self.f, args=(cond, sleeping, woken))
+        p.setDaemon(True)
+        p.start()
+
+        # wait for both children to start sleeping
+        sleeping.acquire()
+        sleeping.acquire()
+
+        # check no process/thread has woken up
+        time.sleep(DELTA)
+        self.assertReturnsIfImplemented(0, get_value, woken)
+
+        # wake up one process/thread
+        cond.acquire()
+        cond.notify()
+        cond.release()
+
+        # check one process/thread has woken up
+        time.sleep(DELTA)
+        self.assertReturnsIfImplemented(1, get_value, woken)
+
+        # wake up another
+        cond.acquire()
+        cond.notify()
+        cond.release()
+
+        # check other has woken up
+        time.sleep(DELTA)
+        self.assertReturnsIfImplemented(2, get_value, woken)
+
+        # check state is not mucked up
+        self.check_invariant(cond)
+        p.join()
+
+    def test_notify_all(self):
+        cond = self.Condition()
+        sleeping = self.Semaphore(0)
+        woken = self.Semaphore(0)
+
+        # start some threads/processes which will timeout
+        for i in range(3):
+            p = self.Process(target=self.f,
+                             args=(cond, sleeping, woken, TIMEOUT1))
+            p.set_daemon(True)
+            p.start()
+
+            t = threading.Thread(target=self.f,
+                                 args=(cond, sleeping, woken, TIMEOUT1))
+            t.setDaemon(True)
+            t.start()
+
+        # wait for them all to sleep
+        for i in range(6):
+            sleeping.acquire()
+
+        # check they have all timed out
+        for i in range(6):
+            woken.acquire()
+        self.assertReturnsIfImplemented(0, get_value, woken)
+
+        # check state is not mucked up
+        self.check_invariant(cond)
+
+        # start some more threads/processes
+        for i in range(3):
+            p = self.Process(target=self.f, args=(cond, sleeping, woken))
+            p.set_daemon(True)
+            p.start()
+
+            t = threading.Thread(target=self.f, args=(cond, sleeping, woken))
+            t.setDaemon(True)
+            t.start()
+
+        # wait for them to all sleep
+        for i in range(6):
+            sleeping.acquire()
+
+        # check no process/thread has woken up
+        time.sleep(DELTA)
+        self.assertReturnsIfImplemented(0, get_value, woken)
+
+        # wake them all up
+        cond.acquire()
+        cond.notify_all()
+        cond.release()
+
+        # check they have all woken
+        time.sleep(DELTA)
+        self.assertReturnsIfImplemented(6, get_value, woken)
+
+        # check state is not mucked up
+        self.check_invariant(cond)
+
+    def test_timeout(self):
+        cond = self.Condition()
+        wait = TimingWrapper(cond.wait)
+        cond.acquire()
+        res = wait(TIMEOUT1)
+        cond.release()
+        self.assertEqual(res, None)
+        self.assertTimingAlmostEqual(wait.elapsed, TIMEOUT1)
+
+
+class _TestEvent(BaseTestCase):
+
+    def _test_event(self, event):
+        time.sleep(TIMEOUT2)
+        event.set()
+
+    def test_event(self):
+        event = self.Event()
+        wait = TimingWrapper(event.wait)
+
+        # Removed temporaily, due to API shear, this does not
+        # work with threading._Event objects. is_set == isSet
+        #self.assertEqual(event.is_set(), False)
+
+        self.assertEqual(wait(0.0), None)
+        self.assertTimingAlmostEqual(wait.elapsed, 0.0)
+        self.assertEqual(wait(TIMEOUT1), None)
+        self.assertTimingAlmostEqual(wait.elapsed, TIMEOUT1)
+
+        event.set()
+
+        # See note above on the API differences
+        # self.assertEqual(event.is_set(), True)
+        self.assertEqual(wait(), None)
+        self.assertTimingAlmostEqual(wait.elapsed, 0.0)
+        self.assertEqual(wait(TIMEOUT1), None)
+        self.assertTimingAlmostEqual(wait.elapsed, 0.0)
+        # self.assertEqual(event.is_set(), True)
+
+        event.clear()
+
+        #self.assertEqual(event.is_set(), False)
+
+        self.Process(target=self._test_event, args=(event,)).start()
+        self.assertEqual(wait(), None)
+
+#
+#
+#
+
+class _TestValue(BaseTestCase):
+
+    codes_values = [
+        ('i', 4343, 24234),
+        ('d', 3.625, -4.25),
+        ('h', -232, 234),
+        ('c', latin('x'), latin('y'))
+        ]
+
+    def _test(self, values):
+        for sv, cv in zip(values, self.codes_values):
+            sv.value = cv[2]
+
+
+    def test_value(self, raw=False):
+        if self.TYPE != 'processes':
+            return
+
+        if raw:
+            values = [self.RawValue(code, value)
+                      for code, value, _ in self.codes_values]
+        else:
+            values = [self.Value(code, value)
+                      for code, value, _ in self.codes_values]
+
+        for sv, cv in zip(values, self.codes_values):
+            self.assertEqual(sv.value, cv[1])
+
+        proc = self.Process(target=self._test, args=(values,))
+        proc.start()
+        proc.join()
+
+        for sv, cv in zip(values, self.codes_values):
+            self.assertEqual(sv.value, cv[2])
+
+    def test_rawvalue(self):
+        self.test_value(raw=True)
+
+    def test_getobj_getlock(self):
+        if self.TYPE != 'processes':
+            return
+
+        val1 = self.Value('i', 5)
+        lock1 = val1.get_lock()
+        obj1 = val1.get_obj()
+
+        val2 = self.Value('i', 5, lock=None)
+        lock2 = val2.get_lock()
+        obj2 = val2.get_obj()
+
+        lock = self.Lock()
+        val3 = self.Value('i', 5, lock=lock)
+        lock3 = val3.get_lock()
+        obj3 = val3.get_obj()
+        self.assertEqual(lock, lock3)
+
+        arr4 = self.RawValue('i', 5)
+        self.assertFalse(hasattr(arr4, 'get_lock'))
+        self.assertFalse(hasattr(arr4, 'get_obj'))
+
+
+class _TestArray(BaseTestCase):
+
+    def f(self, seq):
+        for i in range(1, len(seq)):
+            seq[i] += seq[i-1]
+
+    def test_array(self, raw=False):
+        if self.TYPE != 'processes':
+            return
+
+        seq = [680, 626, 934, 821, 150, 233, 548, 982, 714, 831]
+        if raw:
+            arr = self.RawArray('i', seq)
+        else:
+            arr = self.Array('i', seq)
+
+        self.assertEqual(len(arr), len(seq))
+        self.assertEqual(arr[3], seq[3])
+        self.assertEqual(list(arr[2:7]), list(seq[2:7]))
+
+        arr[4:8] = seq[4:8] = array.array('i', [1, 2, 3, 4])
+
+        self.assertEqual(list(arr[:]), seq)
+
+        self.f(seq)
+
+        p = self.Process(target=self.f, args=(arr,))
+        p.start()
+        p.join()
+
+        self.assertEqual(list(arr[:]), seq)
+
+    def test_rawarray(self):
+        self.test_array(raw=True)
+
+    def test_getobj_getlock_obj(self):
+        if self.TYPE != 'processes':
+            return
+
+        arr1 = self.Array('i', list(range(10)))
+        lock1 = arr1.get_lock()
+        obj1 = arr1.get_obj()
+
+        arr2 = self.Array('i', list(range(10)), lock=None)
+        lock2 = arr2.get_lock()
+        obj2 = arr2.get_obj()
+
+        lock = self.Lock()
+        arr3 = self.Array('i', list(range(10)), lock=lock)
+        lock3 = arr3.get_lock()
+        obj3 = arr3.get_obj()
+        self.assertEqual(lock, lock3)
+
+        arr4 = self.RawArray('i', list(range(10)))
+        self.assertFalse(hasattr(arr4, 'get_lock'))
+        self.assertFalse(hasattr(arr4, 'get_obj'))
+
+#
+#
+#
+
+class _TestContainers(BaseTestCase):
+
+    ALLOWED_TYPES = ('manager',)
+
+    def test_list(self):
+        a = self.list(list(range(10)))
+        self.assertEqual(a[:], list(range(10)))
+
+        b = self.list()
+        self.assertEqual(b[:], [])
+
+        b.extend(list(range(5)))
+        self.assertEqual(b[:], list(range(5)))
+
+        self.assertEqual(b[2], 2)
+        self.assertEqual(b[2:10], [2,3,4])
+
+        b *= 2
+        self.assertEqual(b[:], [0, 1, 2, 3, 4, 0, 1, 2, 3, 4])
+
+        self.assertEqual(b + [5, 6], [0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 5, 6])
+
+        self.assertEqual(a[:], list(range(10)))
+
+        d = [a, b]
+        e = self.list(d)
+        self.assertEqual(
+            e[:],
+            [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [0, 1, 2, 3, 4, 0, 1, 2, 3, 4]]
+            )
+
+        f = self.list([a])
+        a.append('hello')
+        self.assertEqual(f[:], [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'hello']])
+
+    def test_dict(self):
+        d = self.dict()
+        indices = list(range(65, 70))
+        for i in indices:
+            d[i] = chr(i)
+        self.assertEqual(d.copy(), dict((i, chr(i)) for i in indices))
+        self.assertEqual(sorted(d.keys()), indices)
+        self.assertEqual(sorted(d.values()), [chr(i) for i in indices])
+        self.assertEqual(sorted(d.items()), [(i, chr(i)) for i in indices])
+
+    def test_namespace(self):
+        n = self.Namespace()
+        n.name = 'Bob'
+        n.job = 'Builder'
+        n._hidden = 'hidden'
+        self.assertEqual((n.name, n.job), ('Bob', 'Builder'))
+        del n.job
+        self.assertEqual(str(n), "Namespace(name='Bob')")
+        self.assertTrue(hasattr(n, 'name'))
+        self.assertTrue(not hasattr(n, 'job'))
+
+#
+#
+#
+
+def sqr(x, wait=0.0):
+    time.sleep(wait)
+    return x*x
+
+class _TestPool(BaseTestCase):
+
+    def test_apply(self):
+        papply = self.pool.apply
+        self.assertEqual(papply(sqr, (5,)), sqr(5))
+        self.assertEqual(papply(sqr, (), {'x':3}), sqr(x=3))
+
+    def test_map(self):
+        pmap = self.pool.map
+        self.assertEqual(pmap(sqr, list(range(10))), list(map(sqr, list(range(10)))))
+        self.assertEqual(pmap(sqr, list(range(100)), chunksize=20),
+                         list(map(sqr, list(range(100)))))
+
+    def test_async(self):
+        res = self.pool.apply_async(sqr, (7, TIMEOUT1,))
+        get = TimingWrapper(res.get)
+        self.assertEqual(get(), 49)
+        self.assertTimingAlmostEqual(get.elapsed, TIMEOUT1)
+
+    def test_async_timeout(self):
+        res = self.pool.apply_async(sqr, (6, TIMEOUT2 + 0.2))
+        get = TimingWrapper(res.get)
+        self.assertRaises(multiprocessing.TimeoutError, get, timeout=TIMEOUT2)
+        self.assertTimingAlmostEqual(get.elapsed, TIMEOUT2)
+
+    def test_imap(self):
+        it = self.pool.imap(sqr, list(range(10)))
+        self.assertEqual(list(it), list(map(sqr, list(range(10)))))
+
+        it = self.pool.imap(sqr, list(range(10)))
+        for i in range(10):
+            self.assertEqual(next(it), i*i)
+        self.assertRaises(StopIteration, it.__next__)
+
+        it = self.pool.imap(sqr, list(range(1000)), chunksize=100)
+        for i in range(1000):
+            self.assertEqual(next(it), i*i)
+        self.assertRaises(StopIteration, it.__next__)
+
+    def test_imap_unordered(self):
+        it = self.pool.imap_unordered(sqr, list(range(1000)))
+        self.assertEqual(sorted(it), list(map(sqr, list(range(1000)))))
+
+        it = self.pool.imap_unordered(sqr, list(range(1000)), chunksize=53)
+        self.assertEqual(sorted(it), list(map(sqr, list(range(1000)))))
+
+    def test_make_pool(self):
+        p = multiprocessing.Pool(3)
+        self.assertEqual(3, len(p._pool))
+        p.close()
+        p.join()
+
+    def test_terminate(self):
+        if self.TYPE == 'manager':
+            # On Unix a forked process increfs each shared object to
+            # which its parent process held a reference.  If the
+            # forked process gets terminated then there is likely to
+            # be a reference leak.  So to prevent
+            # _TestZZZNumberOfObjects from failing we skip this test
+            # when using a manager.
+            return
+
+        result = self.pool.map_async(
+            time.sleep, [0.1 for i in range(10000)], chunksize=1
+            )
+        self.pool.terminate()
+        join = TimingWrapper(self.pool.join)
+        join()
+        self.assertTrue(join.elapsed < 0.2)
+
+#
+# Test that manager has expected number of shared objects left
+#
+
+class _TestZZZNumberOfObjects(BaseTestCase):
+    # Because test cases are sorted alphabetically, this one will get
+    # run after all the other tests for the manager.  It tests that
+    # there have been no "reference leaks" for the manager's shared
+    # objects.  Note the comment in _TestPool.test_terminate().
+    ALLOWED_TYPES = ('manager',)
+
+    def test_number_of_objects(self):
+        EXPECTED_NUMBER = 1                # the pool object is still alive
+        multiprocessing.active_children()  # discard dead process objs
+        gc.collect()                       # do garbage collection
+        refs = self.manager._number_of_objects()
+        if refs != EXPECTED_NUMBER:
+            print(self.manager._debugInfo())
+
+        self.assertEqual(refs, EXPECTED_NUMBER)
+
+#
+# Test of creating a customized manager class
+#
+
+from multiprocessing.managers import BaseManager, BaseProxy, RemoteError
+
+class FooBar(object):
+    def f(self):
+        return 'f()'
+    def g(self):
+        raise ValueError
+    def _h(self):
+        return '_h()'
+
+def baz():
+    for i in range(10):
+        yield i*i
+
+class IteratorProxy(BaseProxy):
+    _exposed_ = ('next', '__next__')
+    def __iter__(self):
+        return self
+    def __next__(self):
+        return self._callmethod('next')
+    def __next__(self):
+        return self._callmethod('__next__')
+
+class MyManager(BaseManager):
+    pass
+
+MyManager.register('Foo', callable=FooBar)
+MyManager.register('Bar', callable=FooBar, exposed=('f', '_h'))
+MyManager.register('baz', callable=baz, proxytype=IteratorProxy)
+
+
+class _TestMyManager(BaseTestCase):
+
+    ALLOWED_TYPES = ('manager',)
+
+    def test_mymanager(self):
+        manager = MyManager()
+        manager.start()
+
+        foo = manager.Foo()
+        bar = manager.Bar()
+        baz = manager.baz()
+
+        foo_methods = [name for name in ('f', 'g', '_h') if hasattr(foo, name)]
+        bar_methods = [name for name in ('f', 'g', '_h') if hasattr(bar, name)]
+
+        self.assertEqual(foo_methods, ['f', 'g'])
+        self.assertEqual(bar_methods, ['f', '_h'])
+
+        self.assertEqual(foo.f(), 'f()')
+        self.assertRaises(ValueError, foo.g)
+        self.assertEqual(foo._callmethod('f'), 'f()')
+        self.assertRaises(RemoteError, foo._callmethod, '_h')
+
+        self.assertEqual(bar.f(), 'f()')
+        self.assertEqual(bar._h(), '_h()')
+        self.assertEqual(bar._callmethod('f'), 'f()')
+        self.assertEqual(bar._callmethod('_h'), '_h()')
+
+        self.assertEqual(list(baz), [i*i for i in range(10)])
+
+        manager.shutdown()
+
+#
+# Test of connecting to a remote server and using xmlrpclib for serialization
+#
+
+_queue = pyqueue.Queue()
+def get_queue():
+    return _queue
+
+class QueueManager(BaseManager):
+    '''manager class used by server process'''
+QueueManager.register('get_queue', callable=get_queue)
+
+class QueueManager2(BaseManager):
+    '''manager class which specifies the same interface as QueueManager'''
+QueueManager2.register('get_queue')
+
+
+SERIALIZER = 'xmlrpclib'
+
+class _TestRemoteManager(BaseTestCase):
+
+    ALLOWED_TYPES = ('manager',)
+
+    def _putter(self, address, authkey):
+        manager = QueueManager2(
+            address=address, authkey=authkey, serializer=SERIALIZER
+            )
+        manager.connect()
+        queue = manager.get_queue()
+        queue.put(('hello world', None, True, 2.25))
+
+    def test_remote(self):
+        authkey = os.urandom(32)
+
+        manager = QueueManager(
+            address=('localhost', 0), authkey=authkey, serializer=SERIALIZER
+            )
+        manager.start()
+
+        p = self.Process(target=self._putter, args=(manager.address, authkey))
+        p.start()
+
+        manager2 = QueueManager2(
+            address=manager.address, authkey=authkey, serializer=SERIALIZER
+            )
+        manager2.connect()
+        queue = manager2.get_queue()
+
+        # Note that xmlrpclib will deserialize object as a list not a tuple
+        self.assertEqual(queue.get(), ['hello world', None, True, 2.25])
+
+        # Because we are using xmlrpclib for serialization instead of
+        # pickle this will cause a serialization error.
+        self.assertRaises(Exception, queue.put, time.sleep)
+
+        # Make queue finalizer run before the server is stopped
+        del queue
+        manager.shutdown()
+
+#
+#
+#
+
+SENTINEL = latin('')
+
+class _TestConnection(BaseTestCase):
+
+    ALLOWED_TYPES = ('processes', 'threads')
+
+    def _echo(self, conn):
+        for msg in iter(conn.recv_bytes, SENTINEL):
+            conn.send_bytes(msg)
+        conn.close()
+
+    def test_connection(self):
+        conn, child_conn = self.Pipe()
+
+        p = self.Process(target=self._echo, args=(child_conn,))
+        p.set_daemon(True)
+        p.start()
+
+        seq = [1, 2.25, None]
+        msg = latin('hello world')
+        longmsg = msg * 10
+        arr = array.array('i', list(range(4)))
+
+        if self.TYPE == 'processes':
+            self.assertEqual(type(conn.fileno()), int)
+
+        self.assertEqual(conn.send(seq), None)
+        self.assertEqual(conn.recv(), seq)
+
+        self.assertEqual(conn.send_bytes(msg), None)
+        self.assertEqual(conn.recv_bytes(), msg)
+
+        if self.TYPE == 'processes':
+            buffer = array.array('i', [0]*10)
+            expected = list(arr) + [0] * (10 - len(arr))
+            self.assertEqual(conn.send_bytes(arr), None)
+            self.assertEqual(conn.recv_bytes_into(buffer),
+                             len(arr) * buffer.itemsize)
+            self.assertEqual(list(buffer), expected)
+
+            buffer = array.array('i', [0]*10)
+            expected = [0] * 3 + list(arr) + [0] * (10 - 3 - len(arr))
+            self.assertEqual(conn.send_bytes(arr), None)
+            self.assertEqual(conn.recv_bytes_into(buffer, 3 * buffer.itemsize),
+                             len(arr) * buffer.itemsize)
+            self.assertEqual(list(buffer), expected)
+
+            buffer = bytearray(latin(' ' * 40))
+            self.assertEqual(conn.send_bytes(longmsg), None)
+            try:
+                res = conn.recv_bytes_into(buffer)
+            except multiprocessing.BufferTooShort as e:
+                self.assertEqual(e.args, (longmsg,))
+            else:
+                self.fail('expected BufferTooShort, got %s' % res)
+
+        poll = TimingWrapper(conn.poll)
+
+        self.assertEqual(poll(), False)
+        self.assertTimingAlmostEqual(poll.elapsed, 0)
+
+        self.assertEqual(poll(TIMEOUT1), False)
+        self.assertTimingAlmostEqual(poll.elapsed, TIMEOUT1)
+
+        conn.send(None)
+
+        self.assertEqual(poll(TIMEOUT1), True)
+        self.assertTimingAlmostEqual(poll.elapsed, 0)
+
+        self.assertEqual(conn.recv(), None)
+
+        really_big_msg = latin('X') * (1024 * 1024 * 16)   # 16Mb
+        conn.send_bytes(really_big_msg)
+        self.assertEqual(conn.recv_bytes(), really_big_msg)
+
+        conn.send_bytes(SENTINEL)                          # tell child to quit
+        child_conn.close()
+
+        if self.TYPE == 'processes':
+            self.assertEqual(conn.readable, True)
+            self.assertEqual(conn.writable, True)
+            self.assertRaises(EOFError, conn.recv)
+            self.assertRaises(EOFError, conn.recv_bytes)
+
+        p.join()
+
+    def test_duplex_false(self):
+        reader, writer = self.Pipe(duplex=False)
+        self.assertEqual(writer.send(1), None)
+        self.assertEqual(reader.recv(), 1)
+        if self.TYPE == 'processes':
+            self.assertEqual(reader.readable, True)
+            self.assertEqual(reader.writable, False)
+            self.assertEqual(writer.readable, False)
+            self.assertEqual(writer.writable, True)
+            self.assertRaises(IOError, reader.send, 2)
+            self.assertRaises(IOError, writer.recv)
+            self.assertRaises(IOError, writer.poll)
+
+    def test_spawn_close(self):
+        # We test that a pipe connection can be closed by parent
+        # process immediately after child is spawned.  On Windows this
+        # would have sometimes failed on old versions because
+        # child_conn would be closed before the child got a chance to
+        # duplicate it.
+        conn, child_conn = self.Pipe()
+
+        p = self.Process(target=self._echo, args=(child_conn,))
+        p.start()
+        child_conn.close()    # this might complete before child initializes
+
+        msg = latin('hello')
+        conn.send_bytes(msg)
+        self.assertEqual(conn.recv_bytes(), msg)
+
+        conn.send_bytes(SENTINEL)
+        conn.close()
+        p.join()
+
+    def test_sendbytes(self):
+        if self.TYPE != 'processes':
+            return
+
+        msg = latin('abcdefghijklmnopqrstuvwxyz')
+        a, b = self.Pipe()
+
+        a.send_bytes(msg)
+        self.assertEqual(b.recv_bytes(), msg)
+
+        a.send_bytes(msg, 5)
+        self.assertEqual(b.recv_bytes(), msg[5:])
+
+        a.send_bytes(msg, 7, 8)
+        self.assertEqual(b.recv_bytes(), msg[7:7+8])
+
+        a.send_bytes(msg, 26)
+        self.assertEqual(b.recv_bytes(), latin(''))
+
+        a.send_bytes(msg, 26, 0)
+        self.assertEqual(b.recv_bytes(), latin(''))
+
+        self.assertRaises(ValueError, a.send_bytes, msg, 27)
+
+        self.assertRaises(ValueError, a.send_bytes, msg, 22, 5)
+
+        self.assertRaises(ValueError, a.send_bytes, msg, 26, 1)
+
+        self.assertRaises(ValueError, a.send_bytes, msg, -1)
+
+        self.assertRaises(ValueError, a.send_bytes, msg, 4, -1)
+
+
+class _TestListenerClient(BaseTestCase):
+
+    ALLOWED_TYPES = ('processes', 'threads')
+
+    def _test(self, address):
+        conn = self.connection.Client(address)
+        conn.send('hello')
+        conn.close()
+
+    def test_listener_client(self):
+        for family in self.connection.families:
+            l = self.connection.Listener(family=family)
+            p = self.Process(target=self._test, args=(l.address,))
+            p.set_daemon(True)
+            p.start()
+            conn = l.accept()
+            self.assertEqual(conn.recv(), 'hello')
+            p.join()
+            l.close()
+
+#
+# Test of sending connection and socket objects between processes
+#
+
+class _TestPicklingConnections(BaseTestCase):
+
+    ALLOWED_TYPES = ('processes',)
+
+    def _listener(self, conn, families):
+        for fam in families:
+            l = self.connection.Listener(family=fam)
+            conn.send(l.address)
+            new_conn = l.accept()
+            conn.send(new_conn)
+
+        if self.TYPE == 'processes':
+            l = socket.socket()
+            l.bind(('localhost', 0))
+            conn.send(l.getsockname())
+            l.listen(1)
+            new_conn, addr = l.accept()
+            conn.send(new_conn)
+
+        conn.recv()
+
+    def _remote(self, conn):
+        for (address, msg) in iter(conn.recv, None):
+            client = self.connection.Client(address)
+            client.send(msg.upper())
+            client.close()
+
+        if self.TYPE == 'processes':
+            address, msg = conn.recv()
+            client = socket.socket()
+            client.connect(address)
+            client.sendall(msg.upper())
+            client.close()
+
+        conn.close()
+
+    def test_pickling(self):
+        try:
+            multiprocessing.allow_connection_pickling()
+        except ImportError:
+            return
+
+        families = self.connection.families
+
+        lconn, lconn0 = self.Pipe()
+        lp = self.Process(target=self._listener, args=(lconn0, families))
+        lp.start()
+        lconn0.close()
+
+        rconn, rconn0 = self.Pipe()
+        rp = self.Process(target=self._remote, args=(rconn0,))
+        rp.start()
+        rconn0.close()
+
+        for fam in families:
+            msg = ('This connection uses family %s' % fam).encode('ascii')
+            address = lconn.recv()
+            rconn.send((address, msg))
+            new_conn = lconn.recv()
+            self.assertEqual(new_conn.recv(), msg.upper())
+
+        rconn.send(None)
+
+        if self.TYPE == 'processes':
+            msg = latin('This connection uses a normal socket')
+            address = lconn.recv()
+            rconn.send((address, msg))
+            if hasattr(socket, 'fromfd'):
+                new_conn = lconn.recv()
+                self.assertEqual(new_conn.recv(100), msg.upper())
+            else:
+                # XXX On Windows with Py2.6 need to backport fromfd()
+                discard = lconn.recv_bytes()
+
+        lconn.send(None)
+
+        rconn.close()
+        lconn.close()
+
+        lp.join()
+        rp.join()
+
+#
+#
+#
+
+class _TestHeap(BaseTestCase):
+
+    ALLOWED_TYPES = ('processes',)
+
+    def test_heap(self):
+        iterations = 5000
+        maxblocks = 50
+        blocks = []
+
+        # create and destroy lots of blocks of different sizes
+        for i in range(iterations):
+            size = int(random.lognormvariate(0, 1) * 1000)
+            b = multiprocessing.heap.BufferWrapper(size)
+            blocks.append(b)
+            if len(blocks) > maxblocks:
+                i = random.randrange(maxblocks)
+                del blocks[i]
+
+        # get the heap object
+        heap = multiprocessing.heap.BufferWrapper._heap
+
+        # verify the state of the heap
+        all = []
+        occupied = 0
+        for L in list(heap._len_to_seq.values()):
+            for arena, start, stop in L:
+                all.append((heap._arenas.index(arena), start, stop,
+                            stop-start, 'free'))
+        for arena, start, stop in heap._allocated_blocks:
+            all.append((heap._arenas.index(arena), start, stop,
+                        stop-start, 'occupied'))
+            occupied += (stop-start)
+
+        all.sort()
+
+        for i in range(len(all)-1):
+            (arena, start, stop) = all[i][:3]
+            (narena, nstart, nstop) = all[i+1][:3]
+            self.assertTrue((arena != narena and nstart == 0) or
+                            (stop == nstart))
+
+#
+#
+#
+
+try:
+    from ctypes import Structure, Value, copy, c_int, c_double
+except ImportError:
+    Structure = object
+    c_int = c_double = None
+
+class _Foo(Structure):
+    _fields_ = [
+        ('x', c_int),
+        ('y', c_double)
+        ]
+
+class _TestSharedCTypes(BaseTestCase):
+
+    ALLOWED_TYPES = ('processes',)
+
+    def _double(self, x, y, foo, arr, string):
+        x.value *= 2
+        y.value *= 2
+        foo.x *= 2
+        foo.y *= 2
+        string.value *= 2
+        for i in range(len(arr)):
+            arr[i] *= 2
+
+    def test_sharedctypes(self, lock=False):
+        if c_int is None:
+            return
+
+        x = Value('i', 7, lock=lock)
+        y = Value(ctypes.c_double, 1.0/3.0, lock=lock)
+        foo = Value(_Foo, 3, 2, lock=lock)
+        arr = Array('d', list(range(10)), lock=lock)
+        string = Array('c', 20, lock=lock)
+        string.value = 'hello'
+
+        p = self.Process(target=self._double, args=(x, y, foo, arr, string))
+        p.start()
+        p.join()
+
+        self.assertEqual(x.value, 14)
+        self.assertAlmostEqual(y.value, 2.0/3.0)
+        self.assertEqual(foo.x, 6)
+        self.assertAlmostEqual(foo.y, 4.0)
+        for i in range(10):
+            self.assertAlmostEqual(arr[i], i*2)
+        self.assertEqual(string.value, latin('hellohello'))
+
+    def test_synchronize(self):
+        self.test_sharedctypes(lock=True)
+
+    def test_copy(self):
+        if c_int is None:
+            return
+
+        foo = _Foo(2, 5.0)
+        bar = copy(foo)
+        foo.x = 0
+        foo.y = 0
+        self.assertEqual(bar.x, 2)
+        self.assertAlmostEqual(bar.y, 5.0)
+
+#
+#
+#
+
+class _TestFinalize(BaseTestCase):
+
+    ALLOWED_TYPES = ('processes',)
+
+    def _test_finalize(self, conn):
+        class Foo(object):
+            pass
+
+        a = Foo()
+        util.Finalize(a, conn.send, args=('a',))
+        del a           # triggers callback for a
+
+        b = Foo()
+        close_b = util.Finalize(b, conn.send, args=('b',))
+        close_b()       # triggers callback for b
+        close_b()       # does nothing because callback has already been called
+        del b           # does nothing because callback has already been called
+
+        c = Foo()
+        util.Finalize(c, conn.send, args=('c',))
+
+        d10 = Foo()
+        util.Finalize(d10, conn.send, args=('d10',), exitpriority=1)
+
+        d01 = Foo()
+        util.Finalize(d01, conn.send, args=('d01',), exitpriority=0)
+        d02 = Foo()
+        util.Finalize(d02, conn.send, args=('d02',), exitpriority=0)
+        d03 = Foo()
+        util.Finalize(d03, conn.send, args=('d03',), exitpriority=0)
+
+        util.Finalize(None, conn.send, args=('e',), exitpriority=-10)
+
+        util.Finalize(None, conn.send, args=('STOP',), exitpriority=-100)
+
+        # call mutliprocessing's cleanup function then exit process without
+        # garbage collecting locals
+        util._exit_function()
+        conn.close()
+        os._exit(0)
+
+    def test_finalize(self):
+        conn, child_conn = self.Pipe()
+
+        p = self.Process(target=self._test_finalize, args=(child_conn,))
+        p.start()
+        p.join()
+
+        result = [obj for obj in iter(conn.recv, 'STOP')]
+        self.assertEqual(result, ['a', 'b', 'd10', 'd03', 'd02', 'd01', 'e'])
+
+#
+# Test that from ... import * works for each module
+#
+
+class _TestImportStar(BaseTestCase):
+
+    ALLOWED_TYPES = ('processes',)
+
+    def test_import(self):
+        modules = (
+            'multiprocessing', 'multiprocessing.connection',
+            'multiprocessing.heap', 'multiprocessing.managers',
+            'multiprocessing.pool', 'multiprocessing.process',
+            'multiprocessing.reduction', 'multiprocessing.sharedctypes',
+            'multiprocessing.synchronize', 'multiprocessing.util'
+            )
+
+        for name in modules:
+            __import__(name)
+            mod = sys.modules[name]
+
+            for attr in getattr(mod, '__all__', ()):
+                self.assertTrue(
+                    hasattr(mod, attr),
+                    '%r does not have attribute %r' % (mod, attr)
+                    )
+
+#
+# Quick test that logging works -- does not test logging output
+#
+
+class _TestLogging(BaseTestCase):
+
+    ALLOWED_TYPES = ('processes',)
+
+    def test_enable_logging(self):
+        logger = multiprocessing.get_logger()
+        logger.setLevel(util.SUBWARNING)
+        self.assertTrue(logger is not None)
+        logger.debug('this will not be printed')
+        logger.info('nor will this')
+        logger.setLevel(LOG_LEVEL)
+
+    def _test_level(self, conn):
+        logger = multiprocessing.get_logger()
+        conn.send(logger.getEffectiveLevel())
+
+    def test_level(self):
+        LEVEL1 = 32
+        LEVEL2 = 37
+
+        logger = multiprocessing.get_logger()
+        root_logger = logging.getLogger()
+        root_level = root_logger.level
+
+        reader, writer = multiprocessing.Pipe(duplex=False)
+
+        logger.setLevel(LEVEL1)
+        self.Process(target=self._test_level, args=(writer,)).start()
+        self.assertEqual(LEVEL1, reader.recv())
+
+        logger.setLevel(logging.NOTSET)
+        root_logger.setLevel(LEVEL2)
+        self.Process(target=self._test_level, args=(writer,)).start()
+        self.assertEqual(LEVEL2, reader.recv())
+
+        root_logger.setLevel(root_level)
+        logger.setLevel(level=LOG_LEVEL)
+
+#
+# Functions used to create test cases from the base ones in this module
+#
+
+def get_attributes(Source, names):
+    d = {}
+    for name in names:
+        obj = getattr(Source, name)
+        if type(obj) == type(get_attributes):
+            obj = staticmethod(obj)
+        d[name] = obj
+    return d
+
+def create_test_cases(Mixin, type):
+    result = {}
+    glob = globals()
+    Type = type[0].upper() + type[1:]
+
+    for name in list(glob.keys()):
+        if name.startswith('_Test'):
+            base = glob[name]
+            if type in base.ALLOWED_TYPES:
+                newname = 'With' + Type + name[1:]
+                class Temp(base, unittest.TestCase, Mixin):
+                    pass
+                result[newname] = Temp
+                Temp.__name__ = newname
+                Temp.__module__ = Mixin.__module__
+    return result
+
+#
+# Create test cases
+#
+
+class ProcessesMixin(object):
+    TYPE = 'processes'
+    Process = multiprocessing.Process
+    locals().update(get_attributes(multiprocessing, (
+        'Queue', 'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore',
+        'Condition', 'Event', 'Value', 'Array', 'RawValue',
+        'RawArray', 'current_process', 'active_children', 'Pipe',
+        'connection', 'JoinableQueue'
+        )))
+
+testcases_processes = create_test_cases(ProcessesMixin, type='processes')
+globals().update(testcases_processes)
+
+
+class ManagerMixin(object):
+    TYPE = 'manager'
+    Process = multiprocessing.Process
+    manager = object.__new__(multiprocessing.managers.SyncManager)
+    locals().update(get_attributes(manager, (
+        'Queue', 'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore',
+       'Condition', 'Event', 'Value', 'Array', 'list', 'dict',
+        'Namespace', 'JoinableQueue'
+        )))
+
+testcases_manager = create_test_cases(ManagerMixin, type='manager')
+globals().update(testcases_manager)
+
+
+class ThreadsMixin(object):
+    TYPE = 'threads'
+    Process = multiprocessing.dummy.Process
+    locals().update(get_attributes(multiprocessing.dummy, (
+        'Queue', 'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore',
+        'Condition', 'Event', 'Value', 'Array', 'current_process',
+        'active_children', 'Pipe', 'connection', 'dict', 'list',
+        'Namespace', 'JoinableQueue'
+        )))
+
+testcases_threads = create_test_cases(ThreadsMixin, type='threads')
+globals().update(testcases_threads)
+
+#
+#
+#
+
+def test_main(run=None):
+    if run is None:
+        from test.support import run_unittest as run
+
+    util.get_temp_dir()     # creates temp directory for use by all processes
+
+    multiprocessing.get_logger().setLevel(LOG_LEVEL)
+
+    ProcessesMixin.pool = multiprocessing.Pool(4)
+    ThreadsMixin.pool = multiprocessing.dummy.Pool(4)
+    ManagerMixin.manager.__init__()
+    ManagerMixin.manager.start()
+    ManagerMixin.pool = ManagerMixin.manager.Pool(4)
+
+    testcases = (
+        sorted(list(testcases_processes.values()), key=lambda tc:tc.__name__) +
+        sorted(list(testcases_threads.values()), key=lambda tc:tc.__name__) +
+        sorted(list(testcases_manager.values()), key=lambda tc:tc.__name__)
+        )
+
+    loadTestsFromTestCase = unittest.defaultTestLoader.loadTestsFromTestCase
+    suite = unittest.TestSuite(loadTestsFromTestCase(tc) for tc in testcases)
+    run(suite)
+
+    ThreadsMixin.pool.terminate()
+    ProcessesMixin.pool.terminate()
+    ManagerMixin.pool.terminate()
+    ManagerMixin.manager.shutdown()
+
+    del ProcessesMixin.pool, ThreadsMixin.pool, ManagerMixin.pool
+
+def main():
+    test_main(unittest.TextTestRunner(verbosity=2).run)
+
+if __name__ == '__main__':
+    main()

Modified: python/branches/py3k/Modules/_multiprocessing/connection.h
==============================================================================
--- /python/trunk/Modules/_multiprocessing/connection.h	(original)
+++ python/branches/py3k/Modules/_multiprocessing/connection.h	Wed Jun 11 18:44:04 2008
@@ -175,9 +175,9 @@
 		mp_SetError(PyExc_IOError, res);
 	} else {    
 		if (freeme == NULL) {
-			result = PyString_FromStringAndSize(self->buffer, res);
+			result = PyBytes_FromStringAndSize(self->buffer, res);
 		} else {
-			result = PyString_FromStringAndSize(freeme, res);
+			result = PyBytes_FromStringAndSize(freeme, res);
 			PyMem_Free(freeme);
 		}
 	}
@@ -263,7 +263,7 @@
 	if (!pickled_string)
 		goto failure;
 
-	if (PyString_AsStringAndSize(pickled_string, &buffer, &length) < 0)
+	if (PyBytes_AsStringAndSize(pickled_string, &buffer, &length) < 0)
 		goto failure;
 
 	Py_BEGIN_ALLOW_THREADS
@@ -311,9 +311,9 @@
 		mp_SetError(PyExc_IOError, res);
 	} else {    
 		if (freeme == NULL) {
-			temp = PyString_FromStringAndSize(self->buffer, res);
+			temp = PyBytes_FromStringAndSize(self->buffer, res);
 		} else {
-			temp = PyString_FromStringAndSize(freeme, res);
+			temp = PyBytes_FromStringAndSize(freeme, res);
 			PyMem_Free(freeme);
 		}
 	}

Modified: python/branches/py3k/Modules/_multiprocessing/multiprocessing.c
==============================================================================
--- /python/trunk/Modules/_multiprocessing/multiprocessing.c	(original)
+++ python/branches/py3k/Modules/_multiprocessing/multiprocessing.c	Wed Jun 11 18:44:04 2008
@@ -212,20 +212,33 @@
  * Initialize
  */
 
-PyMODINIT_FUNC
-init_multiprocessing(void)
+static struct PyModuleDef multiprocessing_module = {
+	PyModuleDef_HEAD_INIT,
+	"_multiprocessing",
+	NULL,
+	-1,
+	module_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
+
+PyObject*
+PyInit__multiprocessing(void)
 {
 	PyObject *module, *temp;
 
 	/* Initialize module */
-	module = Py_InitModule("_multiprocessing", module_methods);
+	module = PyModule_Create(&multiprocessing_module);
 	if (!module)
-		return;
+		return NULL;
 
 	/* Get copy of objects from pickle */
 	temp = PyImport_ImportModule(PICKLE_MODULE);
 	if (!temp)
-		return;
+		return NULL;
 	pickle_dumps = PyObject_GetAttrString(temp, "dumps");
 	pickle_loads = PyObject_GetAttrString(temp, "loads");
 	pickle_protocol = PyObject_GetAttrString(temp, "HIGHEST_PROTOCOL");
@@ -234,20 +247,20 @@
 	/* Get copy of BufferTooShort */
 	temp = PyImport_ImportModule("multiprocessing");
 	if (!temp)
-		return;
+		return NULL;
 	BufferTooShort = PyObject_GetAttrString(temp, "BufferTooShort");
 	Py_XDECREF(temp);
 
 	/* Add connection type to module */
 	if (PyType_Ready(&ConnectionType) < 0)
-		return;
+		return NULL;
 	Py_INCREF(&ConnectionType);	
 	PyModule_AddObject(module, "Connection", (PyObject*)&ConnectionType);
 
 #if defined(MS_WINDOWS) || HAVE_SEM_OPEN
 	/* Add SemLock type to module */
 	if (PyType_Ready(&SemLockType) < 0)
-		return;
+		return NULL;
 	Py_INCREF(&SemLockType);
 	PyDict_SetItemString(SemLockType.tp_dict, "SEM_VALUE_MAX", 
 			     Py_BuildValue("i", SEM_VALUE_MAX));
@@ -257,7 +270,7 @@
 #ifdef MS_WINDOWS
 	/* Add PipeConnection to module */
 	if (PyType_Ready(&PipeConnectionType) < 0)
-		return;
+		return NULL;
 	Py_INCREF(&PipeConnectionType);
 	PyModule_AddObject(module, "PipeConnection",
 			   (PyObject*)&PipeConnectionType);
@@ -265,30 +278,30 @@
 	/* Initialize win32 class and add to multiprocessing */
 	temp = create_win32_namespace();
 	if (!temp)
-		return;
+		return NULL;
 	PyModule_AddObject(module, "win32", temp);
 
 	/* Initialize the event handle used to signal Ctrl-C */
 	sigint_event = CreateEvent(NULL, TRUE, FALSE, NULL);
 	if (!sigint_event) {
 		PyErr_SetFromWindowsErr(0);
-		return;
+		return NULL;
 	}
 	if (!SetConsoleCtrlHandler(ProcessingCtrlHandler, TRUE)) {
 		PyErr_SetFromWindowsErr(0);
-		return;
+		return NULL;
 	}
 #endif
 
 	/* Add configuration macros */
 	temp = PyDict_New();
 	if (!temp)
-		return;
+		return NULL;
 	if (PyModule_AddObject(module, "flags", temp) < 0)
-		return;
+		return NULL;
 
 #define ADD_FLAG(name) \
-    if (PyDict_SetItemString(temp, #name, Py_BuildValue("i", name)) < 0) return
+       if (PyDict_SetItemString(temp, #name, Py_BuildValue("i", name)) < 0) return NULL
 	
 #ifdef HAVE_SEM_OPEN
 	ADD_FLAG(HAVE_SEM_OPEN);
@@ -305,4 +318,5 @@
 #ifdef HAVE_BROKEN_SEM_UNLINK
 	ADD_FLAG(HAVE_BROKEN_SEM_UNLINK);
 #endif
+        return module;
 }

Modified: python/branches/py3k/setup.py
==============================================================================
--- python/branches/py3k/setup.py	(original)
+++ python/branches/py3k/setup.py	Wed Jun 11 18:44:04 2008
@@ -1110,6 +1110,56 @@
 
         # _fileio -- supposedly cross platform
         exts.append(Extension('_fileio', ['_fileio.c']))
+        # Richard Oudkerk's multiprocessing module
+        if platform == 'win32':             # Windows
+            macros = dict()
+            libraries = ['ws2_32']
+
+        elif platform == 'darwin':          # Mac OSX
+            macros = dict(
+                HAVE_SEM_OPEN=1,
+                HAVE_SEM_TIMEDWAIT=0,
+                HAVE_FD_TRANSFER=1,
+                HAVE_BROKEN_SEM_GETVALUE=1
+                )
+            libraries = []
+
+        elif platform == 'cygwin':          # Cygwin
+            macros = dict(
+                HAVE_SEM_OPEN=1,
+                HAVE_SEM_TIMEDWAIT=1,
+                HAVE_FD_TRANSFER=0,
+                HAVE_BROKEN_SEM_UNLINK=1
+                )
+            libraries = []
+        else:                                   # Linux and other unices
+            macros = dict(
+                HAVE_SEM_OPEN=1,
+                HAVE_SEM_TIMEDWAIT=1,
+                HAVE_FD_TRANSFER=1
+                )
+            libraries = ['rt']
+
+        if platform == 'win32':
+            multiprocessing_srcs = [ '_multiprocessing/multiprocessing.c',
+                                     '_multiprocessing/semaphore.c',
+                                     '_multiprocessing/pipe_connection.c',
+                                     '_multiprocessing/socket_connection.c',
+                                     '_multiprocessing/win32_functions.c'
+                                   ]
+
+        else:
+            multiprocessing_srcs = [ '_multiprocessing/multiprocessing.c',
+                                     '_multiprocessing/socket_connection.c'
+                                   ]
+
+            if macros.get('HAVE_SEM_OPEN', False):
+                multiprocessing_srcs.append('_multiprocessing/semaphore.c')
+
+        exts.append ( Extension('_multiprocessing', multiprocessing_srcs,
+                                 define_macros=list(macros.items()),
+                                 include_dirs=["Modules/_multiprocessing"]))
+        # End multiprocessing
 
         # Platform-specific libraries
         if platform in ('linux2', 'freebsd4', 'freebsd5', 'freebsd6',

From python-3000-checkins at python.org  Wed Jun 11 18:57:55 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Wed, 11 Jun 2008 18:57:55 +0200 (CEST)
Subject: [Python-3000-checkins] r64124 - in python/branches/py3k:
	PCbuild/_multiprocessing.vcproj PCbuild/pcbuild.sln
Message-ID: <20080611165755.3653E1E4008@bag.python.org>

Author: benjamin.peterson
Date: Wed Jun 11 18:57:54 2008
New Revision: 64124

Log:
Merged revisions 64123 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/trunk

........
  r64123 | benjamin.peterson | 2008-06-11 11:50:57 -0500 (Wed, 11 Jun 2008) | 2 lines
  
  fix Windows building for multiprocessing
........


Added:
   python/branches/py3k/PCbuild/_multiprocessing.vcproj
      - copied unchanged from r64123, /python/trunk/PCbuild/_multiprocessing.vcproj
Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/PCbuild/pcbuild.sln

Modified: python/branches/py3k/PCbuild/pcbuild.sln
==============================================================================
--- python/branches/py3k/PCbuild/pcbuild.sln	(original)
+++ python/branches/py3k/PCbuild/pcbuild.sln	Wed Jun 11 18:57:54 2008
@@ -131,6 +131,11 @@
 		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31} = {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_multiprocessing", "_multiprocessing.vcproj", "{9e48b300-37d1-11dd-8c41-005056c00008}"
+	ProjectSection(ProjectDependencies) = postProject
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
+	EndProjectSection
+EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "kill_python", "kill_python.vcproj", "{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}"
 EndProject
 Global
@@ -553,6 +558,22 @@
 		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Release|Win32.Build.0 = Release|Win32
 		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Release|x64.ActiveCfg = Release|x64
 		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Release|x64.Build.0 = Release|x64
+		{9e48b300-37d1-11dd-8c41-005056c00008}.Debug|Win32.ActiveCfg = Debug|Win32
+		{9e48b300-37d1-11dd-8c41-005056c00008}.Debug|Win32.Build.0 = Debug|Win32
+		{9e48b300-37d1-11dd-8c41-005056c00008}.Debug|x64.ActiveCfg = Debug|x64
+		{9e48b300-37d1-11dd-8c41-005056c00008}.Debug|x64.Build.0 = Debug|x64
+		{9e48b300-37d1-11dd-8c41-005056c00008}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
+		{9e48b300-37d1-11dd-8c41-005056c00008}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
+		{9e48b300-37d1-11dd-8c41-005056c00008}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
+		{9e48b300-37d1-11dd-8c41-005056c00008}.PGInstrument|x64.Build.0 = PGInstrument|x64
+		{9e48b300-37d1-11dd-8c41-005056c00008}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
+		{9e48b300-37d1-11dd-8c41-005056c00008}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
+		{9e48b300-37d1-11dd-8c41-005056c00008}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
+		{9e48b300-37d1-11dd-8c41-005056c00008}.PGUpdate|x64.Build.0 = PGUpdate|x64
+		{9e48b300-37d1-11dd-8c41-005056c00008}.Release|Win32.ActiveCfg = Release|Win32
+		{9e48b300-37d1-11dd-8c41-005056c00008}.Release|Win32.Build.0 = Release|Win32
+		{9e48b300-37d1-11dd-8c41-005056c00008}.Release|x64.ActiveCfg = Release|x64
+		{9e48b300-37d1-11dd-8c41-005056c00008}.Release|x64.Build.0 = Release|x64
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE

From python-3000-checkins at python.org  Wed Jun 11 19:40:48 2008
From: python-3000-checkins at python.org (amaury.forgeotdarc)
Date: Wed, 11 Jun 2008 19:40:48 +0200 (CEST)
Subject: [Python-3000-checkins] r64126 - in python/branches/py3k: Misc/NEWS
	Python/import.c Python/pythonrun.c
Message-ID: <20080611174048.525FC1E4008@bag.python.org>

Author: amaury.forgeotdarc
Date: Wed Jun 11 19:40:47 2008
New Revision: 64126

Log:
Issue 1342: Python could not start if installed in a directory
with non-ascii characters.

This is the simple fix, which uses the FileSystemEncoding.
Replacing all the char* with unicode strings is a major rewrite,
and needs more thinking.


Modified:
   python/branches/py3k/Misc/NEWS
   python/branches/py3k/Python/import.c
   python/branches/py3k/Python/pythonrun.c

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Wed Jun 11 19:40:47 2008
@@ -12,6 +12,9 @@
 Core and Builtins
 -----------------
 
+- Issue #1342: On windows, Python could not start when installed in a
+  directory with non-ascii characters.
+
 - Implement PEP 3121: new module initialization and finalization API.
 
 - Removed the already-defunct ``-t`` option.

Modified: python/branches/py3k/Python/import.c
==============================================================================
--- python/branches/py3k/Python/import.c	(original)
+++ python/branches/py3k/Python/import.c	Wed Jun 11 19:40:47 2008
@@ -1364,19 +1364,26 @@
 		if (!v)
 			return NULL;
 		if (PyUnicode_Check(v)) {
-			v = _PyUnicode_AsDefaultEncodedString(v, NULL);
+			v = PyUnicode_AsEncodedString(v, 
+			    Py_FileSystemDefaultEncoding, NULL);
 			if (v == NULL)
 				return NULL;
 		}
-		if (!PyBytes_Check(v))
+		else if (!PyBytes_Check(v))
 			continue;
+		else
+			Py_INCREF(v);
+
 		base = PyBytes_AS_STRING(v);
 		size = PyBytes_GET_SIZE(v);
 		len = size;
 		if (len + 2 + namelen + MAXSUFFIXSIZE >= buflen) {
+			Py_DECREF(v);
 			continue; /* Too long */
 		}
 		strcpy(buf, base);
+		Py_DECREF(v);
+
 		if (strlen(buf) != len) {
 			continue; /* v contains '\0' */
 		}
@@ -3155,8 +3162,8 @@
 	if (!_PyArg_NoKeywords("NullImporter()", kwds))
 		return -1;
 
-	if (!PyArg_ParseTuple(args, "s:NullImporter",
-			      &path))
+	if (!PyArg_ParseTuple(args, "es:NullImporter",
+			      Py_FileSystemDefaultEncoding, &path))
 		return -1;
 
 	pathlen = strlen(path);

Modified: python/branches/py3k/Python/pythonrun.c
==============================================================================
--- python/branches/py3k/Python/pythonrun.c	(original)
+++ python/branches/py3k/Python/pythonrun.c	Wed Jun 11 19:40:47 2008
@@ -695,7 +695,7 @@
 	PyObject *std = NULL;
 	int status = 0, fd;
 	PyObject * encoding_attr;
-	char *encoding, *errors;
+	char *encoding = NULL, *errors;
 
 	/* Hack to avoid a nasty recursion issue when Python is invoked
 	   in verbose mode: pre-import the Latin-1 and UTF-8 codecs */

From python-3000-checkins at python.org  Wed Jun 11 19:46:11 2008
From: python-3000-checkins at python.org (amaury.forgeotdarc)
Date: Wed, 11 Jun 2008 19:46:11 +0200 (CEST)
Subject: [Python-3000-checkins] r64127 -
	python/branches/py3k/Lib/distutils/command/build_ext.py
Message-ID: <20080611174611.1299D1E401D@bag.python.org>

Author: amaury.forgeotdarc
Date: Wed Jun 11 19:46:10 2008
New Revision: 64127

Log:
Follow-up of PEP 3121:
Correct the exported symbol for extension modules built by distutils


Modified:
   python/branches/py3k/Lib/distutils/command/build_ext.py

Modified: python/branches/py3k/Lib/distutils/command/build_ext.py
==============================================================================
--- python/branches/py3k/Lib/distutils/command/build_ext.py	(original)
+++ python/branches/py3k/Lib/distutils/command/build_ext.py	Wed Jun 11 19:46:10 2008
@@ -646,10 +646,10 @@
     def get_export_symbols(self, ext):
         """Return the list of symbols that a shared extension has to
         export.  This either uses 'ext.export_symbols' or, if it's not
-        provided, "init" + module_name.  Only relevant on Windows, where
+        provided, "PyInit_" + module_name.  Only relevant on Windows, where
         the .pyd file (DLL) must export the module "init" function.
         """
-        initfunc_name = "init" + ext.name.split('.')[-1]
+        initfunc_name = "PyInit_" + ext.name.split('.')[-1]
         if initfunc_name not in ext.export_symbols:
             ext.export_symbols.append(initfunc_name)
         return ext.export_symbols

From python-3000-checkins at python.org  Wed Jun 11 20:03:27 2008
From: python-3000-checkins at python.org (georg.brandl)
Date: Wed, 11 Jun 2008 20:03:27 +0200 (CEST)
Subject: [Python-3000-checkins] r64134 - in python/branches/py3k:
	Doc/using/cmdline.rst
Message-ID: <20080611180327.515931E4017@bag.python.org>

Author: georg.brandl
Date: Wed Jun 11 20:03:09 2008
New Revision: 64134

Log:
Merged revisions 64130 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/trunk

........
  r64130 | georg.brandl | 2008-06-11 19:57:44 +0200 (Wed, 11 Jun 2008) | 2 lines
  
  Clarify what ":errorhandler" refers to.
........


Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Doc/using/cmdline.rst

Modified: python/branches/py3k/Doc/using/cmdline.rst
==============================================================================
--- python/branches/py3k/Doc/using/cmdline.rst	(original)
+++ python/branches/py3k/Doc/using/cmdline.rst	Wed Jun 11 20:03:09 2008
@@ -419,6 +419,13 @@
    import of source modules.
 
 
+.. envvar:: PYTHONIOENCODING
+
+   Overrides the encoding used for stdin/stdout/stderr, in the syntax
+   ``encodingname:errorhandler``.  The ``:errorhandler`` part is optional and
+   has the same meaning as in :func:`str.encode`.
+
+
 .. envvar:: PYTHONNOUSERSITE
 
    If this is set, Python won't add the user site directory to sys.path
@@ -460,13 +467,6 @@
    If set, Python will dump objects and reference counts still alive after
    shutting down the interpreter.
 
-.. envvar:: PYTHONIOENCODING
-
-   Overrides the encoding used for stdin/stdout/stderr, in the syntax
-   encodingname:errorhandler, with the :errors part being optional.
-
-   .. versionadded:: 2.6
-
 
 .. envvar:: PYTHONMALLOCSTATS
 

From python-3000-checkins at python.org  Wed Jun 11 20:12:35 2008
From: python-3000-checkins at python.org (amaury.forgeotdarc)
Date: Wed, 11 Jun 2008 20:12:35 +0200 (CEST)
Subject: [Python-3000-checkins] r64136 -
	python/branches/py3k/Modules/_multiprocessing/win32_functions.c
Message-ID: <20080611181235.188871E4011@bag.python.org>

Author: amaury.forgeotdarc
Date: Wed Jun 11 20:12:34 2008
New Revision: 64136

Log:
Adaptation to py3k.


Modified:
   python/branches/py3k/Modules/_multiprocessing/win32_functions.c

Modified: python/branches/py3k/Modules/_multiprocessing/win32_functions.c
==============================================================================
--- python/branches/py3k/Modules/_multiprocessing/win32_functions.c	(original)
+++ python/branches/py3k/Modules/_multiprocessing/win32_functions.c	Wed Jun 11 20:12:34 2008
@@ -176,7 +176,7 @@
 
 	for (i = 0 ; i < 3 ; i++) {
 		if (oArgs[i] != Py_None) {
-			dwArgs[i] = PyInt_AsUnsignedLongMask(oArgs[i]);
+			dwArgs[i] = PyLong_AsUnsignedLongMask(oArgs[i]);
 			if (PyErr_Occurred())
 				return NULL;
 			pArgs[i] = &dwArgs[i];

From python-3000-checkins at python.org  Wed Jun 11 20:35:23 2008
From: python-3000-checkins at python.org (amaury.forgeotdarc)
Date: Wed, 11 Jun 2008 20:35:23 +0200 (CEST)
Subject: [Python-3000-checkins] r64137 -
	python/branches/py3k/Modules/_multiprocessing/multiprocessing.c
Message-ID: <20080611183523.D1AF41E4005@bag.python.org>

Author: amaury.forgeotdarc
Date: Wed Jun 11 20:35:23 2008
New Revision: 64137

Log:
Correctly export the module init function. Needed on Windows.


Modified:
   python/branches/py3k/Modules/_multiprocessing/multiprocessing.c

Modified: python/branches/py3k/Modules/_multiprocessing/multiprocessing.c
==============================================================================
--- python/branches/py3k/Modules/_multiprocessing/multiprocessing.c	(original)
+++ python/branches/py3k/Modules/_multiprocessing/multiprocessing.c	Wed Jun 11 20:35:23 2008
@@ -225,7 +225,7 @@
 };
 
 
-PyObject*
+PyMODINIT_FUNC 
 PyInit__multiprocessing(void)
 {
 	PyObject *module, *temp;

From python-3000-checkins at python.org  Wed Jun 11 20:37:53 2008
From: python-3000-checkins at python.org (georg.brandl)
Date: Wed, 11 Jun 2008 20:37:53 +0200 (CEST)
Subject: [Python-3000-checkins] r64138 - in python/branches/py3k:
	Doc/c-api/object.rst Doc/c-api/unicode.rst
	Doc/library/functions.rst Doc/library/stdtypes.rst
	Doc/library/string.rst Doc/using/cmdline.rst Include/object.h
	Include/unicodeobject.h Lib/doctest.py Lib/test/test_array.py
	Lib/test/test_builtin.py Lib/test/test_format.py
	Lib/test/test_pyexpat.py Lib/test/test_unicode.py Misc/NEWS
	Objects/object.c Objects/stringlib/string_format.h
	Objects/stringlib/stringdefs.h
	Objects/stringlib/unicodedefs.h Objects/unicodectype.c
	Objects/unicodeobject.c Objects/unicodetype_db.h
	Python/bltinmodule.c Python/pythonrun.c
	Tools/unicode/makeunicodedata.py
Message-ID: <20080611183753.DD0121E4005@bag.python.org>

Author: georg.brandl
Date: Wed Jun 11 20:37:52 2008
New Revision: 64138

Log:
#2630: Implement PEP 3138.
The repr() of a string now contains printable Unicode characters unescaped.
The new ascii() builtin can be used to get a repr() with only ASCII characters in it.

PEP and patch were written by Atsuo Ishimoto.


Modified:
   python/branches/py3k/Doc/c-api/object.rst
   python/branches/py3k/Doc/c-api/unicode.rst
   python/branches/py3k/Doc/library/functions.rst
   python/branches/py3k/Doc/library/stdtypes.rst
   python/branches/py3k/Doc/library/string.rst
   python/branches/py3k/Doc/using/cmdline.rst
   python/branches/py3k/Include/object.h
   python/branches/py3k/Include/unicodeobject.h
   python/branches/py3k/Lib/doctest.py
   python/branches/py3k/Lib/test/test_array.py
   python/branches/py3k/Lib/test/test_builtin.py
   python/branches/py3k/Lib/test/test_format.py
   python/branches/py3k/Lib/test/test_pyexpat.py
   python/branches/py3k/Lib/test/test_unicode.py
   python/branches/py3k/Misc/NEWS
   python/branches/py3k/Objects/object.c
   python/branches/py3k/Objects/stringlib/string_format.h
   python/branches/py3k/Objects/stringlib/stringdefs.h
   python/branches/py3k/Objects/stringlib/unicodedefs.h
   python/branches/py3k/Objects/unicodectype.c
   python/branches/py3k/Objects/unicodeobject.c
   python/branches/py3k/Objects/unicodetype_db.h
   python/branches/py3k/Python/bltinmodule.c
   python/branches/py3k/Python/pythonrun.c
   python/branches/py3k/Tools/unicode/makeunicodedata.py

Modified: python/branches/py3k/Doc/c-api/object.rst
==============================================================================
--- python/branches/py3k/Doc/c-api/object.rst	(original)
+++ python/branches/py3k/Doc/c-api/object.rst	Wed Jun 11 20:37:52 2008
@@ -116,8 +116,18 @@
 
    Compute a string representation of object *o*.  Returns the string
    representation on success, *NULL* on failure.  This is the equivalent of the
-   Python expression ``repr(o)``.  Called by the :func:`repr` built-in function and
-   by reverse quotes.
+   Python expression ``repr(o)``.  Called by the :func:`repr` built-in function.
+
+
+.. cfunction:: PyObject* PyObject_ASCII(PyObject *o)
+
+   .. index:: builtin: ascii
+
+   As :cfunc:`PyObject_Repr`, compute a string representation of object *o*, but
+   escape the non-ASCII characters in the string returned by
+   :cfunc:`PyObject_Repr` with ``\x``, ``\u`` or ``\U`` escapes.  This generates
+   a string similar to that returned by :cfunc:`PyObject_Repr` in Python 2.
+   Called by the :func:`ascii` built-in function.
 
 
 .. cfunction:: PyObject* PyObject_Str(PyObject *o)

Modified: python/branches/py3k/Doc/c-api/unicode.rst
==============================================================================
--- python/branches/py3k/Doc/c-api/unicode.rst	(original)
+++ python/branches/py3k/Doc/c-api/unicode.rst	Wed Jun 11 20:37:52 2008
@@ -144,6 +144,18 @@
 
    Return 1 or 0 depending on whether *ch* is an alphanumeric character.
 
+
+.. cfunction:: int Py_UNICODE_ISPRINTABLE(Py_UNICODE ch)
+
+   Return 1 or 0 depending on whether *ch* is a printable character.
+   Nonprintable characters are those characters defined in the Unicode character
+   database as "Other" or "Separator", excepting the ASCII space (0x20) which is
+   considered printable.  (Note that printable characters in this context are
+   those which should not be escaped when :func:`repr` is invoked on a string.
+   It has no bearing on the handling of strings written to :data:`sys.stdout` or
+   :data:`sys.stderr`.)
+
+
 These APIs can be used for fast direct character conversions:
 
 
@@ -266,6 +278,9 @@
    |                   |                     | of what the platform's         |
    |                   |                     | ``printf`` yields.             |
    +-------------------+---------------------+--------------------------------+
+   | :attr:`%A`        | PyObject\*          | The result of calling          |
+   |                   |                     | :func:`ascii`.                 |
+   +-------------------+---------------------+--------------------------------+
    | :attr:`%U`        | PyObject\*          | A unicode object.              |
    +-------------------+---------------------+--------------------------------+
    | :attr:`%V`        | PyObject\*, char \* | A unicode object (which may be |

Modified: python/branches/py3k/Doc/library/functions.rst
==============================================================================
--- python/branches/py3k/Doc/library/functions.rst	(original)
+++ python/branches/py3k/Doc/library/functions.rst	Wed Jun 11 20:37:52 2008
@@ -91,6 +91,14 @@
           return False
 
 
+.. function:: ascii(object)
+
+   As :func:`repr`, return a string containing a printable representation of an
+   object, but escape the non-ASCII characters in the string returned by
+   :func:`repr` using ``\x``, ``\u`` or ``\U`` escapes.  This generates a string
+   similar to that returned by :func:`repr` in Python 2.
+
+
 .. function:: bin(x)
 
    Convert an integer number to a binary string. The result is a valid Python

Modified: python/branches/py3k/Doc/library/stdtypes.rst
==============================================================================
--- python/branches/py3k/Doc/library/stdtypes.rst	(original)
+++ python/branches/py3k/Doc/library/stdtypes.rst	Wed Jun 11 20:37:52 2008
@@ -774,6 +774,17 @@
    least one cased character, false otherwise.
 
 
+.. method:: str.isprintable()
+
+   Return true if all characters in the string are printable or the string is
+   empty, false otherwise.  Nonprintable characters are those characters defined
+   in the Unicode character database as "Other" or "Separator", excepting the
+   ASCII space (0x20) which is considered printable.  (Note that printable
+   characters in this context are those which should not be escaped when
+   :func:`repr` is invoked on a string.  It has no bearing on the handling of
+   strings written to :data:`sys.stdout` or :data:`sys.stderr`.)
+
+
 .. method:: str.isspace()
 
    Return true if there are only whitespace characters in the string and there is

Modified: python/branches/py3k/Doc/library/string.rst
==============================================================================
--- python/branches/py3k/Doc/library/string.rst	(original)
+++ python/branches/py3k/Doc/library/string.rst	Wed Jun 11 20:37:52 2008
@@ -229,8 +229,9 @@
 value to a string before calling :meth:`__format__`, the normal formatting logic
 is bypassed.
 
-Two conversion flags are currently supported: ``'!s'`` which calls :func:`str`
-on the value, and ``'!r'`` which calls :func:`repr`.
+Three conversion flags are currently supported: ``'!s'`` which calls :func:`str`
+on the value, ``'!r'`` which calls :func:`repr` and ``'!a'`` which calls
+:func:`ascii`.
 
 Some examples::
 

Modified: python/branches/py3k/Doc/using/cmdline.rst
==============================================================================
--- python/branches/py3k/Doc/using/cmdline.rst	(original)
+++ python/branches/py3k/Doc/using/cmdline.rst	Wed Jun 11 20:37:52 2008
@@ -425,6 +425,9 @@
    ``encodingname:errorhandler``.  The ``:errorhandler`` part is optional and
    has the same meaning as in :func:`str.encode`.
 
+   For stderr, the ``:errorhandler`` part is ignored; the handler will always be
+   ``'backslashreplace'``.
+
 
 .. envvar:: PYTHONNOUSERSITE
 

Modified: python/branches/py3k/Include/object.h
==============================================================================
--- python/branches/py3k/Include/object.h	(original)
+++ python/branches/py3k/Include/object.h	Wed Jun 11 20:37:52 2008
@@ -425,6 +425,7 @@
 PyAPI_FUNC(void) _PyObject_Dump(PyObject *);
 PyAPI_FUNC(PyObject *) PyObject_Repr(PyObject *);
 PyAPI_FUNC(PyObject *) PyObject_Str(PyObject *);
+PyAPI_FUNC(PyObject *) PyObject_ASCII(PyObject *);
 PyAPI_FUNC(int) PyObject_Compare(PyObject *, PyObject *);
 PyAPI_FUNC(PyObject *) PyObject_RichCompare(PyObject *, PyObject *, int);
 PyAPI_FUNC(int) PyObject_RichCompareBool(PyObject *, PyObject *, int);

Modified: python/branches/py3k/Include/unicodeobject.h
==============================================================================
--- python/branches/py3k/Include/unicodeobject.h	(original)
+++ python/branches/py3k/Include/unicodeobject.h	Wed Jun 11 20:37:52 2008
@@ -220,6 +220,7 @@
 # define _PyUnicode_IsLinebreak _PyUnicodeUCS2_IsLinebreak
 # define _PyUnicode_IsLowercase _PyUnicodeUCS2_IsLowercase
 # define _PyUnicode_IsNumeric _PyUnicodeUCS2_IsNumeric
+# define _PyUnicode_IsPrintable _PyUnicodeUCS2_IsPrintable
 # define _PyUnicode_IsTitlecase _PyUnicodeUCS2_IsTitlecase
 # define _PyUnicode_IsXidStart _PyUnicodeUCS2_IsXidStart
 # define _PyUnicode_IsXidContinue _PyUnicodeUCS2_IsXidContinue
@@ -317,6 +318,7 @@
 # define _PyUnicode_IsLinebreak _PyUnicodeUCS4_IsLinebreak
 # define _PyUnicode_IsLowercase _PyUnicodeUCS4_IsLowercase
 # define _PyUnicode_IsNumeric _PyUnicodeUCS4_IsNumeric
+# define _PyUnicode_IsPrintable _PyUnicodeUCS4_IsPrintable
 # define _PyUnicode_IsTitlecase _PyUnicodeUCS4_IsTitlecase
 # define _PyUnicode_IsXidStart _PyUnicodeUCS4_IsXidStart
 # define _PyUnicode_IsXidContinue _PyUnicodeUCS4_IsXidContinue
@@ -357,6 +359,7 @@
 #define Py_UNICODE_ISDECIMAL(ch) _PyUnicode_IsDecimalDigit(ch)
 #define Py_UNICODE_ISDIGIT(ch) _PyUnicode_IsDigit(ch)
 #define Py_UNICODE_ISNUMERIC(ch) _PyUnicode_IsNumeric(ch)
+#define Py_UNICODE_ISPRINTABLE(ch) _PyUnicode_IsPrintable(ch)
 
 #define Py_UNICODE_TODECIMAL(ch) _PyUnicode_ToDecimalDigit(ch)
 #define Py_UNICODE_TODIGIT(ch) _PyUnicode_ToDigit(ch)
@@ -387,6 +390,7 @@
 #define Py_UNICODE_ISDECIMAL(ch) _PyUnicode_IsDecimalDigit(ch)
 #define Py_UNICODE_ISDIGIT(ch) _PyUnicode_IsDigit(ch)
 #define Py_UNICODE_ISNUMERIC(ch) _PyUnicode_IsNumeric(ch)
+#define Py_UNICODE_ISPRINTABLE(ch) _PyUnicode_IsPrintable(ch)
 
 #define Py_UNICODE_TODECIMAL(ch) _PyUnicode_ToDecimalDigit(ch)
 #define Py_UNICODE_TODIGIT(ch) _PyUnicode_ToDigit(ch)
@@ -1533,6 +1537,10 @@
     Py_UNICODE ch 	/* Unicode character */
     );
 
+PyAPI_FUNC(int) _PyUnicode_IsPrintable(
+    Py_UNICODE ch 	/* Unicode character */
+    );
+
 PyAPI_FUNC(int) _PyUnicode_IsAlpha(
     Py_UNICODE ch 	/* Unicode character */
     );

Modified: python/branches/py3k/Lib/doctest.py
==============================================================================
--- python/branches/py3k/Lib/doctest.py	(original)
+++ python/branches/py3k/Lib/doctest.py	Wed Jun 11 20:37:52 2008
@@ -1440,6 +1440,12 @@
     and returns true if they match; and `output_difference`, which
     returns a string describing the differences between two outputs.
     """
+    def _toAscii(self, s):
+        """
+        Convert string to hex-escaped ASCII string.
+        """
+        return str(s.encode('ASCII', 'backslashreplace'), "ASCII")
+
     def check_output(self, want, got, optionflags):
         """
         Return True iff the actual output from an example (`got`)
@@ -1450,6 +1456,15 @@
         documentation for `TestRunner` for more information about
         option flags.
         """
+
+        # If `want` contains hex-escaped character such as "\u1234",
+        # then `want` is a string of six characters(e.g. [\,u,1,2,3,4]).
+        # On the other hand, `got` could be an another sequence of
+        # characters such as [\u1234], so `want` and `got` should
+        # be folded to hex-escaped ASCII string to compare.
+        got = self._toAscii(got)
+        want = self._toAscii(want)
+
         # Handle the common case first, for efficiency:
         # if they're string-identical, always return true.
         if got == want:

Modified: python/branches/py3k/Lib/test/test_array.py
==============================================================================
--- python/branches/py3k/Lib/test/test_array.py	(original)
+++ python/branches/py3k/Lib/test/test_array.py	Wed Jun 11 20:37:52 2008
@@ -768,7 +768,7 @@
         a = array.array('u', s)
         self.assertEqual(
             repr(a),
-            "array('u', '\\x00=\"\\'a\\\\b\\x80\\xff\\x00\\x01\\u1234')")
+            "array('u', '\\x00=\"\\'a\\\\b\\x80\xff\\x00\\x01\u1234')")
 
         self.assertRaises(TypeError, a.fromunicode)
 

Modified: python/branches/py3k/Lib/test/test_builtin.py
==============================================================================
--- python/branches/py3k/Lib/test/test_builtin.py	(original)
+++ python/branches/py3k/Lib/test/test_builtin.py	Wed Jun 11 20:37:52 2008
@@ -159,6 +159,20 @@
         S = [10, 20, 30]
         self.assertEqual(any(x > 42 for x in S), False)
 
+    def test_ascii(self):
+        self.assertEqual(ascii(''), '\'\'')
+        self.assertEqual(ascii(0), '0')
+        self.assertEqual(ascii(0), '0')
+        self.assertEqual(ascii(()), '()')
+        self.assertEqual(ascii([]), '[]')
+        self.assertEqual(ascii({}), '{}')
+        a = []
+        a.append(a)
+        self.assertEqual(ascii(a), '[[...]]')
+        a = {}
+        a[0] = a
+        self.assertEqual(ascii(a), '{0: {...}}')
+
     def test_neg(self):
         x = -sys.maxsize-1
         self.assert_(isinstance(x, int))

Modified: python/branches/py3k/Lib/test/test_format.py
==============================================================================
--- python/branches/py3k/Lib/test/test_format.py	(original)
+++ python/branches/py3k/Lib/test/test_format.py	Wed Jun 11 20:37:52 2008
@@ -216,6 +216,8 @@
         testformat("%o", 0o42, "42")
         testformat("%o", -0o42, "-42")
         testformat("%o", float(0o42), "42")
+        testformat("%r", "\u0370", "'\u0370'")
+        testformat("%a", "\u0370", "'\\u0370'")
         # Test exception for unknown format characters
         if verbose:
             print('Testing exceptions')
@@ -235,8 +237,8 @@
                 raise
             else:
                 raise TestFailed('did not get expected exception: %s' % excmsg)
-        test_exc('abc %a', 1, ValueError,
-                 "unsupported format character 'a' (0x61) at index 5")
+        test_exc('abc %b', 1, ValueError,
+                 "unsupported format character 'b' (0x62) at index 5")
         #test_exc(unicode('abc %\u3000','raw-unicode-escape'), 1, ValueError,
         #         "unsupported format character '?' (0x3000) at index 5")
         test_exc('%d', '1', TypeError, "%d format: a number is required, not str")

Modified: python/branches/py3k/Lib/test/test_pyexpat.py
==============================================================================
--- python/branches/py3k/Lib/test/test_pyexpat.py	(original)
+++ python/branches/py3k/Lib/test/test_pyexpat.py	Wed Jun 11 20:37:52 2008
@@ -131,7 +131,7 @@
         self.assertEquals(op[1], "Comment: ' comment data '")
         self.assertEquals(op[2], "Notation declared: ('notation', None, 'notation.jpeg', None)")
         self.assertEquals(op[3], "Unparsed entity decl: ('unparsed_entity', None, 'entity.file', None, 'notation')")
-        self.assertEquals(op[4], "Start element: 'root' {'attr1': 'value1', 'attr2': 'value2\\u1f40'}")
+        self.assertEquals(op[4], "Start element: 'root' {'attr1': 'value1', 'attr2': 'value2\u1f40'}")
         self.assertEquals(op[5], "NS decl: 'myns' 'http://www.python.org/namespace'")
         self.assertEquals(op[6], "Start element: 'http://www.python.org/namespace!subelement' {}")
         self.assertEquals(op[7], "Character data: 'Contents of subelements'")

Modified: python/branches/py3k/Lib/test/test_unicode.py
==============================================================================
--- python/branches/py3k/Lib/test/test_unicode.py	(original)
+++ python/branches/py3k/Lib/test/test_unicode.py	Wed Jun 11 20:37:52 2008
@@ -71,6 +71,48 @@
         # raw strings should not have unicode escapes
         self.assertNotEquals(r"\u0020", " ")
 
+    def test_ascii(self):
+        if not sys.platform.startswith('java'):
+            # Test basic sanity of repr()
+            self.assertEqual(ascii('abc'), "'abc'")
+            self.assertEqual(ascii('ab\\c'), "'ab\\\\c'")
+            self.assertEqual(ascii('ab\\'), "'ab\\\\'")
+            self.assertEqual(ascii('\\c'), "'\\\\c'")
+            self.assertEqual(ascii('\\'), "'\\\\'")
+            self.assertEqual(ascii('\n'), "'\\n'")
+            self.assertEqual(ascii('\r'), "'\\r'")
+            self.assertEqual(ascii('\t'), "'\\t'")
+            self.assertEqual(ascii('\b'), "'\\x08'")
+            self.assertEqual(ascii("'\""), """'\\'"'""")
+            self.assertEqual(ascii("'\""), """'\\'"'""")
+            self.assertEqual(ascii("'"), '''"'"''')
+            self.assertEqual(ascii('"'), """'"'""")
+            latin1repr = (
+                "'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r"
+                "\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a"
+                "\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123456789:;<=>?@ABCDEFGHI"
+                "JKLMNOPQRSTUVWXYZ[\\\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\\x7f"
+                "\\x80\\x81\\x82\\x83\\x84\\x85\\x86\\x87\\x88\\x89\\x8a\\x8b\\x8c\\x8d"
+                "\\x8e\\x8f\\x90\\x91\\x92\\x93\\x94\\x95\\x96\\x97\\x98\\x99\\x9a\\x9b"
+                "\\x9c\\x9d\\x9e\\x9f\\xa0\\xa1\\xa2\\xa3\\xa4\\xa5\\xa6\\xa7\\xa8\\xa9"
+                "\\xaa\\xab\\xac\\xad\\xae\\xaf\\xb0\\xb1\\xb2\\xb3\\xb4\\xb5\\xb6\\xb7"
+                "\\xb8\\xb9\\xba\\xbb\\xbc\\xbd\\xbe\\xbf\\xc0\\xc1\\xc2\\xc3\\xc4\\xc5"
+                "\\xc6\\xc7\\xc8\\xc9\\xca\\xcb\\xcc\\xcd\\xce\\xcf\\xd0\\xd1\\xd2\\xd3"
+                "\\xd4\\xd5\\xd6\\xd7\\xd8\\xd9\\xda\\xdb\\xdc\\xdd\\xde\\xdf\\xe0\\xe1"
+                "\\xe2\\xe3\\xe4\\xe5\\xe6\\xe7\\xe8\\xe9\\xea\\xeb\\xec\\xed\\xee\\xef"
+                "\\xf0\\xf1\\xf2\\xf3\\xf4\\xf5\\xf6\\xf7\\xf8\\xf9\\xfa\\xfb\\xfc\\xfd"
+                "\\xfe\\xff'")
+            testrepr = ascii(''.join(map(chr, range(256))))
+            self.assertEqual(testrepr, latin1repr)
+            # Test ascii works on wide unicode escapes without overflow.
+            self.assertEqual(ascii("\U00010000" * 39 + "\uffff" * 4096),
+                             ascii("\U00010000" * 39 + "\uffff" * 4096))
+
+            class WrongRepr:
+                def __repr__(self):
+                    return b'byte-repr'
+            self.assertRaises(TypeError, ascii, WrongRepr())
+
     def test_repr(self):
         if not sys.platform.startswith('java'):
             # Test basic sanity of repr()
@@ -94,20 +136,25 @@
                 "JKLMNOPQRSTUVWXYZ[\\\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\\x7f"
                 "\\x80\\x81\\x82\\x83\\x84\\x85\\x86\\x87\\x88\\x89\\x8a\\x8b\\x8c\\x8d"
                 "\\x8e\\x8f\\x90\\x91\\x92\\x93\\x94\\x95\\x96\\x97\\x98\\x99\\x9a\\x9b"
-                "\\x9c\\x9d\\x9e\\x9f\\xa0\\xa1\\xa2\\xa3\\xa4\\xa5\\xa6\\xa7\\xa8\\xa9"
-                "\\xaa\\xab\\xac\\xad\\xae\\xaf\\xb0\\xb1\\xb2\\xb3\\xb4\\xb5\\xb6\\xb7"
-                "\\xb8\\xb9\\xba\\xbb\\xbc\\xbd\\xbe\\xbf\\xc0\\xc1\\xc2\\xc3\\xc4\\xc5"
-                "\\xc6\\xc7\\xc8\\xc9\\xca\\xcb\\xcc\\xcd\\xce\\xcf\\xd0\\xd1\\xd2\\xd3"
-                "\\xd4\\xd5\\xd6\\xd7\\xd8\\xd9\\xda\\xdb\\xdc\\xdd\\xde\\xdf\\xe0\\xe1"
-                "\\xe2\\xe3\\xe4\\xe5\\xe6\\xe7\\xe8\\xe9\\xea\\xeb\\xec\\xed\\xee\\xef"
-                "\\xf0\\xf1\\xf2\\xf3\\xf4\\xf5\\xf6\\xf7\\xf8\\xf9\\xfa\\xfb\\xfc\\xfd"
-                "\\xfe\\xff'")
+                "\\x9c\\x9d\\x9e\\x9f\\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9"
+                "\xaa\xab\xac\\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
+                "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5"
+                "\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3"
+                "\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1"
+                "\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+                "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd"
+                "\xfe\xff'")
             testrepr = repr(''.join(map(chr, range(256))))
             self.assertEqual(testrepr, latin1repr)
             # Test repr works on wide unicode escapes without overflow.
             self.assertEqual(repr("\U00010000" * 39 + "\uffff" * 4096),
                              repr("\U00010000" * 39 + "\uffff" * 4096))
 
+            class WrongRepr:
+                def __repr__(self):
+                    return b'byte-repr'
+            self.assertRaises(TypeError, repr, WrongRepr())
+
     def test_iterators(self):
         # Make sure unicode objects have an __iter__ method
         it = "\u1111\u2222\u3333".__iter__()
@@ -374,6 +421,13 @@
         self.assertFalse("[".isidentifier())
         self.assertFalse("?".isidentifier())
 
+    def test_isprintable(self):
+        self.assertTrue("".isprintable())
+        self.assertTrue("abcdefg".isprintable())
+        self.assertFalse("abcdefg\n".isprintable())
+        self.assertTrue("\u0370".isprintable())
+        self.assertFalse("\ud800".isprintable())
+
     def test_contains(self):
         # Testing Unicode contains method
         self.assert_('a' in 'abdb')
@@ -544,7 +598,7 @@
         # format specifiers for user defined type
         self.assertEqual('{0:abc}'.format(C()), 'abc')
 
-        # !r and !s coersions
+        # !r, !s and !a coersions
         self.assertEqual('{0!s}'.format('Hello'), 'Hello')
         self.assertEqual('{0!s:}'.format('Hello'), 'Hello')
         self.assertEqual('{0!s:15}'.format('Hello'), 'Hello          ')
@@ -552,6 +606,11 @@
         self.assertEqual('{0!r}'.format('Hello'), "'Hello'")
         self.assertEqual('{0!r:}'.format('Hello'), "'Hello'")
         self.assertEqual('{0!r}'.format(F('Hello')), 'F(Hello)')
+        self.assertEqual('{0!r}'.format(F('\u0370')), 'F(\u0370)')
+        self.assertEqual('{0!a}'.format('Hello'), "'Hello'")
+        self.assertEqual('{0!a:}'.format('Hello'), "'Hello'")
+        self.assertEqual('{0!a}'.format(F('Hello')), 'F(Hello)')
+        self.assertEqual('{0!a}'.format(F('\u0370')), 'F(\\u0370)')
 
         # test fallback to object.__format__
         self.assertEqual('{0}'.format({}), '{}')
@@ -643,6 +702,8 @@
         self.assertEqual("%s, %s, %i, %f, %5.2f" % ("abc", "abc", -1, -2, 1003.57), 'abc, abc, -1, -2.000000, 1003.57')
         if not sys.platform.startswith('java'):
             self.assertEqual("%r, %r" % (b"abc", "abc"), "b'abc', 'abc'")
+            self.assertEqual("%r" % ("\u1234",), "'\u1234'")
+            self.assertEqual("%a" % ("\u1234",), "'\\u1234'")
         self.assertEqual("%(x)s, %(y)s" % {'x':"abc", 'y':"def"}, 'abc, def')
         self.assertEqual("%(x)s, %(\xfc)s" % {'x':"abc", '\xfc':"def"}, 'abc, def')
 

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Wed Jun 11 20:37:52 2008
@@ -12,6 +12,10 @@
 Core and Builtins
 -----------------
 
+- Issue #2630: implement PEP 3138. repr() now returns printable
+  Unicode characters unescaped, to get an ASCII-only representation
+  of an object use ascii().
+
 - Issue #1342: On windows, Python could not start when installed in a
   directory with non-ascii characters.
 

Modified: python/branches/py3k/Objects/object.c
==============================================================================
--- python/branches/py3k/Objects/object.c	(original)
+++ python/branches/py3k/Objects/object.c	Wed Jun 11 20:37:52 2008
@@ -425,6 +425,33 @@
 	return res;
 }
 
+PyObject *
+PyObject_ASCII(PyObject *v)
+{
+	PyObject *repr, *ascii, *res;
+	
+	repr = PyObject_Repr(v);
+	if (repr == NULL)
+		return NULL;
+
+	/* repr is guaranteed to be a PyUnicode object by PyObject_Repr */
+	ascii = PyUnicode_EncodeASCII(
+		PyUnicode_AS_UNICODE(repr),
+		PyUnicode_GET_SIZE(repr),
+		"backslashreplace");
+
+	Py_DECREF(repr);
+	if (ascii == NULL) 
+		return NULL;
+
+	res = PyUnicode_DecodeASCII(
+		PyBytes_AS_STRING(ascii),
+		PyBytes_GET_SIZE(ascii),
+		NULL);
+
+	Py_DECREF(ascii);
+	return res;
+}
 
 /* The new comparison philosophy is: we completely separate three-way
    comparison from rich comparison.  That is, PyObject_Compare() and

Modified: python/branches/py3k/Objects/stringlib/string_format.h
==============================================================================
--- python/branches/py3k/Objects/stringlib/string_format.h	(original)
+++ python/branches/py3k/Objects/stringlib/string_format.h	Wed Jun 11 20:37:52 2008
@@ -766,6 +766,10 @@
         return PyObject_Repr(obj);
     case 's':
         return STRINGLIB_TOSTR(obj);
+#if PY_VERSION_HEX >= 0x03000000
+    case 'a':
+        return STRINGLIB_TOASCII(obj);
+#endif
     default:
 	if (conversion > 32 && conversion < 127) {
 		/* It's the ASCII subrange; casting to char is safe

Modified: python/branches/py3k/Objects/stringlib/stringdefs.h
==============================================================================
--- python/branches/py3k/Objects/stringlib/stringdefs.h	(original)
+++ python/branches/py3k/Objects/stringlib/stringdefs.h	Wed Jun 11 20:37:52 2008
@@ -24,5 +24,5 @@
 #define STRINGLIB_CMP            memcmp
 #define STRINGLIB_TOSTR          PyObject_Str
 #define STRINGLIB_GROUPING       _PyBytes_InsertThousandsGrouping
-
+#define STRINGLIB_TOASCII        PyObject_Repr
 #endif /* !STRINGLIB_STRINGDEFS_H */

Modified: python/branches/py3k/Objects/stringlib/unicodedefs.h
==============================================================================
--- python/branches/py3k/Objects/stringlib/unicodedefs.h	(original)
+++ python/branches/py3k/Objects/stringlib/unicodedefs.h	Wed Jun 11 20:37:52 2008
@@ -25,8 +25,10 @@
 
 #if PY_VERSION_HEX < 0x03000000
 #define STRINGLIB_TOSTR          PyObject_Unicode
+#define STRINGLIB_TOASCII        PyObject_Repr
 #else
 #define STRINGLIB_TOSTR          PyObject_Str
+#define STRINGLIB_TOASCII        PyObject_ASCII
 #endif
 
 #define STRINGLIB_WANT_CONTAINS_OBJ 1

Modified: python/branches/py3k/Objects/unicodectype.c
==============================================================================
--- python/branches/py3k/Objects/unicodectype.c	(original)
+++ python/branches/py3k/Objects/unicodectype.c	Wed Jun 11 20:37:52 2008
@@ -21,6 +21,7 @@
 #define UPPER_MASK 0x80
 #define XID_START_MASK 0x100
 #define XID_CONTINUE_MASK 0x200
+#define NONPRINTABLE_MASK 0x400
 
 typedef struct {
     const Py_UNICODE upper;
@@ -675,6 +676,26 @@
     return _PyUnicode_ToNumeric(ch) != -1.0;
 }
 
+/* Returns 1 for Unicode characters to be hex-escaped when repr()ed,
+   0 otherwise.
+   All characters except those characters defined in the Unicode character
+   database as following categories are considered printable.
+      * Cc (Other, Control)
+      * Cf (Other, Format)
+      * Cs (Other, Surrogate)
+      * Co (Other, Private Use)
+      * Cn (Other, Not Assigned)
+      * Zl Separator, Line ('\u2028', LINE SEPARATOR)
+      * Zp Separator, Paragraph ('\u2029', PARAGRAPH SEPARATOR)
+      * Zs (Separator, Space) other than ASCII space('\x20').
+*/
+int _PyUnicode_IsPrintable(Py_UNICODE ch)
+{
+    const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
+
+    return (ctype->flags & NONPRINTABLE_MASK) == 0;
+}
+
 #ifndef WANT_WCTYPE_FUNCTIONS
 
 /* Returns 1 for Unicode characters having the bidirectional type

Modified: python/branches/py3k/Objects/unicodeobject.c
==============================================================================
--- python/branches/py3k/Objects/unicodeobject.c	(original)
+++ python/branches/py3k/Objects/unicodeobject.c	Wed Jun 11 20:37:52 2008
@@ -645,11 +645,12 @@
 	count = vargs;
 #endif
 #endif
-	/* step 1: count the number of %S/%R format specifications
-	 * (we call PyObject_Str()/PyObject_Repr() for these objects
-	 * once during step 3 and put the result in an array) */
+	/* step 1: count the number of %S/%R/%A format specifications
+	 * (we call PyObject_Str()/PyObject_Repr()/PyObject_ASCII() for 
+	 * these objects once during step 3 and put the result in 
+	   an array) */
 	for (f = format; *f; f++) {
-		if (*f == '%' && (*(f+1)=='S' || *(f+1)=='R'))
+		if (*f == '%' && (*(f+1)=='S' || *(f+1)=='R' || *(f+1)=='A'))
 			++callcount;
 	}
 	/* step 2: allocate memory for the results of
@@ -778,6 +779,19 @@
 				*callresult++ = repr;
 				break;
 			}
+			case 'A':
+			{
+				PyObject *obj = va_arg(count, PyObject *);
+				PyObject *ascii;
+				assert(obj);
+				ascii = PyObject_ASCII(obj);
+				if (!ascii)
+					goto fail;
+				n += PyUnicode_GET_SIZE(ascii);
+				/* Remember the repr and switch to the next slot */
+				*callresult++ = ascii;
+				break;
+			}
 			case 'p':
 				(void) va_arg(count, int);
 				/* maximum 64-bit pointer representation:
@@ -7231,6 +7245,32 @@
     return PyBool_FromLong(PyUnicode_IsIdentifier(self));
 }
 
+PyDoc_STRVAR(isprintable__doc__,
+"S.isprintable() -> bool\n\
+\n\
+Return True if all characters in S are considered\n\
+printable in repr() or S is empty, False otherwise.");
+
+static PyObject*
+unicode_isprintable(PyObject *self)
+{
+    register const Py_UNICODE *p = PyUnicode_AS_UNICODE(self);
+    register const Py_UNICODE *e;
+
+    /* Shortcut for single character strings */
+    if (PyUnicode_GET_SIZE(self) == 1 && Py_UNICODE_ISPRINTABLE(*p)) {
+        Py_RETURN_TRUE;
+    }
+
+    e = p + PyUnicode_GET_SIZE(self);
+    for (; p < e; p++) {
+        if (!Py_UNICODE_ISPRINTABLE(*p)) {
+            Py_RETURN_FALSE;
+        }
+    }
+    Py_RETURN_TRUE;
+}
+
 PyDoc_STRVAR(join__doc__,
 "S.join(sequence) -> str\n\
 \n\
@@ -7608,61 +7648,8 @@
             continue;
         }
 
-#ifdef Py_UNICODE_WIDE
-        /* Map 21-bit characters to '\U00xxxxxx' */
-        else if (ch >= 0x10000) {
-            *p++ = '\\';
-            *p++ = 'U';
-            *p++ = hexdigits[(ch >> 28) & 0x0000000F];
-            *p++ = hexdigits[(ch >> 24) & 0x0000000F];
-            *p++ = hexdigits[(ch >> 20) & 0x0000000F];
-            *p++ = hexdigits[(ch >> 16) & 0x0000000F];
-            *p++ = hexdigits[(ch >> 12) & 0x0000000F];
-            *p++ = hexdigits[(ch >> 8) & 0x0000000F];
-            *p++ = hexdigits[(ch >> 4) & 0x0000000F];
-            *p++ = hexdigits[ch & 0x0000000F];
-	    continue;
-        }
-#else
-	/* Map UTF-16 surrogate pairs to '\U00xxxxxx' */
-	else if (ch >= 0xD800 && ch < 0xDC00) {
-	    Py_UNICODE ch2;
-	    Py_UCS4 ucs;
-
-	    ch2 = *s++;
-	    size--;
-	    if (ch2 >= 0xDC00 && ch2 <= 0xDFFF) {
-		ucs = (((ch & 0x03FF) << 10) | (ch2 & 0x03FF)) + 0x00010000;
-		*p++ = '\\';
-		*p++ = 'U';
-		*p++ = hexdigits[(ucs >> 28) & 0x0000000F];
-		*p++ = hexdigits[(ucs >> 24) & 0x0000000F];
-		*p++ = hexdigits[(ucs >> 20) & 0x0000000F];
-		*p++ = hexdigits[(ucs >> 16) & 0x0000000F];
-		*p++ = hexdigits[(ucs >> 12) & 0x0000000F];
-		*p++ = hexdigits[(ucs >> 8) & 0x0000000F];
-		*p++ = hexdigits[(ucs >> 4) & 0x0000000F];
-		*p++ = hexdigits[ucs & 0x0000000F];
-		continue;
-	    }
-	    /* Fall through: isolated surrogates are copied as-is */
-	    s--;
-	    size++;
-	}
-#endif
-
-        /* Map 16-bit characters to '\uxxxx' */
-        if (ch >= 256) {
-            *p++ = '\\';
-            *p++ = 'u';
-            *p++ = hexdigits[(ch >> 12) & 0x000F];
-            *p++ = hexdigits[(ch >> 8) & 0x000F];
-            *p++ = hexdigits[(ch >> 4) & 0x000F];
-            *p++ = hexdigits[ch & 0x000F];
-        }
-
-        /* Map special whitespace to '\t', \n', '\r' */
-        else if (ch == '\t') {
+	/* Map special whitespace to '\t', \n', '\r' */
+        if (ch == '\t') {
             *p++ = '\\';
             *p++ = 't';
         }
@@ -7676,16 +7663,79 @@
         }
 
         /* Map non-printable US ASCII to '\xhh' */
-        else if (ch < ' ' || ch >= 0x7F) {
+        else if (ch < ' ' || ch == 0x7F) {
             *p++ = '\\';
             *p++ = 'x';
             *p++ = hexdigits[(ch >> 4) & 0x000F];
             *p++ = hexdigits[ch & 0x000F];
         }
 
-        /* Copy everything else as-is */
-        else
-            *p++ = (char) ch;
+        /* Copy ASCII characters as-is */
+        else if (ch < 0x7F) {
+            *p++ = ch;
+        }
+
+	/* Non-ASCII characters */
+        else {
+            Py_UCS4 ucs = ch;
+
+#ifndef Py_UNICODE_WIDE
+            Py_UNICODE ch2 = 0;
+            /* Get code point from surrogate pair */
+            if (size > 0) {
+                ch2 = *s;
+                if (ch >= 0xD800 && ch < 0xDC00 && ch2 >= 0xDC00
+                            && ch2 <= 0xDFFF) {
+                    ucs = (((ch & 0x03FF) << 10) | (ch2 & 0x03FF)) 
+                            + 0x00010000;
+                    s++; 
+                    size--;
+                }
+            }
+#endif
+            /* Map Unicode whitespace and control characters 
+               (categories Z* and C* except ASCII space)
+            */
+            if (!Py_UNICODE_ISPRINTABLE(ucs)) {
+                /* Map 8-bit characters to '\xhh' */
+                if (ucs <= 0xff) {
+                    *p++ = '\\';
+                    *p++ = 'x';
+                    *p++ = hexdigits[(ch >> 4) & 0x000F];
+                    *p++ = hexdigits[ch & 0x000F];
+                }
+                /* Map 21-bit characters to '\U00xxxxxx' */
+                else if (ucs >= 0x10000) {
+                    *p++ = '\\';
+                    *p++ = 'U';
+                    *p++ = hexdigits[(ucs >> 28) & 0x0000000F];
+                    *p++ = hexdigits[(ucs >> 24) & 0x0000000F];
+                    *p++ = hexdigits[(ucs >> 20) & 0x0000000F];
+                    *p++ = hexdigits[(ucs >> 16) & 0x0000000F];
+                    *p++ = hexdigits[(ucs >> 12) & 0x0000000F];
+                    *p++ = hexdigits[(ucs >> 8) & 0x0000000F];
+                    *p++ = hexdigits[(ucs >> 4) & 0x0000000F];
+                    *p++ = hexdigits[ucs & 0x0000000F];
+                }
+                /* Map 16-bit characters to '\uxxxx' */
+                else {
+                    *p++ = '\\';
+                    *p++ = 'u';
+                    *p++ = hexdigits[(ucs >> 12) & 0x000F];
+                    *p++ = hexdigits[(ucs >> 8) & 0x000F];
+                    *p++ = hexdigits[(ucs >> 4) & 0x000F];
+                    *p++ = hexdigits[ucs & 0x000F];
+                }
+            }
+            /* Copy characters as-is */
+            else {
+                *p++ = ch;
+#ifndef Py_UNICODE_WIDE
+                if (ucs >= 0x10000)
+                    *p++ = ch2;
+#endif
+            }
+        }
     }
     /* Add quote */
     *p++ = PyUnicode_AS_UNICODE(repr)[0];
@@ -8372,6 +8422,7 @@
     {"isalpha", (PyCFunction) unicode_isalpha, METH_NOARGS, isalpha__doc__},
     {"isalnum", (PyCFunction) unicode_isalnum, METH_NOARGS, isalnum__doc__},
     {"isidentifier", (PyCFunction) unicode_isidentifier, METH_NOARGS, isidentifier__doc__},
+    {"isprintable", (PyCFunction) unicode_isprintable, METH_NOARGS, isprintable__doc__},
     {"zfill", (PyCFunction) unicode_zfill, METH_VARARGS, zfill__doc__},
     {"format", (PyCFunction) do_string_format, METH_VARARGS | METH_KEYWORDS, format__doc__},
     {"__format__", (PyCFunction) unicode__format__, METH_VARARGS, p_format__doc__},
@@ -8958,6 +9009,7 @@
 
 	    case 's':
 	    case 'r':
+	    case 'a':
 		if (PyUnicode_Check(v) && c == 's') {
 		    temp = v;
 		    Py_INCREF(temp);
@@ -8965,8 +9017,10 @@
 		else {
 		    if (c == 's')
 			temp = PyObject_Str(v);
-		    else
+		    else if (c == 'r')
 			temp = PyObject_Repr(v);
+		    else
+			temp = PyObject_ASCII(v);
 		    if (temp == NULL)
 			goto onError;
                     if (PyUnicode_Check(temp))

Modified: python/branches/py3k/Objects/unicodetype_db.h
==============================================================================
--- python/branches/py3k/Objects/unicodetype_db.h	(original)
+++ python/branches/py3k/Objects/unicodetype_db.h	Wed Jun 11 20:37:52 2008
@@ -3,9 +3,10 @@
 /* a list of unique character type descriptors */
 const _PyUnicode_TypeRecord _PyUnicode_TypeRecords[] = {
     {0, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 1024},
+    {0, 0, 0, 0, 0, 1056},
+    {0, 0, 0, 0, 0, 1072},
     {0, 0, 0, 0, 0, 0},
-    {0, 0, 0, 0, 0, 32},
-    {0, 0, 0, 0, 0, 48},
     {0, 0, 0, 0, 0, 518},
     {0, 0, 0, 1, 1, 518},
     {0, 0, 0, 2, 2, 518},
@@ -162,10 +163,10 @@
     21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 46, 21, 21, 21, 21, 47, 8, 8, 
     48, 49, 8, 8, 8, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
     21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
-    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 50, 32, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 21, 51, 52, 53, 54, 55, 56, 57, 58, 
-    8, 59, 60, 8, 8, 8, 61, 8, 62, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 50, 51, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 21, 52, 53, 54, 55, 56, 57, 58, 59, 
+    8, 60, 61, 8, 8, 8, 62, 8, 63, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
@@ -173,8 +174,8 @@
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 63, 64, 65, 66, 67, 68, 69, 
-    70, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 64, 65, 66, 67, 68, 69, 70, 
+    71, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 21, 21, 21, 21, 21, 
     21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
     21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
@@ -184,11 +185,11 @@
     21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
     21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
     21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
-    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 71, 
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 72, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 21, 21, 72, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 21, 21, 73, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
@@ -306,7 +307,7 @@
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 73, 74, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
+    8, 8, 74, 75, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
@@ -316,145 +317,143 @@
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
-    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 75, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
-    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 
-    32, 32, 75, 
+    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 76, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
+    51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 
+    51, 51, 76, 
 };
 
 static unsigned char index2[] = {
     1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 2, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 3, 3, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 1, 1, 1, 1, 1, 1, 14, 14, 14, 14, 
-    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
-    14, 14, 14, 14, 1, 1, 1, 1, 15, 1, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
-    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 17, 1, 1, 
-    1, 1, 1, 1, 1, 18, 19, 1, 20, 1, 15, 1, 21, 17, 1, 1, 1, 1, 1, 14, 14, 
-    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
-    14, 14, 14, 1, 14, 14, 14, 14, 14, 14, 14, 17, 16, 16, 16, 16, 16, 16, 
-    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 1, 
-    16, 16, 16, 16, 16, 16, 16, 22, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
-    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
-    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
-    23, 24, 25, 26, 23, 24, 23, 24, 23, 24, 17, 23, 24, 23, 24, 23, 24, 23, 
-    24, 23, 24, 23, 24, 23, 24, 23, 24, 17, 23, 24, 23, 24, 23, 24, 23, 24, 
-    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
-    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
-    23, 24, 27, 23, 24, 23, 24, 23, 24, 28, 17, 29, 23, 24, 23, 24, 30, 23, 
-    24, 31, 31, 23, 24, 17, 32, 33, 34, 23, 24, 31, 35, 36, 37, 38, 23, 24, 
-    39, 17, 37, 40, 41, 42, 23, 24, 23, 24, 23, 24, 43, 23, 24, 43, 17, 17, 
-    23, 24, 43, 23, 24, 44, 44, 23, 24, 23, 24, 45, 23, 24, 17, 46, 23, 24, 
-    17, 47, 46, 46, 46, 46, 48, 49, 50, 48, 49, 50, 48, 49, 50, 23, 24, 23, 
-    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 51, 23, 24, 23, 24, 
-    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 17, 48, 49, 50, 
-    23, 24, 52, 53, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
-    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
-    23, 24, 23, 24, 23, 24, 23, 24, 54, 17, 23, 24, 23, 24, 23, 24, 23, 24, 
-    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 17, 17, 17, 17, 17, 17, 55, 23, 
-    24, 56, 55, 17, 17, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 
-    17, 58, 59, 17, 60, 60, 17, 61, 17, 62, 17, 17, 17, 17, 60, 17, 17, 63, 
-    17, 17, 17, 17, 64, 65, 17, 17, 17, 17, 17, 65, 17, 17, 66, 17, 17, 67, 
-    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 68, 17, 17, 68, 17, 17, 17, 17, 
-    68, 17, 69, 69, 17, 17, 17, 17, 17, 17, 70, 17, 71, 17, 17, 17, 17, 17, 
-    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
-    17, 17, 17, 17, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 1, 1, 1, 1, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 46, 46, 46, 46, 46, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 46, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 72, 15, 
+    1, 1, 1, 1, 3, 3, 3, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 4, 4, 4, 4, 4, 4, 4, 15, 15, 15, 15, 
     15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
+    15, 15, 15, 15, 4, 4, 4, 4, 16, 4, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 4, 4, 
+    4, 4, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 18, 4, 4, 
+    1, 4, 4, 4, 4, 19, 20, 4, 21, 4, 16, 4, 22, 18, 4, 4, 4, 4, 4, 15, 15, 
     15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
-    15, 15, 15, 15, 15, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 73, 0, 0, 0, 1, 0, 0, 
-    0, 0, 0, 1, 1, 74, 1, 75, 75, 75, 0, 76, 0, 77, 77, 17, 14, 14, 14, 14, 
-    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 14, 14, 14, 14, 
-    14, 14, 14, 14, 14, 78, 79, 79, 79, 17, 16, 16, 16, 16, 16, 16, 16, 16, 
-    16, 16, 16, 16, 16, 16, 16, 16, 16, 80, 16, 16, 16, 16, 16, 16, 16, 16, 
-    16, 81, 82, 82, 0, 83, 84, 55, 55, 55, 85, 86, 17, 23, 24, 23, 24, 23, 
-    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
-    24, 87, 88, 89, 17, 90, 91, 1, 23, 24, 92, 23, 24, 17, 55, 55, 55, 93, 
-    93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 14, 14, 14, 
-    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
-    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 16, 16, 16, 16, 16, 16, 16, 
+    15, 15, 15, 4, 15, 15, 15, 15, 15, 15, 15, 18, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 4, 
+    17, 17, 17, 17, 17, 17, 17, 23, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
+    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
+    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
+    24, 25, 26, 27, 24, 25, 24, 25, 24, 25, 18, 24, 25, 24, 25, 24, 25, 24, 
+    25, 24, 25, 24, 25, 24, 25, 24, 25, 18, 24, 25, 24, 25, 24, 25, 24, 25, 
+    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
+    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
+    24, 25, 28, 24, 25, 24, 25, 24, 25, 29, 18, 30, 24, 25, 24, 25, 31, 24, 
+    25, 32, 32, 24, 25, 18, 33, 34, 35, 24, 25, 32, 36, 37, 38, 39, 24, 25, 
+    40, 18, 38, 41, 42, 43, 24, 25, 24, 25, 24, 25, 44, 24, 25, 44, 18, 18, 
+    24, 25, 44, 24, 25, 45, 45, 24, 25, 24, 25, 46, 24, 25, 18, 47, 24, 25, 
+    18, 48, 47, 47, 47, 47, 49, 50, 51, 49, 50, 51, 49, 50, 51, 24, 25, 24, 
+    25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 52, 24, 25, 24, 25, 
+    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 18, 49, 50, 51, 
+    24, 25, 53, 54, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
+    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
+    24, 25, 24, 25, 24, 25, 24, 25, 55, 18, 24, 25, 24, 25, 24, 25, 24, 25, 
+    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 18, 18, 18, 18, 18, 18, 56, 24, 
+    25, 57, 56, 18, 18, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 18, 
+    18, 59, 60, 18, 61, 61, 18, 62, 18, 63, 18, 18, 18, 18, 61, 18, 18, 64, 
+    18, 18, 18, 18, 65, 66, 18, 18, 18, 18, 18, 66, 18, 18, 67, 18, 18, 68, 
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 69, 18, 18, 69, 18, 18, 18, 18, 
+    69, 18, 70, 70, 18, 18, 18, 18, 18, 18, 71, 18, 72, 18, 18, 18, 18, 18, 
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
+    18, 18, 18, 18, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 4, 4, 4, 4, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 47, 47, 47, 47, 47, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 47, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
     16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
-    16, 16, 16, 16, 16, 16, 16, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 
-    88, 88, 88, 88, 88, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
-    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
-    24, 23, 24, 1, 15, 15, 15, 15, 0, 1, 1, 23, 24, 23, 24, 23, 24, 23, 24, 
-    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
-    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
-    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 55, 23, 24, 23, 24, 23, 24, 23, 
-    24, 23, 24, 23, 24, 23, 24, 0, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
-    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
-    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 0, 0, 0, 0, 0, 0, 
-    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 0, 0, 46, 1, 1, 1, 1, 1, 1, 0, 95, 95, 95, 95, 
-    95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 
-    95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 17, 0, 1, 
-    1, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 1, 15, 1, 15, 15, 
-    1, 15, 15, 1, 15, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 0, 0, 0, 0, 0, 46, 46, 46, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 
-    1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 15, 15, 15, 15, 15, 15, 0, 
-    0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 
-    0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 15, 15, 15, 15, 15, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 4, 5, 6, 7, 8, 
-    9, 10, 11, 12, 13, 1, 1, 1, 1, 46, 46, 15, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 1, 46, 15, 15, 15, 15, 15, 15, 15, 1, 1, 15, 15, 15, 15, 15, 15, 
-    46, 46, 15, 15, 1, 15, 15, 15, 15, 46, 46, 4, 5, 6, 7, 8, 9, 10, 11, 12, 
-    13, 46, 46, 46, 1, 1, 46, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 
-    46, 15, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 15, 15, 15, 15, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 73, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 0, 0, 0, 0, 4, 4, 0, 0, 0, 0, 74, 0, 0, 0, 4, 0, 0, 
+    0, 0, 0, 4, 4, 75, 4, 76, 76, 76, 0, 77, 0, 78, 78, 18, 15, 15, 15, 15, 
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 
+    15, 15, 15, 15, 15, 79, 80, 80, 80, 18, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 81, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 82, 83, 83, 0, 84, 85, 56, 56, 56, 86, 87, 18, 24, 25, 24, 25, 24, 
+    25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 
+    25, 88, 89, 90, 18, 91, 92, 4, 24, 25, 93, 24, 25, 18, 56, 56, 56, 94, 
+    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 15, 15, 15, 
     15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
-    15, 15, 15, 15, 15, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 46, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 
+    89, 89, 89, 89, 89, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 
+    25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 
+    25, 24, 25, 4, 16, 16, 16, 16, 0, 4, 4, 24, 25, 24, 25, 24, 25, 24, 25, 
+    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
+    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
+    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 56, 24, 25, 24, 25, 24, 25, 24, 
+    25, 24, 25, 24, 25, 24, 25, 0, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
+    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
+    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 0, 0, 0, 0, 0, 0, 
+    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 
+    95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 
+    95, 95, 95, 95, 95, 95, 0, 0, 47, 4, 4, 4, 4, 4, 4, 0, 96, 96, 96, 96, 
+    96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 
+    96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 18, 0, 4, 
+    4, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 16, 16, 16, 4, 16, 4, 16, 16, 
+    4, 16, 16, 4, 16, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 0, 0, 0, 0, 0, 47, 47, 47, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 
+    1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 16, 16, 16, 16, 16, 16, 0, 
+    0, 0, 0, 0, 4, 0, 0, 4, 4, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 
+    0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 5, 6, 7, 8, 9, 
+    10, 11, 12, 13, 14, 4, 4, 4, 4, 47, 47, 16, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 4, 47, 16, 16, 16, 16, 16, 16, 16, 1, 4, 16, 16, 16, 16, 16, 16, 
+    47, 47, 16, 16, 4, 16, 16, 16, 16, 47, 47, 5, 6, 7, 8, 9, 10, 11, 12, 13, 
+    14, 47, 47, 47, 4, 4, 47, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 1, 
+    47, 16, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 47, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
@@ -466,233 +465,233 @@
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 15, 46, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 46, 15, 
-    15, 15, 15, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 15, 15, 1, 
-    1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 46, 0, 0, 0, 15, 15, 15, 0, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 46, 
-    46, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 0, 46, 0, 0, 0, 
-    46, 46, 46, 46, 0, 0, 15, 46, 15, 15, 15, 15, 15, 15, 15, 0, 0, 15, 15, 
-    0, 0, 15, 15, 15, 46, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 46, 46, 0, 
-    46, 46, 46, 15, 15, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 46, 46, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 15, 15, 15, 0, 46, 46, 46, 46, 46, 
-    46, 0, 0, 0, 0, 46, 46, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 46, 
-    46, 0, 46, 46, 0, 46, 46, 0, 46, 46, 0, 0, 15, 0, 15, 15, 15, 15, 15, 0, 
-    0, 0, 0, 15, 15, 0, 0, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 
-    46, 46, 46, 0, 46, 0, 0, 0, 0, 0, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 
-    15, 15, 46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 0, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 0, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 
-    46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 0, 46, 46, 46, 46, 46, 0, 0, 15, 
-    46, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 0, 15, 15, 15, 0, 0, 
-    46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 15, 15, 0, 0, 4, 
-    5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 15, 15, 15, 0, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 46, 46, 0, 
-    0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 0, 46, 46, 
-    46, 46, 46, 0, 0, 15, 46, 15, 15, 15, 15, 15, 15, 0, 0, 0, 15, 15, 0, 0, 
-    15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 46, 46, 0, 46, 
-    46, 46, 0, 0, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 46, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 46, 0, 46, 46, 46, 46, 46, 46, 0, 
-    0, 0, 46, 46, 46, 0, 46, 46, 46, 46, 0, 0, 0, 46, 46, 0, 46, 0, 46, 46, 
-    0, 0, 0, 46, 46, 0, 0, 0, 46, 46, 46, 0, 0, 0, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 15, 15, 15, 15, 15, 0, 0, 0, 15, 15, 
-    15, 0, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 15, 15, 15, 0, 46, 46, 46, 46, 46, 
-    46, 46, 46, 0, 46, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 0, 0, 0, 0, 15, 15, 15, 15, 
-    15, 15, 15, 0, 15, 15, 15, 0, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 15, 
-    15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 0, 0, 0, 0, 4, 5, 6, 7, 8, 9, 10, 
-    11, 12, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 
-    0, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 0, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 0, 0, 
-    15, 46, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 0, 15, 15, 15, 15, 0, 
-    0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 46, 0, 46, 46, 0, 0, 0, 0, 
-    4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 15, 15, 0, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 
-    0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 0, 0, 15, 15, 15, 
-    0, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 
-    46, 46, 0, 0, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 0, 0, 46, 46, 46, 
-    46, 46, 46, 46, 0, 0, 0, 15, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 0, 15, 
-    0, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 15, 15, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 15, 46, 96, 15, 15, 15, 15, 15, 15, 
-    15, 0, 0, 0, 0, 1, 46, 46, 46, 46, 46, 46, 46, 15, 15, 15, 15, 15, 15, 
-    15, 15, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 1, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 46, 46, 0, 46, 0, 0, 46, 46, 0, 46, 0, 0, 46, 0, 0, 0, 
-    0, 0, 0, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 0, 
-    46, 0, 46, 0, 0, 46, 46, 0, 46, 46, 46, 46, 15, 46, 96, 15, 15, 15, 15, 
-    15, 15, 0, 15, 15, 46, 0, 0, 46, 46, 46, 46, 46, 0, 46, 0, 15, 15, 15, 
-    15, 15, 15, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 46, 46, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 46, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 15, 15, 1, 1, 1, 1, 1, 1, 4, 5, 6, 7, 8, 9, 10, 
-    11, 12, 13, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 15, 1, 15, 1, 15, 1, 1, 1, 
-    1, 15, 15, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 1, 15, 15, 
-    46, 46, 46, 46, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 1, 1, 
-    1, 1, 1, 1, 1, 1, 15, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 0, 46, 46, 
-    0, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 
-    4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 1, 1, 1, 1, 1, 46, 46, 46, 46, 46, 
-    46, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 
-    97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 
-    97, 97, 97, 97, 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 1, 46, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 0, 0, 46, 46, 46, 46, 46, 46, 
-    46, 0, 46, 0, 46, 46, 46, 46, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 
-    46, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 
-    46, 46, 46, 46, 0, 0, 46, 46, 46, 46, 46, 46, 46, 0, 46, 0, 46, 46, 46, 
-    46, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 0, 46, 46, 46, 46, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 0, 0, 0, 0, 15, 1, 1, 1, 1, 1, 1, 1, 1, 1, 98, 99, 100, 
-    101, 102, 103, 104, 105, 106, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 1, 1, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 2, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 1, 1, 0, 0, 0, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    1, 1, 1, 107, 107, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 15, 
-    15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 15, 15, 15, 1, 1, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 0, 15, 15, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 1, 1, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 1, 1, 
-    1, 46, 1, 1, 1, 1, 46, 15, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 
-    0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 15, 15, 15, 2, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 
-    0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 15, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 
-    0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 15, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 4, 
-    5, 6, 7, 8, 9, 10, 11, 12, 13, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 0, 0, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 46, 46, 46, 46, 46, 46, 46, 15, 15, 0, 0, 
-    0, 0, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 0, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 15, 15, 15, 15, 15, 0, 0, 1, 1, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 16, 47, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 0, 47, 16, 
+    16, 16, 16, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 16, 16, 4, 
+    4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 47, 0, 0, 0, 16, 16, 16, 0, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 47, 
+    47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 0, 0, 0, 
+    47, 47, 47, 47, 0, 0, 16, 47, 16, 16, 16, 16, 16, 16, 16, 0, 0, 16, 16, 
+    0, 0, 16, 16, 16, 47, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 47, 47, 0, 
+    47, 47, 47, 16, 16, 0, 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 47, 47, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 16, 16, 16, 0, 47, 47, 47, 47, 
+    47, 47, 0, 0, 0, 0, 47, 47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 
+    47, 47, 0, 47, 47, 0, 47, 47, 0, 47, 47, 0, 0, 16, 0, 16, 16, 16, 16, 16, 
+    0, 0, 0, 0, 16, 16, 0, 0, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    47, 47, 47, 47, 0, 47, 0, 0, 0, 0, 0, 0, 0, 5, 6, 7, 8, 9, 10, 11, 12, 
+    13, 14, 16, 16, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 
+    16, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 0, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 0, 47, 47, 47, 47, 47, 0, 
+    0, 16, 47, 16, 16, 16, 16, 16, 16, 16, 16, 0, 16, 16, 16, 0, 16, 16, 16, 
+    0, 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 16, 16, 0, 
+    0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 16, 16, 16, 0, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 47, 
+    47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 0, 47, 
+    47, 47, 47, 47, 0, 0, 16, 47, 16, 16, 16, 16, 16, 16, 0, 0, 0, 16, 16, 0, 
+    0, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 47, 47, 0, 47, 
+    47, 47, 0, 0, 0, 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 4, 47, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 47, 0, 47, 47, 47, 47, 47, 47, 0, 
+    0, 0, 47, 47, 47, 0, 47, 47, 47, 47, 0, 0, 0, 47, 47, 0, 47, 0, 47, 47, 
+    0, 0, 0, 47, 47, 0, 0, 0, 47, 47, 47, 0, 0, 0, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 16, 16, 16, 16, 16, 0, 0, 0, 16, 16, 
+    16, 0, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 16, 16, 16, 0, 47, 47, 47, 47, 47, 
+    47, 47, 47, 0, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 0, 0, 0, 0, 16, 16, 16, 16, 
+    16, 16, 16, 0, 16, 16, 16, 0, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 16, 
+    16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 0, 0, 0, 0, 5, 6, 7, 8, 9, 10, 11, 
+    12, 13, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 
+    0, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 0, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 0, 0, 
+    16, 47, 16, 16, 16, 16, 16, 16, 16, 0, 16, 16, 16, 0, 16, 16, 16, 16, 0, 
+    0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 47, 0, 47, 47, 0, 0, 0, 0, 
+    5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 16, 16, 0, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 
+    0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 0, 0, 16, 16, 16, 
+    0, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 
+    47, 47, 0, 0, 0, 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 0, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 0, 0, 47, 47, 47, 
+    47, 47, 47, 47, 0, 0, 0, 16, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 0, 16, 
+    0, 16, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 16, 16, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 16, 47, 97, 16, 16, 16, 16, 16, 16, 
+    16, 0, 0, 0, 0, 4, 47, 47, 47, 47, 47, 47, 47, 16, 16, 16, 16, 16, 16, 
+    16, 16, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 4, 4, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 47, 47, 0, 47, 0, 0, 47, 47, 0, 47, 0, 0, 47, 0, 0, 0, 
+    0, 0, 0, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 0, 
+    47, 0, 47, 0, 0, 47, 47, 0, 47, 47, 47, 47, 16, 47, 97, 16, 16, 16, 16, 
+    16, 16, 0, 16, 16, 47, 0, 0, 47, 47, 47, 47, 47, 0, 47, 0, 16, 16, 16, 
+    16, 16, 16, 0, 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, 0, 47, 47, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 47, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 16, 16, 4, 4, 4, 4, 4, 4, 5, 6, 7, 8, 9, 10, 11, 
+    12, 13, 14, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 16, 4, 16, 4, 16, 4, 4, 4, 
+    4, 16, 16, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 4, 16, 16, 
+    47, 47, 47, 47, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 16, 16, 0, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 4, 4, 
+    4, 4, 4, 4, 4, 4, 16, 4, 4, 4, 4, 4, 4, 0, 0, 4, 4, 4, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 0, 47, 47, 
+    0, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 
+    5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 4, 4, 4, 4, 4, 4, 47, 47, 47, 47, 47, 
+    47, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 
+    98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 
+    98, 98, 98, 98, 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 4, 47, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 0, 0, 47, 47, 47, 47, 47, 47, 
+    47, 0, 47, 0, 47, 47, 47, 47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 
+    47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 
+    47, 47, 47, 47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 0, 47, 47, 47, 
+    47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 0, 47, 47, 47, 47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 0, 0, 0, 0, 16, 4, 4, 4, 4, 4, 4, 4, 4, 4, 99, 100, 101, 
+    102, 103, 104, 105, 106, 107, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 4, 4, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 2, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 4, 4, 0, 0, 0, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    4, 4, 4, 108, 108, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 16, 
+    16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 16, 16, 16, 4, 4, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 0, 16, 16, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 1, 1, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 4, 4, 
+    4, 47, 4, 4, 4, 4, 47, 16, 0, 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, 0, 
+    0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 16, 16, 16, 2, 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 
+    0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 16, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 
+    0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 4, 0, 0, 0, 4, 4, 5, 
+    6, 7, 8, 9, 10, 11, 12, 13, 14, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 0, 0, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 47, 47, 47, 47, 47, 47, 47, 16, 16, 0, 0, 
+    0, 0, 0, 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, 0, 0, 0, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 16, 16, 16, 16, 16, 0, 0, 4, 4, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
@@ -700,132 +699,134 @@
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
-    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
-    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 17, 17, 17, 17, 17, 17, 
-    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 46, 17, 
-    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
-    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 15, 15, 
-    15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 24, 23, 24, 23, 24, 23, 24, 
-    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
-    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
-    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
-    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
-    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
-    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
-    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
-    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 17, 17, 
-    17, 17, 17, 108, 0, 0, 0, 0, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
-    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
-    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
-    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
-    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 
-    24, 23, 24, 23, 24, 23, 24, 0, 0, 0, 0, 0, 0, 109, 109, 109, 109, 109, 
-    109, 109, 109, 110, 110, 110, 110, 110, 110, 110, 110, 109, 109, 109, 
-    109, 109, 109, 0, 0, 110, 110, 110, 110, 110, 110, 0, 0, 109, 109, 109, 
-    109, 109, 109, 109, 109, 110, 110, 110, 110, 110, 110, 110, 110, 109, 
-    109, 109, 109, 109, 109, 109, 109, 110, 110, 110, 110, 110, 110, 110, 
-    110, 109, 109, 109, 109, 109, 109, 0, 0, 110, 110, 110, 110, 110, 110, 0, 
-    0, 17, 109, 17, 109, 17, 109, 17, 109, 0, 110, 0, 110, 0, 110, 0, 110, 
-    109, 109, 109, 109, 109, 109, 109, 109, 110, 110, 110, 110, 110, 110, 
-    110, 110, 111, 111, 112, 112, 112, 112, 113, 113, 114, 114, 115, 115, 
-    116, 116, 0, 0, 109, 109, 109, 109, 109, 109, 109, 109, 117, 117, 117, 
-    117, 117, 117, 117, 117, 109, 109, 109, 109, 109, 109, 109, 109, 117, 
-    117, 117, 117, 117, 117, 117, 117, 109, 109, 109, 109, 109, 109, 109, 
-    109, 117, 117, 117, 117, 117, 117, 117, 117, 109, 109, 17, 118, 17, 0, 
-    17, 17, 110, 110, 119, 119, 120, 1, 121, 1, 1, 1, 17, 118, 17, 0, 17, 17, 
-    122, 122, 122, 122, 120, 1, 1, 1, 109, 109, 17, 17, 0, 0, 17, 17, 110, 
-    110, 123, 123, 0, 1, 1, 1, 109, 109, 17, 17, 17, 89, 17, 17, 110, 110, 
-    124, 124, 92, 1, 1, 1, 0, 0, 17, 118, 17, 0, 17, 17, 125, 125, 126, 126, 
-    120, 1, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 
-    1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 15, 15, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 15, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 127, 17, 0, 
-    0, 128, 129, 130, 131, 132, 133, 1, 1, 1, 1, 1, 17, 127, 21, 18, 19, 128, 
-    129, 130, 131, 132, 133, 1, 1, 1, 1, 1, 0, 46, 46, 46, 46, 46, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
-    15, 1, 1, 1, 1, 15, 1, 1, 1, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 55, 1, 1, 1, 1, 55, 1, 
-    1, 17, 55, 55, 55, 17, 17, 55, 55, 55, 17, 1, 55, 1, 1, 107, 55, 55, 55, 
-    55, 55, 1, 1, 1, 1, 1, 1, 55, 1, 134, 1, 55, 1, 135, 136, 55, 55, 107, 
-    17, 55, 55, 1, 55, 17, 46, 46, 46, 46, 17, 1, 1, 17, 17, 55, 55, 1, 1, 1, 
-    1, 1, 55, 17, 17, 17, 17, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 
-    137, 137, 137, 137, 137, 138, 138, 138, 138, 138, 138, 138, 138, 138, 
-    138, 138, 138, 138, 138, 138, 138, 107, 107, 107, 107, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 21, 18, 19, 128, 129, 130, 131, 132, 133, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 21, 18, 19, 128, 129, 130, 131, 132, 133, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 21, 18, 19, 128, 129, 130, 131, 132, 133, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 139, 139, 139, 139, 139, 139, 139, 139, 
-    139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 
-    139, 139, 139, 139, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 
+    0, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 18, 18, 18, 18, 18, 18, 
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 47, 18, 
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 16, 16, 
+    16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 25, 24, 25, 24, 25, 24, 25, 
+    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
+    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
+    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
+    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
+    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
+    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
+    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
+    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 18, 18, 
+    18, 18, 18, 109, 0, 0, 0, 0, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 
+    25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 
+    25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 
+    25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 
+    25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 
+    25, 24, 25, 24, 25, 24, 25, 0, 0, 0, 0, 0, 0, 110, 110, 110, 110, 110, 
+    110, 110, 110, 111, 111, 111, 111, 111, 111, 111, 111, 110, 110, 110, 
+    110, 110, 110, 0, 0, 111, 111, 111, 111, 111, 111, 0, 0, 110, 110, 110, 
+    110, 110, 110, 110, 110, 111, 111, 111, 111, 111, 111, 111, 111, 110, 
+    110, 110, 110, 110, 110, 110, 110, 111, 111, 111, 111, 111, 111, 111, 
+    111, 110, 110, 110, 110, 110, 110, 0, 0, 111, 111, 111, 111, 111, 111, 0, 
+    0, 18, 110, 18, 110, 18, 110, 18, 110, 0, 111, 0, 111, 0, 111, 0, 111, 
+    110, 110, 110, 110, 110, 110, 110, 110, 111, 111, 111, 111, 111, 111, 
+    111, 111, 112, 112, 113, 113, 113, 113, 114, 114, 115, 115, 116, 116, 
+    117, 117, 0, 0, 110, 110, 110, 110, 110, 110, 110, 110, 118, 118, 118, 
+    118, 118, 118, 118, 118, 110, 110, 110, 110, 110, 110, 110, 110, 118, 
+    118, 118, 118, 118, 118, 118, 118, 110, 110, 110, 110, 110, 110, 110, 
+    110, 118, 118, 118, 118, 118, 118, 118, 118, 110, 110, 18, 119, 18, 0, 
+    18, 18, 111, 111, 120, 120, 121, 4, 122, 4, 4, 4, 18, 119, 18, 0, 18, 18, 
+    123, 123, 123, 123, 121, 4, 4, 4, 110, 110, 18, 18, 0, 0, 18, 18, 111, 
+    111, 124, 124, 0, 4, 4, 4, 110, 110, 18, 18, 18, 90, 18, 18, 111, 111, 
+    125, 125, 93, 4, 4, 4, 0, 0, 18, 119, 18, 0, 18, 18, 126, 126, 127, 127, 
+    121, 4, 4, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 1, 1, 
+    1, 1, 1, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 16, 16, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 16, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 128, 18, 0, 
+    0, 129, 130, 131, 132, 133, 134, 4, 4, 4, 4, 4, 18, 128, 22, 19, 20, 129, 
+    130, 131, 132, 133, 134, 4, 4, 4, 4, 4, 0, 47, 47, 47, 47, 47, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 4, 4, 4, 4, 16, 4, 4, 4, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 56, 4, 4, 4, 4, 56, 4, 
+    4, 18, 56, 56, 56, 18, 18, 56, 56, 56, 18, 4, 56, 4, 4, 108, 56, 56, 56, 
+    56, 56, 4, 4, 4, 4, 4, 4, 56, 4, 135, 4, 56, 4, 136, 137, 56, 56, 108, 
+    18, 56, 56, 4, 56, 18, 47, 47, 47, 47, 18, 4, 4, 18, 18, 56, 56, 4, 4, 4, 
+    4, 4, 56, 18, 18, 18, 18, 4, 4, 4, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 
+    138, 138, 138, 138, 138, 139, 139, 139, 139, 139, 139, 139, 139, 139, 
+    139, 139, 139, 139, 139, 139, 139, 108, 108, 108, 108, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 22, 19, 20, 129, 130, 131, 132, 133, 134, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 22, 19, 20, 129, 130, 131, 132, 133, 134, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 22, 19, 20, 129, 130, 131, 132, 133, 134, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 140, 140, 140, 140, 140, 140, 140, 140, 
     140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 
-    140, 140, 127, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 21, 18, 19, 128, 129, 130, 
-    131, 132, 133, 1, 127, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 
+    140, 140, 140, 140, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 
+    141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 
+    141, 141, 128, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 22, 19, 20, 129, 130, 131, 
+    132, 133, 134, 4, 128, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 21, 18, 
-    19, 128, 129, 130, 131, 132, 133, 1, 21, 18, 19, 128, 129, 130, 131, 132, 
-    133, 1, 21, 18, 19, 128, 129, 130, 131, 132, 133, 1, 1, 0, 0, 0, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    4, 4, 4, 4, 0, 4, 4, 4, 4, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 0, 4, 0, 4, 4, 4, 4, 0, 0, 0, 4, 0, 4, 4, 4, 4, 4, 4, 4, 0, 0, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 22, 19, 
+    20, 129, 130, 131, 132, 133, 134, 4, 22, 19, 20, 129, 130, 131, 132, 133, 
+    134, 4, 22, 19, 20, 129, 130, 131, 132, 133, 134, 4, 4, 0, 0, 0, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
@@ -834,134 +835,133 @@
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 
-    94, 94, 94, 94, 94, 94, 94, 94, 94, 0, 95, 95, 95, 95, 95, 95, 95, 95, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 95, 
     95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 
     95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 
-    95, 95, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 24, 23, 24, 23, 24, 23, 24, 
-    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
-    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
-    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
-    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
-    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 
-    23, 24, 17, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    1, 1, 1, 1, 1, 1, 1, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 
-    141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 
-    141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 0, 46, 
-    46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 
-    46, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 
-    0, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 
-    1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 
-    0, 0, 0, 2, 1, 1, 1, 1, 46, 46, 107, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 107, 107, 107, 107, 107, 107, 107, 
-    107, 107, 15, 15, 15, 15, 15, 15, 1, 46, 46, 46, 46, 46, 1, 1, 107, 107, 
-    107, 46, 46, 1, 1, 1, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 0, 0, 15, 15, 1, 1, 46, 46, 46, 1, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 1, 46, 46, 46, 46, 0, 0, 0, 
-    0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 
-    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    95, 95, 95, 95, 95, 95, 95, 95, 95, 0, 96, 96, 96, 96, 96, 96, 96, 96, 
+    96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 
+    96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 
+    96, 96, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 25, 24, 25, 24, 25, 24, 25, 
+    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
+    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
+    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
+    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
+    24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 24, 25, 
+    24, 25, 18, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    4, 4, 4, 4, 4, 4, 4, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 
+    142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 
+    142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 
+    47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 
+    47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 
+    0, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 4, 
+    4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 
+    0, 0, 0, 2, 4, 4, 4, 4, 47, 47, 108, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 108, 108, 108, 108, 108, 108, 108, 
+    108, 108, 16, 16, 16, 16, 16, 16, 4, 47, 47, 47, 47, 47, 4, 4, 108, 108, 
+    108, 47, 47, 4, 4, 4, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 0, 0, 16, 16, 4, 4, 47, 47, 47, 4, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 4, 47, 47, 47, 47, 0, 0, 0, 
+    0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 
+    0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
@@ -970,10 +970,10 @@
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 46, 46, 15, 46, 46, 46, 15, 46, 46, 46, 46, 15, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 15, 15, 15, 15, 15, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 47, 47, 16, 47, 47, 47, 16, 47, 47, 47, 47, 16, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 16, 16, 16, 16, 16, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
@@ -981,200 +981,212 @@
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 
-    17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 
-    17, 17, 0, 0, 0, 0, 0, 46, 15, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 1, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 
-    46, 0, 46, 0, 46, 46, 0, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 73, 73, 73, 73, 73, 73, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 73, 73, 1, 1, 0, 0, 15, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 1, 1, 1, 15, 15, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 15, 15, 15, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 73, 46, 73, 
-    46, 73, 0, 73, 46, 73, 46, 73, 46, 73, 46, 73, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 1, 0, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 1, 
-    1, 1, 1, 1, 1, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 
-    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 1, 1, 1, 1, 15, 1, 16, 
-    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
-    16, 16, 16, 16, 16, 16, 16, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 96, 
-    96, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 46, 46, 
-    46, 46, 46, 46, 0, 0, 46, 46, 46, 46, 46, 46, 0, 0, 46, 46, 46, 46, 46, 
-    46, 0, 0, 46, 46, 46, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 
-    1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    0, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 107, 
-    107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 
-    107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 
-    107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 
-    107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 
+    0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 47, 
+    16, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 4, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 0, 47, 0, 47, 47, 0, 
+    47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 74, 74, 74, 74, 74, 74, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 4, 4, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 74, 74, 4, 4, 0, 0, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 
+    0, 0, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 16, 
+    16, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 16, 16, 16, 4, 4, 4, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 0, 4, 4, 4, 4, 0, 0, 0, 0, 74, 47, 74, 47, 74, 0, 74, 47, 74, 
+    47, 74, 47, 74, 47, 74, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 0, 0, 1, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 4, 4, 4, 4, 4, 4, 4, 15, 15, 
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
+    15, 15, 15, 15, 15, 15, 4, 4, 4, 4, 16, 4, 17, 17, 17, 17, 17, 17, 17, 
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
+    17, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 97, 97, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 47, 47, 47, 47, 47, 47, 0, 0, 
+    47, 47, 47, 47, 47, 47, 0, 0, 47, 47, 47, 47, 47, 47, 0, 0, 47, 47, 47, 
+    0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 0, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 1, 1, 1, 4, 4, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 0, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 4, 
+    4, 4, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 108, 108, 108, 108, 108, 
+    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
+    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
+    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
+    108, 108, 108, 108, 108, 108, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 0, 1, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 1, 107, 
-    107, 107, 107, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 
-    142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 
-    142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 143, 143, 
+    0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 4, 
+    4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    0, 4, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 4, 108, 108, 108, 108, 
+    108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 143, 143, 143, 
     143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 
     143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 
-    143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    143, 143, 143, 143, 143, 143, 143, 143, 143, 144, 144, 144, 144, 144, 
+    144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 
+    144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 
+    144, 144, 144, 144, 144, 144, 144, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 5, 6, 
+    7, 8, 9, 10, 11, 12, 13, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 
+    47, 47, 47, 47, 47, 0, 0, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 
+    47, 0, 0, 0, 47, 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 46, 46, 46, 46, 46, 46, 0, 0, 46, 0, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 0, 46, 46, 0, 0, 0, 46, 0, 0, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 16, 16, 16, 0, 16, 16, 0, 0, 0, 0, 0, 16, 
+    16, 16, 16, 47, 47, 47, 47, 0, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 0, 0, 0, 0, 16, 16, 16, 0, 0, 0, 0, 16, 22, 19, 20, 129, 4, 4, 4, 
+    4, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 15, 15, 15, 0, 15, 15, 0, 0, 0, 
-    0, 0, 15, 15, 15, 15, 46, 46, 46, 46, 0, 46, 46, 46, 0, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 0, 0, 0, 0, 15, 15, 15, 0, 0, 0, 0, 15, 21, 18, 19, 
-    128, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 15, 15, 15, 15, 15, 
-    1, 1, 1, 15, 15, 15, 15, 15, 15, 1, 1, 1, 1, 1, 1, 1, 1, 15, 15, 15, 15, 
-    15, 15, 15, 15, 1, 1, 15, 15, 15, 15, 15, 15, 15, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 15, 15, 
-    15, 15, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 15, 15, 15, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 16, 16, 16, 16, 16, 4, 4, 4, 
+    16, 16, 16, 16, 16, 16, 1, 1, 1, 1, 1, 1, 1, 1, 16, 16, 16, 16, 16, 16, 
+    16, 16, 4, 4, 16, 16, 16, 16, 16, 16, 16, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 16, 16, 16, 
+    16, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 16, 16, 16, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
@@ -1182,89 +1194,89 @@
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 
+    0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 
-    55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 
-    55, 55, 55, 55, 55, 55, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
-    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 55, 55, 55, 55, 
-    55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 
-    55, 55, 55, 55, 17, 17, 17, 17, 17, 17, 17, 0, 17, 17, 17, 17, 17, 17, 
-    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 55, 55, 55, 55, 55, 55, 
-    55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 
-    55, 55, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
-    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 55, 0, 55, 55, 0, 0, 55, 0, 0, 
-    55, 55, 0, 0, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 17, 17, 
-    17, 17, 0, 17, 0, 17, 17, 17, 17, 17, 17, 17, 0, 17, 17, 17, 17, 17, 17, 
-    17, 17, 17, 17, 17, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 
-    55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 17, 17, 17, 17, 17, 
-    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
-    17, 17, 17, 55, 55, 0, 55, 55, 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, 
-    55, 0, 55, 55, 55, 55, 55, 55, 55, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
-    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 55, 
-    55, 0, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 0, 55, 0, 0, 0, 55, 55, 55, 
-    55, 55, 55, 55, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
-    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 55, 55, 55, 55, 55, 
-    55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 
-    55, 55, 55, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
-    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 55, 55, 55, 55, 55, 55, 55, 
-    55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 
-    55, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
-    17, 17, 17, 17, 17, 17, 17, 17, 17, 55, 55, 55, 55, 55, 55, 55, 55, 55, 
-    55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 17, 
-    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
-    17, 17, 17, 17, 17, 17, 17, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 
-    55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 17, 17, 17, 
-    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
-    17, 17, 17, 17, 17, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 
-    55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 17, 17, 17, 17, 17, 
-    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
-    17, 17, 17, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 
-    55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 17, 17, 17, 17, 17, 17, 17, 
-    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
-    17, 17, 17, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 
-    55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 1, 17, 17, 17, 17, 17, 17, 
-    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
-    17, 1, 17, 17, 17, 17, 17, 17, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 
-    55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 1, 17, 17, 
-    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
-    17, 17, 17, 17, 17, 1, 17, 17, 17, 17, 17, 17, 55, 55, 55, 55, 55, 55, 
-    55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 
-    55, 1, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
-    17, 17, 17, 17, 17, 17, 17, 17, 17, 1, 17, 17, 17, 17, 17, 17, 55, 55, 
-    55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 
-    55, 55, 55, 55, 55, 1, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 
-    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 1, 17, 17, 17, 17, 
-    17, 17, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 
-    55, 55, 55, 55, 55, 55, 55, 55, 55, 1, 17, 17, 17, 17, 17, 17, 17, 17, 
-    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 1, 
-    17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 4, 
-    5, 6, 7, 8, 9, 10, 11, 12, 13, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 4, 5, 6, 
-    7, 8, 9, 10, 11, 12, 13, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 
-    46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 56, 56, 
+    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
+    56, 56, 56, 56, 56, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 56, 56, 56, 56, 56, 
+    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
+    56, 56, 56, 18, 18, 18, 18, 18, 18, 18, 0, 18, 18, 18, 18, 18, 18, 18, 
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 56, 56, 56, 56, 56, 56, 56, 
+    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
+    56, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 56, 0, 56, 56, 0, 0, 56, 0, 0, 56, 
+    56, 0, 0, 56, 56, 56, 56, 0, 56, 56, 56, 56, 56, 56, 56, 56, 18, 18, 18, 
+    18, 0, 18, 0, 18, 18, 18, 18, 18, 18, 18, 0, 18, 18, 18, 18, 18, 18, 18, 
+    18, 18, 18, 18, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
+    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 18, 18, 18, 18, 18, 18, 
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
+    18, 18, 56, 56, 0, 56, 56, 56, 56, 0, 0, 56, 56, 56, 56, 56, 56, 56, 56, 
+    0, 56, 56, 56, 56, 56, 56, 56, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 56, 56, 
+    0, 56, 56, 56, 56, 0, 56, 56, 56, 56, 56, 0, 56, 0, 0, 0, 56, 56, 56, 56, 
+    56, 56, 56, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 56, 56, 56, 56, 56, 56, 
+    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
+    56, 56, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 56, 56, 56, 56, 56, 56, 56, 56, 
+    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
+    18, 18, 18, 18, 18, 18, 18, 18, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
+    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 18, 18, 
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
+    18, 18, 18, 18, 18, 18, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
+    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 18, 18, 18, 18, 
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
+    18, 18, 18, 18, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
+    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 18, 18, 18, 18, 18, 18, 
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
+    18, 18, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
+    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 18, 18, 18, 18, 18, 18, 18, 18, 
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
+    18, 18, 0, 0, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
+    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 4, 18, 18, 18, 18, 18, 18, 18, 
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
+    4, 18, 18, 18, 18, 18, 18, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
+    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 4, 18, 18, 18, 
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
+    18, 18, 18, 18, 4, 18, 18, 18, 18, 18, 18, 56, 56, 56, 56, 56, 56, 56, 
+    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
+    4, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
+    18, 18, 18, 18, 18, 18, 18, 18, 4, 18, 18, 18, 18, 18, 18, 56, 56, 56, 
+    56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
+    56, 56, 56, 56, 4, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 4, 18, 18, 18, 18, 18, 
+    18, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
+    56, 56, 56, 56, 56, 56, 56, 56, 4, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 4, 18, 
+    18, 18, 18, 18, 18, 0, 0, 0, 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 5, 6, 
+    7, 8, 9, 10, 11, 12, 13, 14, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 5, 6, 7, 
+    8, 9, 10, 11, 12, 13, 14, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
+    47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
@@ -1284,20 +1296,20 @@
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 
-    15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
@@ -1311,3 +1323,6 @@
     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 
 };
 
+
+
+

Modified: python/branches/py3k/Python/bltinmodule.c
==============================================================================
--- python/branches/py3k/Python/bltinmodule.c	(original)
+++ python/branches/py3k/Python/bltinmodule.c	Wed Jun 11 20:37:52 2008
@@ -265,6 +265,20 @@
 \n\
 Return True if bool(x) is True for any x in the iterable.");
 
+static PyObject *
+builtin_ascii(PyObject *self, PyObject *v)
+{
+	return PyObject_ASCII(v);
+}
+
+PyDoc_STRVAR(ascii_doc,
+"ascii(object) -> string\n\
+\n\
+As repr(), return a string containing a printable representation of an\n\
+object, but escape the non-ASCII characters in the string returned by\n\
+repr() using \\x, \\u or \\U escapes.  This generates a string similar\n\
+to that returned by repr() in Python 2.");
+
 
 static PyObject *
 builtin_bin(PyObject *self, PyObject *v)
@@ -2188,6 +2202,7 @@
  	{"abs",		builtin_abs,        METH_O, abs_doc},
  	{"all",		builtin_all,        METH_O, all_doc},
  	{"any",		builtin_any,        METH_O, any_doc},
+ 	{"ascii",	builtin_ascii,      METH_O, ascii_doc},
 	{"bin",		builtin_bin,	    METH_O, bin_doc},
  	{"chr",		builtin_chr,        METH_VARARGS, chr_doc},
  	{"cmp",		builtin_cmp,        METH_VARARGS, cmp_doc},

Modified: python/branches/py3k/Python/pythonrun.c
==============================================================================
--- python/branches/py3k/Python/pythonrun.c	(original)
+++ python/branches/py3k/Python/pythonrun.c	Wed Jun 11 20:37:52 2008
@@ -793,7 +793,7 @@
 	}
 	else {
 		if (!(std = PyFile_FromFd(fd, "<stderr>", "w", -1, encoding,
-					  errors, "\n", 0))) {
+					  "backslashreplace", "\n", 0))) {
 			goto error;
 		}
 	} /* if (fd < 0) */

Modified: python/branches/py3k/Tools/unicode/makeunicodedata.py
==============================================================================
--- python/branches/py3k/Tools/unicode/makeunicodedata.py	(original)
+++ python/branches/py3k/Tools/unicode/makeunicodedata.py	Wed Jun 11 20:37:52 2008
@@ -20,6 +20,7 @@
 # 2002-11-25 mvl  add UNIDATA_VERSION
 # 2004-05-29 perky add east asian width information
 # 2006-03-10 mvl  update to Unicode 4.1; add UCD 3.2 delta
+# 2008-06-11 gb   add NONPRINTABLE_MASK for Atsuo Ishimoto's ascii() patch
 #
 # written by Fredrik Lundh (fredrik at pythonware.com)
 #
@@ -60,6 +61,7 @@
 UPPER_MASK = 0x80
 XID_START_MASK = 0x100
 XID_CONTINUE_MASK = 0x200
+NONPRINTABLE_MASK = 0x400
 
 def maketables(trace=0):
 
@@ -71,7 +73,7 @@
                           EASTASIAN_WIDTH % version,
                           DERIVED_CORE_PROPERTIES % version)
 
-    print(len(filter(None, unicode.table)), "characters")
+    print(len(list(filter(None, unicode.table))), "characters")
 
     for version in old_versions:
         print("--- Reading", UNICODE_DATA % ("-"+version), "...")
@@ -79,7 +81,7 @@
                                   COMPOSITION_EXCLUSIONS % ("-"+version),
                                   EASTASIAN_WIDTH % ("-"+version),
                                   DERIVED_CORE_PROPERTIES % ("-"+version))
-        print(len(filter(None, old_unicode.table)), "characters")
+        print(len(list(filter(None, old_unicode.table))), "characters")
         merge_old_version(version, unicode, old_unicode)
 
     makeunicodename(unicode, trace)
@@ -371,6 +373,10 @@
                 flags |= TITLE_MASK
             if category == "Lu":
                 flags |= UPPER_MASK
+            if category[0] == "C":
+                flags |= NONPRINTABLE_MASK
+            if category[0] == "Z" and char != " ":
+                flags |= NONPRINTABLE_MASK
             if "XID_Start" in properties:
                 flags |= XID_START_MASK
             if "XID_Continue" in properties:
@@ -465,7 +471,7 @@
             if name and name[0] != "<":
                 names[char] = name + chr(0)
 
-    print(len(n for n in names if n is not None), "distinct names")
+    print(len(list(n for n in names if n is not None)), "distinct names")
 
     # collect unique words from names (note that we differ between
     # words inside a sentence, and words ending a sentence.  the

From python-3000-checkins at python.org  Wed Jun 11 21:14:15 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Wed, 11 Jun 2008 21:14:15 +0200 (CEST)
Subject: [Python-3000-checkins] r64144 - in python/branches/py3k:
	Doc/library/threading.rst Lib/_threading_local.py
	Lib/logging/__init__.py Lib/multiprocessing/dummy/__init__.py
	Lib/multiprocessing/managers.py Lib/multiprocessing/pool.py
	Lib/multiprocessing/queues.py Lib/multiprocessing/reduction.py
	Lib/multiprocessing/synchronize.py Lib/queue.py
	Lib/test/test_dummy_threading.py
	Lib/test/test_multiprocessing.py Lib/test/test_queue.py
	Lib/test/test_smtplib.py Lib/test/test_socket.py
	Lib/test/test_socketserver.py Lib/test/test_threading.py
	Lib/test/threaded_import_hangers.py Lib/threading.py Misc/NEWS
Message-ID: <20080611191415.D491C1E4010@bag.python.org>

Author: benjamin.peterson
Date: Wed Jun 11 21:14:14 2008
New Revision: 64144

Log:
Merged revisions 64125 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/trunk

........
  r64125 | benjamin.peterson | 2008-06-11 12:27:50 -0500 (Wed, 11 Jun 2008) | 2 lines
  
  give the threading API PEP 8 names
........


Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Doc/library/threading.rst
   python/branches/py3k/Lib/_threading_local.py
   python/branches/py3k/Lib/logging/__init__.py
   python/branches/py3k/Lib/multiprocessing/dummy/__init__.py
   python/branches/py3k/Lib/multiprocessing/managers.py
   python/branches/py3k/Lib/multiprocessing/pool.py
   python/branches/py3k/Lib/multiprocessing/queues.py
   python/branches/py3k/Lib/multiprocessing/reduction.py
   python/branches/py3k/Lib/multiprocessing/synchronize.py
   python/branches/py3k/Lib/queue.py
   python/branches/py3k/Lib/test/test_dummy_threading.py
   python/branches/py3k/Lib/test/test_multiprocessing.py
   python/branches/py3k/Lib/test/test_queue.py
   python/branches/py3k/Lib/test/test_smtplib.py
   python/branches/py3k/Lib/test/test_socket.py
   python/branches/py3k/Lib/test/test_socketserver.py
   python/branches/py3k/Lib/test/test_threading.py
   python/branches/py3k/Lib/test/threaded_import_hangers.py
   python/branches/py3k/Lib/threading.py
   python/branches/py3k/Misc/NEWS

Modified: python/branches/py3k/Doc/library/threading.rst
==============================================================================
--- python/branches/py3k/Doc/library/threading.rst	(original)
+++ python/branches/py3k/Doc/library/threading.rst	Wed Jun 11 21:14:14 2008
@@ -15,7 +15,7 @@
 This module defines the following functions and objects:
 
 
-.. function:: activeCount()
+.. function:: active_count()
 
    Return the number of :class:`Thread` objects currently alive.  The returned
    count is equal to the length of the list returned by :func:`enumerate`.
@@ -29,7 +29,7 @@
    thread.
 
 
-.. function:: currentThread()
+.. function:: current_thread()
 
    Return the current :class:`Thread` object, corresponding to the caller's thread
    of control.  If the caller's thread of control was not created through the
@@ -39,10 +39,10 @@
 
 .. function:: enumerate()
 
-   Return a list of all :class:`Thread` objects currently alive.  The list includes
-   daemonic threads, dummy thread objects created by :func:`currentThread`, and the
-   main thread.  It excludes terminated threads and threads that have not yet been
-   started.
+   Return a list of all :class:`Thread` objects currently alive.  The list
+   includes daemonic threads, dummy thread objects created by
+   :func:`current_thread`, and the main thread.  It excludes terminated threads
+   and threads that have not yet been started.
 
 
 .. function:: Event()
@@ -387,7 +387,7 @@
    lock, its caller should.
 
 
-.. method:: Condition.notifyAll()
+.. method:: Condition.notify_all()
 
    Wake up all threads waiting on this condition.  This method acts like
    :meth:`notify`, but wakes up all waiting threads instead of one. If the calling
@@ -544,12 +544,12 @@
 thread until the thread whose :meth:`join` method is called is terminated.
 
 A thread has a name.  The name can be passed to the constructor, set with the
-:meth:`setName` method, and retrieved with the :meth:`getName` method.
+:meth:`set_name` method, and retrieved with the :meth:`get_name` method.
 
 A thread can be flagged as a "daemon thread".  The significance of this flag is
 that the entire Python program exits when only daemon threads are left.  The
 initial value is inherited from the creating thread.  The flag can be set with
-the :meth:`setDaemon` method and retrieved with the :meth:`isDaemon` method.
+the :meth:`set_daemon` method and retrieved with the :meth:`is_daemon` method.
 
 There is a "main thread" object; this corresponds to the initial thread of
 control in the Python program.  It is not a daemon thread.
@@ -629,12 +629,12 @@
    raises the same exception.
 
 
-.. method:: Thread.getName()
+.. method:: Thread.get_name()
 
    Return the thread's name.
 
 
-.. method:: Thread.setName(name)
+.. method:: Thread.set_name(name)
 
    Set the thread's name.
 
@@ -643,18 +643,16 @@
    constructor.
 
 
-.. method:: Thread.getIdent()
+.. method:: Thread.get_ident()
 
    Return the 'thread identifier' of this thread or None if the thread has not
-   been started.  This is a nonzero integer.  See the :mod:`thread` module's
-   :func:`get_ident()` function.  Thread identifiers may be recycled when a
-   thread exits and another thread is created.  The identifier is returned
-   even after the thread has exited.
+   been started.  This is a nonzero integer.  See the :func:`thread.get_ident()`
+   function.  Thread identifiers may be recycled when a thread exits and another
+   thread is created.  The identifier is returned even after the thread has
+   exited.
 
-   .. versionadded:: 2.6
 
-
-.. method:: Thread.isAlive()
+.. method:: Thread.is_alive()
 
    Return whether the thread is alive.
 
@@ -663,12 +661,12 @@
    returns a list of all alive threads.
 
 
-.. method:: Thread.isDaemon()
+.. method:: Thread.is_daemon()
 
    Return the thread's daemon flag.
 
 
-.. method:: Thread.setDaemon(daemonic)
+.. method:: Thread.set_daemon(daemonic)
 
    Set the thread's daemon flag to the Boolean value *daemonic*. This must be
    called before :meth:`start` is called, otherwise :exc:`RuntimeError` is raised.

Modified: python/branches/py3k/Lib/_threading_local.py
==============================================================================
--- python/branches/py3k/Lib/_threading_local.py	(original)
+++ python/branches/py3k/Lib/_threading_local.py	Wed Jun 11 21:14:14 2008
@@ -161,16 +161,16 @@
         # __init__ being called, to make sure we don't call it
         # again ourselves.
         dict = object.__getattribute__(self, '__dict__')
-        currentThread().__dict__[key] = dict
+        current_thread().__dict__[key] = dict
 
         return self
 
 def _patch(self):
     key = object.__getattribute__(self, '_local__key')
-    d = currentThread().__dict__.get(key)
+    d = current_thread().__dict__.get(key)
     if d is None:
         d = {}
-        currentThread().__dict__[key] = d
+        current_thread().__dict__[key] = d
         object.__setattr__(self, '__dict__', d)
 
         # we have a new instance dict, so call out __init__ if we have
@@ -237,4 +237,4 @@
                 except KeyError:
                     pass # didn't have anything in this thread
 
-from threading import currentThread, RLock
+from threading import current_thread, RLock

Modified: python/branches/py3k/Lib/logging/__init__.py
==============================================================================
--- python/branches/py3k/Lib/logging/__init__.py	(original)
+++ python/branches/py3k/Lib/logging/__init__.py	Wed Jun 11 21:14:14 2008
@@ -258,7 +258,7 @@
         self.relativeCreated = (self.created - _startTime) * 1000
         if logThreads and thread:
             self.thread = thread.get_ident()
-            self.threadName = threading.currentThread().getName()
+            self.threadName = threading.current_thread().get_name()
         else:
             self.thread = None
             self.threadName = None

Modified: python/branches/py3k/Lib/multiprocessing/dummy/__init__.py
==============================================================================
--- python/branches/py3k/Lib/multiprocessing/dummy/__init__.py	(original)
+++ python/branches/py3k/Lib/multiprocessing/dummy/__init__.py	Wed Jun 11 21:14:14 2008
@@ -48,24 +48,17 @@
         threading.Thread.start(self)
 
     def get_exitcode(self):
-        if self._start_called and not self.isAlive():
+        if self._start_called and not self.is_alive():
             return 0
         else:
             return None
 
-    # XXX
-    if sys.version_info < (3, 0):
-        is_alive = threading.Thread.isAlive.__func__
-        get_name = threading.Thread.getName.__func__
-        set_name = threading.Thread.setName.__func__
-        is_daemon = threading.Thread.isDaemon.__func__
-        set_daemon = threading.Thread.setDaemon.__func__
-    else:
-        is_alive = threading.Thread.isAlive
-        get_name = threading.Thread.getName
-        set_name = threading.Thread.setName
-        is_daemon = threading.Thread.isDaemon
-        set_daemon = threading.Thread.setDaemon
+
+    is_alive = threading.Thread.is_alive
+    get_name = threading.Thread.get_name
+    set_name = threading.Thread.set_name
+    is_daemon = threading.Thread.is_daemon
+    set_daemon = threading.Thread.set_daemon
 
 #
 #
@@ -74,22 +67,22 @@
 class Condition(threading._Condition):
     # XXX
     if sys.version_info < (3, 0):
-        notify_all = threading._Condition.notifyAll.__func__
+        notify_all = threading._Condition.notify_all.__func__
     else:
-        notify_all = threading._Condition.notifyAll
+        notify_all = threading._Condition.notify_all
 
 #
 #
 #
 
 Process = DummyProcess
-current_process = threading.currentThread
+current_process = threading.current_thread
 current_process()._children = weakref.WeakKeyDictionary()
 
 def active_children():
     children = current_process()._children
     for p in list(children):
-        if not p.isAlive():
+        if not p.is_alive():
             children.pop(p, None)
     return list(children)
 

Modified: python/branches/py3k/Lib/multiprocessing/managers.py
==============================================================================
--- python/branches/py3k/Lib/multiprocessing/managers.py	(original)
+++ python/branches/py3k/Lib/multiprocessing/managers.py	Wed Jun 11 21:14:14 2008
@@ -169,7 +169,7 @@
                     except (OSError, IOError):
                         continue
                     t = threading.Thread(target=self.handle_request, args=(c,))
-                    t.setDaemon(True)
+                    t.set_daemon(True)
                     t.start()
             except (KeyboardInterrupt, SystemExit):
                 pass
@@ -216,7 +216,7 @@
         Handle requests from the proxies in a particular process/thread
         '''
         util.debug('starting server thread to service %r',
-                   threading.currentThread().getName())
+                   threading.current_thread().get_name())
 
         recv = conn.recv
         send = conn.send
@@ -266,7 +266,7 @@
 
             except EOFError:
                 util.debug('got EOF -- exiting thread serving %r',
-                           threading.currentThread().getName())
+                           threading.current_thread().get_name())
                 sys.exit(0)
 
             except Exception:
@@ -279,7 +279,7 @@
                     send(('#UNSERIALIZABLE', repr(msg)))
             except Exception as e:
                 util.info('exception in thread serving %r',
-                        threading.currentThread().getName())
+                        threading.current_thread().get_name())
                 util.info(' ... message was %r', msg)
                 util.info(' ... exception was %r', e)
                 conn.close()
@@ -401,7 +401,7 @@
         '''
         Spawn a new thread to serve this connection
         '''
-        threading.currentThread().setName(name)
+        threading.current_thread().set_name(name)
         c.send(('#RETURN', None))
         self.serve_client(c)
 
@@ -715,8 +715,8 @@
     def _connect(self):
         util.debug('making connection to manager')
         name = current_process().get_name()
-        if threading.currentThread().getName() != 'MainThread':
-            name += '|' + threading.currentThread().getName()
+        if threading.current_thread().get_name() != 'MainThread':
+            name += '|' + threading.current_thread().get_name()
         conn = self._Client(self._token.address, authkey=self._authkey)
         dispatch(conn, None, 'accept_connection', (name,))
         self._tls.connection = conn
@@ -729,7 +729,7 @@
             conn = self._tls.connection
         except AttributeError:
             util.debug('thread %r does not own a connection',
-                       threading.currentThread().getName())
+                       threading.current_thread().get_name())
             self._connect()
             conn = self._tls.connection
 
@@ -790,7 +790,7 @@
         # the process owns no more references to objects for this manager
         if not idset and hasattr(tls, 'connection'):
             util.debug('thread %r has no more proxies so closing conn',
-                       threading.currentThread().getName())
+                       threading.current_thread().get_name())
             tls.connection.close()
             del tls.connection
 
@@ -969,13 +969,13 @@
 
 class ConditionProxy(AcquirerProxy):
     # XXX will Condition.notfyAll() name be available in Py3.0?
-    _exposed_ = ('acquire', 'release', 'wait', 'notify', 'notifyAll')
+    _exposed_ = ('acquire', 'release', 'wait', 'notify', 'notify_all')
     def wait(self, timeout=None):
         return self._callmethod('wait', (timeout,))
     def notify(self):
         return self._callmethod('notify')
     def notify_all(self):
-        return self._callmethod('notifyAll')
+        return self._callmethod('notify_all')
 
 class EventProxy(BaseProxy):
     # XXX will Event.isSet name be available in Py3.0?

Modified: python/branches/py3k/Lib/multiprocessing/pool.py
==============================================================================
--- python/branches/py3k/Lib/multiprocessing/pool.py	(original)
+++ python/branches/py3k/Lib/multiprocessing/pool.py	Wed Jun 11 21:14:14 2008
@@ -107,7 +107,7 @@
             target=Pool._handle_tasks,
             args=(self._taskqueue, self._quick_put, self._outqueue, self._pool)
             )
-        self._task_handler.setDaemon(True)
+        self._task_handler.set_daemon(True)
         self._task_handler._state = RUN
         self._task_handler.start()
 
@@ -115,7 +115,7 @@
             target=Pool._handle_results,
             args=(self._outqueue, self._quick_get, self._cache)
             )
-        self._result_handler.setDaemon(True)
+        self._result_handler.set_daemon(True)
         self._result_handler._state = RUN
         self._result_handler.start()
 
@@ -213,7 +213,7 @@
 
     @staticmethod
     def _handle_tasks(taskqueue, put, outqueue, pool):
-        thread = threading.currentThread()
+        thread = threading.current_thread()
 
         for taskseq, set_length in iter(taskqueue.get, None):
             i = -1
@@ -252,7 +252,7 @@
 
     @staticmethod
     def _handle_results(outqueue, get, cache):
-        thread = threading.currentThread()
+        thread = threading.current_thread()
 
         while 1:
             try:
@@ -346,7 +346,7 @@
         # task_handler may be blocked trying to put items on inqueue
         debug('removing tasks from inqueue until task handler finished')
         inqueue._rlock.acquire()
-        while task_handler.isAlive() and inqueue._reader.poll():
+        while task_handler.is_alive() and inqueue._reader.poll():
             inqueue._reader.recv()
             time.sleep(0)
 
@@ -362,7 +362,7 @@
         debug('helping task handler/workers to finish')
         cls._help_stuff_finish(inqueue, task_handler, len(pool))
 
-        assert result_handler.isAlive() or len(cache) == 0
+        assert result_handler.is_alive() or len(cache) == 0
 
         result_handler._state = TERMINATE
         outqueue.put(None)                  # sentinel
@@ -591,6 +591,6 @@
         try:
             inqueue.queue.clear()
             inqueue.queue.extend([None] * size)
-            inqueue.not_empty.notifyAll()
+            inqueue.not_empty.notify_all()
         finally:
             inqueue.not_empty.release()

Modified: python/branches/py3k/Lib/multiprocessing/queues.py
==============================================================================
--- python/branches/py3k/Lib/multiprocessing/queues.py	(original)
+++ python/branches/py3k/Lib/multiprocessing/queues.py	Wed Jun 11 21:14:14 2008
@@ -155,7 +155,7 @@
                   self._wlock, self._writer.close),
             name='QueueFeederThread'
             )
-        self._thread.setDaemon(True)
+        self._thread.set_daemon(True)
 
         debug('doing self._thread.start()')
         self._thread.start()

Modified: python/branches/py3k/Lib/multiprocessing/reduction.py
==============================================================================
--- python/branches/py3k/Lib/multiprocessing/reduction.py	(original)
+++ python/branches/py3k/Lib/multiprocessing/reduction.py	Wed Jun 11 21:14:14 2008
@@ -84,7 +84,7 @@
                 debug('starting listener and thread for sending handles')
                 _listener = Listener(authkey=current_process().get_authkey())
                 t = threading.Thread(target=_serve)
-                t.setDaemon(True)
+                t.set_daemon(True)
                 t.start()
         finally:
             _lock.release()

Modified: python/branches/py3k/Lib/multiprocessing/synchronize.py
==============================================================================
--- python/branches/py3k/Lib/multiprocessing/synchronize.py	(original)
+++ python/branches/py3k/Lib/multiprocessing/synchronize.py	Wed Jun 11 21:14:14 2008
@@ -109,8 +109,8 @@
         try:
             if self._semlock._is_mine():
                 name = current_process().get_name()
-                if threading.currentThread().getName() != 'MainThread':
-                    name += '|' + threading.currentThread().getName()
+                if threading.current_thread().get_name() != 'MainThread':
+                    name += '|' + threading.current_thread().get_name()
             elif self._semlock._get_value() == 1:
                 name = 'None'
             elif self._semlock._count() > 0:
@@ -134,8 +134,8 @@
         try:
             if self._semlock._is_mine():
                 name = current_process().get_name()
-                if threading.currentThread().getName() != 'MainThread':
-                    name += '|' + threading.currentThread().getName()
+                if threading.current_thread().get_name() != 'MainThread':
+                    name += '|' + threading.current_thread().get_name()
                 count = self._semlock._count()
             elif self._semlock._get_value() == 1:
                 name, count = 'None', 0

Modified: python/branches/py3k/Lib/queue.py
==============================================================================
--- python/branches/py3k/Lib/queue.py	(original)
+++ python/branches/py3k/Lib/queue.py	Wed Jun 11 21:14:14 2008
@@ -62,7 +62,7 @@
             if unfinished <= 0:
                 if unfinished < 0:
                     raise ValueError('task_done() called too many times')
-                self.all_tasks_done.notifyAll()
+                self.all_tasks_done.notify_all()
             self.unfinished_tasks = unfinished
         finally:
             self.all_tasks_done.release()

Modified: python/branches/py3k/Lib/test/test_dummy_threading.py
==============================================================================
--- python/branches/py3k/Lib/test/test_dummy_threading.py	(original)
+++ python/branches/py3k/Lib/test/test_dummy_threading.py	Wed Jun 11 21:14:14 2008
@@ -16,7 +16,7 @@
             #delay = random.random() * 2
             delay = 0
             if support.verbose:
-                print('task', self.getName(), 'will run for', delay, 'sec')
+                print('task', self.get_name(), 'will run for', delay, 'sec')
             sema.acquire()
             mutex.acquire()
             running += 1
@@ -25,11 +25,11 @@
             mutex.release()
             time.sleep(delay)
             if support.verbose:
-                print('task', self.getName(), 'done')
+                print('task', self.get_name(), 'done')
             mutex.acquire()
             running -= 1
             if support.verbose:
-                print(self.getName(), 'is finished.', running, 'tasks are running')
+                print(self.get_name(), 'is finished.', running, 'tasks are running')
             mutex.release()
             sema.release()
 

Modified: python/branches/py3k/Lib/test/test_multiprocessing.py
==============================================================================
--- python/branches/py3k/Lib/test/test_multiprocessing.py	(original)
+++ python/branches/py3k/Lib/test/test_multiprocessing.py	Wed Jun 11 21:14:14 2008
@@ -632,7 +632,7 @@
         p.start()
 
         p = threading.Thread(target=self.f, args=(cond, sleeping, woken))
-        p.setDaemon(True)
+        p.set_daemon(True)
         p.start()
 
         # wait for both children to start sleeping
@@ -679,7 +679,7 @@
 
             t = threading.Thread(target=self.f,
                                  args=(cond, sleeping, woken, TIMEOUT1))
-            t.setDaemon(True)
+            t.set_daemon(True)
             t.start()
 
         # wait for them all to sleep
@@ -701,7 +701,7 @@
             p.start()
 
             t = threading.Thread(target=self.f, args=(cond, sleeping, woken))
-            t.setDaemon(True)
+            t.set_daemon(True)
             t.start()
 
         # wait for them to all sleep

Modified: python/branches/py3k/Lib/test/test_queue.py
==============================================================================
--- python/branches/py3k/Lib/test/test_queue.py	(original)
+++ python/branches/py3k/Lib/test/test_queue.py	Wed Jun 11 21:14:14 2008
@@ -52,11 +52,11 @@
         self.t.start()
         self.result = block_func(*block_args)
         # If block_func returned before our thread made the call, we failed!
-        if not self.t.startedEvent.isSet():
+        if not self.t.startedEvent.is_set():
             self.fail("blocking function '%r' appeared not to block" %
                       block_func)
         self.t.join(10) # make sure the thread terminates
-        if self.t.isAlive():
+        if self.t.is_alive():
             self.fail("trigger function '%r' appeared to not return" %
                       trigger_func)
         return self.result
@@ -76,10 +76,10 @@
                                  expected_exception_class)
         finally:
             self.t.join(10) # make sure the thread terminates
-            if self.t.isAlive():
+            if self.t.is_alive():
                 self.fail("trigger function '%r' appeared to not return" %
                                  trigger_func)
-            if not self.t.startedEvent.isSet():
+            if not self.t.startedEvent.is_set():
                 self.fail("trigger thread ended but event never set")
 
 

Modified: python/branches/py3k/Lib/test/test_smtplib.py
==============================================================================
--- python/branches/py3k/Lib/test/test_smtplib.py	(original)
+++ python/branches/py3k/Lib/test/test_smtplib.py	Wed Jun 11 21:14:14 2008
@@ -109,7 +109,7 @@
 
             # when the client conversation is finished, it will
             # set client_evt, and it's then ok to kill the server
-            if client_evt.isSet():
+            if client_evt.is_set():
                 serv.close()
                 break
 
@@ -118,7 +118,7 @@
     except socket.timeout:
         pass
     finally:
-        if not client_evt.isSet():
+        if not client_evt.is_set():
             # allow some time for the client to read the result
             time.sleep(0.5)
             serv.close()

Modified: python/branches/py3k/Lib/test/test_socket.py
==============================================================================
--- python/branches/py3k/Lib/test/test_socket.py	(original)
+++ python/branches/py3k/Lib/test/test_socket.py	Wed Jun 11 21:14:14 2008
@@ -108,7 +108,7 @@
             self.clientRun, (test_method,))
 
         self.__setUp()
-        if not self.server_ready.isSet():
+        if not self.server_ready.is_set():
             self.server_ready.set()
         self.client_ready.wait()
 

Modified: python/branches/py3k/Lib/test/test_socketserver.py
==============================================================================
--- python/branches/py3k/Lib/test/test_socketserver.py	(original)
+++ python/branches/py3k/Lib/test/test_socketserver.py	Wed Jun 11 21:14:14 2008
@@ -139,7 +139,7 @@
             # Time between requests is short enough that we won't wake
             # up spuriously too many times.
             kwargs={'poll_interval':0.01})
-        t.setDaemon(True)  # In case this function raises.
+        t.set_daemon(True)  # In case this function raises.
         t.start()
         if verbose: print("server running")
         for i in range(3):

Modified: python/branches/py3k/Lib/test/test_threading.py
==============================================================================
--- python/branches/py3k/Lib/test/test_threading.py	(original)
+++ python/branches/py3k/Lib/test/test_threading.py	Wed Jun 11 21:14:14 2008
@@ -34,7 +34,7 @@
         delay = random.random() / 10000.0
         if verbose:
             print('task %s will run for %.1f usec' %
-                  (self.getName(), delay * 1e6))
+                  (self.get_name(), delay * 1e6))
 
         with self.sema:
             with self.mutex:
@@ -45,13 +45,15 @@
 
             time.sleep(delay)
             if verbose:
-                print('task', self.getName(), 'done')
+                print('task', self.get_name(), 'done')
+
             with self.mutex:
                 self.nrunning.dec()
                 self.testcase.assert_(self.nrunning.get() >= 0)
                 if verbose:
                     print('%s is finished. %d tasks are running' %
-                          (self.getName(), self.nrunning.get()))
+                          (self.get_name(), self.nrunning.get()))
+
 
 class ThreadTests(unittest.TestCase):
 
@@ -72,7 +74,7 @@
         for i in range(NUMTASKS):
             t = TestThread("<thread %d>"%i, self, sema, mutex, numrunning)
             threads.append(t)
-            self.failUnlessEqual(t.getIdent(), None)
+            self.failUnlessEqual(t.get_ident(), None)
             self.assert_(re.match('<TestThread\(.*, initial\)>', repr(t)))
             t.start()
 
@@ -80,8 +82,8 @@
             print('waiting for all tasks to complete')
         for t in threads:
             t.join(NUMTASKS)
-            self.assert_(not t.isAlive())
-            self.failIfEqual(t.getIdent(), 0)
+            self.assert_(not t.is_alive())
+            self.failIfEqual(t.get_ident(), 0)
             self.assert_(re.match('<TestThread\(.*, \w+ -?\d+\)>', repr(t)))
         if verbose:
             print('all tasks done')
@@ -171,7 +173,7 @@
                     worker_saw_exception.set()
 
         t = Worker()
-        t.setDaemon(True) # so if this fails, we don't hang Python at shutdown
+        t.set_daemon(True) # so if this fails, we don't hang Python at shutdown
         t.start()
         if verbose:
             print("    started worker thread")
@@ -257,12 +259,12 @@
                 print('program blocked; aborting')
                 os._exit(2)
             t = threading.Thread(target=killer)
-            t.setDaemon(True)
+            t.set_daemon(True)
             t.start()
 
             # This is the trace function
             def func(frame, event, arg):
-                threading.currentThread()
+                threading.current_thread()
                 return func
 
             sys.settrace(func)
@@ -347,8 +349,8 @@
         self.assertRaises(ValueError, threading.Semaphore, value = -sys.maxsize)
 
     def test_joining_current_thread(self):
-        currentThread = threading.currentThread()
-        self.assertRaises(RuntimeError, currentThread.join);
+        current_thread = threading.current_thread()
+        self.assertRaises(RuntimeError, current_thread.join);
 
     def test_joining_inactive_thread(self):
         thread = threading.Thread()
@@ -357,7 +359,7 @@
     def test_daemonize_active_thread(self):
         thread = threading.Thread()
         thread.start()
-        self.assertRaises(RuntimeError, thread.setDaemon, True)
+        self.assertRaises(RuntimeError, thread.set_daemon, True)
 
 
 def test_main():

Modified: python/branches/py3k/Lib/test/threaded_import_hangers.py
==============================================================================
--- python/branches/py3k/Lib/test/threaded_import_hangers.py	(original)
+++ python/branches/py3k/Lib/test/threaded_import_hangers.py	Wed Jun 11 21:14:14 2008
@@ -38,5 +38,5 @@
     t = Worker(func, args)
     t.start()
     t.join(TIMEOUT)
-    if t.isAlive():
+    if t.is_alive():
         errors.append("%s appeared to hang" % name)

Modified: python/branches/py3k/Lib/threading.py
==============================================================================
--- python/branches/py3k/Lib/threading.py	(original)
+++ python/branches/py3k/Lib/threading.py	Wed Jun 11 21:14:14 2008
@@ -8,7 +8,7 @@
 from collections import deque
 
 # Rename some stuff so "from threading import *" is safe
-__all__ = ['activeCount', 'Condition', 'currentThread', 'enumerate', 'Event',
+__all__ = ['active_count', 'Condition', 'current_thread', 'enumerate', 'Event',
            'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Thread',
            'Timer', 'setprofile', 'settrace', 'local', 'stack_size']
 
@@ -40,7 +40,7 @@
             if self._verbose:
                 format = format % args
                 format = "%s: %s\n" % (
-                    currentThread().getName(), format)
+                    current_thread().get_name(), format)
                 _sys.stderr.write(format)
 
 else:
@@ -83,11 +83,11 @@
         owner = self._owner
         return "<%s(%s, %d)>" % (
                 self.__class__.__name__,
-                owner and owner.getName(),
+                owner and owner.get_name(),
                 self._count)
 
     def acquire(self, blocking=1):
-        me = currentThread()
+        me = current_thread()
         if self._owner is me:
             self._count = self._count + 1
             if __debug__:
@@ -107,7 +107,7 @@
     __enter__ = acquire
 
     def release(self):
-        if self._owner is not currentThread():
+        if self._owner is not current_thread():
             raise RuntimeError("cannot release un-aquired lock")
         self._count = count = self._count - 1
         if not count:
@@ -141,7 +141,7 @@
         return (count, owner)
 
     def _is_owned(self):
-        return self._owner is currentThread()
+        return self._owner is current_thread()
 
 
 def Condition(*args, **kwargs):
@@ -190,7 +190,7 @@
         self._lock.acquire()           # Ignore saved state
 
     def _is_owned(self):
-        # Return True if lock is owned by currentThread.
+        # Return True if lock is owned by current_thread.
         # This method is called only if __lock doesn't have _is_owned().
         if self._lock.acquire(0):
             self._lock.release()
@@ -258,7 +258,7 @@
             except ValueError:
                 pass
 
-    def notifyAll(self):
+    def notify_all(self):
         self.notify(len(self._waiters))
 
 
@@ -337,14 +337,14 @@
         self._cond = Condition(Lock())
         self._flag = False
 
-    def isSet(self):
+    def is_set(self):
         return self._flag
 
     def set(self):
         self._cond.acquire()
         try:
             self._flag = True
-            self._cond.notifyAll()
+            self._cond.notify_all()
         finally:
             self._cond.release()
 
@@ -412,12 +412,12 @@
 
     def _set_daemon(self):
         # Overridden in _MainThread and _DummyThread
-        return currentThread().isDaemon()
+        return current_thread().is_daemon()
 
     def __repr__(self):
         assert self._initialized, "Thread.__init__() was not called"
         status = "initial"
-        if self._started.isSet():
+        if self._started.is_set():
             status = "started"
         if self._stopped:
             status = "stopped"
@@ -431,7 +431,7 @@
         if not self._initialized:
             raise RuntimeError("thread.__init__() not called")
 
-        if self._started.isSet():
+        if self._started.is_set():
             raise RuntimeError("thread already started")
         if __debug__:
             self._note("%s.start(): starting thread", self)
@@ -502,7 +502,7 @@
                 # self.
                 if _sys:
                     _sys.stderr.write("Exception in thread %s:\n%s\n" %
-                                      (self.getName(), _format_exc()))
+                                      (self.get_name(), _format_exc()))
                 else:
                     # Do the best job possible w/o a huge amt. of code to
                     # approximate a traceback (code ideas from
@@ -510,7 +510,7 @@
                     exc_type, exc_value, exc_tb = self._exc_info()
                     try:
                         print((
-                            "Exception in thread " + self.getName() +
+                            "Exception in thread " + self.get_name() +
                             " (most likely raised during interpreter shutdown):"), file=self._stderr)
                         print((
                             "Traceback (most recent call last):"), file=self._stderr)
@@ -549,7 +549,7 @@
     def _stop(self):
         self._block.acquire()
         self._stopped = True
-        self._block.notifyAll()
+        self._block.notify_all()
         self._block.release()
 
     def _delete(self):
@@ -582,7 +582,7 @@
                 # There must not be any python code between the previous line
                 # and after the lock is released.  Otherwise a tracing function
                 # could try to acquire the lock again in the same thread, (in
-                # currentThread()), and would block.
+                # current_thread()), and would block.
         except KeyError:
             if 'dummy_threading' not in _sys.modules:
                 raise
@@ -590,9 +590,9 @@
     def join(self, timeout=None):
         if not self._initialized:
             raise RuntimeError("Thread.__init__() not called")
-        if not self._started.isSet():
+        if not self._started.is_set():
             raise RuntimeError("cannot join thread before it is started")
-        if self is currentThread():
+        if self is current_thread():
             raise RuntimeError("cannot join current thread")
 
         if __debug__:
@@ -621,30 +621,30 @@
         finally:
             self._block.release()
 
-    def getName(self):
+    def get_name(self):
         assert self._initialized, "Thread.__init__() not called"
         return self._name
 
-    def setName(self, name):
+    def set_name(self, name):
         assert self._initialized, "Thread.__init__() not called"
         self._name = str(name)
 
-    def getIdent(self):
+    def get_ident(self):
         assert self._initialized, "Thread.__init__() not called"
         return self._ident
 
-    def isAlive(self):
+    def is_alive(self):
         assert self._initialized, "Thread.__init__() not called"
-        return self._started.isSet() and not self._stopped
+        return self._started.is_set() and not self._stopped
 
-    def isDaemon(self):
+    def is_daemon(self):
         assert self._initialized, "Thread.__init__() not called"
         return self._daemonic
 
-    def setDaemon(self, daemonic):
+    def set_daemon(self, daemonic):
         if not self._initialized:
             raise RuntimeError("Thread.__init__() not called")
-        if self._started.isSet():
+        if self._started.is_set():
             raise RuntimeError("cannot set daemon status of active thread");
         self._daemonic = daemonic
 
@@ -675,7 +675,7 @@
 
     def run(self):
         self.finished.wait(self.interval)
-        if not self.finished.isSet():
+        if not self.finished.is_set():
             self.function(*self.args, **self.kwargs)
         self.finished.set()
 
@@ -709,16 +709,16 @@
 
 def _pickSomeNonDaemonThread():
     for t in enumerate():
-        if not t.isDaemon() and t.isAlive():
+        if not t.is_daemon() and t.is_alive():
             return t
     return None
 
 
 # Dummy thread class to represent threads not started here.
 # These aren't garbage collected when they die, nor can they be waited for.
-# If they invoke anything in threading.py that calls currentThread(), they
+# If they invoke anything in threading.py that calls current_thread(), they
 # leave an entry in the _active dict forever after.
-# Their purpose is to return *something* from currentThread().
+# Their purpose is to return *something* from current_thread().
 # They are marked as daemon threads so we won't wait for them
 # when we exit (conform previous semantics).
 
@@ -747,14 +747,14 @@
 
 # Global API functions
 
-def currentThread():
+def current_thread():
     try:
         return _active[_get_ident()]
     except KeyError:
-        ##print "currentThread(): no current thread for", _get_ident()
+        ##print "current_thread(): no current thread for", _get_ident()
         return _DummyThread()
 
-def activeCount():
+def active_count():
     _active_limbo_lock.acquire()
     count = len(_active) + len(_limbo)
     _active_limbo_lock.release()
@@ -831,7 +831,7 @@
             counter = 0
             while counter < self.quota:
                 counter = counter + 1
-                self.queue.put("%s.%d" % (self.getName(), counter))
+                self.queue.put("%s.%d" % (self.get_name(), counter))
                 _sleep(random() * 0.00001)
 
 

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Wed Jun 11 21:14:14 2008
@@ -160,6 +160,8 @@
 
 - The test.test_support module has been renamed to test.support.
 
+- The threading module API's were renamed to by PEP 8 complaint.
+
 Tools/Demos
 -----------
 

From python-3000-checkins at python.org  Wed Jun 11 21:16:54 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Wed, 11 Jun 2008 21:16:54 +0200 (CEST)
Subject: [Python-3000-checkins] r64145 - python/branches/py3k
Message-ID: <20080611191654.1D06F1E4005@bag.python.org>

Author: benjamin.peterson
Date: Wed Jun 11 21:16:53 2008
New Revision: 64145

Log:
Blocked revisions 64128,64133 via svnmerge

........
  r64128 | benjamin.peterson | 2008-06-11 12:50:00 -0500 (Wed, 11 Jun 2008) | 2 lines
  
  add aliases to threading module
........
  r64133 | benjamin.peterson | 2008-06-11 13:02:31 -0500 (Wed, 11 Jun 2008) | 2 lines
  
  add old names back into __all__
........


Modified:
   python/branches/py3k/   (props changed)

From python-3000-checkins at python.org  Wed Jun 11 22:05:22 2008
From: python-3000-checkins at python.org (georg.brandl)
Date: Wed, 11 Jun 2008 22:05:22 +0200 (CEST)
Subject: [Python-3000-checkins] r64148 -
	python/branches/py3k/Doc/library/someos.rst
Message-ID: <20080611200522.89ACF1E4005@bag.python.org>

Author: georg.brandl
Date: Wed Jun 11 22:05:22 2008
New Revision: 64148

Log:
Add dummy_threading to toctree.


Modified:
   python/branches/py3k/Doc/library/someos.rst

Modified: python/branches/py3k/Doc/library/someos.rst
==============================================================================
--- python/branches/py3k/Doc/library/someos.rst	(original)
+++ python/branches/py3k/Doc/library/someos.rst	Wed Jun 11 22:05:22 2008
@@ -15,6 +15,7 @@
 
    select.rst
    threading.rst
+   dummy_threading.rst
    _thread.rst
    _dummy_thread.rst
    multiprocessing.rst

From python-3000-checkins at python.org  Wed Jun 11 22:21:58 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Wed, 11 Jun 2008 22:21:58 +0200 (CEST)
Subject: [Python-3000-checkins] r64149 - in python/branches/py3k:
	Doc/c-api/typeobj.rst Include/object.h Misc/NEWS
	Modules/datetimemodule.c Objects/boolobject.c
	Objects/complexobject.c Objects/floatobject.c
	Objects/longobject.c Objects/setobject.c
	Objects/weakrefobject.c PC/winreg.c
Message-ID: <20080611202158.2DF591E400B@bag.python.org>

Author: benjamin.peterson
Date: Wed Jun 11 22:21:57 2008
New Revision: 64149

Log:
Remove nb_reserved (nb_coerce), nb_hex, and nb_oct from PyNumberMethods


Modified:
   python/branches/py3k/Doc/c-api/typeobj.rst
   python/branches/py3k/Include/object.h
   python/branches/py3k/Misc/NEWS
   python/branches/py3k/Modules/datetimemodule.c
   python/branches/py3k/Objects/boolobject.c
   python/branches/py3k/Objects/complexobject.c
   python/branches/py3k/Objects/floatobject.c
   python/branches/py3k/Objects/longobject.c
   python/branches/py3k/Objects/setobject.c
   python/branches/py3k/Objects/weakrefobject.c
   python/branches/py3k/PC/winreg.c

Modified: python/branches/py3k/Doc/c-api/typeobj.rst
==============================================================================
--- python/branches/py3k/Doc/c-api/typeobj.rst	(original)
+++ python/branches/py3k/Doc/c-api/typeobj.rst	Wed Jun 11 22:21:57 2008
@@ -1049,13 +1049,9 @@
             binaryfunc nb_and;
             binaryfunc nb_xor;
             binaryfunc nb_or;
-            int nb_reserved;  /* unused, must be zero */
             unaryfunc nb_int;
             unaryfunc nb_long;
             unaryfunc nb_float;
-            
-            unaryfunc nb_oct; /* not used anymore, must be zero */
-            unaryfunc nb_hex; /* not used anymore, must be zero */
 
             binaryfunc nb_inplace_add;
             binaryfunc nb_inplace_subtract;

Modified: python/branches/py3k/Include/object.h
==============================================================================
--- python/branches/py3k/Include/object.h	(original)
+++ python/branches/py3k/Include/object.h	Wed Jun 11 22:21:57 2008
@@ -215,13 +215,9 @@
 	binaryfunc nb_and;
 	binaryfunc nb_xor;
 	binaryfunc nb_or;
-	int nb_reserved; /* unused, used to be nb_coerce */
 	unaryfunc nb_int;
 	unaryfunc nb_long;
 	unaryfunc nb_float;
-	/* NB: nb_oct and nb_hex are not used anymore. */
-	unaryfunc nb_oct;
-	unaryfunc nb_hex;
 
 	binaryfunc nb_inplace_add;
 	binaryfunc nb_inplace_subtract;

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Wed Jun 11 22:21:57 2008
@@ -60,6 +60,9 @@
   f_exc_type, f_exc_value, and f_exc_traceback cannot be accessed from Python
   code anymore.
 
+- Three of PyNumberMethods' members, nb_coerce, nb_hex, and nb_oct, have been
+  removed.
+
 Extension Modules
 -----------------
 

Modified: python/branches/py3k/Modules/datetimemodule.c
==============================================================================
--- python/branches/py3k/Modules/datetimemodule.c	(original)
+++ python/branches/py3k/Modules/datetimemodule.c	Wed Jun 11 22:21:57 2008
@@ -2103,12 +2103,9 @@
 	0,					/*nb_and*/
 	0,					/*nb_xor*/
 	0,					/*nb_or*/
-	0,					/*nb_reserved*/
 	0,					/*nb_int*/
 	0,					/*nb_long*/
 	0,					/*nb_float*/
-	0,					/*nb_oct*/
-	0, 					/*nb_hex*/
 	0,					/*nb_inplace_add*/
 	0,					/*nb_inplace_subtract*/
 	0,					/*nb_inplace_multiply*/

Modified: python/branches/py3k/Objects/boolobject.c
==============================================================================
--- python/branches/py3k/Objects/boolobject.c	(original)
+++ python/branches/py3k/Objects/boolobject.c	Wed Jun 11 22:21:57 2008
@@ -108,12 +108,9 @@
 	bool_and,		/* nb_and */
 	bool_xor,		/* nb_xor */
 	bool_or,		/* nb_or */
-	0,			/* nb_reserved */
 	0,			/* nb_int */
 	0,			/* nb_long */
 	0,			/* nb_float */
-	0,			/* nb_oct */
-	0,		 	/* nb_hex */
 	0,			/* nb_inplace_add */
 	0,			/* nb_inplace_subtract */
 	0,			/* nb_inplace_multiply */

Modified: python/branches/py3k/Objects/complexobject.c
==============================================================================
--- python/branches/py3k/Objects/complexobject.c	(original)
+++ python/branches/py3k/Objects/complexobject.c	Wed Jun 11 22:21:57 2008
@@ -1067,12 +1067,9 @@
 	0,					/* nb_and */
 	0,					/* nb_xor */
 	0,					/* nb_or */
-	0,					/* nb_reserved */
 	complex_int,				/* nb_int */
 	complex_long,				/* nb_long */
 	complex_float,				/* nb_float */
-	0,					/* nb_oct */
-	0,					/* nb_hex */
 	0,					/* nb_inplace_add */
 	0,					/* nb_inplace_subtract */
 	0,					/* nb_inplace_multiply*/

Modified: python/branches/py3k/Objects/floatobject.c
==============================================================================
--- python/branches/py3k/Objects/floatobject.c	(original)
+++ python/branches/py3k/Objects/floatobject.c	Wed Jun 11 22:21:57 2008
@@ -1381,12 +1381,9 @@
 	0,		/*nb_and*/
 	0,		/*nb_xor*/
 	0,		/*nb_or*/
-	0,		/*nb_reserved*/
 	float_trunc,	/*nb_int*/
 	float_trunc,	/*nb_long*/
 	float_float,	/*nb_float*/
-	0,		/* nb_oct */
-	0,		/* nb_hex */
 	0,		/* nb_inplace_add */
 	0,		/* nb_inplace_subtract */
 	0,		/* nb_inplace_multiply */

Modified: python/branches/py3k/Objects/longobject.c
==============================================================================
--- python/branches/py3k/Objects/longobject.c	(original)
+++ python/branches/py3k/Objects/longobject.c	Wed Jun 11 22:21:57 2008
@@ -3713,12 +3713,9 @@
 			long_and,	/*nb_and*/
 			long_xor,	/*nb_xor*/
 			long_or,	/*nb_or*/
-			0,		/*nb_reserved*/
 			long_long,	/*nb_int*/
 			long_long,	/*nb_long*/
 			long_float,	/*nb_float*/
-			0,		/*nb_oct*/ /* not used */
-			0,		/*nb_hex*/ /* not used */
 	0,				/* nb_inplace_add */
 	0,				/* nb_inplace_subtract */
 	0,				/* nb_inplace_multiply */

Modified: python/branches/py3k/Objects/setobject.c
==============================================================================
--- python/branches/py3k/Objects/setobject.c	(original)
+++ python/branches/py3k/Objects/setobject.c	Wed Jun 11 22:21:57 2008
@@ -2015,12 +2015,9 @@
 	(binaryfunc)set_and,		/*nb_and*/
 	(binaryfunc)set_xor,		/*nb_xor*/
 	(binaryfunc)set_or,		/*nb_or*/
-	0,				/*nb_reserved*/
 	0,				/*nb_int*/
 	0,				/*nb_long*/
 	0,				/*nb_float*/
-	0,				/*nb_oct*/
-	0, 				/*nb_hex*/
 	0,				/*nb_inplace_add*/
 	(binaryfunc)set_isub,		/*nb_inplace_subtract*/
 	0,				/*nb_inplace_multiply*/

Modified: python/branches/py3k/Objects/weakrefobject.c
==============================================================================
--- python/branches/py3k/Objects/weakrefobject.c	(original)
+++ python/branches/py3k/Objects/weakrefobject.c	Wed Jun 11 22:21:57 2008
@@ -594,12 +594,9 @@
     proxy_and,              /*nb_and*/
     proxy_xor,              /*nb_xor*/
     proxy_or,               /*nb_or*/
-    0,                      /*nb_reserved*/
     proxy_int,              /*nb_int*/
     proxy_long,             /*nb_long*/
     proxy_float,            /*nb_float*/
-    0,                      /*nb_oct*/
-    0,                      /*nb_hex*/
     proxy_iadd,             /*nb_inplace_add*/
     proxy_isub,             /*nb_inplace_subtract*/
     proxy_imul,             /*nb_inplace_multiply*/

Modified: python/branches/py3k/PC/winreg.c
==============================================================================
--- python/branches/py3k/PC/winreg.c	(original)
+++ python/branches/py3k/PC/winreg.c	Wed Jun 11 22:21:57 2008
@@ -450,12 +450,9 @@
 	PyHKEY_binaryFailureFunc,	/* nb_and */
 	PyHKEY_binaryFailureFunc,	/* nb_xor */
 	PyHKEY_binaryFailureFunc,	/* nb_or */
-	0,				/* nb_reserved */
 	PyHKEY_intFunc,			/* nb_int */
 	PyHKEY_unaryFailureFunc,	/* nb_long */
 	PyHKEY_unaryFailureFunc,	/* nb_float */
-	PyHKEY_unaryFailureFunc,	/* nb_oct */
-	PyHKEY_unaryFailureFunc,	/* nb_hex */
 };
 
 

From python-3000-checkins at python.org  Wed Jun 11 23:55:49 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Wed, 11 Jun 2008 23:55:49 +0200 (CEST)
Subject: [Python-3000-checkins] r64151 -
	python/branches/py3k/Lib/test/test_xmlrpc.py
Message-ID: <20080611215549.0DC941E400C@bag.python.org>

Author: benjamin.peterson
Date: Wed Jun 11 23:55:48 2008
New Revision: 64151

Log:
fix hanging test_xmlrpc


Modified:
   python/branches/py3k/Lib/test/test_xmlrpc.py

Modified: python/branches/py3k/Lib/test/test_xmlrpc.py
==============================================================================
--- python/branches/py3k/Lib/test/test_xmlrpc.py	(original)
+++ python/branches/py3k/Lib/test/test_xmlrpc.py	Wed Jun 11 23:55:48 2008
@@ -320,7 +320,7 @@
     def tearDown(self):
         # wait on the server thread to terminate
         self.evt.wait(4.0)
-        if not self.evt.isSet():
+        if not self.evt.is_set():
             self.evt.set()
             stop_serving()
             raise RuntimeError("timeout reached, test has failed")

From python-3000-checkins at python.org  Thu Jun 12 00:43:07 2008
From: python-3000-checkins at python.org (alexandre.vassalotti)
Date: Thu, 12 Jun 2008 00:43:07 +0200 (CEST)
Subject: [Python-3000-checkins] r64152 - in python/branches/py3k:
	Lib/pickle.py Lib/pickletools.py Lib/test/pickletester.py
	Lib/test/test_pickle.py Lib/test/test_pickletools.py
	Misc/NEWS Modules/_pickle.c setup.py
Message-ID: <20080611224307.904B41E4005@bag.python.org>

Author: alexandre.vassalotti
Date: Thu Jun 12 00:43:06 2008
New Revision: 64152

Log:
Issue 2917: Merge the pickle and cPickle module.



Added:
   python/branches/py3k/Modules/_pickle.c   (contents, props changed)
Modified:
   python/branches/py3k/Lib/pickle.py
   python/branches/py3k/Lib/pickletools.py
   python/branches/py3k/Lib/test/pickletester.py
   python/branches/py3k/Lib/test/test_pickle.py
   python/branches/py3k/Lib/test/test_pickletools.py
   python/branches/py3k/Misc/NEWS
   python/branches/py3k/setup.py

Modified: python/branches/py3k/Lib/pickle.py
==============================================================================
--- python/branches/py3k/Lib/pickle.py	(original)
+++ python/branches/py3k/Lib/pickle.py	Thu Jun 12 00:43:06 2008
@@ -174,7 +174,7 @@
 
 # Pickling machinery
 
-class Pickler:
+class _Pickler:
 
     def __init__(self, file, protocol=None):
         """This takes a binary file for writing a pickle data stream.
@@ -182,21 +182,19 @@
         All protocols now read and write bytes.
 
         The optional protocol argument tells the pickler to use the
-        given protocol; supported protocols are 0, 1, 2.  The default
-        protocol is 2; it's been supported for many years now.
-
-        Protocol 1 is more efficient than protocol 0; protocol 2 is
-        more efficient than protocol 1.
+        given protocol; supported protocols are 0, 1, 2, 3.  The default
+        protocol is 3; a backward-incompatible protocol designed for
+        Python 3.0.
 
         Specifying a negative protocol version selects the highest
         protocol version supported.  The higher the protocol used, the
         more recent the version of Python needed to read the pickle
         produced.
 
-        The file parameter must have a write() method that accepts a single
-        string argument.  It can thus be an open file object, a StringIO
-        object, or any other custom object that meets this interface.
-
+        The file argument must have a write() method that accepts a single
+        bytes argument. It can thus be a file object opened for binary
+        writing, a io.BytesIO instance, or any other custom object that
+        meets this interface.
         """
         if protocol is None:
             protocol = DEFAULT_PROTOCOL
@@ -204,7 +202,10 @@
             protocol = HIGHEST_PROTOCOL
         elif not 0 <= protocol <= HIGHEST_PROTOCOL:
             raise ValueError("pickle protocol must be <= %d" % HIGHEST_PROTOCOL)
-        self.write = file.write
+        try:
+            self.write = file.write
+        except AttributeError:
+            raise TypeError("file must have a 'write' attribute")
         self.memo = {}
         self.proto = int(protocol)
         self.bin = protocol >= 1
@@ -270,10 +271,10 @@
 
         return GET + repr(i).encode("ascii") + b'\n'
 
-    def save(self, obj):
+    def save(self, obj, save_persistent_id=True):
         # Check for persistent id (defined by a subclass)
         pid = self.persistent_id(obj)
-        if pid:
+        if pid is not None and save_persistent_id:
             self.save_pers(pid)
             return
 
@@ -341,7 +342,7 @@
     def save_pers(self, pid):
         # Save a persistent id reference
         if self.bin:
-            self.save(pid)
+            self.save(pid, save_persistent_id=False)
             self.write(BINPERSID)
         else:
             self.write(PERSID + str(pid).encode("ascii") + b'\n')
@@ -350,13 +351,13 @@
                     listitems=None, dictitems=None, obj=None):
         # This API is called by some subclasses
 
-        # Assert that args is a tuple or None
+        # Assert that args is a tuple
         if not isinstance(args, tuple):
-            raise PicklingError("args from reduce() should be a tuple")
+            raise PicklingError("args from save_reduce() should be a tuple")
 
         # Assert that func is callable
         if not hasattr(func, '__call__'):
-            raise PicklingError("func from reduce should be callable")
+            raise PicklingError("func from save_reduce() should be callable")
 
         save = self.save
         write = self.write
@@ -438,31 +439,6 @@
             self.write(obj and TRUE or FALSE)
     dispatch[bool] = save_bool
 
-    def save_int(self, obj, pack=struct.pack):
-        if self.bin:
-            # If the int is small enough to fit in a signed 4-byte 2's-comp
-            # format, we can store it more efficiently than the general
-            # case.
-            # First one- and two-byte unsigned ints:
-            if obj >= 0:
-                if obj <= 0xff:
-                    self.write(BININT1 + bytes([obj]))
-                    return
-                if obj <= 0xffff:
-                    self.write(BININT2 + bytes([obj&0xff, obj>>8]))
-                    return
-            # Next check for 4-byte signed ints:
-            high_bits = obj >> 31  # note that Python shift sign-extends
-            if high_bits == 0 or high_bits == -1:
-                # All high bits are copies of bit 2**31, so the value
-                # fits in a 4-byte signed int.
-                self.write(BININT + pack("<i", obj))
-                return
-        # Text pickle, or int too big to fit in signed 4-byte format.
-        self.write(INT + repr(obj).encode("ascii") + b'\n')
-    # XXX save_int is merged into save_long
-    # dispatch[int] = save_int
-
     def save_long(self, obj, pack=struct.pack):
         if self.bin:
             # If the int is small enough to fit in a signed 4-byte 2's-comp
@@ -503,7 +479,7 @@
 
     def save_bytes(self, obj, pack=struct.pack):
         if self.proto < 3:
-            self.save_reduce(bytes, (list(obj),))
+            self.save_reduce(bytes, (list(obj),), obj=obj)
             return
         n = len(obj)
         if n < 256:
@@ -579,12 +555,6 @@
 
     dispatch[tuple] = save_tuple
 
-    # save_empty_tuple() isn't used by anything in Python 2.3.  However, I
-    # found a Pickler subclass in Zope3 that calls it, so it's not harmless
-    # to remove it.
-    def save_empty_tuple(self, obj):
-        self.write(EMPTY_TUPLE)
-
     def save_list(self, obj):
         write = self.write
 
@@ -696,7 +666,7 @@
             module = whichmodule(obj, name)
 
         try:
-            __import__(module)
+            __import__(module, level=0)
             mod = sys.modules[module]
             klass = getattr(mod, name)
         except (ImportError, KeyError, AttributeError):
@@ -720,9 +690,19 @@
                 else:
                     write(EXT4 + pack("<i", code))
                 return
+        # Non-ASCII identifiers are supported only with protocols >= 3.
+        if self.proto >= 3:
+            write(GLOBAL + bytes(module, "utf-8") + b'\n' +
+                  bytes(name, "utf-8") + b'\n')
+        else:
+            try:
+                write(GLOBAL + bytes(module, "ascii") + b'\n' +
+                      bytes(name, "ascii") + b'\n')
+            except UnicodeEncodeError:
+                raise PicklingError(
+                    "can't pickle global identifier '%s.%s' using "
+                    "pickle protocol %i" % (module, name, self.proto))
 
-        write(GLOBAL + bytes(module, "utf-8") + b'\n' +
-              bytes(name, "utf-8") + b'\n')
         self.memoize(obj)
 
     dispatch[FunctionType] = save_global
@@ -781,7 +761,7 @@
 
 # Unpickling machinery
 
-class Unpickler:
+class _Unpickler:
 
     def __init__(self, file, *, encoding="ASCII", errors="strict"):
         """This takes a binary file for reading a pickle data stream.
@@ -841,6 +821,9 @@
         while stack[k] is not mark: k = k-1
         return k
 
+    def persistent_load(self, pid):
+        raise UnpickingError("unsupported persistent id encountered")
+
     dispatch = {}
 
     def load_proto(self):
@@ -850,7 +833,7 @@
     dispatch[PROTO[0]] = load_proto
 
     def load_persid(self):
-        pid = self.readline()[:-1]
+        pid = self.readline()[:-1].decode("ascii")
         self.append(self.persistent_load(pid))
     dispatch[PERSID[0]] = load_persid
 
@@ -879,9 +862,9 @@
             val = True
         else:
             try:
-                val = int(data)
+                val = int(data, 0)
             except ValueError:
-                val = int(data)
+                val = int(data, 0)
         self.append(val)
     dispatch[INT[0]] = load_int
 
@@ -933,7 +916,8 @@
                 break
         else:
             raise ValueError("insecure string pickle: %r" % orig)
-        self.append(codecs.escape_decode(rep)[0])
+        self.append(codecs.escape_decode(rep)[0]
+                    .decode(self.encoding, self.errors))
     dispatch[STRING[0]] = load_string
 
     def load_binstring(self):
@@ -975,7 +959,7 @@
     dispatch[TUPLE[0]] = load_tuple
 
     def load_empty_tuple(self):
-        self.stack.append(())
+        self.append(())
     dispatch[EMPTY_TUPLE[0]] = load_empty_tuple
 
     def load_tuple1(self):
@@ -991,11 +975,11 @@
     dispatch[TUPLE3[0]] = load_tuple3
 
     def load_empty_list(self):
-        self.stack.append([])
+        self.append([])
     dispatch[EMPTY_LIST[0]] = load_empty_list
 
     def load_empty_dictionary(self):
-        self.stack.append({})
+        self.append({})
     dispatch[EMPTY_DICT[0]] = load_empty_dictionary
 
     def load_list(self):
@@ -1022,13 +1006,13 @@
     def _instantiate(self, klass, k):
         args = tuple(self.stack[k+1:])
         del self.stack[k:]
-        instantiated = 0
+        instantiated = False
         if (not args and
                 isinstance(klass, type) and
                 not hasattr(klass, "__getinitargs__")):
             value = _EmptyClass()
             value.__class__ = klass
-            instantiated = 1
+            instantiated = True
         if not instantiated:
             try:
                 value = klass(*args)
@@ -1038,8 +1022,8 @@
         self.append(value)
 
     def load_inst(self):
-        module = self.readline()[:-1]
-        name = self.readline()[:-1]
+        module = self.readline()[:-1].decode("ascii")
+        name = self.readline()[:-1].decode("ascii")
         klass = self.find_class(module, name)
         self._instantiate(klass, self.marker())
     dispatch[INST[0]] = load_inst
@@ -1059,8 +1043,8 @@
     dispatch[NEWOBJ[0]] = load_newobj
 
     def load_global(self):
-        module = self.readline()[:-1]
-        name = self.readline()[:-1]
+        module = self.readline()[:-1].decode("utf-8")
+        name = self.readline()[:-1].decode("utf-8")
         klass = self.find_class(module, name)
         self.append(klass)
     dispatch[GLOBAL[0]] = load_global
@@ -1095,11 +1079,7 @@
 
     def find_class(self, module, name):
         # Subclasses may override this
-        if isinstance(module, bytes_types):
-            module = module.decode("utf-8")
-        if isinstance(name, bytes_types):
-            name = name.decode("utf-8")
-        __import__(module)
+        __import__(module, level=0)
         mod = sys.modules[module]
         klass = getattr(mod, name)
         return klass
@@ -1131,31 +1111,33 @@
     dispatch[DUP[0]] = load_dup
 
     def load_get(self):
-        self.append(self.memo[self.readline()[:-1].decode("ascii")])
+        i = int(self.readline()[:-1])
+        self.append(self.memo[i])
     dispatch[GET[0]] = load_get
 
     def load_binget(self):
-        i = ord(self.read(1))
-        self.append(self.memo[repr(i)])
+        i = self.read(1)[0]
+        self.append(self.memo[i])
     dispatch[BINGET[0]] = load_binget
 
     def load_long_binget(self):
         i = mloads(b'i' + self.read(4))
-        self.append(self.memo[repr(i)])
+        self.append(self.memo[i])
     dispatch[LONG_BINGET[0]] = load_long_binget
 
     def load_put(self):
-        self.memo[self.readline()[:-1].decode("ascii")] = self.stack[-1]
+        i = int(self.readline()[:-1])
+        self.memo[i] = self.stack[-1]
     dispatch[PUT[0]] = load_put
 
     def load_binput(self):
-        i = ord(self.read(1))
-        self.memo[repr(i)] = self.stack[-1]
+        i = self.read(1)[0]
+        self.memo[i] = self.stack[-1]
     dispatch[BINPUT[0]] = load_binput
 
     def load_long_binput(self):
         i = mloads(b'i' + self.read(4))
-        self.memo[repr(i)] = self.stack[-1]
+        self.memo[i] = self.stack[-1]
     dispatch[LONG_BINPUT[0]] = load_long_binput
 
     def load_append(self):
@@ -1321,6 +1303,15 @@
         n -= 1 << (nbytes * 8)
     return n
 
+# Use the faster _pickle if possible
+try:
+    from _pickle import *
+except ImportError:
+    Pickler, Unpickler = _Pickler, _Unpickler
+    PickleError = _PickleError
+    PicklingError = _PicklingError
+    UnpicklingError = _UnpicklingError
+
 # Shorthands
 
 def dump(obj, file, protocol=None):
@@ -1333,14 +1324,14 @@
     assert isinstance(res, bytes_types)
     return res
 
-def load(file):
-    return Unpickler(file).load()
+def load(file, *, encoding="ASCII", errors="strict"):
+    return Unpickler(file, encoding=encoding, errors=errors).load()
 
-def loads(s):
+def loads(s, *, encoding="ASCII", errors="strict"):
     if isinstance(s, str):
         raise TypeError("Can't load pickle from unicode string")
     file = io.BytesIO(s)
-    return Unpickler(file).load()
+    return Unpickler(file, encoding=encoding, errors=errors).load()
 
 # Doctest
 

Modified: python/branches/py3k/Lib/pickletools.py
==============================================================================
--- python/branches/py3k/Lib/pickletools.py	(original)
+++ python/branches/py3k/Lib/pickletools.py	Thu Jun 12 00:43:06 2008
@@ -2079,11 +2079,12 @@
    70: t        TUPLE      (MARK at 49)
    71: p    PUT        5
    74: R    REDUCE
-   75: V    UNICODE    'def'
-   80: p    PUT        6
-   83: s    SETITEM
-   84: a    APPEND
-   85: .    STOP
+   75: p    PUT        6
+   78: V    UNICODE    'def'
+   83: p    PUT        7
+   86: s    SETITEM
+   87: a    APPEND
+   88: .    STOP
 highest protocol among opcodes = 0
 
 Try again with a "binary" pickle.
@@ -2115,11 +2116,12 @@
    49: t            TUPLE      (MARK at 37)
    50: q        BINPUT     5
    52: R        REDUCE
-   53: X        BINUNICODE 'def'
-   61: q        BINPUT     6
-   63: s        SETITEM
-   64: e        APPENDS    (MARK at 3)
-   65: .    STOP
+   53: q        BINPUT     6
+   55: X        BINUNICODE 'def'
+   63: q        BINPUT     7
+   65: s        SETITEM
+   66: e        APPENDS    (MARK at 3)
+   67: .    STOP
 highest protocol among opcodes = 1
 
 Exercise the INST/OBJ/BUILD family.

Modified: python/branches/py3k/Lib/test/pickletester.py
==============================================================================
--- python/branches/py3k/Lib/test/pickletester.py	(original)
+++ python/branches/py3k/Lib/test/pickletester.py	Thu Jun 12 00:43:06 2008
@@ -362,7 +362,7 @@
     return x
 
 class AbstractPickleTests(unittest.TestCase):
-    # Subclass must define self.dumps, self.loads, self.error.
+    # Subclass must define self.dumps, self.loads.
 
     _testdata = create_data()
 
@@ -463,8 +463,9 @@
             self.assertEqual(list(x[0].attr.keys()), [1])
             self.assert_(x[0].attr[1] is x)
 
-    def test_garyp(self):
-        self.assertRaises(self.error, self.loads, b'garyp')
+    def test_get(self):
+        self.assertRaises(KeyError, self.loads, b'g0\np0')
+        self.assertEquals(self.loads(b'((Kdtp0\nh\x00l.))'), [(100,), (100,)])
 
     def test_insecure_strings(self):
         # XXX Some of these tests are temporarily disabled
@@ -955,7 +956,7 @@
         f = open(TESTFN, "wb")
         try:
             f.close()
-            self.assertRaises(ValueError, self.module.dump, 123, f)
+            self.assertRaises(ValueError, pickle.dump, 123, f)
         finally:
             os.remove(TESTFN)
 
@@ -964,24 +965,24 @@
         f = open(TESTFN, "wb")
         try:
             f.close()
-            self.assertRaises(ValueError, self.module.dump, 123, f)
+            self.assertRaises(ValueError, pickle.dump, 123, f)
         finally:
             os.remove(TESTFN)
 
     def test_highest_protocol(self):
         # Of course this needs to be changed when HIGHEST_PROTOCOL changes.
-        self.assertEqual(self.module.HIGHEST_PROTOCOL, 3)
+        self.assertEqual(pickle.HIGHEST_PROTOCOL, 3)
 
     def test_callapi(self):
         from io import BytesIO
         f = BytesIO()
         # With and without keyword arguments
-        self.module.dump(123, f, -1)
-        self.module.dump(123, file=f, protocol=-1)
-        self.module.dumps(123, -1)
-        self.module.dumps(123, protocol=-1)
-        self.module.Pickler(f, -1)
-        self.module.Pickler(f, protocol=-1)
+        pickle.dump(123, f, -1)
+        pickle.dump(123, file=f, protocol=-1)
+        pickle.dumps(123, -1)
+        pickle.dumps(123, protocol=-1)
+        pickle.Pickler(f, -1)
+        pickle.Pickler(f, protocol=-1)
 
 class AbstractPersistentPicklerTests(unittest.TestCase):
 

Modified: python/branches/py3k/Lib/test/test_pickle.py
==============================================================================
--- python/branches/py3k/Lib/test/test_pickle.py	(original)
+++ python/branches/py3k/Lib/test/test_pickle.py	Thu Jun 12 00:43:06 2008
@@ -7,37 +7,42 @@
 from test.pickletester import AbstractPickleModuleTests
 from test.pickletester import AbstractPersistentPicklerTests
 
-class PickleTests(AbstractPickleTests, AbstractPickleModuleTests):
+try:
+    import _pickle
+    has_c_implementation = True
+except ImportError:
+    has_c_implementation = False
 
-    module = pickle
-    error = KeyError
 
-    def dumps(self, arg, proto=None):
-        return pickle.dumps(arg, proto)
+class PickleTests(AbstractPickleModuleTests):
+    pass
 
-    def loads(self, buf):
-        return pickle.loads(buf)
 
-class PicklerTests(AbstractPickleTests):
+class PyPicklerTests(AbstractPickleTests):
 
-    error = KeyError
+    pickler = pickle._Pickler
+    unpickler = pickle._Unpickler
 
     def dumps(self, arg, proto=None):
         f = io.BytesIO()
-        p = pickle.Pickler(f, proto)
+        p = self.pickler(f, proto)
         p.dump(arg)
         f.seek(0)
         return bytes(f.read())
 
     def loads(self, buf):
         f = io.BytesIO(buf)
-        u = pickle.Unpickler(f)
+        u = self.unpickler(f)
         return u.load()
 
-class PersPicklerTests(AbstractPersistentPicklerTests):
+
+class PyPersPicklerTests(AbstractPersistentPicklerTests):
+
+    pickler = pickle._Pickler
+    unpickler = pickle._Unpickler
 
     def dumps(self, arg, proto=None):
-        class PersPickler(pickle.Pickler):
+        class PersPickler(self.pickler):
             def persistent_id(subself, obj):
                 return self.persistent_id(obj)
         f = io.BytesIO()
@@ -47,19 +52,29 @@
         return f.read()
 
     def loads(self, buf):
-        class PersUnpickler(pickle.Unpickler):
+        class PersUnpickler(self.unpickler):
             def persistent_load(subself, obj):
                 return self.persistent_load(obj)
         f = io.BytesIO(buf)
         u = PersUnpickler(f)
         return u.load()
 
+
+if has_c_implementation:
+    class CPicklerTests(PyPicklerTests):
+        pickler = _pickle.Pickler
+        unpickler = _pickle.Unpickler
+
+    class CPersPicklerTests(PyPersPicklerTests):
+        pickler = _pickle.Pickler
+        unpickler = _pickle.Unpickler
+
+
 def test_main():
-    support.run_unittest(
-        PickleTests,
-        PicklerTests,
-        PersPicklerTests
-    )
+    tests = [PickleTests, PyPicklerTests, PyPersPicklerTests]
+    if has_c_implementation:
+        tests.extend([CPicklerTests, CPersPicklerTests])
+    support.run_unittest(*tests)
     support.run_doctest(pickle)
 
 if __name__ == "__main__":

Modified: python/branches/py3k/Lib/test/test_pickletools.py
==============================================================================
--- python/branches/py3k/Lib/test/test_pickletools.py	(original)
+++ python/branches/py3k/Lib/test/test_pickletools.py	Thu Jun 12 00:43:06 2008
@@ -12,8 +12,6 @@
     def loads(self, buf):
         return pickle.loads(buf)
 
-    module = pickle
-    error = KeyError
 
 def test_main():
     support.run_unittest(OptimizedPickleTests)

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Thu Jun 12 00:43:06 2008
@@ -78,6 +78,10 @@
 Library
 -------
 
+- The ``pickle`` module is now automatically use an optimized C
+  implementation of Pickler and Unpickler when available. The
+  ``cPickle`` module is no longer needed.
+
 - Removed the ``htmllib`` and ``sgmllib`` modules.
 
 - The deprecated ``SmartCookie`` and ``SimpleCookie`` classes have

Added: python/branches/py3k/Modules/_pickle.c
==============================================================================
--- (empty file)
+++ python/branches/py3k/Modules/_pickle.c	Thu Jun 12 00:43:06 2008
@@ -0,0 +1,4546 @@
+#include "Python.h"
+#include "structmember.h"
+
+PyDoc_STRVAR(pickle_module_doc,
+"Optimized C implementation for the Python pickle module.");
+
+/* Bump this when new opcodes are added to the pickle protocol. */
+enum {
+    HIGHEST_PROTOCOL = 3,
+    DEFAULT_PROTOCOL = 3
+};
+
+
+/* Pickle opcodes. These must be kept updated with pickle.py.
+   Extensive docs are in pickletools.py. */
+enum opcode {
+    MARK            = '(',
+    STOP            = '.',
+    POP             = '0',
+    POP_MARK        = '1',
+    DUP             = '2',
+    FLOAT           = 'F',
+    INT             = 'I',
+    BININT          = 'J',
+    BININT1         = 'K',
+    LONG            = 'L',
+    BININT2         = 'M',
+    NONE            = 'N',
+    PERSID          = 'P',
+    BINPERSID       = 'Q',
+    REDUCE          = 'R',
+    STRING          = 'S',
+    BINSTRING       = 'T',
+    SHORT_BINSTRING = 'U',
+    UNICODE         = 'V',
+    BINUNICODE      = 'X',
+    APPEND          = 'a',
+    BUILD           = 'b',
+    GLOBAL          = 'c',
+    DICT            = 'd',
+    EMPTY_DICT      = '}',
+    APPENDS         = 'e',
+    GET             = 'g',
+    BINGET          = 'h',
+    INST            = 'i',
+    LONG_BINGET     = 'j',
+    LIST            = 'l',
+    EMPTY_LIST      = ']',
+    OBJ             = 'o',
+    PUT             = 'p',
+    BINPUT          = 'q',
+    LONG_BINPUT     = 'r',
+    SETITEM         = 's',
+    TUPLE           = 't',
+    EMPTY_TUPLE     = ')',
+    SETITEMS        = 'u',
+    BINFLOAT        = 'G',
+
+    /* Protocol 2. */
+    PROTO       = '\x80',
+    NEWOBJ      = '\x81',
+    EXT1        = '\x82',
+    EXT2        = '\x83',
+    EXT4        = '\x84',
+    TUPLE1      = '\x85',
+    TUPLE2      = '\x86',
+    TUPLE3      = '\x87',
+    NEWTRUE     = '\x88',
+    NEWFALSE    = '\x89',
+    LONG1       = '\x8a',
+    LONG4       = '\x8b',
+
+    /* Protocol 3 (Python 3.x) */
+    BINBYTES       = 'B',
+    SHORT_BINBYTES = 'C',
+};
+
+/* These aren't opcodes -- they're ways to pickle bools before protocol 2
+ * so that unpicklers written before bools were introduced unpickle them
+ * as ints, but unpicklers after can recognize that bools were intended.
+ * Note that protocol 2 added direct ways to pickle bools.
+ */
+#undef TRUE
+#define TRUE  "I01\n"
+#undef FALSE
+#define FALSE "I00\n"
+
+enum {
+   /* Keep in synch with pickle.Pickler._BATCHSIZE.  This is how many elements
+      batch_list/dict() pumps out before doing APPENDS/SETITEMS.  Nothing will
+      break if this gets out of synch with pickle.py, but it's unclear that would
+      help anything either. */
+    BATCHSIZE = 1000,
+
+    /* Nesting limit until Pickler, when running in "fast mode", starts
+       checking for self-referential data-structures. */
+    FAST_NESTING_LIMIT = 50,
+
+    /* Size of the write buffer of Pickler. Higher values will reduce the
+       number of calls to the write() method of the output stream. */
+    WRITE_BUF_SIZE = 256,
+};
+
+/* Exception classes for pickle. These should override the ones defined in
+   pickle.py, when the C-optimized Pickler and Unpickler are used. */
+static PyObject *PickleError;
+static PyObject *PicklingError;
+static PyObject *UnpicklingError;
+
+/* copyreg.dispatch_table, {type_object: pickling_function} */
+static PyObject *dispatch_table;
+/* For EXT[124] opcodes. */
+/* copyreg._extension_registry, {(module_name, function_name): code} */
+static PyObject *extension_registry;
+/* copyreg._inverted_registry, {code: (module_name, function_name)} */
+static PyObject *inverted_registry;
+/* copyreg._extension_cache, {code: object} */
+static PyObject *extension_cache;
+
+/* XXX: Are these really nescessary? */
+/* As the name says, an empty tuple. */
+static PyObject *empty_tuple;
+/* For looking up name pairs in copyreg._extension_registry. */
+static PyObject *two_tuple;
+
+static int
+stack_underflow(void)
+{
+    PyErr_SetString(UnpicklingError, "unpickling stack underflow");
+    return -1;
+}
+
+/* Internal data type used as the unpickling stack. */
+typedef struct {
+    PyObject_HEAD
+    int length;   /* number of initial slots in data currently used */
+    int size;     /* number of slots in data allocated */
+    PyObject **data;
+} Pdata;
+
+static void
+Pdata_dealloc(Pdata *self)
+{
+    int i;
+    PyObject **p;
+
+    for (i = self->length, p = self->data; --i >= 0; p++) {
+        Py_DECREF(*p);
+    }
+    if (self->data)
+        PyMem_Free(self->data);
+    PyObject_Del(self);
+}
+
+static PyTypeObject Pdata_Type = {
+    PyVarObject_HEAD_INIT(NULL, 0)
+    "_pickle.Pdata",              /*tp_name*/
+    sizeof(Pdata),                /*tp_basicsize*/
+    0,                            /*tp_itemsize*/
+    (destructor)Pdata_dealloc,    /*tp_dealloc*/
+};
+
+static PyObject *
+Pdata_New(void)
+{
+    Pdata *self;
+
+    if (!(self = PyObject_New(Pdata, &Pdata_Type)))
+        return NULL;
+    self->size = 8;
+    self->length = 0;
+    self->data = PyMem_Malloc(self->size * sizeof(PyObject *));
+    if (self->data)
+        return (PyObject *)self;
+    Py_DECREF(self);
+    return PyErr_NoMemory();
+}
+
+
+/* Retain only the initial clearto items.  If clearto >= the current
+ * number of items, this is a (non-erroneous) NOP.
+ */
+static int
+Pdata_clear(Pdata *self, int clearto)
+{
+    int i;
+    PyObject **p;
+
+    if (clearto < 0)
+        return stack_underflow();
+    if (clearto >= self->length)
+        return 0;
+
+    for (i = self->length, p = self->data + clearto; --i >= clearto; p++) {
+        Py_CLEAR(*p);
+    }
+    self->length = clearto;
+
+    return 0;
+}
+
+static int
+Pdata_grow(Pdata *self)
+{
+    int bigger;
+    size_t nbytes;
+    PyObject **tmp;
+
+    bigger = (self->size << 1) + 1;
+    if (bigger <= 0)            /* was 0, or new value overflows */
+        goto nomemory;
+    if ((int)(size_t)bigger != bigger)
+        goto nomemory;
+    nbytes = (size_t)bigger * sizeof(PyObject *);
+    if (nbytes / sizeof(PyObject *) != (size_t)bigger)
+        goto nomemory;
+    tmp = PyMem_Realloc(self->data, nbytes);
+    if (tmp == NULL)
+        goto nomemory;
+    self->data = tmp;
+    self->size = bigger;
+    return 0;
+
+  nomemory:
+    PyErr_NoMemory();
+    return -1;
+}
+
+/* D is a Pdata*.  Pop the topmost element and store it into V, which
+ * must be an lvalue holding PyObject*.  On stack underflow, UnpicklingError
+ * is raised and V is set to NULL.
+ */
+static PyObject *
+Pdata_pop(Pdata *self)
+{
+    if (self->length == 0) {
+        PyErr_SetString(UnpicklingError, "bad pickle data");
+        return NULL;
+    }
+    return self->data[--(self->length)];
+}
+#define PDATA_POP(D, V) do { (V) = Pdata_pop((D)); } while (0)
+
+static int
+Pdata_push(Pdata *self, PyObject *obj)
+{
+    if (self->length == self->size && Pdata_grow(self) < 0) {
+        return -1;
+    }
+    self->data[self->length++] = obj;
+    return 0;
+}
+
+/* Push an object on stack, transferring its ownership to the stack. */
+#define PDATA_PUSH(D, O, ER) do {                               \
+        if (Pdata_push((D), (O)) < 0) return (ER); } while(0)
+
+/* Push an object on stack, adding a new reference to the object. */
+#define PDATA_APPEND(D, O, ER) do {                             \
+        Py_INCREF((O));                                         \
+        if (Pdata_push((D), (O)) < 0) return (ER); } while(0)
+
+static PyObject *
+Pdata_poptuple(Pdata *self, Py_ssize_t start)
+{
+    PyObject *tuple;
+    Py_ssize_t len, i, j;
+
+    len = self->length - start;
+    tuple = PyTuple_New(len);
+    if (tuple == NULL)
+        return NULL;
+    for (i = start, j = 0; j < len; i++, j++)
+        PyTuple_SET_ITEM(tuple, j, self->data[i]);
+
+    self->length = start;
+    return tuple;
+}
+
+static PyObject *
+Pdata_poplist(Pdata *self, Py_ssize_t start)
+{
+    PyObject *list;
+    Py_ssize_t len, i, j;
+
+    len = self->length - start;
+    list = PyList_New(len);
+    if (list == NULL)
+        return NULL;
+    for (i = start, j = 0; j < len; i++, j++)
+        PyList_SET_ITEM(list, j, self->data[i]);
+
+    self->length = start;
+    return list;
+}
+
+typedef struct PicklerObject {
+    PyObject_HEAD
+    PyObject *write;            /* write() method of the output stream */
+    PyObject *memo;             /* Memo dictionary, keep track of the seen
+                                   objects to support self-referential objects
+                                   pickling.  */
+    PyObject *pers_func;        /* persistent_id() method, can be NULL */
+    PyObject *arg;
+    int proto;                  /* Pickle protocol number, >= 0 */
+    int bin;                    /* Boolean, true if proto > 0 */
+    int nesting;                /* Current nesting level, this is to guard
+                                   save() from going into infinite recursion
+                                   and segfaulting. */
+    int buf_size;               /* Size of the current buffered pickle data */
+    char *write_buf;            /* Write buffer, this is to avoid calling the
+                                   write() method of the output stream too
+                                   often. */
+    int fast;                   /* Enable fast mode if set to a true value.
+                                   The fast mode disable the usage of memo,
+                                   therefore speeding the pickling process by
+                                   not generating superfluous PUT opcodes. It
+                                   should not be used if with self-referential
+                                   objects. */
+    int fast_nesting;
+    PyObject *fast_memo;
+} PicklerObject;
+
+typedef struct UnpicklerObject {
+    PyObject_HEAD
+    Pdata *stack;               /* Pickle data stack, store unpickled objects. */
+    PyObject *readline;         /* readline() method of the output stream */
+    PyObject *read;             /* read() method of the output stream */
+    PyObject *memo;             /* Memo dictionary, provide the objects stored
+                                   using the PUT opcodes. */
+    PyObject *arg;
+    PyObject *pers_func;        /* persistent_load() method, can be NULL. */
+    PyObject *last_string;      /* Reference to the last string read by the
+                                   readline() method.  */
+    char *buffer;               /* Reading buffer. */
+    char *encoding;             /* Name of the encoding to be used for
+                                   decoding strings pickled using Python
+                                   2.x. The default value is "ASCII" */
+    char *errors;               /* Name of errors handling scheme to used when
+                                   decoding strings. The default value is
+                                   "strict". */
+    int *marks;                 /* Mark stack, used for unpickling container
+                                   objects. */
+    Py_ssize_t num_marks;       /* Number of marks in the mark stack. */
+    Py_ssize_t marks_size;      /* Current allocated size of the mark stack. */
+} UnpicklerObject;
+
+/* Forward declarations */
+static int save(PicklerObject *, PyObject *, int);
+static int save_reduce(PicklerObject *, PyObject *, PyObject *);
+static PyTypeObject Pickler_Type;
+static PyTypeObject Unpickler_Type;
+
+
+/* Helpers for creating the argument tuple passed to functions. This has the
+   performance advantage of calling PyTuple_New() only once. */
+
+#define ARG_TUP(self, obj) do {                             \
+        if ((self)->arg || ((self)->arg=PyTuple_New(1))) {  \
+            Py_XDECREF(PyTuple_GET_ITEM((self)->arg, 0));   \
+            PyTuple_SET_ITEM((self)->arg, 0, (obj));        \
+        }                                                   \
+        else {                                              \
+            Py_DECREF((obj));                               \
+        }                                                   \
+    } while (0)
+
+#define FREE_ARG_TUP(self) do {                 \
+        if ((self)->arg->ob_refcnt > 1)         \
+            Py_CLEAR((self)->arg);              \
+    } while (0)
+
+/* A temporary cleaner API for fast single argument function call.
+
+   XXX: Does caching the argument tuple provides any real performance benefits?
+
+   A quick benchmark, on a 2.0GHz Athlon64 3200+ running Linux 2.6.24 with
+   glibc 2.7, tells me that it takes roughly 20,000,000 PyTuple_New(1) calls
+   when the tuple is retrieved from the freelist (i.e, call PyTuple_New() then
+   immediately DECREF it) and 1,200,000 calls when allocating brand new tuples
+   (i.e, call PyTuple_New() and store the returned value in an array), to save
+   one second (wall clock time). Either ways, the loading time a pickle stream
+   large enough to generate this number of calls would be massively
+   overwhelmed by other factors, like I/O throughput, the GC traversal and
+   object allocation overhead. So, I really doubt these functions provide any
+   real benefits.
+
+   On the other hand, oprofile reports that pickle spends a lot of time in
+   these functions. But, that is probably more related to the function call
+   overhead, than the argument tuple allocation.
+
+   XXX: And, what is the reference behavior of these? Steal, borrow? At first
+   glance, it seems to steal the reference of 'arg' and borrow the reference
+   of 'func'.
+ */
+static PyObject *
+pickler_call(PicklerObject *self, PyObject *func, PyObject *arg)
+{
+    PyObject *result = NULL;
+
+    ARG_TUP(self, arg);
+    if (self->arg) {
+        result = PyObject_Call(func, self->arg, NULL);
+        FREE_ARG_TUP(self);
+    }
+    return result;
+}
+
+static PyObject *
+unpickler_call(UnpicklerObject *self, PyObject *func, PyObject *arg)
+{
+    PyObject *result = NULL;
+
+    ARG_TUP(self, arg);
+    if (self->arg) {
+        result = PyObject_Call(func, self->arg, NULL);
+        FREE_ARG_TUP(self);
+    }
+    return result;
+}
+
+static Py_ssize_t
+pickler_write(PicklerObject *self, const char *s, Py_ssize_t n)
+{
+    PyObject *data, *result;
+
+    if (s == NULL) {
+        if (!(self->buf_size))
+            return 0;
+        data = PyBytes_FromStringAndSize(self->write_buf, self->buf_size);
+        if (data == NULL)
+            return -1;
+    }
+    else {
+        if (self->buf_size && (n + self->buf_size) > WRITE_BUF_SIZE) {
+            if (pickler_write(self, NULL, 0) < 0)
+                return -1;
+        }
+
+        if (n > WRITE_BUF_SIZE) {
+            if (!(data = PyBytes_FromStringAndSize(s, n)))
+                return -1;
+        }
+        else {
+            memcpy(self->write_buf + self->buf_size, s, n);
+            self->buf_size += n;
+            return n;
+        }
+    }
+
+    /* object with write method */
+    result = pickler_call(self, self->write, data);
+    if (result == NULL)
+        return -1;
+
+    Py_DECREF(result);
+    self->buf_size = 0;
+    return n;
+}
+
+/* XXX: These read/readline functions ought to be optimized. Buffered I/O
+   might help a lot, especially with the new (but much slower) io library.
+   On the other hand, the added complexity might not worth it.
+ */
+
+/* Read at least n characters from the input stream and set s to the current
+   reading position. */
+static Py_ssize_t
+unpickler_read(UnpicklerObject *self, char **s, Py_ssize_t n)
+{
+    PyObject *len;
+    PyObject *data;
+
+    len = PyLong_FromSsize_t(n);
+    if (len == NULL)
+        return -1;
+
+    data = unpickler_call(self, self->read, len);
+    if (data == NULL)
+        return -1;
+
+    /* XXX: Should bytearray be supported too? */
+    if (!PyBytes_Check(data)) {
+        PyErr_SetString(PyExc_ValueError,
+                        "read() from the underlying stream did not"
+                        "return bytes");
+        return -1;
+    }
+
+    Py_XDECREF(self->last_string);
+    self->last_string = data;
+
+    if (!(*s = PyBytes_AS_STRING(data)))
+        return -1;
+
+    return n;
+}
+
+static Py_ssize_t
+unpickler_readline(UnpicklerObject *self, char **s)
+{
+    PyObject *data;
+
+    data = PyObject_CallObject(self->readline, empty_tuple);
+    if (data == NULL)
+        return -1;
+
+    /* XXX: Should bytearray be supported too? */
+    if (!PyBytes_Check(data)) {
+        PyErr_SetString(PyExc_ValueError,
+                        "readline() from the underlying stream did not"
+                        "return bytes");
+        return -1;
+    }
+
+    Py_XDECREF(self->last_string);
+    self->last_string = data;
+
+    if (!(*s = PyBytes_AS_STRING(data)))
+        return -1;
+
+    return PyBytes_GET_SIZE(data);
+}
+
+/* Generate a GET opcode for an object stored in the memo. The 'key' argument
+   should be the address of the object as returned by PyLong_FromVoidPtr(). */
+static int
+memo_get(PicklerObject *self, PyObject *key)
+{
+    PyObject *value;
+    PyObject *memo_id;
+    long x;
+    char pdata[30];
+    int len;
+
+    value = PyDict_GetItemWithError(self->memo, key);
+    if (value == NULL) {
+        if (!PyErr_Occurred())
+            PyErr_SetObject(PyExc_KeyError, key);
+        return -1;
+    }
+
+    memo_id = PyTuple_GetItem(value, 0);
+    if (memo_id == NULL)
+        return -1;
+
+    if (!PyLong_Check(memo_id)) {
+        PyErr_SetString(PicklingError, "memo id must be an integer");
+        return -1;
+    }
+    x = PyLong_AsLong(memo_id);
+    if (x == -1 && PyErr_Occurred())
+        return -1;
+
+    if (!self->bin) {
+        pdata[0] = GET;
+        PyOS_snprintf(pdata + 1, sizeof(pdata) - 1, "%ld\n", x);
+        len = (int)strlen(pdata);
+    }
+    else {
+        if (x < 256) {
+            pdata[0] = BINGET;
+            pdata[1] = (unsigned char)(x & 0xff);
+            len = 2;
+        }
+        else if (x <= 0xffffffffL) {
+            pdata[0] = LONG_BINGET;
+            pdata[1] = (unsigned char)(x & 0xff);
+            pdata[2] = (unsigned char)((x >> 8) & 0xff);
+            pdata[3] = (unsigned char)((x >> 16) & 0xff);
+            pdata[4] = (unsigned char)((x >> 24) & 0xff);
+            len = 5;
+        }
+        else { /* unlikely */
+            PyErr_SetString(PicklingError,
+                            "memo id too large for LONG_BINGET");
+            return -1;
+        }
+    }
+
+    if (pickler_write(self, pdata, len) < 0)
+        return -1;
+
+    return 0;
+}
+
+/* Store an object in the memo, assign it a new unique ID based on the number
+   of objects currently stored in the memo and generate a PUT opcode. */
+static int
+memo_put(PicklerObject *self, PyObject *obj)
+{
+    PyObject *key = NULL;
+    PyObject *memo_id = NULL;
+    PyObject *tuple = NULL;
+    long x;
+    char pdata[30];
+    int len;
+    int status = 0;
+
+    if (self->fast)
+        return 0;
+
+    key = PyLong_FromVoidPtr(obj);
+    if (key == NULL)
+        goto error;
+    if ((x = PyDict_Size(self->memo)) < 0)
+        goto error;
+    memo_id = PyLong_FromLong(x);
+    if (memo_id == NULL)
+        goto error;
+    tuple = PyTuple_New(2);
+    if (tuple == NULL)
+        goto error;
+
+    Py_INCREF(memo_id);
+    PyTuple_SET_ITEM(tuple, 0, memo_id);
+    Py_INCREF(obj);
+    PyTuple_SET_ITEM(tuple, 1, obj);
+    if (PyDict_SetItem(self->memo, key, tuple) < 0)
+        goto error;
+
+    if (!self->bin) {
+        pdata[0] = PUT;
+        PyOS_snprintf(pdata + 1, sizeof(pdata) - 1, "%ld\n", x);
+        len = strlen(pdata);
+    }
+    else {
+        if (x < 256) {
+            pdata[0] = BINPUT;
+            pdata[1] = x;
+            len = 2;
+        }
+        else if (x <= 0xffffffffL) {
+            pdata[0] = LONG_BINPUT;
+            pdata[1] = (unsigned char)(x & 0xff);
+            pdata[2] = (unsigned char)((x >> 8) & 0xff);
+            pdata[3] = (unsigned char)((x >> 16) & 0xff);
+            pdata[4] = (unsigned char)((x >> 24) & 0xff);
+            len = 5;
+        }
+        else { /* unlikely */
+            PyErr_SetString(PicklingError,
+                            "memo id too large for LONG_BINPUT");
+            return -1;
+        }
+    }
+
+    if (pickler_write(self, pdata, len) < 0)
+        goto error;
+
+    if (0) {
+  error:
+        status = -1;
+    }
+
+    Py_XDECREF(key);
+    Py_XDECREF(memo_id);
+    Py_XDECREF(tuple);
+
+    return status;
+}
+
+static PyObject *
+whichmodule(PyObject *global, PyObject *global_name)
+{
+    Py_ssize_t i, j;
+    static PyObject *module_str = NULL;
+    static PyObject *main_str = NULL;
+    PyObject *module_name;
+    PyObject *modules_dict;
+    PyObject *module;
+    PyObject *obj;
+
+    if (module_str == NULL) {
+        module_str = PyUnicode_InternFromString("__module__");
+        if (module_str == NULL)
+            return NULL;
+        main_str = PyUnicode_InternFromString("__main__");
+        if (main_str == NULL)
+            return NULL;
+    }
+
+    module_name = PyObject_GetAttr(global, module_str);
+
+    /* In some rare cases (e.g., random.getrandbits), __module__ can be
+       None. If it is so, then search sys.modules for the module of
+       global.  */
+    if (module_name == Py_None) {
+        Py_DECREF(module_name);
+        goto search;
+    }
+
+    if (module_name) {
+        return module_name;
+    }
+    if (PyErr_ExceptionMatches(PyExc_AttributeError))
+        PyErr_Clear();
+    else
+        return NULL;
+
+  search:
+    modules_dict = PySys_GetObject("modules");
+    if (modules_dict == NULL)
+        return NULL;
+
+    i = 0;
+    module_name = NULL;
+    while ((j = PyDict_Next(modules_dict, &i, &module_name, &module))) {
+        if (PyObject_Compare(module_name, main_str) == 0)
+            continue;
+
+        obj = PyObject_GetAttr(module, global_name);
+        if (obj == NULL) {
+            if (PyErr_ExceptionMatches(PyExc_AttributeError))
+                PyErr_Clear();
+            else
+                return NULL;
+            continue;
+        }
+
+        if (obj != global) {
+            Py_DECREF(obj);
+            continue;
+        }
+
+        Py_DECREF(obj);
+        break;
+    }
+
+    /* If no module is found, use __main__. */
+    if (!j) {
+        module_name = main_str;
+    }
+
+    Py_INCREF(module_name);
+    return module_name;
+}
+
+/* fast_save_enter() and fast_save_leave() are guards against recursive
+   objects when Pickler is used with the "fast mode" (i.e., with object
+   memoization disabled). If the nesting of a list or dict object exceed
+   FAST_NESTING_LIMIT, these guards will start keeping an internal
+   reference to the seen list or dict objects and check whether these objects
+   are recursive. These are not strictly necessary, since save() has a
+   hard-coded recursion limit, but they give a nicer error message than the
+   typical RuntimeError. */
+static int
+fast_save_enter(PicklerObject *self, PyObject *obj)
+{
+    /* if fast_nesting < 0, we're doing an error exit. */
+    if (++self->fast_nesting >= FAST_NESTING_LIMIT) {
+        PyObject *key = NULL;
+        if (self->fast_memo == NULL) {
+            self->fast_memo = PyDict_New();
+            if (self->fast_memo == NULL) {
+                self->fast_nesting = -1;
+                return 0;
+            }
+        }
+        key = PyLong_FromVoidPtr(obj);
+        if (key == NULL)
+            return 0;
+        if (PyDict_GetItem(self->fast_memo, key)) {
+            Py_DECREF(key);
+            PyErr_Format(PyExc_ValueError,
+                         "fast mode: can't pickle cyclic objects "
+                         "including object type %.200s at %p",
+                         obj->ob_type->tp_name, obj);
+            self->fast_nesting = -1;
+            return 0;
+        }
+        if (PyDict_SetItem(self->fast_memo, key, Py_None) < 0) {
+            Py_DECREF(key);
+            self->fast_nesting = -1;
+            return 0;
+        }
+        Py_DECREF(key);
+    }
+    return 1;
+}
+
+static int
+fast_save_leave(PicklerObject *self, PyObject *obj)
+{
+    if (self->fast_nesting-- >= FAST_NESTING_LIMIT) {
+        PyObject *key = PyLong_FromVoidPtr(obj);
+        if (key == NULL)
+            return 0;
+        if (PyDict_DelItem(self->fast_memo, key) < 0) {
+            Py_DECREF(key);
+            return 0;
+        }
+        Py_DECREF(key);
+    }
+    return 1;
+}
+
+static int
+save_none(PicklerObject *self, PyObject *obj)
+{
+    const char none_op = NONE;
+    if (pickler_write(self, &none_op, 1) < 0)
+        return -1;
+
+    return 0;
+}
+
+static int
+save_bool(PicklerObject *self, PyObject *obj)
+{
+    static const char *buf[2] = { FALSE, TRUE };
+    const char len[2] = {sizeof(FALSE) - 1, sizeof(TRUE) - 1};
+    int p = (obj == Py_True);
+
+    if (self->proto >= 2) {
+        const char bool_op = p ? NEWTRUE : NEWFALSE;
+        if (pickler_write(self, &bool_op, 1) < 0)
+            return -1;
+    }
+    else if (pickler_write(self, buf[p], len[p]) < 0)
+        return -1;
+
+    return 0;
+}
+
+static int
+save_int(PicklerObject *self, long x)
+{
+    char pdata[32];
+    int len = 0;
+
+    if (!self->bin
+#if SIZEOF_LONG > 4
+        || x > 0x7fffffffL || x < -0x80000000L
+#endif
+        ) {
+        /* Text-mode pickle, or long too big to fit in the 4-byte
+         * signed BININT format:  store as a string.
+         */
+        pdata[0] = LONG;        /* use LONG for consistence with pickle.py */
+        PyOS_snprintf(pdata + 1, sizeof(pdata) - 1, "%ld\n", x);
+        if (pickler_write(self, pdata, strlen(pdata)) < 0)
+            return -1;
+    }
+    else {
+        /* Binary pickle and x fits in a signed 4-byte int. */
+        pdata[1] = (unsigned char)(x & 0xff);
+        pdata[2] = (unsigned char)((x >> 8) & 0xff);
+        pdata[3] = (unsigned char)((x >> 16) & 0xff);
+        pdata[4] = (unsigned char)((x >> 24) & 0xff);
+
+        if ((pdata[4] == 0) && (pdata[3] == 0)) {
+            if (pdata[2] == 0) {
+                pdata[0] = BININT1;
+                len = 2;
+            }
+            else {
+                pdata[0] = BININT2;
+                len = 3;
+            }
+        }
+        else {
+            pdata[0] = BININT;
+            len = 5;
+        }
+
+        if (pickler_write(self, pdata, len) < 0)
+            return -1;
+    }
+
+    return 0;
+}
+
+static int
+save_long(PicklerObject *self, PyObject *obj)
+{
+    PyObject *repr = NULL;
+    Py_ssize_t size;
+    long val = PyLong_AsLong(obj);
+    int status = 0;
+
+    const char long_op = LONG;
+
+    if (val == -1 && PyErr_Occurred()) {
+        /* out of range for int pickling */
+        PyErr_Clear();
+    }
+    else
+        return save_int(self, val);
+
+    if (self->proto >= 2) {
+        /* Linear-time pickling. */
+        size_t nbits;
+        size_t nbytes;
+        unsigned char *pdata;
+        char header[5];
+        int i;
+        int sign = _PyLong_Sign(obj);
+
+        if (sign == 0) {
+            header[0] = LONG1;
+            header[1] = 0;      /* It's 0 -- an empty bytestring. */
+            if (pickler_write(self, header, 2) < 0)
+                goto error;
+            return 0;
+        }
+        nbits = _PyLong_NumBits(obj);
+        if (nbits == (size_t)-1 && PyErr_Occurred())
+            goto error;
+        /* How many bytes do we need?  There are nbits >> 3 full
+         * bytes of data, and nbits & 7 leftover bits.  If there
+         * are any leftover bits, then we clearly need another
+         * byte.  Wnat's not so obvious is that we *probably*
+         * need another byte even if there aren't any leftovers:
+         * the most-significant bit of the most-significant byte
+         * acts like a sign bit, and it's usually got a sense
+         * opposite of the one we need.  The exception is longs
+         * of the form -(2**(8*j-1)) for j > 0.  Such a long is
+         * its own 256's-complement, so has the right sign bit
+         * even without the extra byte.  That's a pain to check
+         * for in advance, though, so we always grab an extra
+         * byte at the start, and cut it back later if possible.
+         */
+        nbytes = (nbits >> 3) + 1;
+        if (nbytes > INT_MAX) {
+            PyErr_SetString(PyExc_OverflowError,
+                            "long too large to pickle");
+            goto error;
+        }
+        repr = PyUnicode_FromStringAndSize(NULL, (int)nbytes);
+        if (repr == NULL)
+            goto error;
+        pdata = (unsigned char *)PyUnicode_AsString(repr);
+        i = _PyLong_AsByteArray((PyLongObject *)obj,
+                                pdata, nbytes,
+                                1 /* little endian */ , 1 /* signed */ );
+        if (i < 0)
+            goto error;
+        /* If the long is negative, this may be a byte more than
+         * needed.  This is so iff the MSB is all redundant sign
+         * bits.
+         */
+        if (sign < 0 &&
+            nbytes > 1 && 
+            pdata[nbytes - 1] == 0xff &&
+            (pdata[nbytes - 2] & 0x80) != 0) {
+            nbytes--;
+        }
+
+        if (nbytes < 256) {
+            header[0] = LONG1;
+            header[1] = (unsigned char)nbytes;
+            size = 2;
+        }
+        else {
+            header[0] = LONG4;
+            size = (int)nbytes;
+            for (i = 1; i < 5; i++) {
+                header[i] = (unsigned char)(size & 0xff);
+                size >>= 8;
+            }
+            size = 5;
+        }
+        if (pickler_write(self, header, size) < 0 ||
+            pickler_write(self, (char *)pdata, (int)nbytes) < 0)
+            goto error;
+    }
+    else {
+        char *string;
+
+        /* proto < 2:  write the repr and newline.  This is quadratic-time
+           (in the number of digits), in both directions. */
+
+        repr = PyObject_Repr(obj);
+        if (repr == NULL)
+            goto error;
+
+        string = PyUnicode_AsStringAndSize(repr, &size);
+        if (string == NULL)
+            goto error;
+
+        if (pickler_write(self, &long_op, 1) < 0 ||
+            pickler_write(self, string, size) < 0 ||
+            pickler_write(self, "\n", 1) < 0)
+            goto error;
+    }
+
+    if (0) {
+  error:
+      status = -1;
+    }
+    Py_XDECREF(repr);
+
+    return status;
+}
+
+static int
+save_float(PicklerObject *self, PyObject *obj)
+{
+    double x = PyFloat_AS_DOUBLE((PyFloatObject *)obj);
+
+    if (self->bin) {
+        char pdata[9];
+        pdata[0] = BINFLOAT;
+        if (_PyFloat_Pack8(x, (unsigned char *)&pdata[1], 0) < 0)
+            return -1;
+        if (pickler_write(self, pdata, 9) < 0)
+            return -1;
+    }
+    else {
+        char pdata[250];
+        pdata[0] = FLOAT;
+        PyOS_ascii_formatd(pdata + 1, sizeof(pdata) - 2, "%.17g", x);
+        /* Extend the formatted string with a newline character */
+        strcat(pdata, "\n");
+
+        if (pickler_write(self, pdata, strlen(pdata)) < 0)
+            return -1;
+    }
+
+    return 0;
+}
+
+static int
+save_bytes(PicklerObject *self, PyObject *obj)
+{
+    if (self->proto < 3) {
+        /* Older pickle protocols do not have an opcode for pickling bytes
+           objects. Therefore, we need to fake the copy protocol (i.e.,
+           the __reduce__ method) to permit bytes object unpickling. */
+        PyObject *reduce_value = NULL;
+        PyObject *bytelist = NULL;
+        int status;
+
+        bytelist = PySequence_List(obj);
+        if (bytelist == NULL)
+            return -1;
+
+        reduce_value = Py_BuildValue("(O(O))", (PyObject *)&PyBytes_Type,
+                                     bytelist);
+        if (reduce_value == NULL) {
+            Py_DECREF(bytelist);
+            return -1;
+        }
+
+        /* save_reduce() will memoize the object automatically. */
+        status = save_reduce(self, reduce_value, obj);
+        Py_DECREF(reduce_value);
+        Py_DECREF(bytelist);
+        return status;
+    }
+    else {
+        Py_ssize_t size;
+        char header[5];
+        int len;
+
+        size = PyBytes_Size(obj);
+        if (size < 0)
+            return -1;
+
+        if (size < 256) {
+            header[0] = SHORT_BINBYTES;
+            header[1] = (unsigned char)size;
+            len = 2;
+        }
+        else if (size <= 0xffffffffL) {
+            header[0] = BINBYTES;
+            header[1] = (unsigned char)(size & 0xff);
+            header[2] = (unsigned char)((size >> 8) & 0xff);
+            header[3] = (unsigned char)((size >> 16) & 0xff);
+            header[4] = (unsigned char)((size >> 24) & 0xff);
+            len = 5;
+        }
+        else {
+            return -1;          /* string too large */
+        }
+
+        if (pickler_write(self, header, len) < 0)
+            return -1;
+
+        if (pickler_write(self, PyBytes_AS_STRING(obj), size) < 0)
+            return -1;
+
+        if (memo_put(self, obj) < 0)
+            return -1;
+
+        return 0;
+    }
+}
+
+/* A copy of PyUnicode_EncodeRawUnicodeEscape() that also translates
+   backslash and newline characters to \uXXXX escapes. */
+static PyObject *
+raw_unicode_escape(const Py_UNICODE *s, Py_ssize_t size)
+{
+    PyObject *repr, *result;
+    char *p;
+    char *q;
+
+    static const char *hexdigits = "0123456789abcdef";
+
+#ifdef Py_UNICODE_WIDE
+    repr = PyBytes_FromStringAndSize(NULL, 10 * size);
+#else
+    repr = PyBytes_FromStringAndSize(NULL, 6 * size);
+#endif
+    if (repr == NULL)
+        return NULL;
+    if (size == 0)
+        goto done;
+
+    p = q = PyBytes_AS_STRING(repr);
+    while (size-- > 0) {
+        Py_UNICODE ch = *s++;
+#ifdef Py_UNICODE_WIDE
+        /* Map 32-bit characters to '\Uxxxxxxxx' */
+        if (ch >= 0x10000) {
+            *p++ = '\\';
+            *p++ = 'U';
+            *p++ = hexdigits[(ch >> 28) & 0xf];
+            *p++ = hexdigits[(ch >> 24) & 0xf];
+            *p++ = hexdigits[(ch >> 20) & 0xf];
+            *p++ = hexdigits[(ch >> 16) & 0xf];
+            *p++ = hexdigits[(ch >> 12) & 0xf];
+            *p++ = hexdigits[(ch >> 8) & 0xf];
+            *p++ = hexdigits[(ch >> 4) & 0xf];
+            *p++ = hexdigits[ch & 15];
+        }
+        else
+#endif
+        /* Map 16-bit characters to '\uxxxx' */
+        if (ch >= 256 || ch == '\\' || ch == '\n') {
+            *p++ = '\\';
+            *p++ = 'u';
+            *p++ = hexdigits[(ch >> 12) & 0xf];
+            *p++ = hexdigits[(ch >> 8) & 0xf];
+            *p++ = hexdigits[(ch >> 4) & 0xf];
+            *p++ = hexdigits[ch & 15];
+        }
+	/* Copy everything else as-is */
+        else
+            *p++ = (char) ch;
+    }
+    size = p - q;
+
+  done:
+    result = PyBytes_FromStringAndSize(PyBytes_AS_STRING(repr), size);
+    Py_DECREF(repr);
+    return result;
+}
+
+static int
+save_unicode(PicklerObject *self, PyObject *obj)
+{
+    Py_ssize_t size;
+    PyObject *encoded = NULL;
+
+    if (self->bin) {
+        char pdata[5];
+
+        encoded = PyUnicode_AsUTF8String(obj);
+        if (encoded == NULL)
+            goto error;
+
+        size = PyBytes_GET_SIZE(encoded);
+        if (size < 0 || size > 0xffffffffL)
+            goto error;          /* string too large */
+
+        pdata[0] = BINUNICODE;
+        pdata[1] = (unsigned char)(size & 0xff);
+        pdata[2] = (unsigned char)((size >> 8) & 0xff);
+        pdata[3] = (unsigned char)((size >> 16) & 0xff);
+        pdata[4] = (unsigned char)((size >> 24) & 0xff);
+
+        if (pickler_write(self, pdata, 5) < 0)
+            goto error;
+
+        if (pickler_write(self, PyBytes_AS_STRING(encoded), size) < 0)
+            goto error;
+    }
+    else {
+        const char unicode_op = UNICODE;
+
+        encoded = raw_unicode_escape(PyUnicode_AS_UNICODE(obj),
+                                     PyUnicode_GET_SIZE(obj));
+        if (encoded == NULL)
+            goto error;
+
+        if (pickler_write(self, &unicode_op, 1) < 0)
+            goto error;
+
+        size = PyBytes_GET_SIZE(encoded);
+        if (pickler_write(self, PyBytes_AS_STRING(encoded), size) < 0)
+            goto error;
+
+        if (pickler_write(self, "\n", 1) < 0)
+            goto error;
+    }
+    if (memo_put(self, obj) < 0)
+        goto error;
+
+    Py_DECREF(encoded);
+    return 0;
+
+  error:
+    Py_XDECREF(encoded);
+    return -1;
+}
+
+/* A helper for save_tuple.  Push the len elements in tuple t on the stack. */
+static int
+store_tuple_elements(PicklerObject *self, PyObject *t, int len)
+{
+    int i;
+
+    assert(PyTuple_Size(t) == len);
+
+    for (i = 0; i < len; i++) {
+        PyObject *element = PyTuple_GET_ITEM(t, i);
+
+        if (element == NULL)
+            return -1;
+        if (save(self, element, 0) < 0)
+            return -1;
+    }
+
+    return 0;
+}
+
+/* Tuples are ubiquitous in the pickle protocols, so many techniques are
+ * used across protocols to minimize the space needed to pickle them.
+ * Tuples are also the only builtin immutable type that can be recursive
+ * (a tuple can be reached from itself), and that requires some subtle
+ * magic so that it works in all cases.  IOW, this is a long routine.
+ */
+static int
+save_tuple(PicklerObject *self, PyObject *obj)
+{
+    PyObject *memo_key = NULL;
+    int len, i;
+    int status = 0;
+
+    const char mark_op = MARK;
+    const char tuple_op = TUPLE;
+    const char pop_op = POP;
+    const char pop_mark_op = POP_MARK;
+    const char len2opcode[] = {EMPTY_TUPLE, TUPLE1, TUPLE2, TUPLE3};
+
+    if ((len = PyTuple_Size(obj)) < 0)
+        return -1;
+
+    if (len == 0) {
+        char pdata[2];
+
+        if (self->proto) {
+            pdata[0] = EMPTY_TUPLE;
+            len = 1;
+        }
+        else {
+            pdata[0] = MARK;
+            pdata[1] = TUPLE;
+            len = 2;
+        }
+        if (pickler_write(self, pdata, len) < 0)
+            return -1;
+        return 0;
+    }
+
+    /* id(tuple) isn't in the memo now.  If it shows up there after
+     * saving the tuple elements, the tuple must be recursive, in
+     * which case we'll pop everything we put on the stack, and fetch
+     * its value from the memo.
+     */
+    memo_key = PyLong_FromVoidPtr(obj);
+    if (memo_key == NULL)
+        return -1;
+
+    if (len <= 3 && self->proto >= 2) {
+        /* Use TUPLE{1,2,3} opcodes. */
+        if (store_tuple_elements(self, obj, len) < 0)
+            goto error;
+
+        if (PyDict_GetItem(self->memo, memo_key)) {
+            /* pop the len elements */
+            for (i = 0; i < len; i++)
+                if (pickler_write(self, &pop_op, 1) < 0)
+                    goto error;
+            /* fetch from memo */
+            if (memo_get(self, memo_key) < 0)
+                goto error;
+
+            Py_DECREF(memo_key);
+            return 0;
+        }
+        else { /* Not recursive. */
+            if (pickler_write(self, len2opcode + len, 1) < 0)
+                goto error;
+        }
+        goto memoize;
+    }
+
+    /* proto < 2 and len > 0, or proto >= 2 and len > 3.
+     * Generate MARK e1 e2 ... TUPLE
+     */
+    if (pickler_write(self, &mark_op, 1) < 0)
+        goto error;
+
+    if (store_tuple_elements(self, obj, len) < 0)
+        goto error;
+
+    if (PyDict_GetItem(self->memo, memo_key)) {
+        /* pop the stack stuff we pushed */
+        if (self->bin) {
+            if (pickler_write(self, &pop_mark_op, 1) < 0)
+                goto error;
+        }
+        else {
+            /* Note that we pop one more than len, to remove
+             * the MARK too.
+             */
+            for (i = 0; i <= len; i++)
+                if (pickler_write(self, &pop_op, 1) < 0)
+                    goto error;
+        }
+        /* fetch from memo */
+        if (memo_get(self, memo_key) < 0)
+            goto error;
+
+        Py_DECREF(memo_key);
+        return 0;
+    }
+    else { /* Not recursive. */
+        if (pickler_write(self, &tuple_op, 1) < 0)
+            goto error;
+    }
+
+  memoize:
+    if (memo_put(self, obj) < 0)
+        goto error;
+
+    if (0) {
+  error:
+        status = -1;
+    }
+
+    Py_DECREF(memo_key);
+    return status;
+}
+
+/* iter is an iterator giving items, and we batch up chunks of
+ *     MARK item item ... item APPENDS
+ * opcode sequences.  Calling code should have arranged to first create an
+ * empty list, or list-like object, for the APPENDS to operate on.
+ * Returns 0 on success, <0 on error.
+ */
+static int
+batch_list(PicklerObject *self, PyObject *iter)
+{
+    PyObject *obj;
+    PyObject *slice[BATCHSIZE];
+    int i, n;
+
+    const char mark_op = MARK;
+    const char append_op = APPEND;
+    const char appends_op = APPENDS;
+
+    assert(iter != NULL);
+
+    /* XXX: I think this function could be made faster by avoiding the
+       iterator interface and fetching objects directly from list using
+       PyList_GET_ITEM.
+    */
+
+    if (self->proto == 0) {
+        /* APPENDS isn't available; do one at a time. */
+        for (;;) {
+            obj = PyIter_Next(iter);
+            if (obj == NULL) {
+                if (PyErr_Occurred())
+                    return -1;
+                break;
+            }
+            i = save(self, obj, 0);
+            Py_DECREF(obj);
+            if (i < 0)
+                return -1;
+            if (pickler_write(self, &append_op, 1) < 0)
+                return -1;
+        }
+        return 0;
+    }
+
+    /* proto > 0:  write in batches of BATCHSIZE. */
+    do {
+        /* Get next group of (no more than) BATCHSIZE elements. */
+        for (n = 0; n < BATCHSIZE; n++) {
+            obj = PyIter_Next(iter);
+            if (obj == NULL) {
+                if (PyErr_Occurred())
+                    goto error;
+                break;
+            }
+            slice[n] = obj;
+        }
+
+        if (n > 1) {
+            /* Pump out MARK, slice[0:n], APPENDS. */
+            if (pickler_write(self, &mark_op, 1) < 0)
+                goto error;
+            for (i = 0; i < n; i++) {
+                if (save(self, slice[i], 0) < 0)
+                    goto error;
+            }
+            if (pickler_write(self, &appends_op, 1) < 0)
+                goto error;
+        }
+        else if (n == 1) {
+            if (save(self, slice[0], 0) < 0 || 
+                pickler_write(self, &append_op, 1) < 0)
+                goto error;
+        }
+
+        for (i = 0; i < n; i++) {
+            Py_DECREF(slice[i]);
+        }
+    } while (n == BATCHSIZE);
+    return 0;
+
+  error:
+    while (--n >= 0) {
+        Py_DECREF(slice[n]);
+    }
+    return -1;
+}
+
+static int
+save_list(PicklerObject *self, PyObject *obj)
+{
+    PyObject *iter;
+    char header[3];
+    int len;
+    int status = 0;
+
+    if (self->fast && !fast_save_enter(self, obj))
+        goto error;
+
+    /* Create an empty list. */
+    if (self->bin) {
+        header[0] = EMPTY_LIST;
+        len = 1;
+    }
+    else {
+        header[0] = MARK;
+        header[1] = LIST;
+        len = 2;
+    }
+
+    if (pickler_write(self, header, len) < 0)
+        goto error;
+
+    /* Get list length, and bow out early if empty. */
+    if ((len = PyList_Size(obj)) < 0)
+        goto error;
+
+    if (memo_put(self, obj) < 0)
+        goto error;
+
+    if (len != 0) {
+        /* Save the list elements. */
+        iter = PyObject_GetIter(obj);
+        if (iter == NULL)
+            goto error;
+        status = batch_list(self, iter);
+        Py_DECREF(iter);
+    }
+
+    if (0) {
+  error:
+        status = -1;
+    }
+
+    if (self->fast && !fast_save_leave(self, obj))
+        status = -1;
+
+    return status;
+}
+
+/* iter is an iterator giving (key, value) pairs, and we batch up chunks of
+ *     MARK key value ... key value SETITEMS
+ * opcode sequences.  Calling code should have arranged to first create an
+ * empty dict, or dict-like object, for the SETITEMS to operate on.
+ * Returns 0 on success, <0 on error.
+ *
+ * This is very much like batch_list().  The difference between saving
+ * elements directly, and picking apart two-tuples, is so long-winded at
+ * the C level, though, that attempts to combine these routines were too
+ * ugly to bear.
+ */
+static int
+batch_dict(PicklerObject *self, PyObject *iter)
+{
+    PyObject *obj;
+    PyObject *slice[BATCHSIZE];
+    int i, n;
+
+    const char mark_op = MARK;
+    const char setitem_op = SETITEM;
+    const char setitems_op = SETITEMS;
+
+    assert(iter != NULL);
+
+    if (self->proto == 0) {
+        /* SETITEMS isn't available; do one at a time. */
+        for (;;) {
+            obj = PyIter_Next(iter);
+            if (obj == NULL) {
+                if (PyErr_Occurred())
+                    return -1;
+                break;
+            }
+            if (!PyTuple_Check(obj) || PyTuple_Size(obj) != 2) {
+                PyErr_SetString(PyExc_TypeError, "dict items "
+                                "iterator must return 2-tuples");
+                return -1;
+            }
+            i = save(self, PyTuple_GET_ITEM(obj, 0), 0);
+            if (i >= 0)
+                i = save(self, PyTuple_GET_ITEM(obj, 1), 0);
+            Py_DECREF(obj);
+            if (i < 0)
+                return -1;
+            if (pickler_write(self, &setitem_op, 1) < 0)
+                return -1;
+        }
+        return 0;
+    }
+
+    /* proto > 0:  write in batches of BATCHSIZE. */
+    do {
+        /* Get next group of (no more than) BATCHSIZE elements. */
+        for (n = 0; n < BATCHSIZE; n++) {
+            obj = PyIter_Next(iter);
+            if (obj == NULL) {
+                if (PyErr_Occurred())
+                    goto error;
+                break;
+            }
+            if (!PyTuple_Check(obj) || PyTuple_Size(obj) != 2) {
+                PyErr_SetString(PyExc_TypeError, "dict items "
+                                "iterator must return 2-tuples");
+                goto error;
+            }
+            slice[n] = obj;
+        }
+
+        if (n > 1) {
+            /* Pump out MARK, slice[0:n], SETITEMS. */
+            if (pickler_write(self, &mark_op, 1) < 0)
+                goto error;
+            for (i = 0; i < n; i++) {
+                obj = slice[i];
+                if (save(self, PyTuple_GET_ITEM(obj, 0), 0) < 0 ||
+                    save(self, PyTuple_GET_ITEM(obj, 1), 0) < 0)
+                    goto error;
+            }
+            if (pickler_write(self, &setitems_op, 1) < 0)
+                goto error;
+        }
+        else if (n == 1) {
+            obj = slice[0];
+            if (save(self, PyTuple_GET_ITEM(obj, 0), 0) < 0 ||
+                save(self, PyTuple_GET_ITEM(obj, 1), 0) < 0 ||
+                pickler_write(self, &setitem_op, 1) < 0)
+                goto error;
+        }
+
+        for (i = 0; i < n; i++) {
+            Py_DECREF(slice[i]);
+        }
+    } while (n == BATCHSIZE);
+    return 0;
+
+  error:
+    while (--n >= 0) {
+        Py_DECREF(slice[n]);
+    }
+    return -1;
+}
+
+static int
+save_dict(PicklerObject *self, PyObject *obj)
+{
+    PyObject *items, *iter;
+    char header[3];
+    int len;
+    int status = 0;
+
+    if (self->fast && !fast_save_enter(self, obj))
+        goto error;
+
+    /* Create an empty dict. */
+    if (self->bin) {
+        header[0] = EMPTY_DICT;
+        len = 1;
+    }
+    else {
+        header[0] = MARK;
+        header[1] = DICT;
+        len = 2;
+    }
+
+    if (pickler_write(self, header, len) < 0)
+        goto error;
+
+    /* Get dict size, and bow out early if empty. */
+    if ((len = PyDict_Size(obj)) < 0)
+        goto error;
+
+    if (memo_put(self, obj) < 0)
+        goto error;
+
+    if (len != 0) {
+        /* Save the dict items. */
+        items = PyObject_CallMethod(obj, "items", "()");
+        if (items == NULL)
+            goto error;
+        iter = PyObject_GetIter(items);
+        Py_DECREF(items);
+        if (iter == NULL)
+            goto error;
+        status = batch_dict(self, iter);
+        Py_DECREF(iter);
+    }
+
+    if (0) {
+  error:
+        status = -1;
+    }
+
+    if (self->fast && !fast_save_leave(self, obj))
+        status = -1;
+
+    return status;
+}
+
+static int
+save_global(PicklerObject *self, PyObject *obj, PyObject *name)
+{
+    static PyObject *name_str = NULL;
+    PyObject *global_name = NULL;
+    PyObject *module_name = NULL;
+    PyObject *module = NULL;
+    PyObject *cls;
+    int status = 0;
+
+    const char global_op = GLOBAL;
+
+    if (name_str == NULL) {
+        name_str = PyUnicode_InternFromString("__name__");
+        if (name_str == NULL)
+            goto error;
+    }
+
+    if (name) {
+        global_name = name;
+        Py_INCREF(global_name);
+    }
+    else {
+        global_name = PyObject_GetAttr(obj, name_str);
+        if (global_name == NULL)
+            goto error;
+    }
+
+    module_name = whichmodule(obj, global_name);
+    if (module_name == NULL)
+        goto error;
+
+    /* XXX: Change to use the import C API directly with level=0 to disallow
+       relative imports.
+
+       XXX: PyImport_ImportModuleLevel could be used. However, this bypasses
+       builtins.__import__. Therefore, _pickle, unlike pickle.py, will ignore
+       custom import functions (IMHO, this would be a nice security
+       feature). The import C API would need to be extended to support the
+       extra parameters of __import__ to fix that. */
+    module = PyImport_Import(module_name);
+    if (module == NULL) {
+        PyErr_Format(PicklingError,
+                     "Can't pickle %R: import of module %R failed",
+                     obj, module_name);
+        goto error;
+    }
+    cls = PyObject_GetAttr(module, global_name);
+    if (cls == NULL) {
+        PyErr_Format(PicklingError,
+                     "Can't pickle %R: attribute lookup %S.%S failed",
+                     obj, module_name, global_name);
+        goto error;
+    }
+    if (cls != obj) {
+        Py_DECREF(cls);
+        PyErr_Format(PicklingError,
+                     "Can't pickle %R: it's not the same object as %S.%S",
+                     obj, module_name, global_name);
+        goto error;
+    }
+    Py_DECREF(cls);
+
+    if (self->proto >= 2) {
+        /* See whether this is in the extension registry, and if
+         * so generate an EXT opcode.
+         */
+        PyObject *code_obj;      /* extension code as Python object */
+        long code;               /* extension code as C value */
+        char pdata[5];
+        int n;
+
+        PyTuple_SET_ITEM(two_tuple, 0, module_name);
+        PyTuple_SET_ITEM(two_tuple, 1, global_name);
+        code_obj = PyDict_GetItem(extension_registry, two_tuple);
+        /* The object is not registered in the extension registry.
+           This is the most likely code path. */
+        if (code_obj == NULL)
+            goto gen_global;
+
+        /* XXX: pickle.py doesn't check neither the type, nor the range
+           of the value returned by the extension_registry. It should for
+           consistency. */
+
+        /* Verify code_obj has the right type and value. */
+        if (!PyLong_Check(code_obj)) {
+            PyErr_Format(PicklingError,
+                         "Can't pickle %R: extension code %R isn't an integer",
+                         obj, code_obj);
+            goto error;
+        }
+        code = PyLong_AS_LONG(code_obj);
+        if (code <= 0 || code > 0x7fffffffL) {
+            PyErr_Format(PicklingError,
+                         "Can't pickle %R: extension code %ld is out of range",
+                         obj, code);
+            goto error;
+        }
+
+        /* Generate an EXT opcode. */
+        if (code <= 0xff) {
+            pdata[0] = EXT1;
+            pdata[1] = (unsigned char)code;
+            n = 2;
+        }
+        else if (code <= 0xffff) {
+            pdata[0] = EXT2;
+            pdata[1] = (unsigned char)(code & 0xff);
+            pdata[2] = (unsigned char)((code >> 8) & 0xff);
+            n = 3;
+        }
+        else {
+            pdata[0] = EXT4;
+            pdata[1] = (unsigned char)(code & 0xff);
+            pdata[2] = (unsigned char)((code >> 8) & 0xff);
+            pdata[3] = (unsigned char)((code >> 16) & 0xff);
+            pdata[4] = (unsigned char)((code >> 24) & 0xff);
+            n = 5;
+        }
+
+        if (pickler_write(self, pdata, n) < 0)
+            goto error;
+    }
+    else {
+        /* Generate a normal global opcode if we are using a pickle
+           protocol <= 2, or if the object is not registered in the
+           extension registry. */
+        PyObject *encoded;
+        PyObject *(*unicode_encoder)(PyObject *);
+
+  gen_global:
+        if (pickler_write(self, &global_op, 1) < 0)
+            goto error;
+
+        /* Since Python 3.0 now supports non-ASCII identifiers, we encode both
+           the module name and the global name using UTF-8. We do so only when
+           we are using the pickle protocol newer than version 3. This is to
+           ensure compatibility with older Unpickler running on Python 2.x. */
+        if (self->proto >= 3) {
+            unicode_encoder = PyUnicode_AsUTF8String;
+        }
+        else {
+            unicode_encoder = PyUnicode_AsASCIIString;
+        }
+
+        /* Save the name of the module. */
+        encoded = unicode_encoder(module_name);
+        if (encoded == NULL) {
+            if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError))
+                PyErr_Format(PicklingError,
+                             "can't pickle module identifier '%S' using "
+                             "pickle protocol %i", module_name, self->proto);
+            goto error;
+        }
+        if (pickler_write(self, PyBytes_AS_STRING(encoded),
+                          PyBytes_GET_SIZE(encoded)) < 0) {
+            Py_DECREF(encoded);
+            goto error;
+        }
+        Py_DECREF(encoded);
+        if(pickler_write(self, "\n", 1) < 0)
+            goto error;
+
+        /* Save the name of the module. */
+        encoded = unicode_encoder(global_name);
+        if (encoded == NULL) {
+            if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError))
+                PyErr_Format(PicklingError,
+                             "can't pickle global identifier '%S' using "
+                             "pickle protocol %i", global_name, self->proto);
+            goto error;
+        }
+        if (pickler_write(self, PyBytes_AS_STRING(encoded),
+                          PyBytes_GET_SIZE(encoded)) < 0) {
+            Py_DECREF(encoded);
+            goto error;
+        }
+        Py_DECREF(encoded);
+        if(pickler_write(self, "\n", 1) < 0)
+            goto error;
+
+        /* Memoize the object. */
+        if (memo_put(self, obj) < 0)
+            goto error;
+    }
+
+    if (0) {
+  error:
+        status = -1;
+    }
+    Py_XDECREF(module_name);
+    Py_XDECREF(global_name);
+    Py_XDECREF(module);
+
+    return status;
+}
+
+static int
+save_pers(PicklerObject *self, PyObject *obj, PyObject *func)
+{
+    PyObject *pid = NULL;
+    int status = 0;
+
+    const char persid_op = PERSID;
+    const char binpersid_op = BINPERSID;
+
+    Py_INCREF(obj);
+    pid = pickler_call(self, func, obj);
+    if (pid == NULL)
+        return -1;
+
+    if (pid != Py_None) {
+        if (self->bin) {
+            if (save(self, pid, 1) < 0 ||
+                pickler_write(self, &binpersid_op, 1) < 0)
+                goto error;
+        }
+        else {
+            PyObject *pid_str = NULL;
+            char *pid_ascii_bytes;
+            Py_ssize_t size;
+
+            pid_str = PyObject_Str(pid);
+            if (pid_str == NULL)
+                goto error;
+
+            /* XXX: Should it check whether the persistent id only contains
+               ASCII characters? And what if the pid contains embedded
+               newlines? */
+            pid_ascii_bytes = PyUnicode_AsStringAndSize(pid_str, &size);
+            Py_DECREF(pid_str);
+            if (pid_ascii_bytes == NULL)
+                goto error;
+
+            if (pickler_write(self, &persid_op, 1) < 0 ||
+                pickler_write(self, pid_ascii_bytes, size) < 0 ||
+                pickler_write(self, "\n", 1) < 0)
+                goto error;
+        }
+        status = 1;
+    }
+
+    if (0) {
+  error:
+        status = -1;
+    }
+    Py_XDECREF(pid);
+
+    return status;
+}
+
+/* We're saving obj, and args is the 2-thru-5 tuple returned by the
+ * appropriate __reduce__ method for obj.
+ */
+static int
+save_reduce(PicklerObject *self, PyObject *args, PyObject *obj)
+{
+    PyObject *callable;
+    PyObject *argtup;
+    PyObject *state = NULL;
+    PyObject *listitems = NULL;
+    PyObject *dictitems = NULL;
+
+    int use_newobj = self->proto >= 2;
+
+    const char reduce_op = REDUCE;
+    const char build_op = BUILD;
+    const char newobj_op = NEWOBJ;
+
+    if (!PyArg_UnpackTuple(args, "save_reduce", 2, 5,
+                           &callable, &argtup, &state, &listitems, &dictitems))
+        return -1;
+
+    if (!PyCallable_Check(callable)) {
+        PyErr_SetString(PicklingError,
+                        "first argument of save_reduce() must be callable");
+        return -1;
+    }
+    if (!PyTuple_Check(argtup)) {
+        PyErr_SetString(PicklingError,
+                        "second argument of save_reduce() must be a tuple");
+        return -1;
+    }
+
+    if (state == Py_None)
+        state = NULL;
+    if (listitems == Py_None)
+        listitems = NULL;
+    if (dictitems == Py_None)
+        dictitems = NULL;
+
+    /* Protocol 2 special case: if callable's name is __newobj__, use
+       NEWOBJ. */
+    if (use_newobj) {
+        static PyObject *newobj_str = NULL;
+        PyObject *name_str;
+
+        if (newobj_str == NULL) {
+            newobj_str = PyUnicode_InternFromString("__newobj__");
+        }
+
+        name_str = PyObject_GetAttrString(callable, "__name__");
+        if (name_str == NULL) {
+            if (PyErr_ExceptionMatches(PyExc_AttributeError))
+                PyErr_Clear();
+            else
+                return -1;
+            use_newobj = 0;
+        }
+        else {
+            use_newobj = PyUnicode_Check(name_str) && 
+                PyUnicode_Compare(name_str, newobj_str) == 0;
+            Py_DECREF(name_str);
+        }
+    }
+    if (use_newobj) {
+        PyObject *cls;
+        PyObject *newargtup;
+        PyObject *obj_class;
+        int p;
+
+        /* Sanity checks. */
+        if (Py_SIZE(argtup) < 1) {
+            PyErr_SetString(PicklingError, "__newobj__ arglist is empty");
+            return -1;
+        }
+
+        cls = PyTuple_GET_ITEM(argtup, 0);
+        if (!PyObject_HasAttrString(cls, "__new__")) {
+            PyErr_SetString(PicklingError, "args[0] from "
+                            "__newobj__ args has no __new__");
+            return -1;
+        }
+
+        if (obj != NULL) {
+            obj_class = PyObject_GetAttrString(obj, "__class__");
+            if (obj_class == NULL) {
+                if (PyErr_ExceptionMatches(PyExc_AttributeError))
+                    PyErr_Clear();
+                else
+                    return -1;
+            }
+            p = obj_class != cls;    /* true iff a problem */
+            Py_DECREF(obj_class);
+            if (p) {
+                PyErr_SetString(PicklingError, "args[0] from "
+                                "__newobj__ args has the wrong class");
+                return -1;
+            }
+        }
+        /* XXX: These calls save() are prone to infinite recursion. Imagine
+           what happen if the value returned by the __reduce__() method of
+           some extension type contains another object of the same type. Ouch!
+
+           Here is a quick example, that I ran into, to illustrate what I
+           mean:
+
+             >>> import pickle, copyreg
+             >>> copyreg.dispatch_table.pop(complex)
+             >>> pickle.dumps(1+2j)
+             Traceback (most recent call last):
+               ...
+             RuntimeError: maximum recursion depth exceeded
+
+           Removing the complex class from copyreg.dispatch_table made the
+           __reduce_ex__() method emit another complex object:
+
+             >>> (1+1j).__reduce_ex__(2)
+             (<function __newobj__ at 0xb7b71c3c>,
+               (<class 'complex'>, (1+1j)), None, None, None)
+
+           Thus when save() was called on newargstup (the 2nd item) recursion
+           ensued. Of course, the bug was in the complex class which had a
+           broken __getnewargs__() that emitted another complex object. But,
+           the point, here, is it is quite easy to end up with a broken reduce
+           function. */
+
+        /* Save the class and its __new__ arguments. */
+        if (save(self, cls, 0) < 0)
+            return -1;
+
+        newargtup = PyTuple_GetSlice(argtup, 1, Py_SIZE(argtup));
+        if (newargtup == NULL)
+            return -1;
+
+        p = save(self, newargtup, 0);
+        Py_DECREF(newargtup);
+        if (p < 0)
+            return -1;
+
+        /* Add NEWOBJ opcode. */
+        if (pickler_write(self, &newobj_op, 1) < 0)
+            return -1;
+    }
+    else { /* Not using NEWOBJ. */
+        if (save(self, callable, 0) < 0 ||
+            save(self, argtup, 0) < 0 ||
+            pickler_write(self, &reduce_op, 1) < 0)
+            return -1;
+    }
+
+    /* obj can be NULL when save_reduce() is used directly. A NULL obj means
+       the caller do not want to memoize the object. Not particularly useful,
+       but that is to mimic the behavior save_reduce() in pickle.py when
+       obj is None. */
+    if (obj && memo_put(self, obj) < 0)
+        return -1;
+
+    if (listitems && batch_list(self, listitems) < 0)
+        return -1;
+
+    if (dictitems && batch_dict(self, dictitems) < 0)
+        return -1;
+
+    if (state) {
+        if (save(self, state, 0) < 0 || 
+            pickler_write(self, &build_op, 1) < 0)
+            return -1;
+    }
+
+    return 0;
+}
+
+static int
+save(PicklerObject *self, PyObject *obj, int pers_save)
+{
+    PyTypeObject *type;
+    PyObject *reduce_func = NULL;
+    PyObject *reduce_value = NULL;
+    PyObject *memo_key = NULL;
+    int status = 0;
+
+    /* XXX: Use Py_EnterRecursiveCall()? */
+    if (++self->nesting > Py_GetRecursionLimit()) {
+        PyErr_SetString(PyExc_RuntimeError,
+                        "maximum recursion depth exceeded");
+        goto error;
+    }
+
+    /* The extra pers_save argument is necessary to avoid calling save_pers()
+       on its returned object. */
+    if (!pers_save && self->pers_func) {
+        /* save_pers() returns:
+            -1   to signal an error;
+             0   if it did nothing successfully;
+             1   if a persistent id was saved.
+         */
+        if ((status = save_pers(self, obj, self->pers_func)) != 0)
+            goto done;
+    }
+
+    type = Py_TYPE(obj);
+
+    /* XXX: The old cPickle had an optimization that used switch-case
+       statement dispatching on the first letter of the type name. It was
+       probably not a bad idea after all. If benchmarks shows that particular
+       optimization had some real benefits, it would be nice to add it
+       back. */
+
+    /* Atom types; these aren't memoized, so don't check the memo. */
+
+    if (obj == Py_None) {
+        status = save_none(self, obj);
+        goto done;
+    }
+    else if (obj == Py_False || obj == Py_True) {
+        status = save_bool(self, obj);
+        goto done;
+    }
+    else if (type == &PyLong_Type) {
+        status = save_long(self, obj);
+        goto done;
+    }
+    else if (type == &PyFloat_Type) {
+        status = save_float(self, obj);
+        goto done;
+    }
+
+    /* Check the memo to see if it has the object. If so, generate
+       a GET (or BINGET) opcode, instead of pickling the object
+       once again. */
+    memo_key = PyLong_FromVoidPtr(obj);
+    if (memo_key == NULL)
+        goto error;
+    if (PyDict_GetItem(self->memo, memo_key)) {
+        if (memo_get(self, memo_key) < 0)
+            goto error;
+        goto done;
+    }
+
+    if (type == &PyBytes_Type) {
+        status = save_bytes(self, obj);
+        goto done;
+    }
+    else if (type == &PyUnicode_Type) {
+        status = save_unicode(self, obj);
+        goto done;
+    }
+    else if (type == &PyDict_Type) {
+        status = save_dict(self, obj);
+        goto done;
+    }
+    else if (type == &PyList_Type) {
+        status = save_list(self, obj);
+        goto done;
+    }
+    else if (type == &PyTuple_Type) {
+        status = save_tuple(self, obj);
+        goto done;
+    }
+    else if (type == &PyType_Type) {
+        status = save_global(self, obj, NULL);
+        goto done;
+    }
+    else if (type == &PyFunction_Type) {
+        status = save_global(self, obj, NULL);
+        if (status < 0 && PyErr_ExceptionMatches(PickleError)) {
+            /* fall back to reduce */
+            PyErr_Clear();
+        }
+        else {
+            goto done;
+        }
+    }
+    else if (type == &PyCFunction_Type) {
+        status = save_global(self, obj, NULL);
+        goto done;
+    }
+    else if (PyType_IsSubtype(type, &PyType_Type)) {
+        status = save_global(self, obj, NULL);
+        goto done;
+    }
+
+    /* XXX: This part needs some unit tests. */
+
+    /* Get a reduction callable, and call it.  This may come from
+     * copyreg.dispatch_table, the object's __reduce_ex__ method,
+     * or the object's __reduce__ method.
+     */
+    reduce_func = PyDict_GetItem(dispatch_table, (PyObject *)type);
+    if (reduce_func != NULL) {
+        /* Here, the reference count of the reduce_func object returned by
+           PyDict_GetItem needs to be increased to be consistent with the one
+           returned by PyObject_GetAttr. This is allow us to blindly DECREF
+           reduce_func at the end of the save() routine.
+        */
+        Py_INCREF(reduce_func);
+        Py_INCREF(obj);
+        reduce_value = pickler_call(self, reduce_func, obj);
+    }
+    else {
+        static PyObject *reduce_str = NULL;
+        static PyObject *reduce_ex_str = NULL;
+
+        /* Cache the name of the reduce methods. */
+        if (reduce_str == NULL) {
+            reduce_str = PyUnicode_InternFromString("__reduce__");
+            if (reduce_str == NULL)
+                goto error;
+            reduce_ex_str = PyUnicode_InternFromString("__reduce_ex__");
+            if (reduce_ex_str == NULL)
+                goto error;
+        }
+
+        /* XXX: If the __reduce__ method is defined, __reduce_ex__ is
+           automatically defined as __reduce__. While this is convenient, this
+           make it impossible to know which method was actually called. Of
+           course, this is not a big deal. But still, it would be nice to let
+           the user know which method was called when something go
+           wrong. Incidentally, this means if __reduce_ex__ is not defined, we
+           don't actually have to check for a __reduce__ method. */
+
+        /* Check for a __reduce_ex__ method. */
+        reduce_func = PyObject_GetAttr(obj, reduce_ex_str);
+        if (reduce_func != NULL) {
+            PyObject *proto;
+            proto = PyLong_FromLong(self->proto);
+            if (proto != NULL) {
+                reduce_value = pickler_call(self, reduce_func, proto);
+            }
+        }
+        else {
+            if (PyErr_ExceptionMatches(PyExc_AttributeError))
+                PyErr_Clear();
+            else
+                goto error;
+            /* Check for a __reduce__ method. */
+            reduce_func = PyObject_GetAttr(obj, reduce_str);
+            if (reduce_func != NULL) {
+                reduce_value = PyObject_Call(reduce_func, empty_tuple, NULL);
+            }
+            else {
+                PyErr_Format(PicklingError, "can't pickle '%.200s' object: %R",
+                             type->tp_name, obj);
+                goto error;
+            }
+        }
+    }
+
+    if (reduce_value == NULL)
+        goto error;
+
+    if (PyUnicode_Check(reduce_value)) {
+        status = save_global(self, obj, reduce_value);
+        goto done;
+    }
+
+    if (!PyTuple_Check(reduce_value)) {
+        PyErr_SetString(PicklingError,
+                        "__reduce__ must return a string or tuple");
+        goto error;
+    }
+    if (Py_SIZE(reduce_value) < 2 || Py_SIZE(reduce_value) > 5) {
+        PyErr_SetString(PicklingError, "tuple returned by __reduce__ "
+                        "must contain 2 through 5 elements");
+        goto error;
+    }
+    if (!PyTuple_Check(PyTuple_GET_ITEM(reduce_value, 1))) {
+        PyErr_SetString(PicklingError, "second item of the tuple "
+                        "returned by __reduce__ must be a tuple");
+        goto error;
+    }
+
+    status = save_reduce(self, reduce_value, obj);
+
+    if (0) {
+  error:
+        status = -1;
+    }
+  done:
+    self->nesting--;
+    Py_XDECREF(memo_key);
+    Py_XDECREF(reduce_func);
+    Py_XDECREF(reduce_value);
+
+    return status;
+}
+
+static int
+dump(PicklerObject *self, PyObject *obj)
+{
+    const char stop_op = STOP;
+
+    if (self->proto >= 2) {
+        char header[2];
+
+        header[0] = PROTO;
+        assert(self->proto >= 0 && self->proto < 256);
+        header[1] = (unsigned char)self->proto;
+        if (pickler_write(self, header, 2) < 0)
+            return -1;
+    }
+
+    if (save(self, obj, 0) < 0 ||
+        pickler_write(self, &stop_op, 1) < 0 ||
+        pickler_write(self, NULL, 0) < 0)
+        return -1;
+
+    return 0;
+}
+
+PyDoc_STRVAR(Pickler_clear_memo_doc,
+"clear_memo() -> None. Clears the pickler's \"memo\"."
+"\n"
+"The memo is the data structure that remembers which objects the\n"
+"pickler has already seen, so that shared or recursive objects are\n"
+"pickled by reference and not by value.  This method is useful when\n"
+"re-using picklers.");
+
+static PyObject *
+Pickler_clear_memo(PicklerObject *self)
+{
+    if (self->memo)
+        PyDict_Clear(self->memo);
+
+    Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(Pickler_dump_doc,
+"dump(obj) -> None. Write a pickled representation of obj to the open file.");
+
+static PyObject *
+Pickler_dump(PicklerObject *self, PyObject *args)
+{
+    PyObject *obj;
+
+    if (!PyArg_ParseTuple(args, "O:dump", &obj))
+        return NULL;
+
+    if (dump(self, obj) < 0)
+        return NULL;
+
+    Py_RETURN_NONE;
+}
+
+static struct PyMethodDef Pickler_methods[] = {
+    {"dump", (PyCFunction)Pickler_dump, METH_VARARGS,
+     Pickler_dump_doc},
+    {"clear_memo", (PyCFunction)Pickler_clear_memo, METH_NOARGS,
+     Pickler_clear_memo_doc},
+    {NULL, NULL}                /* sentinel */
+};
+
+static void
+Pickler_dealloc(PicklerObject *self)
+{
+    PyObject_GC_UnTrack(self);
+
+    Py_XDECREF(self->write);
+    Py_XDECREF(self->memo);
+    Py_XDECREF(self->pers_func);
+    Py_XDECREF(self->arg);
+    Py_XDECREF(self->fast_memo);
+
+    PyMem_Free(self->write_buf);
+
+    Py_TYPE(self)->tp_free((PyObject *)self);
+}
+
+static int
+Pickler_traverse(PicklerObject *self, visitproc visit, void *arg)
+{
+    Py_VISIT(self->write);
+    Py_VISIT(self->memo);
+    Py_VISIT(self->pers_func);
+    Py_VISIT(self->arg);
+    Py_VISIT(self->fast_memo);
+    return 0;
+}
+
+static int
+Pickler_clear(PicklerObject *self)
+{
+    Py_CLEAR(self->write);
+    Py_CLEAR(self->memo);
+    Py_CLEAR(self->pers_func);
+    Py_CLEAR(self->arg);
+    Py_CLEAR(self->fast_memo);
+
+    PyMem_Free(self->write_buf);
+    self->write_buf = NULL;
+
+    return 0;
+}
+
+PyDoc_STRVAR(Pickler_doc,
+"Pickler(file, protocol=None)"
+"\n"
+"This takes a binary file for writing a pickle data stream.\n"
+"\n"
+"The optional protocol argument tells the pickler to use the\n"
+"given protocol; supported protocols are 0, 1, 2, 3.  The default\n"
+"protocol is 3; a backward-incompatible protocol designed for\n"
+"Python 3.0.\n"
+"\n"
+"Specifying a negative protocol version selects the highest\n"
+"protocol version supported.  The higher the protocol used, the\n"
+"more recent the version of Python needed to read the pickle\n"
+"produced.\n"
+"\n"
+"The file argument must have a write() method that accepts a single\n"
+"bytes argument. It can thus be a file object opened for binary\n"
+"writing, a io.BytesIO instance, or any other custom object that\n"
+"meets this interface.\n");
+
+static int
+Pickler_init(PicklerObject *self, PyObject *args, PyObject *kwds)
+{
+    static char *kwlist[] = {"file", "protocol", 0};
+    PyObject *file;
+    PyObject *proto_obj = NULL;
+    long proto = 0;
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:Pickler",
+                                     kwlist, &file, &proto_obj))
+        return -1;
+
+    /* In case of multiple __init__() calls, clear previous content. */
+    if (self->write != NULL)
+        (void)Pickler_clear(self);
+
+    if (proto_obj == NULL || proto_obj == Py_None)
+        proto = DEFAULT_PROTOCOL;
+    else
+        proto = PyLong_AsLong(proto_obj);
+
+    if (proto < 0)
+        proto = HIGHEST_PROTOCOL;
+    if (proto > HIGHEST_PROTOCOL) {
+        PyErr_Format(PyExc_ValueError, "pickle protocol must be <= %d",
+                     HIGHEST_PROTOCOL);
+        return -1;
+    }
+
+	self->proto = proto;
+	self->bin = proto > 0;
+	self->arg = NULL;
+    self->nesting = 0;
+	self->fast = 0;
+	self->fast_nesting = 0;
+	self->fast_memo = NULL;
+
+    if (!PyObject_HasAttrString(file, "write")) {
+        PyErr_SetString(PyExc_TypeError,
+                        "file must have a 'write' attribute");
+        return -1;
+    }
+    self->write = PyObject_GetAttrString(file, "write");
+    if (self->write == NULL)
+        return -1;
+	self->buf_size = 0;
+    self->write_buf = (char *)PyMem_Malloc(WRITE_BUF_SIZE);
+    if (self->write_buf == NULL) {
+        PyErr_NoMemory();
+        return -1;
+    }
+    self->pers_func = NULL;
+    if (PyObject_HasAttrString((PyObject *)self, "persistent_id")) {
+        self->pers_func = PyObject_GetAttrString((PyObject *)self,
+                                                 "persistent_id");
+        if (self->pers_func == NULL)
+            return -1;
+    }
+    self->memo = PyDict_New();
+    if (self->memo == NULL)
+        return -1;
+
+    return 0;
+}
+
+static PyObject *
+Pickler_get_memo(PicklerObject *self)
+{
+    if (self->memo == NULL)
+        PyErr_SetString(PyExc_AttributeError, "memo");
+    else
+        Py_INCREF(self->memo);
+    return self->memo;
+}
+
+static int
+Pickler_set_memo(PicklerObject *self, PyObject *value)
+{
+    PyObject *tmp;
+
+    if (value == NULL) {
+        PyErr_SetString(PyExc_TypeError,
+                        "attribute deletion is not supported");
+        return -1;
+    }
+    if (!PyDict_Check(value)) {
+        PyErr_SetString(PyExc_TypeError, "memo must be a dictionary");
+        return -1;
+    }
+
+    tmp = self->memo;
+    Py_INCREF(value);
+    self->memo = value;
+    Py_XDECREF(tmp);
+
+    return 0;
+}
+
+static PyObject *
+Pickler_get_persid(PicklerObject *self)
+{
+    if (self->pers_func == NULL)
+        PyErr_SetString(PyExc_AttributeError, "persistent_id");
+    else
+        Py_INCREF(self->pers_func);
+    return self->pers_func;
+}
+
+static int
+Pickler_set_persid(PicklerObject *self, PyObject *value)
+{
+    PyObject *tmp;
+
+    if (value == NULL) {
+        PyErr_SetString(PyExc_TypeError,
+                        "attribute deletion is not supported");
+        return -1;
+    }
+    if (!PyCallable_Check(value)) {
+        PyErr_SetString(PyExc_TypeError,
+                        "persistent_id must be a callable taking one argument");
+        return -1;
+    }
+
+    tmp = self->pers_func;
+    Py_INCREF(value);
+    self->pers_func = value;
+    Py_XDECREF(tmp);      /* self->pers_func can be NULL, so be careful. */
+
+    return 0;
+}
+
+static PyMemberDef Pickler_members[] = {
+    {"bin", T_INT, offsetof(PicklerObject, bin)},
+    {"fast", T_INT, offsetof(PicklerObject, fast)},
+    {NULL}
+};
+
+static PyGetSetDef Pickler_getsets[] = {
+    {"memo",          (getter)Pickler_get_memo,
+                      (setter)Pickler_set_memo},
+    {"persistent_id", (getter)Pickler_get_persid,
+                      (setter)Pickler_set_persid},
+    {NULL}
+};
+
+static PyTypeObject Pickler_Type = {
+    PyVarObject_HEAD_INIT(NULL, 0)
+    "_pickle.Pickler"  ,                /*tp_name*/
+    sizeof(PicklerObject),              /*tp_basicsize*/
+    0,                                  /*tp_itemsize*/
+    (destructor)Pickler_dealloc,        /*tp_dealloc*/
+    0,                                  /*tp_print*/
+    0,                                  /*tp_getattr*/
+    0,                                  /*tp_setattr*/
+    0,                                  /*tp_compare*/
+    0,                                  /*tp_repr*/
+    0,                                  /*tp_as_number*/
+    0,                                  /*tp_as_sequence*/
+    0,                                  /*tp_as_mapping*/
+    0,                                  /*tp_hash*/
+    0,                                  /*tp_call*/
+    0,                                  /*tp_str*/
+    0,                                  /*tp_getattro*/
+    0,                                  /*tp_setattro*/
+    0,                                  /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
+    Pickler_doc,                        /*tp_doc*/
+    (traverseproc)Pickler_traverse,     /*tp_traverse*/
+    (inquiry)Pickler_clear,             /*tp_clear*/
+    0,                                  /*tp_richcompare*/
+    0,                                  /*tp_weaklistoffset*/
+    0,                                  /*tp_iter*/
+    0,                                  /*tp_iternext*/
+    Pickler_methods,                    /*tp_methods*/
+    Pickler_members,                    /*tp_members*/
+    Pickler_getsets,                    /*tp_getset*/
+    0,                                  /*tp_base*/
+    0,                                  /*tp_dict*/
+    0,                                  /*tp_descr_get*/
+    0,                                  /*tp_descr_set*/
+    0,                                  /*tp_dictoffset*/
+    (initproc)Pickler_init,             /*tp_init*/
+    PyType_GenericAlloc,                /*tp_alloc*/
+    PyType_GenericNew,                  /*tp_new*/
+    PyObject_GC_Del,                    /*tp_free*/
+    0,                                  /*tp_is_gc*/
+};
+
+/* Temporary helper for calling self.find_class(). 
+
+   XXX: It would be nice to able to avoid Python function call overhead, by
+   using directly the C version of find_class(), when find_class() is not
+   overridden by a subclass. Although, this could become rather hackish. A
+   simpler optimization would be to call the C function when self is not a
+   subclass instance. */
+static PyObject *
+find_class(UnpicklerObject *self, PyObject *module_name, PyObject *global_name)
+{
+    return PyObject_CallMethod((PyObject *)self, "find_class", "OO",
+                               module_name, global_name);
+}
+
+static int
+marker(UnpicklerObject *self)
+{
+    if (self->num_marks < 1) {
+        PyErr_SetString(UnpicklingError, "could not find MARK");
+        return -1;
+    }
+
+    return self->marks[--self->num_marks];
+}
+
+static int
+load_none(UnpicklerObject *self)
+{
+    PDATA_APPEND(self->stack, Py_None, -1);
+    return 0;
+}
+
+static int
+bad_readline(void)
+{
+    PyErr_SetString(UnpicklingError, "pickle data was truncated");
+    return -1;
+}
+
+static int
+load_int(UnpicklerObject *self)
+{
+    PyObject *value;
+    char *endptr, *s;
+    Py_ssize_t len;
+    long x;
+
+    if ((len = unpickler_readline(self, &s)) < 0)
+        return -1;
+    if (len < 2)
+        return bad_readline();
+
+    errno = 0;
+    /* XXX: Should the base argument of strtol() be explicitly set to 10? */
+    x = strtol(s, &endptr, 0);
+
+    if (errno || (*endptr != '\n') || (endptr[1] != '\0')) {
+        /* Hm, maybe we've got something long.  Let's try reading
+         * it as a Python long object. */
+        errno = 0;
+        /* XXX: Same thing about the base here. */
+        value = PyLong_FromString(s, NULL, 0); 
+        if (value == NULL) {
+            PyErr_SetString(PyExc_ValueError,
+                            "could not convert string to int");
+            return -1;
+        }
+    }
+    else {
+        if (len == 3 && (x == 0 || x == 1)) {
+            if ((value = PyBool_FromLong(x)) == NULL)
+                return -1;
+        }
+        else {
+            if ((value = PyLong_FromLong(x)) == NULL)
+                return -1;
+        }
+    }
+
+    PDATA_PUSH(self->stack, value, -1);
+    return 0;
+}
+
+static int
+load_bool(UnpicklerObject *self, PyObject *boolean)
+{
+    assert(boolean == Py_True || boolean == Py_False);
+    PDATA_APPEND(self->stack, boolean, -1);
+    return 0;
+}
+
+/* s contains x bytes of a little-endian integer.  Return its value as a
+ * C int.  Obscure:  when x is 1 or 2, this is an unsigned little-endian
+ * int, but when x is 4 it's a signed one.  This is an historical source
+ * of x-platform bugs.
+ */
+static long
+calc_binint(char *s, int size)
+{
+    unsigned char c;
+    int i;
+    long x = 0L;
+
+    for (i = 0; i < size; i++) {
+        c = (unsigned char)s[i];
+        x |= (long)c << (i * 8);
+    }
+#if SIZEOF_LONG > 4
+    /* Unlike BININT1 and BININT2, BININT (more accurately BININT4)
+     * is signed, so on a box with longs bigger than 4 bytes we need
+     * to extend a BININT's sign bit to the full width.
+     */
+    if (x == 4 && x & (1L << 31))
+        x |= (~0L) << 32;
+#endif
+    return x;
+}
+
+static int
+load_binintx(UnpicklerObject *self, char *s, int size)
+{
+    PyObject *value;
+    long x;
+
+    x = calc_binint(s, size);
+
+    if ((value = PyLong_FromLong(x)) == NULL)
+        return -1;
+
+    PDATA_PUSH(self->stack, value, -1);
+    return 0;
+}
+
+static int
+load_binint(UnpicklerObject *self)
+{
+    char *s;
+
+    if (unpickler_read(self, &s, 4) < 0)
+        return -1;
+
+    return load_binintx(self, s, 4);
+}
+
+static int
+load_binint1(UnpicklerObject *self)
+{
+    char *s;
+
+    if (unpickler_read(self, &s, 1) < 0)
+        return -1;
+
+    return load_binintx(self, s, 1);
+}
+
+static int
+load_binint2(UnpicklerObject *self)
+{
+    char *s;
+
+    if (unpickler_read(self, &s, 2) < 0)
+        return -1;
+
+    return load_binintx(self, s, 2);
+}
+
+static int
+load_long(UnpicklerObject *self)
+{
+    PyObject *value;
+    char *s;
+    Py_ssize_t len;
+
+    if ((len = unpickler_readline(self, &s)) < 0)
+        return -1;
+    if (len < 2)
+        return bad_readline();
+
+    /* XXX: Should the base argument explicitly set to 10? */
+    if ((value = PyLong_FromString(s, NULL, 0)) == NULL)
+        return -1;
+
+    PDATA_PUSH(self->stack, value, -1);
+    return 0;
+}
+
+/* 'size' bytes contain the # of bytes of little-endian 256's-complement
+ * data following.
+ */
+static int
+load_counted_long(UnpicklerObject *self, int size)
+{
+    PyObject *value;
+    char *nbytes;
+    char *pdata;
+
+    assert(size == 1 || size == 4);
+    if (unpickler_read(self, &nbytes, size) < 0)
+        return -1;
+
+    size = calc_binint(nbytes, size);
+    if (size < 0) {
+        /* Corrupt or hostile pickle -- we never write one like this */
+        PyErr_SetString(UnpicklingError,
+                        "LONG pickle has negative byte count");
+        return -1;
+    }
+
+    if (size == 0)
+        value = PyLong_FromLong(0L);
+    else {
+        /* Read the raw little-endian bytes and convert. */
+        if (unpickler_read(self, &pdata, size) < 0)
+            return -1;
+        value = _PyLong_FromByteArray((unsigned char *)pdata, (size_t)size,
+                                      1 /* little endian */ , 1 /* signed */ );
+    }
+    if (value == NULL)
+        return -1;
+    PDATA_PUSH(self->stack, value, -1);
+    return 0;
+}
+
+static int
+load_float(UnpicklerObject *self)
+{
+    PyObject *value;
+    char *endptr, *s;
+    Py_ssize_t len;
+    double d;
+
+    if ((len = unpickler_readline(self, &s)) < 0)
+        return -1;
+    if (len < 2)
+        return bad_readline();
+
+    errno = 0;
+    d = PyOS_ascii_strtod(s, &endptr);
+
+    if (errno || (endptr[0] != '\n') || (endptr[1] != '\0')) {
+        PyErr_SetString(PyExc_ValueError, "could not convert string to float");
+        return -1;
+    }
+
+    if ((value = PyFloat_FromDouble(d)) == NULL)
+        return -1;
+
+    PDATA_PUSH(self->stack, value, -1);
+    return 0;
+}
+
+static int
+load_binfloat(UnpicklerObject *self)
+{
+    PyObject *value;
+    double x;
+    char *s;
+
+    if (unpickler_read(self, &s, 8) < 0)
+        return -1;
+
+    x = _PyFloat_Unpack8((unsigned char *)s, 0);
+    if (x == -1.0 && PyErr_Occurred())
+        return -1;
+
+    if ((value = PyFloat_FromDouble(x)) == NULL)
+        return -1;
+
+    PDATA_PUSH(self->stack, value, -1);
+    return 0;
+}
+
+static int
+load_string(UnpicklerObject *self)
+{
+    PyObject *bytes;
+    PyObject *str = NULL;
+    Py_ssize_t len;
+    char *s, *p;
+
+    if ((len = unpickler_readline(self, &s)) < 0)
+        return -1;
+    if (len < 3)
+        return bad_readline();
+    if ((s = strdup(s)) == NULL) {
+        PyErr_NoMemory();
+        return -1;
+    }
+
+    /* Strip outermost quotes */
+    while (s[len - 1] <= ' ')
+        len--;
+    if (s[0] == '"' && s[len - 1] == '"') {
+        s[len - 1] = '\0';
+        p = s + 1;
+        len -= 2;
+    }
+    else if (s[0] == '\'' && s[len - 1] == '\'') {
+        s[len - 1] = '\0';
+        p = s + 1;
+        len -= 2;
+    }
+    else {
+        free(s);
+        PyErr_SetString(PyExc_ValueError, "insecure string pickle");
+        return -1;
+    }
+
+    /* Use the PyBytes API to decode the string, since that is what is used
+       to encode, and then coerce the result to Unicode. */
+    bytes = PyBytes_DecodeEscape(p, len, NULL, 0, NULL);
+    free(s);
+    if (bytes == NULL)
+        return -1;
+    str = PyUnicode_FromEncodedObject(bytes, self->encoding, self->errors);
+    Py_DECREF(bytes);
+    if (str == NULL)
+        return -1;
+
+    PDATA_PUSH(self->stack, str, -1);
+    return 0;
+}
+
+static int
+load_binbytes(UnpicklerObject *self)
+{
+    PyObject *bytes;
+    long x;
+    char *s;
+
+    if (unpickler_read(self, &s, 4) < 0)
+        return -1;
+
+    x = calc_binint(s, 4);
+    if (x < 0) {
+        PyErr_SetString(UnpicklingError, 
+                        "BINBYTES pickle has negative byte count");
+        return -1;
+    }
+
+    if (unpickler_read(self, &s, x) < 0)
+        return -1;
+    bytes = PyBytes_FromStringAndSize(s, x);
+    if (bytes == NULL)
+        return -1;
+
+    PDATA_PUSH(self->stack, bytes, -1);
+    return 0;
+}
+
+static int
+load_short_binbytes(UnpicklerObject *self)
+{
+    PyObject *bytes;
+    unsigned char x;
+    char *s;
+
+    if (unpickler_read(self, &s, 1) < 0)
+        return -1;
+
+    x = (unsigned char)s[0];
+
+    if (unpickler_read(self, &s, x) < 0)
+        return -1;
+
+    bytes = PyBytes_FromStringAndSize(s, x);
+    if (bytes == NULL)
+        return -1;
+
+    PDATA_PUSH(self->stack, bytes, -1);
+    return 0;
+}
+
+static int
+load_binstring(UnpicklerObject *self)
+{
+    PyObject *str;
+    long x;
+    char *s;
+
+    if (unpickler_read(self, &s, 4) < 0)
+        return -1;
+
+    x = calc_binint(s, 4);
+    if (x < 0) {
+        PyErr_SetString(UnpicklingError, 
+                        "BINSTRING pickle has negative byte count");
+        return -1;
+    }
+
+    if (unpickler_read(self, &s, x) < 0)
+        return -1;
+
+    /* Convert Python 2.x strings to unicode. */
+    str = PyUnicode_Decode(s, x, self->encoding, self->errors);
+    if (str == NULL)
+        return -1;
+
+    PDATA_PUSH(self->stack, str, -1);
+    return 0;
+}
+
+static int
+load_short_binstring(UnpicklerObject *self)
+{
+    PyObject *str;
+    unsigned char x;
+    char *s;
+
+    if (unpickler_read(self, &s, 1) < 0)
+        return -1;
+
+    x = (unsigned char)s[0];
+
+    if (unpickler_read(self, &s, x) < 0)
+        return -1;
+
+    /* Convert Python 2.x strings to unicode. */
+    str = PyUnicode_Decode(s, x, self->encoding, self->errors);
+    if (str == NULL)
+        return -1;
+
+    PDATA_PUSH(self->stack, str, -1);
+    return 0;
+}
+
+static int
+load_unicode(UnpicklerObject *self)
+{
+    PyObject *str;
+    Py_ssize_t len;
+    char *s;
+
+    if ((len = unpickler_readline(self, &s)) < 0)
+        return -1;
+    if (len < 1)
+        return bad_readline();
+
+    str = PyUnicode_DecodeRawUnicodeEscape(s, len - 1, NULL);
+    if (str == NULL)
+        return -1;
+
+    PDATA_PUSH(self->stack, str, -1);
+    return 0;
+}
+
+static int
+load_binunicode(UnpicklerObject *self)
+{
+    PyObject *str;
+    long size;
+    char *s;
+
+    if (unpickler_read(self, &s, 4) < 0)
+        return -1;
+
+    size = calc_binint(s, 4);
+    if (size < 0) {
+        PyErr_SetString(UnpicklingError, 
+                        "BINUNICODE pickle has negative byte count");
+        return -1;
+    }
+
+    if (unpickler_read(self, &s, size) < 0)
+        return -1;
+
+    str = PyUnicode_DecodeUTF8(s, size, NULL);
+    if (str == NULL)
+        return -1;
+
+    PDATA_PUSH(self->stack, str, -1);
+    return 0;
+}
+
+static int
+load_tuple(UnpicklerObject *self)
+{
+    PyObject *tuple;
+    int i;
+
+    if ((i = marker(self)) < 0)
+        return -1;
+
+    tuple = Pdata_poptuple(self->stack, i);
+    if (tuple == NULL)
+        return -1;
+    PDATA_PUSH(self->stack, tuple, -1);
+    return 0;
+}
+
+static int
+load_counted_tuple(UnpicklerObject *self, int len)
+{
+    PyObject *tuple;
+
+    tuple = PyTuple_New(len);
+    if (tuple == NULL)
+        return -1;
+
+    while (--len >= 0) {
+        PyObject *item;
+
+        PDATA_POP(self->stack, item);
+        if (item == NULL)
+            return -1;
+        PyTuple_SET_ITEM(tuple, len, item);
+    }
+    PDATA_PUSH(self->stack, tuple, -1);
+    return 0;
+}
+
+static int
+load_empty_list(UnpicklerObject *self)
+{
+    PyObject *list;
+
+    if ((list = PyList_New(0)) == NULL)
+        return -1;
+    PDATA_PUSH(self->stack, list, -1);
+    return 0;
+}
+
+static int
+load_empty_dict(UnpicklerObject *self)
+{
+    PyObject *dict;
+
+    if ((dict = PyDict_New()) == NULL)
+        return -1;
+    PDATA_PUSH(self->stack, dict, -1);
+    return 0;
+}
+
+static int
+load_list(UnpicklerObject *self)
+{
+    PyObject *list;
+    int i;
+
+    if ((i = marker(self)) < 0)
+        return -1;
+
+    list = Pdata_poplist(self->stack, i);
+    if (list == NULL)
+        return -1;
+    PDATA_PUSH(self->stack, list, -1);
+    return 0;
+}
+
+static int
+load_dict(UnpicklerObject *self)
+{
+    PyObject *dict, *key, *value;
+    int i, j, k;
+
+    if ((i = marker(self)) < 0)
+        return -1;
+    j = self->stack->length;
+
+    if ((dict = PyDict_New()) == NULL)
+        return -1;
+
+    for (k = i + 1; k < j; k += 2) {
+        key = self->stack->data[k - 1];
+        value = self->stack->data[k];
+        if (PyDict_SetItem(dict, key, value) < 0) {
+            Py_DECREF(dict);
+            return -1;
+        }
+    }
+    Pdata_clear(self->stack, i);
+    PDATA_PUSH(self->stack, dict, -1);
+    return 0;
+}
+
+static PyObject *
+instantiate(PyObject *cls, PyObject *args)
+{
+    PyObject *r = NULL;
+
+    /* XXX: The pickle.py module does not create instances this way when the
+       args tuple is empty. See Unpickler._instantiate(). */
+    if ((r = PyObject_CallObject(cls, args)))
+        return r;
+
+    /* XXX: Is this still nescessary? */
+    {
+        PyObject *tp, *v, *tb, *tmp_value;
+
+        PyErr_Fetch(&tp, &v, &tb);
+        tmp_value = v;
+        /* NULL occurs when there was a KeyboardInterrupt */
+        if (tmp_value == NULL)
+            tmp_value = Py_None;
+        if ((r = PyTuple_Pack(3, tmp_value, cls, args))) {
+            Py_XDECREF(v);
+            v = r;
+        }
+        PyErr_Restore(tp, v, tb);
+    }
+    return NULL;
+}
+
+static int
+load_obj(UnpicklerObject *self)
+{
+    PyObject *cls, *args, *obj = NULL;
+    int i;
+
+    if ((i = marker(self)) < 0)
+        return -1;
+
+    args = Pdata_poptuple(self->stack, i + 1);
+    if (args == NULL)
+        return -1;
+
+    PDATA_POP(self->stack, cls);
+    if (cls) {
+        obj = instantiate(cls, args);
+        Py_DECREF(cls);
+    }
+    Py_DECREF(args);
+    if (obj == NULL)
+        return -1;
+
+    PDATA_PUSH(self->stack, obj, -1);
+    return 0;
+}
+
+static int
+load_inst(UnpicklerObject *self)
+{
+    PyObject *cls = NULL;
+    PyObject *args = NULL;
+    PyObject *obj = NULL;
+    PyObject *module_name;
+    PyObject *class_name;
+    Py_ssize_t len;
+    int i;
+    char *s;
+
+    if ((i = marker(self)) < 0)
+        return -1;
+    if ((len = unpickler_readline(self, &s)) < 0)
+        return -1;
+    if (len < 2)
+        return bad_readline();
+
+    /* Here it is safe to use PyUnicode_DecodeASCII(), even though non-ASCII
+       identifiers are permitted in Python 3.0, since the INST opcode is only
+       supported by older protocols on Python 2.x. */
+    module_name = PyUnicode_DecodeASCII(s, len - 1, "strict");
+    if (module_name == NULL)
+        return -1;
+
+    if ((len = unpickler_readline(self, &s)) >= 0) {
+        if (len < 2)
+            return bad_readline();
+        class_name = PyUnicode_DecodeASCII(s, len - 1, "strict");
+        if (class_name == NULL) {
+            cls = find_class(self, module_name, class_name);
+            Py_DECREF(class_name);
+        }
+    }
+    Py_DECREF(module_name);
+
+    if (cls == NULL)
+        return -1;
+
+    if ((args = Pdata_poptuple(self->stack, i)) != NULL) {
+        obj = instantiate(cls, args);
+        Py_DECREF(args);
+    }
+    Py_DECREF(cls);
+
+    if (obj == NULL)
+        return -1;
+
+    PDATA_PUSH(self->stack, obj, -1);
+    return 0;
+}
+
+static int
+load_newobj(UnpicklerObject *self)
+{
+    PyObject *args = NULL;
+    PyObject *clsraw = NULL;
+    PyTypeObject *cls;          /* clsraw cast to its true type */
+    PyObject *obj;
+
+    /* Stack is ... cls argtuple, and we want to call
+     * cls.__new__(cls, *argtuple).
+     */
+    PDATA_POP(self->stack, args);
+    if (args == NULL)
+        goto error;
+    if (!PyTuple_Check(args)) {
+        PyErr_SetString(UnpicklingError, "NEWOBJ expected an arg " "tuple.");
+        goto error;
+    }
+
+    PDATA_POP(self->stack, clsraw);
+    cls = (PyTypeObject *)clsraw;
+    if (cls == NULL)
+        goto error;
+    if (!PyType_Check(cls)) {
+        PyErr_SetString(UnpicklingError, "NEWOBJ class argument "
+                        "isn't a type object");
+        goto error;
+    }
+    if (cls->tp_new == NULL) {
+        PyErr_SetString(UnpicklingError, "NEWOBJ class argument "
+                        "has NULL tp_new");
+        goto error;
+    }
+
+    /* Call __new__. */
+    obj = cls->tp_new(cls, args, NULL);
+    if (obj == NULL)
+        goto error;
+
+    Py_DECREF(args);
+    Py_DECREF(clsraw);
+    PDATA_PUSH(self->stack, obj, -1);
+    return 0;
+
+  error:
+    Py_XDECREF(args);
+    Py_XDECREF(clsraw);
+    return -1;
+}
+
+static int
+load_global(UnpicklerObject *self)
+{
+    PyObject *global = NULL;
+    PyObject *module_name;
+    PyObject *global_name;
+    Py_ssize_t len;
+    char *s;
+
+    if ((len = unpickler_readline(self, &s)) < 0)
+        return -1;
+    if (len < 2)
+        return bad_readline();
+    module_name = PyUnicode_DecodeUTF8(s, len - 1, "strict");
+    if (!module_name)
+        return -1;
+
+    if ((len = unpickler_readline(self, &s)) >= 0) {
+        if (len < 2) {
+            Py_DECREF(module_name);
+            return bad_readline();
+        }
+        global_name = PyUnicode_DecodeUTF8(s, len - 1, "strict");
+        if (global_name) {
+            global = find_class(self, module_name, global_name);
+            Py_DECREF(global_name);
+        }
+    }
+    Py_DECREF(module_name);
+
+    if (global == NULL)
+        return -1;
+    PDATA_PUSH(self->stack, global, -1);
+    return 0;
+}
+
+static int
+load_persid(UnpicklerObject *self)
+{
+    PyObject *pid;
+    Py_ssize_t len;
+    char *s;
+
+    if (self->pers_func) {
+        if ((len = unpickler_readline(self, &s)) < 0)
+            return -1;
+        if (len < 2)
+            return bad_readline();
+
+        pid = PyBytes_FromStringAndSize(s, len - 1);
+        if (pid == NULL)
+            return -1;
+
+        /* Ugh... this does not leak since unpickler_call() steals the
+           reference to pid first. */
+        pid = unpickler_call(self, self->pers_func, pid);
+        if (pid == NULL)
+            return -1;
+
+        PDATA_PUSH(self->stack, pid, -1);
+        return 0;
+    }
+    else {
+        PyErr_SetString(UnpicklingError,
+                        "A load persistent id instruction was encountered,\n"
+                        "but no persistent_load function was specified.");
+        return -1;
+    }
+}
+
+static int
+load_binpersid(UnpicklerObject *self)
+{
+    PyObject *pid;
+
+    if (self->pers_func) {
+        PDATA_POP(self->stack, pid);
+        if (pid == NULL)
+            return -1;
+
+        /* Ugh... this does not leak since unpickler_call() steals the
+           reference to pid first. */
+        pid = unpickler_call(self, self->pers_func, pid);
+        if (pid == NULL)
+            return -1;
+
+        PDATA_PUSH(self->stack, pid, -1);
+        return 0;
+    }
+    else {
+        PyErr_SetString(UnpicklingError,
+                        "A load persistent id instruction was encountered,\n"
+                        "but no persistent_load function was specified.");
+        return -1;
+    }
+}
+
+static int
+load_pop(UnpicklerObject *self)
+{
+    int len;
+
+    if ((len = self->stack->length) <= 0)
+        return stack_underflow();
+
+    /* Note that we split the (pickle.py) stack into two stacks,
+     * an object stack and a mark stack. We have to be clever and
+     * pop the right one. We do this by looking at the top of the
+     * mark stack.
+     */
+
+    if ((self->num_marks > 0) && (self->marks[self->num_marks - 1] == len))
+        self->num_marks--;
+    else {
+        len--;
+        Py_DECREF(self->stack->data[len]);
+        self->stack->length = len;
+    }
+
+    return 0;
+}
+
+static int
+load_pop_mark(UnpicklerObject *self)
+{
+    int i;
+
+    if ((i = marker(self)) < 0)
+        return -1;
+
+    Pdata_clear(self->stack, i);
+
+    return 0;
+}
+
+static int
+load_dup(UnpicklerObject *self)
+{
+    PyObject *last;
+    int len;
+
+    if ((len = self->stack->length) <= 0)
+        return stack_underflow();
+    last = self->stack->data[len - 1];
+    PDATA_APPEND(self->stack, last, -1);
+    return 0;
+}
+
+static int
+load_get(UnpicklerObject *self)
+{
+    PyObject *key, *value;
+    Py_ssize_t len;
+    char *s;
+
+    if ((len = unpickler_readline(self, &s)) < 0)
+        return -1;
+    if (len < 2)
+        return bad_readline();
+
+    key = PyLong_FromString(s, NULL, 10);
+    if (key == NULL)
+        return -1;
+
+    value = PyDict_GetItemWithError(self->memo, key);
+    if (value == NULL) {
+        if (!PyErr_Occurred())
+            PyErr_SetObject(PyExc_KeyError, key);
+        Py_DECREF(key);
+        return -1;
+    }
+    Py_DECREF(key);
+
+    PDATA_APPEND(self->stack, value, -1);
+    return 0;
+}
+
+static int
+load_binget(UnpicklerObject *self)
+{
+    PyObject *key, *value;
+    char *s;
+
+    if (unpickler_read(self, &s, 1) < 0)
+        return -1;
+
+    /* Here, the unsigned cast is necessary to avoid negative values. */
+    key = PyLong_FromLong((long)(unsigned char)s[0]);
+    if (key == NULL)
+        return -1;
+
+    value = PyDict_GetItemWithError(self->memo, key);
+    if (value == NULL) {
+        if (!PyErr_Occurred())
+            PyErr_SetObject(PyExc_KeyError, key);
+        Py_DECREF(key);
+        return -1;
+    }
+    Py_DECREF(key);
+
+    PDATA_APPEND(self->stack, value, -1);
+    return 0;
+}
+
+static int
+load_long_binget(UnpicklerObject *self)
+{
+    PyObject *key, *value;
+    char *s;
+    long k;
+
+    if (unpickler_read(self, &s, 4) < 0)
+        return -1;
+
+    k = (long)(unsigned char)s[0];
+    k |= (long)(unsigned char)s[1] << 8;
+    k |= (long)(unsigned char)s[2] << 16;
+    k |= (long)(unsigned char)s[3] << 24;
+
+    key = PyLong_FromLong(k);
+    if (key == NULL)
+        return -1;
+
+    value = PyDict_GetItemWithError(self->memo, key);
+    if (value == NULL) {
+        if (!PyErr_Occurred())
+            PyErr_SetObject(PyExc_KeyError, key);
+        Py_DECREF(key);
+        return -1;
+    }
+    Py_DECREF(key);
+
+    PDATA_APPEND(self->stack, value, -1);
+    return 0;
+}
+
+/* Push an object from the extension registry (EXT[124]).  nbytes is
+ * the number of bytes following the opcode, holding the index (code) value.
+ */
+static int
+load_extension(UnpicklerObject *self, int nbytes)
+{
+    char *codebytes;            /* the nbytes bytes after the opcode */
+    long code;                  /* calc_binint returns long */
+    PyObject *py_code;          /* code as a Python int */
+    PyObject *obj;              /* the object to push */
+    PyObject *pair;             /* (module_name, class_name) */
+    PyObject *module_name, *class_name;
+
+    assert(nbytes == 1 || nbytes == 2 || nbytes == 4);
+    if (unpickler_read(self, &codebytes, nbytes) < 0)
+        return -1;
+    code = calc_binint(codebytes, nbytes);
+    if (code <= 0) {            /* note that 0 is forbidden */
+        /* Corrupt or hostile pickle. */
+        PyErr_SetString(UnpicklingError, "EXT specifies code <= 0");
+        return -1;
+    }
+
+    /* Look for the code in the cache. */
+    py_code = PyLong_FromLong(code);
+    if (py_code == NULL)
+        return -1;
+    obj = PyDict_GetItem(extension_cache, py_code);
+    if (obj != NULL) {
+        /* Bingo. */
+        Py_DECREF(py_code);
+        PDATA_APPEND(self->stack, obj, -1);
+        return 0;
+    }
+
+    /* Look up the (module_name, class_name) pair. */
+    pair = PyDict_GetItem(inverted_registry, py_code);
+    if (pair == NULL) {
+        Py_DECREF(py_code);
+        PyErr_Format(PyExc_ValueError, "unregistered extension "
+                     "code %ld", code);
+        return -1;
+    }
+    /* Since the extension registry is manipulable via Python code,
+     * confirm that pair is really a 2-tuple of strings.
+     */
+    if (!PyTuple_Check(pair) || PyTuple_Size(pair) != 2 ||
+        !PyUnicode_Check(module_name = PyTuple_GET_ITEM(pair, 0)) ||
+        !PyUnicode_Check(class_name = PyTuple_GET_ITEM(pair, 1))) {
+        Py_DECREF(py_code);
+        PyErr_Format(PyExc_ValueError, "_inverted_registry[%ld] "
+                     "isn't a 2-tuple of strings", code);
+        return -1;
+    }
+    /* Load the object. */
+    obj = find_class(self, module_name, class_name);
+    if (obj == NULL) {
+        Py_DECREF(py_code);
+        return -1;
+    }
+    /* Cache code -> obj. */
+    code = PyDict_SetItem(extension_cache, py_code, obj);
+    Py_DECREF(py_code);
+    if (code < 0) {
+        Py_DECREF(obj);
+        return -1;
+    }
+    PDATA_PUSH(self->stack, obj, -1);
+    return 0;
+}
+
+static int
+load_put(UnpicklerObject *self)
+{
+    PyObject *key, *value;
+    Py_ssize_t len;
+    char *s;
+    int x;
+
+    if ((len = unpickler_readline(self, &s)) < 0)
+        return -1;
+    if (len < 2)
+        return bad_readline();
+    if ((x = self->stack->length) <= 0)
+        return stack_underflow();
+
+    key = PyLong_FromString(s, NULL, 10);
+    if (key == NULL)
+        return -1;
+    value = self->stack->data[x - 1];
+
+    x = PyDict_SetItem(self->memo, key, value);
+    Py_DECREF(key);
+    return x;
+}
+
+static int
+load_binput(UnpicklerObject *self)
+{
+    PyObject *key, *value;
+    char *s;
+    int x;
+
+    if (unpickler_read(self, &s, 1) < 0)
+        return -1;
+    if ((x = self->stack->length) <= 0)
+        return stack_underflow();
+
+    key = PyLong_FromLong((long)(unsigned char)s[0]);
+    if (key == NULL)
+        return -1;
+    value = self->stack->data[x - 1];
+
+    x = PyDict_SetItem(self->memo, key, value);
+    Py_DECREF(key);
+    return x;
+}
+
+static int
+load_long_binput(UnpicklerObject *self)
+{
+    PyObject *key, *value;
+    long k;
+    char *s;
+    int x;
+
+    if (unpickler_read(self, &s, 4) < 0)
+        return -1;
+    if ((x = self->stack->length) <= 0)
+        return stack_underflow();
+
+    k = (long)(unsigned char)s[0];
+    k |= (long)(unsigned char)s[1] << 8;
+    k |= (long)(unsigned char)s[2] << 16;
+    k |= (long)(unsigned char)s[3] << 24;
+
+    key = PyLong_FromLong(k);
+    if (key == NULL)
+        return -1;
+    value = self->stack->data[x - 1];
+
+    x = PyDict_SetItem(self->memo, key, value);
+    Py_DECREF(key);
+    return x;
+}
+
+static int
+do_append(UnpicklerObject *self, int x)
+{
+    PyObject *value;
+    PyObject *list;
+    int len, i;
+
+    len = self->stack->length;
+    if (x > len || x <= 0)
+        return stack_underflow();
+    if (len == x)  /* nothing to do */
+        return 0;
+
+    list = self->stack->data[x - 1];
+
+    if (PyList_Check(list)) {
+        PyObject *slice;
+        Py_ssize_t list_len;
+
+        slice = Pdata_poplist(self->stack, x);
+        if (!slice)
+            return -1;
+        list_len = PyList_GET_SIZE(list);
+        i = PyList_SetSlice(list, list_len, list_len, slice);
+        Py_DECREF(slice);
+        return i;
+    }
+    else {
+        PyObject *append_func;
+
+        append_func = PyObject_GetAttrString(list, "append");
+        if (append_func == NULL)
+            return -1;
+        for (i = x; i < len; i++) {
+            PyObject *result;
+
+            value = self->stack->data[i];
+            result = unpickler_call(self, append_func, value);
+            if (result == NULL) {
+                Pdata_clear(self->stack, i + 1);
+                self->stack->length = x;
+                return -1;
+            }
+            Py_DECREF(result);
+        }
+        self->stack->length = x;
+    }
+
+    return 0;
+}
+
+static int
+load_append(UnpicklerObject *self)
+{
+    return do_append(self, self->stack->length - 1);
+}
+
+static int
+load_appends(UnpicklerObject *self)
+{
+    return do_append(self, marker(self));
+}
+
+static int
+do_setitems(UnpicklerObject *self, int x)
+{
+    PyObject *value, *key;
+    PyObject *dict;
+    int len, i;
+    int status = 0;
+
+    len = self->stack->length;
+    if (x > len || x <= 0)
+        return stack_underflow();
+    if (len == x)  /* nothing to do */
+        return 0;
+    if ((len - x) % 2 != 0) { 
+        /* Currupt or hostile pickle -- we never write one like this. */
+        PyErr_SetString(UnpicklingError, "odd number of items for SETITEMS");
+        return -1;
+    }
+
+    /* Here, dict does not actually need to be a PyDict; it could be anything
+       that supports the __setitem__ attribute. */
+    dict = self->stack->data[x - 1];
+
+    for (i = x + 1; i < len; i += 2) {
+        key = self->stack->data[i - 1];
+        value = self->stack->data[i];
+        if (PyObject_SetItem(dict, key, value) < 0) {
+            status = -1;
+            break;
+        }
+    }
+
+    Pdata_clear(self->stack, x);
+    return status;
+}
+
+static int
+load_setitem(UnpicklerObject *self)
+{
+    return do_setitems(self, self->stack->length - 2);
+}
+
+static int
+load_setitems(UnpicklerObject *self)
+{
+    return do_setitems(self, marker(self));
+}
+
+static int
+load_build(UnpicklerObject *self)
+{
+    PyObject *state, *inst, *slotstate;
+    PyObject *setstate;
+    int status = 0;
+
+    /* Stack is ... instance, state.  We want to leave instance at
+     * the stack top, possibly mutated via instance.__setstate__(state).
+     */
+    if (self->stack->length < 2)
+        return stack_underflow();
+
+    PDATA_POP(self->stack, state);
+    if (state == NULL)
+        return -1;
+
+    inst = self->stack->data[self->stack->length - 1];
+
+    setstate = PyObject_GetAttrString(inst, "__setstate__");
+    if (setstate == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) {
+        PyErr_Clear();
+    }
+    else {
+        PyObject *result;
+
+        /* The explicit __setstate__ is responsible for everything. */
+        result = unpickler_call(self, setstate, state);
+        Py_DECREF(setstate);
+        if (result == NULL)
+            return -1;
+        Py_DECREF(result);
+        return 0;
+    }
+
+    /* A default __setstate__.  First see whether state embeds a
+     * slot state dict too (a proto 2 addition).
+     */
+    if (PyTuple_Check(state) && Py_SIZE(state) == 2) {
+        PyObject *tmp = state;
+
+        state = PyTuple_GET_ITEM(tmp, 0);
+        slotstate = PyTuple_GET_ITEM(tmp, 1);
+        Py_INCREF(state);
+        Py_INCREF(slotstate);
+        Py_DECREF(tmp);
+    }
+    else
+        slotstate = NULL;
+
+    /* Set inst.__dict__ from the state dict (if any). */
+    if (state != Py_None) {
+        PyObject *dict;
+
+        if (!PyDict_Check(state)) {
+            PyErr_SetString(UnpicklingError, "state is not a dictionary");
+            goto error;
+        }
+        dict = PyObject_GetAttrString(inst, "__dict__");
+        if (dict == NULL)
+            goto error;
+
+        PyDict_Update(dict, state);
+        Py_DECREF(dict);
+    }
+
+    /* Also set instance attributes from the slotstate dict (if any). */
+    if (slotstate != NULL) {
+        PyObject *d_key, *d_value;
+        Py_ssize_t i;
+
+        if (!PyDict_Check(slotstate)) {
+            PyErr_SetString(UnpicklingError,
+                            "slot state is not a dictionary");
+            goto error;
+        }
+        i = 0;
+        while (PyDict_Next(slotstate, &i, &d_key, &d_value)) {
+            if (PyObject_SetAttr(inst, d_key, d_value) < 0)
+                goto error;
+        }
+    }
+
+    if (0) {
+  error:
+        status = -1;
+    }
+
+    Py_DECREF(state);
+    Py_XDECREF(slotstate);
+    return status;
+}
+
+static int
+load_mark(UnpicklerObject *self)
+{
+
+    /* Note that we split the (pickle.py) stack into two stacks, an
+     * object stack and a mark stack. Here we push a mark onto the
+     * mark stack.
+     */
+
+    if ((self->num_marks + 1) >= self->marks_size) {
+        size_t alloc;
+        int *marks;
+
+        /* Use the size_t type to check for overflow. */
+        alloc = ((size_t)self->num_marks << 1) + 20;
+        if (alloc > PY_SSIZE_T_MAX || alloc <= (self->num_marks + 1)) {
+            PyErr_NoMemory();
+            return -1;
+        }
+
+        if (self->marks == NULL)
+            marks = (int *)PyMem_Malloc(alloc * sizeof(int));
+        else
+            marks = (int *)PyMem_Realloc(self->marks, alloc * sizeof(int));
+        if (marks == NULL) {
+            PyErr_NoMemory();
+            return -1;
+        }
+        self->marks = marks;
+        self->marks_size = (Py_ssize_t)alloc;
+    }
+
+    self->marks[self->num_marks++] = self->stack->length;
+
+    return 0;
+}
+
+static int
+load_reduce(UnpicklerObject *self)
+{
+    PyObject *callable = NULL;
+    PyObject *argtup = NULL;
+    PyObject *obj = NULL;
+
+    PDATA_POP(self->stack, argtup);
+    if (argtup == NULL)
+        return -1;
+    PDATA_POP(self->stack, callable);
+    if (callable) {
+        obj = instantiate(callable, argtup);
+        Py_DECREF(callable);
+    }
+    Py_DECREF(argtup);
+
+    if (obj == NULL)
+        return -1;
+
+    PDATA_PUSH(self->stack, obj, -1);
+    return 0;
+}
+
+/* Just raises an error if we don't know the protocol specified.  PROTO
+ * is the first opcode for protocols >= 2.
+ */
+static int
+load_proto(UnpicklerObject *self)
+{
+    char *s;
+    int i;
+
+    if (unpickler_read(self, &s, 1) < 0)
+        return -1;
+
+    i = (unsigned char)s[0];
+    if (i <= HIGHEST_PROTOCOL)
+        return 0;
+
+    PyErr_Format(PyExc_ValueError, "unsupported pickle protocol: %d", i);
+    return -1;
+}
+
+static PyObject *
+load(UnpicklerObject *self)
+{
+    PyObject *err;
+    PyObject *value = NULL;
+    char *s;
+
+    self->num_marks = 0;
+    if (self->stack->length)
+        Pdata_clear(self->stack, 0);
+
+    /* Convenient macros for the dispatch while-switch loop just below. */
+#define OP(opcode, load_func) \
+    case opcode: if (load_func(self) < 0) break; continue;
+
+#define OP_ARG(opcode, load_func, arg) \
+    case opcode: if (load_func(self, (arg)) < 0) break; continue;
+
+    while (1) {
+        if (unpickler_read(self, &s, 1) < 0)
+            break;
+
+        switch ((enum opcode)s[0]) {
+        OP(NONE, load_none)
+        OP(BININT, load_binint)
+        OP(BININT1, load_binint1)
+        OP(BININT2, load_binint2)
+        OP(INT, load_int)
+        OP(LONG, load_long)
+        OP_ARG(LONG1, load_counted_long, 1)
+        OP_ARG(LONG4, load_counted_long, 4)
+        OP(FLOAT, load_float)
+        OP(BINFLOAT, load_binfloat)
+        OP(BINBYTES, load_binbytes)
+        OP(SHORT_BINBYTES, load_short_binbytes)
+        OP(BINSTRING, load_binstring)
+        OP(SHORT_BINSTRING, load_short_binstring)
+        OP(STRING, load_string)
+        OP(UNICODE, load_unicode)
+        OP(BINUNICODE, load_binunicode)
+        OP_ARG(EMPTY_TUPLE, load_counted_tuple, 0)
+        OP_ARG(TUPLE1, load_counted_tuple, 1)
+        OP_ARG(TUPLE2, load_counted_tuple, 2)
+        OP_ARG(TUPLE3, load_counted_tuple, 3)
+        OP(TUPLE, load_tuple)
+        OP(EMPTY_LIST, load_empty_list)
+        OP(LIST, load_list)
+        OP(EMPTY_DICT, load_empty_dict)
+        OP(DICT, load_dict)
+        OP(OBJ, load_obj)
+        OP(INST, load_inst)
+        OP(NEWOBJ, load_newobj)
+        OP(GLOBAL, load_global)
+        OP(APPEND, load_append)
+        OP(APPENDS, load_appends)
+        OP(BUILD, load_build)
+        OP(DUP, load_dup)
+        OP(BINGET, load_binget)
+        OP(LONG_BINGET, load_long_binget)
+        OP(GET, load_get)
+        OP(MARK, load_mark)
+        OP(BINPUT, load_binput)
+        OP(LONG_BINPUT, load_long_binput)
+        OP(PUT, load_put)
+        OP(POP, load_pop)
+        OP(POP_MARK, load_pop_mark)
+        OP(SETITEM, load_setitem)
+        OP(SETITEMS, load_setitems)
+        OP(PERSID, load_persid)
+        OP(BINPERSID, load_binpersid)
+        OP(REDUCE, load_reduce)
+        OP(PROTO, load_proto)
+        OP_ARG(EXT1, load_extension, 1)
+        OP_ARG(EXT2, load_extension, 2)
+        OP_ARG(EXT4, load_extension, 4)
+        OP_ARG(NEWTRUE, load_bool, Py_True)
+        OP_ARG(NEWFALSE, load_bool, Py_False)
+
+        case STOP:
+            break;
+
+        case '\0':
+            PyErr_SetNone(PyExc_EOFError);
+            return NULL;
+
+        default:
+            PyErr_Format(UnpicklingError,
+                         "invalid load key, '%c'.", s[0]);
+            return NULL;
+        }
+
+        break;                  /* and we are done! */
+    }
+
+    /* XXX: It is not clear what this is actually for. */
+    if ((err = PyErr_Occurred())) {
+        if (err == PyExc_EOFError) {
+            PyErr_SetNone(PyExc_EOFError);
+        }
+        return NULL;
+    }
+
+    PDATA_POP(self->stack, value);
+    return value;
+}
+
+PyDoc_STRVAR(Unpickler_load_doc,
+"load() -> object. Load a pickle."
+"\n"
+"Read a pickled object representation from the open file object given in\n"
+"the constructor, and return the reconstituted object hierarchy specified\n"
+"therein.\n");
+
+static PyObject *
+Unpickler_load(UnpicklerObject *self)
+{
+    /* Check whether the Unpickler was initialized correctly. This prevents
+       segfaulting if a subclass overridden __init__ with a function that does
+       not call Unpickler.__init__(). Here, we simply ensure that self->read
+       is not NULL. */
+    if (self->read == NULL) {
+        PyErr_Format(UnpicklingError, 
+                     "Unpickler.__init__() was not called by %s.__init__()",
+                     Py_TYPE(self)->tp_name);
+        return NULL;
+    }
+
+    return load(self);
+}
+
+/* The name of find_class() is misleading. In newer pickle protocols, this
+   function is used for loading any global (i.e., functions), not just
+   classes. The name is kept only for backward compatibility. */
+
+PyDoc_STRVAR(Unpickler_find_class_doc,
+"find_class(module_name, global_name) -> object.\n"
+"\n"
+"Return an object from a specified module, importing the module if\n"
+"necessary.  Subclasses may override this method (e.g. to restrict\n"
+"unpickling of arbitrary classes and functions).\n"
+"\n"
+"This method is called whenever a class or a function object is\n"
+"needed.  Both arguments passed are str objects.\n");
+
+static PyObject *
+Unpickler_find_class(UnpicklerObject *self, PyObject *args)
+{
+    PyObject *global;
+    PyObject *modules_dict;
+    PyObject *module;
+    PyObject *module_name, *global_name;
+
+    if (!PyArg_UnpackTuple(args, "find_class", 2, 2,
+                           &module_name, &global_name))
+        return NULL;
+
+    modules_dict = PySys_GetObject("modules");
+    if (modules_dict == NULL)
+        return NULL;
+
+    module = PyDict_GetItem(modules_dict, module_name);
+    if (module == NULL) {
+        module = PyImport_Import(module_name);
+        if (module == NULL)
+            return NULL;
+        global = PyObject_GetAttr(module, global_name);
+        Py_DECREF(module);
+    }
+    else { 
+        global = PyObject_GetAttr(module, global_name);
+    }
+    return global;
+}
+
+static struct PyMethodDef Unpickler_methods[] = {
+    {"load", (PyCFunction)Unpickler_load, METH_NOARGS,
+     Unpickler_load_doc},
+    {"find_class", (PyCFunction)Unpickler_find_class, METH_VARARGS,
+     Unpickler_find_class_doc},
+    {NULL, NULL}                /* sentinel */
+};
+
+static void
+Unpickler_dealloc(UnpicklerObject *self)
+{
+    PyObject_GC_UnTrack((PyObject *)self);
+    Py_XDECREF(self->readline);
+    Py_XDECREF(self->read);
+    Py_XDECREF(self->memo);
+    Py_XDECREF(self->stack);
+    Py_XDECREF(self->pers_func);
+    Py_XDECREF(self->arg);
+    Py_XDECREF(self->last_string);
+
+    PyMem_Free(self->marks);
+    free(self->encoding);
+    free(self->errors);
+
+    Py_TYPE(self)->tp_free((PyObject *)self);
+}
+
+static int
+Unpickler_traverse(UnpicklerObject *self, visitproc visit, void *arg)
+{
+    Py_VISIT(self->readline);
+    Py_VISIT(self->read);
+    Py_VISIT(self->memo);
+    Py_VISIT(self->stack);
+    Py_VISIT(self->pers_func);
+    Py_VISIT(self->arg);
+    Py_VISIT(self->last_string);
+    return 0;
+}
+
+static int
+Unpickler_clear(UnpicklerObject *self)
+{
+    Py_CLEAR(self->readline);
+    Py_CLEAR(self->read);
+    Py_CLEAR(self->memo);
+    Py_CLEAR(self->stack);
+    Py_CLEAR(self->pers_func);
+    Py_CLEAR(self->arg);
+    Py_CLEAR(self->last_string);
+
+    PyMem_Free(self->marks);
+    self->marks = NULL;
+    free(self->encoding);
+    self->encoding = NULL;
+    free(self->errors);
+    self->errors = NULL;
+
+    return 0;
+}
+
+PyDoc_STRVAR(Unpickler_doc,
+"Unpickler(file, *, encoding='ASCII', errors='strict')"
+"\n"
+"This takes a binary file for reading a pickle data stream.\n"
+"\n"
+"The protocol version of the pickle is detected automatically, so no\n"
+"proto argument is needed.\n"
+"\n"
+"The file-like object must have two methods, a read() method\n"
+"that takes an integer argument, and a readline() method that\n"
+"requires no arguments.  Both methods should return bytes.\n"
+"Thus file-like object can be a binary file object opened for\n"
+"reading, a BytesIO object, or any other custom object that\n"
+"meets this interface.\n"
+"\n"
+"Optional keyword arguments are encoding and errors, which are\n"
+"used to decode 8-bit string instances pickled by Python 2.x.\n"
+"These default to 'ASCII' and 'strict', respectively.\n");
+
+static int
+Unpickler_init(UnpicklerObject *self, PyObject *args, PyObject *kwds)
+{
+    static char *kwlist[] = {"file", "encoding", "errors", 0};
+    PyObject *file;
+    char *encoding = NULL;
+    char *errors = NULL;
+
+    /* XXX: That is an horrible error message. But, I don't know how to do
+       better... */
+    if (Py_SIZE(args) != 1) {
+        PyErr_Format(PyExc_TypeError,
+                     "%s takes exactly one positional argument (%zd given)",
+                     Py_TYPE(self)->tp_name, Py_SIZE(args));
+        return -1;
+    }
+
+    /* Arguments parsing needs to be done in the __init__() method to allow
+       subclasses to define their own __init__() method, which may (or may
+       not) support Unpickler arguments. However, this means we need to be
+       extra careful in the other Unpickler methods, since a subclass could
+       forget to call Unpickler.__init__() thus breaking our internal
+       invariants. */
+    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|ss:Unpickler", kwlist,
+                                     &file, &encoding, &errors))
+        return -1;
+
+    /* In case of multiple __init__() calls, clear previous content. */
+    if (self->read != NULL)
+        (void)Unpickler_clear(self);
+
+    self->read = PyObject_GetAttrString(file, "read");
+    self->readline = PyObject_GetAttrString(file, "readline");
+    if (self->readline == NULL || self->read == NULL)
+        return -1;
+
+    if (encoding == NULL)
+        encoding = "ASCII";
+    if (errors == NULL)
+        errors = "strict";
+
+    self->encoding = strdup(encoding);
+    self->errors = strdup(errors);
+    if (self->encoding == NULL || self->errors == NULL) {
+        PyErr_NoMemory();
+        return -1;
+    }
+
+    if (PyObject_HasAttrString((PyObject *)self, "persistent_load")) {
+        self->pers_func = PyObject_GetAttrString((PyObject *)self,
+                                                 "persistent_load");
+        if (self->pers_func == NULL)
+            return -1;
+    }
+    else {
+        self->pers_func = NULL;
+    }
+
+    self->stack = (Pdata *)Pdata_New();
+    if (self->stack == NULL)
+        return -1;
+
+    self->memo = PyDict_New();
+    if (self->memo == NULL)
+        return -1;
+
+    return 0;
+}
+
+static PyObject *
+Unpickler_get_memo(UnpicklerObject *self)
+{
+    if (self->memo == NULL)
+        PyErr_SetString(PyExc_AttributeError, "memo");
+    else
+        Py_INCREF(self->memo);
+    return self->memo;
+}
+
+static int
+Unpickler_set_memo(UnpicklerObject *self, PyObject *value)
+{
+    PyObject *tmp;
+
+    if (value == NULL) {
+        PyErr_SetString(PyExc_TypeError,
+                        "attribute deletion is not supported");
+        return -1;
+    }
+    if (!PyDict_Check(value)) {
+        PyErr_SetString(PyExc_TypeError, "memo must be a dictionary");
+        return -1;
+    }
+
+    tmp = self->memo;
+    Py_INCREF(value);
+    self->memo = value;
+    Py_XDECREF(tmp);
+
+    return 0;
+}
+
+static PyObject *
+Unpickler_get_persload(UnpicklerObject *self)
+{
+    if (self->pers_func == NULL)
+        PyErr_SetString(PyExc_AttributeError, "persistent_load");
+    else
+        Py_INCREF(self->pers_func);
+    return self->pers_func;
+}
+
+static int
+Unpickler_set_persload(UnpicklerObject *self, PyObject *value)
+{
+    PyObject *tmp;
+
+    if (value == NULL) {
+        PyErr_SetString(PyExc_TypeError,
+                        "attribute deletion is not supported");
+        return -1;
+    }
+    if (!PyCallable_Check(value)) {
+        PyErr_SetString(PyExc_TypeError,
+                        "persistent_load must be a callable taking "
+                        "one argument");
+        return -1;
+    }
+
+    tmp = self->pers_func;
+    Py_INCREF(value);
+    self->pers_func = value;
+    Py_XDECREF(tmp);      /* self->pers_func can be NULL, so be careful. */
+
+    return 0;
+}
+
+static PyGetSetDef Unpickler_getsets[] = {
+    {"memo", (getter)Unpickler_get_memo, (setter)Unpickler_set_memo},
+    {"persistent_load", (getter)Unpickler_get_persload,
+                        (setter)Unpickler_set_persload},
+    {NULL}
+};
+
+static PyTypeObject Unpickler_Type = {
+    PyVarObject_HEAD_INIT(NULL, 0)
+    "_pickle.Unpickler",                /*tp_name*/
+    sizeof(UnpicklerObject),            /*tp_basicsize*/
+    0,                                  /*tp_itemsize*/
+    (destructor)Unpickler_dealloc,      /*tp_dealloc*/
+    0,                                  /*tp_print*/
+    0,                                  /*tp_getattr*/
+    0,	                                /*tp_setattr*/
+    0,                                  /*tp_compare*/
+    0,                                  /*tp_repr*/
+    0,                                  /*tp_as_number*/
+    0,                                  /*tp_as_sequence*/
+    0,                                  /*tp_as_mapping*/
+    0,                                  /*tp_hash*/
+    0,                                  /*tp_call*/
+    0,                                  /*tp_str*/
+    0,                                  /*tp_getattro*/
+    0,                                  /*tp_setattro*/
+    0,                                  /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
+    Unpickler_doc,                      /*tp_doc*/
+    (traverseproc)Unpickler_traverse,   /*tp_traverse*/
+    (inquiry)Unpickler_clear,           /*tp_clear*/
+    0,                                  /*tp_richcompare*/
+    0,                                  /*tp_weaklistoffset*/
+    0,                                  /*tp_iter*/
+    0,                                  /*tp_iternext*/
+    Unpickler_methods,                  /*tp_methods*/
+    0,                                  /*tp_members*/
+    Unpickler_getsets,                  /*tp_getset*/
+    0,                                  /*tp_base*/
+    0,                                  /*tp_dict*/
+    0,                                  /*tp_descr_get*/
+    0,                                  /*tp_descr_set*/
+    0,                                  /*tp_dictoffset*/
+    (initproc)Unpickler_init,           /*tp_init*/
+    PyType_GenericAlloc,                /*tp_alloc*/
+    PyType_GenericNew,                  /*tp_new*/
+    PyObject_GC_Del,                    /*tp_free*/
+    0,                                  /*tp_is_gc*/
+};
+
+static int
+init_stuff(void)
+{
+    PyObject *copyreg;
+
+    copyreg = PyImport_ImportModule("copyreg");
+    if (!copyreg)
+        return -1;
+
+    dispatch_table = PyObject_GetAttrString(copyreg, "dispatch_table");
+    if (!dispatch_table)
+        goto error;
+
+    extension_registry = \
+        PyObject_GetAttrString(copyreg, "_extension_registry");
+    if (!extension_registry)
+        goto error;
+
+    inverted_registry = PyObject_GetAttrString(copyreg, "_inverted_registry");
+    if (!inverted_registry)
+        goto error;
+
+    extension_cache = PyObject_GetAttrString(copyreg, "_extension_cache");
+    if (!extension_cache)
+        goto error;
+
+    Py_DECREF(copyreg);
+
+    empty_tuple = PyTuple_New(0);
+    if (empty_tuple == NULL)
+        return -1;
+
+    two_tuple = PyTuple_New(2);
+    if (two_tuple == NULL)
+        return -1;
+    /* We use this temp container with no regard to refcounts, or to
+     * keeping containees alive.  Exempt from GC, because we don't
+     * want anything looking at two_tuple() by magic.
+     */
+    PyObject_GC_UnTrack(two_tuple);
+
+    return 0;
+
+  error:
+    Py_DECREF(copyreg);
+    return -1;
+}
+
+static struct PyModuleDef _picklemodule = {
+    PyModuleDef_HEAD_INIT,
+    "_pickle",
+    pickle_module_doc,
+    -1,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL
+};
+
+PyMODINIT_FUNC
+PyInit__pickle(void)
+{
+    PyObject *m;
+
+    if (PyType_Ready(&Unpickler_Type) < 0)
+        return NULL;
+    if (PyType_Ready(&Pickler_Type) < 0)
+        return NULL;
+    if (PyType_Ready(&Pdata_Type) < 0)
+        return NULL;
+
+    /* Create the module and add the functions. */
+    m = PyModule_Create(&_picklemodule);
+    if (m == NULL)
+        return NULL;
+
+    if (PyModule_AddObject(m, "Pickler", (PyObject *)&Pickler_Type) < 0)
+        return NULL;
+    if (PyModule_AddObject(m, "Unpickler", (PyObject *)&Unpickler_Type) < 0)
+        return NULL;
+
+    /* Initialize the exceptions. */
+    PickleError = PyErr_NewException("_pickle.PickleError", NULL, NULL);
+    if (PickleError == NULL)
+        return NULL;
+    PicklingError = \
+        PyErr_NewException("_pickle.PicklingError", PickleError, NULL);
+    if (PicklingError == NULL)
+        return NULL;
+    UnpicklingError = \
+        PyErr_NewException("_pickle.UnpicklingError", PickleError, NULL);
+    if (UnpicklingError == NULL)
+        return NULL;
+
+    if (PyModule_AddObject(m, "PickleError", PickleError) < 0)
+        return NULL;
+    if (PyModule_AddObject(m, "PicklingError", PicklingError) < 0)
+        return NULL;
+    if (PyModule_AddObject(m, "UnpicklingError", UnpicklingError) < 0)
+        return NULL;
+
+    if (init_stuff() < 0)
+        return NULL;
+
+    return m;
+}

Modified: python/branches/py3k/setup.py
==============================================================================
--- python/branches/py3k/setup.py	(original)
+++ python/branches/py3k/setup.py	Thu Jun 12 00:43:06 2008
@@ -422,6 +422,8 @@
         exts.append( Extension("_functools", ["_functoolsmodule.c"]) )
         # Memory-based IO accelerator modules
         exts.append( Extension("_bytesio", ["_bytesio.c"]) )
+        # C-optimized pickle replacement
+        exts.append( Extension("_pickle", ["_pickle.c"]) )
         # atexit
         exts.append( Extension("atexit", ["atexitmodule.c"]) )
         # _json speedups

From python-3000-checkins at python.org  Thu Jun 12 00:55:42 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Thu, 12 Jun 2008 00:55:42 +0200 (CEST)
Subject: [Python-3000-checkins] r64153 -
	python/branches/py3k/Lib/test/test_ssl.py
Message-ID: <20080611225542.1A9B01E4005@bag.python.org>

Author: benjamin.peterson
Date: Thu Jun 12 00:55:41 2008
New Revision: 64153

Log:
fix test_ssl


Modified:
   python/branches/py3k/Lib/test/test_ssl.py

Modified: python/branches/py3k/Lib/test/test_ssl.py
==============================================================================
--- python/branches/py3k/Lib/test/test_ssl.py	(original)
+++ python/branches/py3k/Lib/test/test_ssl.py	Thu Jun 12 00:55:41 2008
@@ -201,7 +201,7 @@
                 self.sock.setblocking(1)
                 self.sslconn = None
                 threading.Thread.__init__(self)
-                self.setDaemon(True)
+                self.set_daemon(True)
 
             def wrap_conn (self):
                 try:
@@ -317,7 +317,7 @@
             self.flag = None
             self.active = False
             threading.Thread.__init__(self)
-            self.setDaemon(False)
+            self.set_daemon(False)
 
         def start (self, flag=None):
             self.flag = flag
@@ -473,7 +473,7 @@
             self.server = self.HTTPSServer(
                 (HOST, self.port), self.RootedHTTPRequestHandler, certfile)
             threading.Thread.__init__(self)
-            self.setDaemon(True)
+            self.set_daemon(True)
 
         def __str__(self):
             return "<%s %s>" % (self.__class__.__name__, self.server)
@@ -558,7 +558,7 @@
             self.port = support.find_unused_port()
             self.server = self.EchoServer(self.port, certfile)
             threading.Thread.__init__(self)
-            self.setDaemon(True)
+            self.set_daemon(True)
 
         def __str__(self):
             return "<%s %s>" % (self.__class__.__name__, self.server)

From python-3000-checkins at python.org  Thu Jun 12 00:58:37 2008
From: python-3000-checkins at python.org (alexandre.vassalotti)
Date: Thu, 12 Jun 2008 00:58:37 +0200 (CEST)
Subject: [Python-3000-checkins] r64154 - in python/branches/py3k: Lib/io.py
	Lib/test/test_memoryio.py Lib/test/test_minidom.py
	Lib/test/test_uu.py Lib/xml/dom/minidom.py Misc/NEWS
	Modules/_stringio.c setup.py
Message-ID: <20080611225837.58D711E4005@bag.python.org>

Author: alexandre.vassalotti
Date: Thu Jun 12 00:58:36 2008
New Revision: 64154

Log:
Issue 2918: Merge StringIO and cStringIO.



Added:
   python/branches/py3k/Modules/_stringio.c   (contents, props changed)
Modified:
   python/branches/py3k/Lib/io.py
   python/branches/py3k/Lib/test/test_memoryio.py
   python/branches/py3k/Lib/test/test_minidom.py
   python/branches/py3k/Lib/test/test_uu.py
   python/branches/py3k/Lib/xml/dom/minidom.py
   python/branches/py3k/Misc/NEWS
   python/branches/py3k/setup.py

Modified: python/branches/py3k/Lib/io.py
==============================================================================
--- python/branches/py3k/Lib/io.py	(original)
+++ python/branches/py3k/Lib/io.py	Thu Jun 12 00:58:36 2008
@@ -1769,20 +1769,20 @@
     def newlines(self):
         return self._decoder.newlines if self._decoder else None
 
-class StringIO(TextIOWrapper):
-    """An in-memory stream for text. The initial_value argument sets the
-    value of object. The other arguments are like those of TextIOWrapper's
-    constructor.
+class _StringIO(TextIOWrapper):
+    """Text I/O implementation using an in-memory buffer.
+
+    The initial_value argument sets the value of object.  The newline
+    argument is like the one of TextIOWrapper's constructor.
     """
 
     # XXX This is really slow, but fully functional
 
-    def __init__(self, initial_value="", encoding="utf-8",
-                 errors="strict", newline="\n"):
-        super(StringIO, self).__init__(BytesIO(),
-                                       encoding=encoding,
-                                       errors=errors,
-                                       newline=newline)
+    def __init__(self, initial_value="", newline="\n"):
+        super(_StringIO, self).__init__(BytesIO(),
+                                        encoding="utf-8",
+                                        errors="strict",
+                                        newline=newline)
         if initial_value:
             if not isinstance(initial_value, str):
                 initial_value = str(initial_value)
@@ -1792,3 +1792,271 @@
     def getvalue(self):
         self.flush()
         return self.buffer.getvalue().decode(self._encoding, self._errors)
+
+try:
+    import _stringio
+
+    # This subclass is a reimplementation of the TextIOWrapper
+    # interface without any of its text decoding facilities. All the
+    # stored data is manipulated with the efficient
+    # _stringio._StringIO extension type. Also, the newline decoding
+    # mechanism of IncrementalNewlineDecoder is reimplemented here for
+    # efficiency. Doing otherwise, would require us to implement a
+    # fake decoder which would add an additional and unnecessary layer
+    # on top of the _StringIO methods.
+
+    class StringIO(_stringio._StringIO, TextIOBase):
+        """Text I/O implementation using an in-memory buffer.
+
+        The initial_value argument sets the value of object.  The newline
+        argument is like the one of TextIOWrapper's constructor.
+        """
+
+        _CHUNK_SIZE = 4096
+
+        def __init__(self, initial_value="", newline="\n"):
+            if newline not in (None, "", "\n", "\r", "\r\n"):
+                raise ValueError("illegal newline value: %r" % (newline,))
+
+            self._readuniversal = not newline
+            self._readtranslate = newline is None
+            self._readnl = newline
+            self._writetranslate = newline != ""
+            self._writenl = newline or os.linesep
+            self._pending = ""
+            self._seennl = 0
+
+            # Reset the buffer first, in case __init__ is called
+            # multiple times.
+            self.truncate(0)
+            if initial_value is None:
+                initial_value = ""
+            self.write(initial_value)
+            self.seek(0)
+
+        @property
+        def buffer(self):
+            raise UnsupportedOperation("%s.buffer attribute is unsupported" %
+                                       self.__class__.__name__)
+
+        def _decode_newlines(self, input, final=False):
+            # decode input (with the eventual \r from a previous pass)
+            if self._pending:
+                input = self._pending + input
+
+            # retain last \r even when not translating data:
+            # then readline() is sure to get \r\n in one pass
+            if input.endswith("\r") and not final:
+                input = input[:-1]
+                self._pending = "\r"
+            else:
+                self._pending = ""
+
+            # Record which newlines are read
+            crlf = input.count('\r\n')
+            cr = input.count('\r') - crlf
+            lf = input.count('\n') - crlf
+            self._seennl |= (lf and self._LF) | (cr and self._CR) \
+                         | (crlf and self._CRLF)
+
+            if self._readtranslate:
+                if crlf:
+                    output = input.replace("\r\n", "\n")
+                if cr:
+                    output = input.replace("\r", "\n")
+            else:
+                output = input
+
+            return output
+
+        def writable(self):
+            return True
+
+        def readable(self):
+            return True
+
+        def seekable(self):
+            return True
+
+        _read = _stringio._StringIO.read
+        _write = _stringio._StringIO.write
+        _tell = _stringio._StringIO.tell
+        _seek = _stringio._StringIO.seek
+        _truncate = _stringio._StringIO.truncate
+        _getvalue = _stringio._StringIO.getvalue
+
+        def getvalue(self) -> str:
+            """Retrieve the entire contents of the object."""
+            if self.closed:
+                raise ValueError("read on closed file")
+            return self._getvalue()
+
+        def write(self, s: str) -> int:
+            """Write string s to file.
+
+            Returns the number of characters written.
+            """
+            if self.closed:
+                raise ValueError("write to closed file")
+            if not isinstance(s, str):
+                raise TypeError("can't write %s to text stream" %
+                                s.__class__.__name__)
+            length = len(s)
+            if self._writetranslate and self._writenl != "\n":
+                s = s.replace("\n", self._writenl)
+            self._pending = ""
+            self._write(s)
+            return length
+
+        def read(self, n: int = None) -> str:
+            """Read at most n characters, returned as a string.
+
+            If the argument is negative or omitted, read until EOF
+            is reached. Return an empty string at EOF.
+            """
+            if self.closed:
+                raise ValueError("read to closed file")
+            if n is None:
+                n = -1
+            res = self._pending
+            if n < 0:
+                res += self._decode_newlines(self._read(), True)
+                self._pending = ""
+                return res
+            else:
+                res = self._decode_newlines(self._read(n), True)
+                self._pending = res[n:]
+                return res[:n]
+
+        def tell(self) -> int:
+            """Tell the current file position."""
+            if self.closed:
+                raise ValueError("tell from closed file")
+            if self._pending:
+                return self._tell() - len(self._pending)
+            else:
+                return self._tell()
+
+        def seek(self, pos: int = None, whence: int = 0) -> int:
+            """Change stream position.
+
+            Seek to character offset pos relative to position indicated by whence:
+                0  Start of stream (the default).  pos should be >= 0;
+                1  Current position - pos must be 0;
+                2  End of stream - pos must be 0.
+            Returns the new absolute position.
+            """
+            if self.closed:
+                raise ValueError("seek from closed file")
+            self._pending = ""
+            return self._seek(pos, whence)
+
+        def truncate(self, pos: int = None) -> int:
+            """Truncate size to pos.
+
+            The pos argument defaults to the current file position, as
+            returned by tell().  Imply an absolute seek to pos.
+            Returns the new absolute position.
+            """
+            if self.closed:
+                raise ValueError("truncate from closed file")
+            self._pending = ""
+            return self._truncate(pos)
+
+        def readline(self, limit: int = None) -> str:
+            if self.closed:
+                raise ValueError("read from closed file")
+            if limit is None:
+                limit = -1
+            if limit >= 0:
+                # XXX: Hack to support limit argument, for backwards
+                # XXX  compatibility
+                line = self.readline()
+                if len(line) <= limit:
+                    return line
+                line, self._pending = line[:limit], line[limit:] + self._pending
+                return line
+
+            line = self._pending
+            self._pending = ""
+
+            start = 0
+            pos = endpos = None
+            while True:
+                if self._readtranslate:
+                    # Newlines are already translated, only search for \n
+                    pos = line.find('\n', start)
+                    if pos >= 0:
+                        endpos = pos + 1
+                        break
+                    else:
+                        start = len(line)
+
+                elif self._readuniversal:
+                    # Universal newline search. Find any of \r, \r\n, \n
+                    # The decoder ensures that \r\n are not split in two pieces
+
+                    # In C we'd look for these in parallel of course.
+                    nlpos = line.find("\n", start)
+                    crpos = line.find("\r", start)
+                    if crpos == -1:
+                        if nlpos == -1:
+                            # Nothing found
+                            start = len(line)
+                        else:
+                            # Found \n
+                            endpos = nlpos + 1
+                            break
+                    elif nlpos == -1:
+                        # Found lone \r
+                        endpos = crpos + 1
+                        break
+                    elif nlpos < crpos:
+                        # Found \n
+                        endpos = nlpos + 1
+                        break
+                    elif nlpos == crpos + 1:
+                        # Found \r\n
+                        endpos = crpos + 2
+                        break
+                    else:
+                        # Found \r
+                        endpos = crpos + 1
+                        break
+                else:
+                    # non-universal
+                    pos = line.find(self._readnl)
+                    if pos >= 0:
+                        endpos = pos + len(self._readnl)
+                        break
+
+                # No line ending seen yet - get more data
+                more_line = self.read(self._CHUNK_SIZE)
+                if more_line:
+                    line += more_line
+                else:
+                    # end of file
+                    return line
+
+            self._pending = line[endpos:]
+            return line[:endpos]
+
+        _LF = 1
+        _CR = 2
+        _CRLF = 4
+
+        @property
+        def newlines(self):
+            return (None,
+                    "\n",
+                    "\r",
+                    ("\r", "\n"),
+                    "\r\n",
+                    ("\n", "\r\n"),
+                    ("\r", "\r\n"),
+                    ("\r", "\n", "\r\n")
+                   )[self._seennl]
+
+
+except ImportError:
+    StringIO = _StringIO

Modified: python/branches/py3k/Lib/test/test_memoryio.py
==============================================================================
--- python/branches/py3k/Lib/test/test_memoryio.py	(original)
+++ python/branches/py3k/Lib/test/test_memoryio.py	Thu Jun 12 00:58:36 2008
@@ -10,7 +10,7 @@
 import sys
 
 try:
-    import _bytesio
+    import _bytesio, _stringio
     has_c_implementation = True
 except ImportError:
     has_c_implementation = False
@@ -373,7 +373,7 @@
 
 class PyStringIOTest(MemoryTestMixin, unittest.TestCase):
     buftype = str
-    ioclass = io.StringIO
+    ioclass = io._StringIO
     EOF = ""
 
     def test_relative_seek(self):
@@ -404,10 +404,14 @@
     class CBytesIOTest(PyBytesIOTest):
         ioclass = io.BytesIO
 
+    class CStringIOTest(PyStringIOTest):
+        ioclass = io.StringIO
+
+
 def test_main():
     tests = [PyBytesIOTest, PyStringIOTest]
     if has_c_implementation:
-        tests.extend([CBytesIOTest])
+        tests.extend([CBytesIOTest, CStringIOTest])
     support.run_unittest(*tests)
 
 if __name__ == '__main__':

Modified: python/branches/py3k/Lib/test/test_minidom.py
==============================================================================
--- python/branches/py3k/Lib/test/test_minidom.py	(original)
+++ python/branches/py3k/Lib/test/test_minidom.py	Thu Jun 12 00:58:36 2008
@@ -3,7 +3,6 @@
 import os
 import sys
 import pickle
-from io import StringIO
 from test.support import verbose, run_unittest, TestSkipped
 import unittest
 
@@ -80,7 +79,7 @@
         self.confirm(t == s, "looking for %s, found %s" % (repr(s), repr(t)))
 
     def testParseFromFile(self):
-        dom = parse(StringIO(open(tstfile).read()))
+        dom = parse(open(tstfile))
         dom.unlink()
         self.confirm(isinstance(dom, Document))
 

Modified: python/branches/py3k/Lib/test/test_uu.py
==============================================================================
--- python/branches/py3k/Lib/test/test_uu.py	(original)
+++ python/branches/py3k/Lib/test/test_uu.py	Thu Jun 12 00:58:36 2008
@@ -17,6 +17,32 @@
 M5&AE('-M;V]T:\"US8V%L960@<'ET:&]N(&-R97!T(&]V97(@=&AE('-L965P
 (:6YG(&1O9PH """
 
+# Stolen from io.py
+class FakeIO(io.TextIOWrapper):
+    """Text I/O implementation using an in-memory buffer.
+
+    Can be a used as a drop-in replacement for sys.stdin and sys.stdout.
+    """
+
+    # XXX This is really slow, but fully functional
+
+    def __init__(self, initial_value="", encoding="utf-8",
+                 errors="strict", newline="\n"):
+        super(FakeIO, self).__init__(io.BytesIO(),
+                                     encoding=encoding,
+                                     errors=errors,
+                                     newline=newline)
+        if initial_value:
+            if not isinstance(initial_value, str):
+                initial_value = str(initial_value)
+            self.write(initial_value)
+            self.seek(0)
+
+    def getvalue(self):
+        self.flush()
+        return self.buffer.getvalue().decode(self._encoding, self._errors)
+
+
 def encodedtextwrapped(mode, filename):
     return (bytes("begin %03o %s\n" % (mode, filename), "ascii") +
             encodedtext + b"\n \nend\n")
@@ -76,15 +102,15 @@
         sys.stdout = self.stdout
 
     def test_encode(self):
-        sys.stdin = io.StringIO(plaintext.decode("ascii"))
-        sys.stdout = io.StringIO()
+        sys.stdin = FakeIO(plaintext.decode("ascii"))
+        sys.stdout = FakeIO()
         uu.encode("-", "-", "t1", 0o666)
         self.assertEqual(sys.stdout.getvalue(),
                          encodedtextwrapped(0o666, "t1").decode("ascii"))
 
     def test_decode(self):
-        sys.stdin = io.StringIO(encodedtextwrapped(0o666, "t1").decode("ascii"))
-        sys.stdout = io.StringIO()
+        sys.stdin = FakeIO(encodedtextwrapped(0o666, "t1").decode("ascii"))
+        sys.stdout = FakeIO()
         uu.decode("-", "-")
         stdout = sys.stdout
         sys.stdout = self.stdout

Modified: python/branches/py3k/Lib/xml/dom/minidom.py
==============================================================================
--- python/branches/py3k/Lib/xml/dom/minidom.py	(original)
+++ python/branches/py3k/Lib/xml/dom/minidom.py	Thu Jun 12 00:58:36 2008
@@ -14,6 +14,7 @@
  * SAX 2 namespaces
 """
 
+import codecs
 import io
 import xml.dom
 
@@ -49,16 +50,16 @@
         # indent = the indentation string to prepend, per level
         # newl = the newline string to append
         use_encoding = "utf-8" if encoding is None else encoding
-        writer = io.StringIO(encoding=use_encoding)
+        writer = codecs.getwriter(use_encoding)(io.BytesIO())
         if self.nodeType == Node.DOCUMENT_NODE:
             # Can pass encoding only to document, to put it into XML header
             self.writexml(writer, "", indent, newl, encoding)
         else:
             self.writexml(writer, "", indent, newl)
         if encoding is None:
-            return writer.getvalue()
+            return writer.stream.getvalue().decode(use_encoding)
         else:
-            return writer.buffer.getvalue()
+            return writer.stream.getvalue()
 
     def hasChildNodes(self):
         if self.childNodes:

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Thu Jun 12 00:58:36 2008
@@ -78,6 +78,8 @@
 Library
 -------
 
+- Added C optimized implementation of io.StringIO.
+
 - The ``pickle`` module is now automatically use an optimized C
   implementation of Pickler and Unpickler when available. The
   ``cPickle`` module is no longer needed.

Added: python/branches/py3k/Modules/_stringio.c
==============================================================================
--- (empty file)
+++ python/branches/py3k/Modules/_stringio.c	Thu Jun 12 00:58:36 2008
@@ -0,0 +1,379 @@
+#include "Python.h"
+
+/* This module is a stripped down version of _bytesio.c with a Py_UNICODE
+   buffer. Most of the functionality is provided by subclassing _StringIO. */
+
+
+typedef struct {
+    PyObject_HEAD
+    Py_UNICODE *buf;
+    Py_ssize_t pos;
+    Py_ssize_t string_size;
+    size_t buf_size;
+} StringIOObject;
+
+
+/* Internal routine for changing the size, in terms of characters, of the
+   buffer of StringIO objects.  The caller should ensure that the 'size'
+   argument is non-negative.  Returns 0 on success, -1 otherwise. */
+static int
+resize_buffer(StringIOObject *self, size_t size)
+{
+    /* Here, unsigned types are used to avoid dealing with signed integer
+       overflow, which is undefined in C. */
+    size_t alloc = self->buf_size;
+    Py_UNICODE *new_buf = NULL;
+
+    assert(self->buf != NULL);
+
+    /* For simplicity, stay in the range of the signed type. Anyway, Python
+       doesn't allow strings to be longer than this. */
+    if (size > PY_SSIZE_T_MAX)
+        goto overflow;
+
+    if (size < alloc / 2) {
+        /* Major downsize; resize down to exact size. */
+        alloc = size + 1;
+    }
+    else if (size < alloc) {
+        /* Within allocated size; quick exit */
+        return 0;
+    }
+    else if (size <= alloc * 1.125) {
+        /* Moderate upsize; overallocate similar to list_resize() */
+        alloc = size + (size >> 3) + (size < 9 ? 3 : 6);
+    }
+    else {
+        /* Major upsize; resize up to exact size */
+        alloc = size + 1;
+    }
+
+    if (alloc > ((size_t)-1) / sizeof(Py_UNICODE))
+        goto overflow;
+    new_buf = (Py_UNICODE *)PyMem_Realloc(self->buf,
+                                          alloc * sizeof(Py_UNICODE));
+    if (new_buf == NULL) {
+        PyErr_NoMemory();
+        return -1;
+    }
+    self->buf_size = alloc;
+    self->buf = new_buf;
+
+    return 0;
+
+  overflow:
+    PyErr_SetString(PyExc_OverflowError,
+                    "new buffer size too large");
+    return -1;
+}
+
+/* Internal routine for writing a string of characters to the buffer of a
+   StringIO object. Returns the number of bytes wrote, or -1 on error. */
+static Py_ssize_t
+write_str(StringIOObject *self, const Py_UNICODE *str, Py_ssize_t len)
+{
+    assert(self->buf != NULL);
+    assert(self->pos >= 0);
+    assert(len >= 0);
+
+    /* This overflow check is not strictly necessary. However, it avoids us to
+       deal with funky things like comparing an unsigned and a signed
+       integer. */
+    if (self->pos > PY_SSIZE_T_MAX - len) {
+        PyErr_SetString(PyExc_OverflowError,
+                        "new position too large");
+        return -1;
+    }
+    if (self->pos + len > self->string_size) {
+        if (resize_buffer(self, self->pos + len) < 0)
+            return -1;
+    }
+
+    if (self->pos > self->string_size) {
+        /* In case of overseek, pad with null bytes the buffer region between
+           the end of stream and the current position.
+
+          0   lo      string_size                           hi
+          |   |<---used--->|<----------available----------->|
+          |   |            <--to pad-->|<---to write--->    |
+          0   buf                   positon
+
+        */
+        memset(self->buf + self->string_size, '\0',
+               (self->pos - self->string_size) * sizeof(Py_UNICODE));
+    }
+
+    /* Copy the data to the internal buffer, overwriting some of the
+       existing data if self->pos < self->string_size. */
+    memcpy(self->buf + self->pos, str, len * sizeof(Py_UNICODE));
+    self->pos += len;
+
+    /* Set the new length of the internal string if it has changed */
+    if (self->string_size < self->pos) {
+        self->string_size = self->pos;
+    }
+
+    return len;
+}
+
+static PyObject *
+stringio_getvalue(StringIOObject *self)
+{
+    return PyUnicode_FromUnicode(self->buf, self->string_size);
+}
+
+static PyObject *
+stringio_tell(StringIOObject *self)
+{
+    return PyLong_FromSsize_t(self->pos);
+}
+
+static PyObject *
+stringio_read(StringIOObject *self, PyObject *args)
+{
+    Py_ssize_t size, n;
+    Py_UNICODE *output;
+    PyObject *arg = Py_None;
+
+    if (!PyArg_ParseTuple(args, "|O:read", &arg))
+        return NULL;
+
+    if (PyLong_Check(arg)) {
+        size = PyLong_AsSsize_t(arg);
+    }
+    else if (arg == Py_None) {
+        /* Read until EOF is reached, by default. */
+        size = -1;
+    }
+    else {
+        PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
+                     Py_TYPE(arg)->tp_name);
+        return NULL;
+    }
+
+    /* adjust invalid sizes */
+    n = self->string_size - self->pos;
+    if (size < 0 || size > n) {
+        size = n;
+        if (size < 0)
+            size = 0;
+    }
+
+    assert(self->buf != NULL);
+    output = self->buf + self->pos;
+    self->pos += size;
+
+    return PyUnicode_FromUnicode(output, size);
+}
+
+static PyObject *
+stringio_truncate(StringIOObject *self, PyObject *args)
+{
+    Py_ssize_t size;
+    PyObject *arg = Py_None;
+
+    if (!PyArg_ParseTuple(args, "|O:truncate", &arg))
+        return NULL;
+
+    if (PyLong_Check(arg)) {
+        size = PyLong_AsSsize_t(arg);
+    }
+    else if (arg == Py_None) {
+        /* Truncate to current position if no argument is passed. */
+        size = self->pos;
+    }
+    else {
+        PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
+                     Py_TYPE(arg)->tp_name);
+        return NULL;
+    }
+
+    if (size < 0) {
+        PyErr_Format(PyExc_ValueError,
+                     "Negative size value %zd", size);
+        return NULL;
+    }
+
+    if (size < self->string_size) {
+        self->string_size = size;
+        if (resize_buffer(self, size) < 0)
+            return NULL;
+    }
+    self->pos = size;
+
+    return PyLong_FromSsize_t(size);
+}
+
+static PyObject *
+stringio_seek(StringIOObject *self, PyObject *args)
+{
+    Py_ssize_t pos;
+    int mode = 0;
+
+    if (!PyArg_ParseTuple(args, "n|i:seek", &pos, &mode))
+        return NULL;
+
+    if (mode != 0 && mode != 1 && mode != 2) {
+        PyErr_Format(PyExc_ValueError,
+                     "Invalid whence (%i, should be 0, 1 or 2)", mode);
+        return NULL;
+    }
+    else if (pos < 0 && mode == 0) {
+        PyErr_Format(PyExc_ValueError,
+                     "Negative seek position %zd", pos);
+        return NULL;
+    }
+    else if (mode != 0 && pos != 0) {
+        PyErr_SetString(PyExc_IOError,
+                        "Can't do nonzero cur-relative seeks");
+        return NULL;
+    }
+
+    /* mode 0: offset relative to beginning of the string.
+       mode 1: no change to current position.
+       mode 2: change position to end of file. */
+    if (mode == 1) {
+        pos = self->pos;
+    }
+    else if (mode == 2) {
+        pos = self->string_size;
+    }
+
+    self->pos = pos;
+
+    return PyLong_FromSsize_t(self->pos);
+}
+
+static PyObject *
+stringio_write(StringIOObject *self, PyObject *obj)
+{
+    const Py_UNICODE *str;
+    Py_ssize_t size;
+    Py_ssize_t n = 0;
+
+    if (PyUnicode_Check(obj)) {
+        str = PyUnicode_AsUnicode(obj);
+        size = PyUnicode_GetSize(obj);
+    }
+    else {
+        PyErr_Format(PyExc_TypeError, "string argument expected, got '%s'",
+                     Py_TYPE(obj)->tp_name);
+        return NULL;
+    }
+
+    if (size != 0) {
+        n = write_str(self, str, size);
+        if (n < 0)
+            return NULL;
+    }
+
+    return PyLong_FromSsize_t(n);
+}
+
+static void
+stringio_dealloc(StringIOObject *self)
+{
+    PyMem_Free(self->buf);
+    Py_TYPE(self)->tp_free(self);
+}
+
+static PyObject *
+stringio_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    StringIOObject *self;
+
+    assert(type != NULL && type->tp_alloc != NULL);
+    self = (StringIOObject *)type->tp_alloc(type, 0);
+    if (self == NULL)
+        return NULL;
+
+    self->string_size = 0;
+    self->pos = 0;
+    self->buf_size = 0;
+    self->buf = (Py_UNICODE *)PyMem_Malloc(0);
+    if (self->buf == NULL) {
+        Py_DECREF(self);
+        return PyErr_NoMemory();
+    }
+
+    return (PyObject *)self;
+}
+
+static struct PyMethodDef stringio_methods[] = {
+    {"getvalue",   (PyCFunction)stringio_getvalue, METH_VARARGS, NULL},
+    {"read",       (PyCFunction)stringio_read,     METH_VARARGS, NULL},
+    {"tell",       (PyCFunction)stringio_tell,     METH_NOARGS,  NULL},
+    {"truncate",   (PyCFunction)stringio_truncate, METH_VARARGS, NULL},
+    {"seek",       (PyCFunction)stringio_seek,     METH_VARARGS, NULL},
+    {"write",      (PyCFunction)stringio_write,    METH_O,       NULL},
+    {NULL, NULL}        /* sentinel */
+};
+
+static PyTypeObject StringIO_Type = {
+    PyVarObject_HEAD_INIT(NULL, 0)
+    "_stringio._StringIO",                     /*tp_name*/
+    sizeof(StringIOObject),                    /*tp_basicsize*/
+    0,                                         /*tp_itemsize*/
+    (destructor)stringio_dealloc,              /*tp_dealloc*/
+    0,                                         /*tp_print*/
+    0,                                         /*tp_getattr*/
+    0,                                         /*tp_setattr*/
+    0,                                         /*tp_compare*/
+    0,                                         /*tp_repr*/
+    0,                                         /*tp_as_number*/
+    0,                                         /*tp_as_sequence*/
+    0,                                         /*tp_as_mapping*/
+    0,                                         /*tp_hash*/
+    0,                                         /*tp_call*/
+    0,                                         /*tp_str*/
+    0,                                         /*tp_getattro*/
+    0,                                         /*tp_setattro*/
+    0,                                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /*tp_flags*/
+    0,                                         /*tp_doc*/
+    0,                                         /*tp_traverse*/
+    0,                                         /*tp_clear*/
+    0,                                         /*tp_richcompare*/
+    0,                                         /*tp_weaklistoffset*/
+    0,                                         /*tp_iter*/
+    0,                                         /*tp_iternext*/
+    stringio_methods,                          /*tp_methods*/
+    0,                                         /*tp_members*/
+    0,                                         /*tp_getset*/
+    0,                                         /*tp_base*/
+    0,                                         /*tp_dict*/
+    0,                                         /*tp_descr_get*/
+    0,                                         /*tp_descr_set*/
+    0,                                         /*tp_dictoffset*/
+    0,                                         /*tp_init*/
+    0,                                         /*tp_alloc*/
+    stringio_new,                              /*tp_new*/
+};
+
+static struct PyModuleDef _stringiomodule = {
+	PyModuleDef_HEAD_INIT,
+	"_stringio",
+	NULL,
+	-1,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
+PyMODINIT_FUNC
+PyInit__stringio(void)
+{
+    PyObject *m;
+
+    if (PyType_Ready(&StringIO_Type) < 0)
+        return NULL;
+    m = PyModule_Create(&_stringiomodule);
+    if (m == NULL)
+        return NULL;
+    Py_INCREF(&StringIO_Type);
+    if (PyModule_AddObject(m, "_StringIO", (PyObject *)&StringIO_Type) < 0)
+        return NULL;
+    return m;
+}

Modified: python/branches/py3k/setup.py
==============================================================================
--- python/branches/py3k/setup.py	(original)
+++ python/branches/py3k/setup.py	Thu Jun 12 00:58:36 2008
@@ -422,6 +422,7 @@
         exts.append( Extension("_functools", ["_functoolsmodule.c"]) )
         # Memory-based IO accelerator modules
         exts.append( Extension("_bytesio", ["_bytesio.c"]) )
+        exts.append( Extension("_stringio", ["_stringio.c"]) )
         # C-optimized pickle replacement
         exts.append( Extension("_pickle", ["_pickle.c"]) )
         # atexit

From python-3000-checkins at python.org  Thu Jun 12 01:28:22 2008
From: python-3000-checkins at python.org (alexandre.vassalotti)
Date: Thu, 12 Jun 2008 01:28:22 +0200 (CEST)
Subject: [Python-3000-checkins] r64155 - python/branches/py3k/Lib/pickle.py
Message-ID: <20080611232822.7F1EC1E4005@bag.python.org>

Author: alexandre.vassalotti
Date: Thu Jun 12 01:28:22 2008
New Revision: 64155

Log:
Removed exception renaming cruft in pickle.py.


Modified:
   python/branches/py3k/Lib/pickle.py

Modified: python/branches/py3k/Lib/pickle.py
==============================================================================
--- python/branches/py3k/Lib/pickle.py	(original)
+++ python/branches/py3k/Lib/pickle.py	Thu Jun 12 01:28:22 2008
@@ -1308,9 +1308,6 @@
     from _pickle import *
 except ImportError:
     Pickler, Unpickler = _Pickler, _Unpickler
-    PickleError = _PickleError
-    PicklingError = _PicklingError
-    UnpicklingError = _UnpicklingError
 
 # Shorthands
 

From python-3000-checkins at python.org  Thu Jun 12 01:38:41 2008
From: python-3000-checkins at python.org (alexandre.vassalotti)
Date: Thu, 12 Jun 2008 01:38:41 +0200 (CEST)
Subject: [Python-3000-checkins] r64156 - in python/branches/py3k/PC:
	VS8.0/pythoncore.vcproj config.c
Message-ID: <20080611233841.3620F1E4005@bag.python.org>

Author: alexandre.vassalotti
Date: Thu Jun 12 01:38:40 2008
New Revision: 64156

Log:
Added Windows build config for _stringio and _pickle.


Modified:
   python/branches/py3k/PC/VS8.0/pythoncore.vcproj
   python/branches/py3k/PC/config.c

Modified: python/branches/py3k/PC/VS8.0/pythoncore.vcproj
==============================================================================
--- python/branches/py3k/PC/VS8.0/pythoncore.vcproj	(original)
+++ python/branches/py3k/PC/VS8.0/pythoncore.vcproj	Thu Jun 12 01:38:40 2008
@@ -986,10 +986,18 @@
 				RelativePath="..\..\Modules\_fileio.c"
 				>
 			</File>
-                        <File^M
-                                RelativePath="..\..\Modules\_bytesio.c"^M
-                                >^M
-                        </File>^M
+			<File
+				RelativePath="..\..\Modules\_bytesio.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_stringio.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_pickle.c"
+				>
+			</File>
 			<File
 				RelativePath="..\..\Modules\_functoolsmodule.c"
 				>

Modified: python/branches/py3k/PC/config.c
==============================================================================
--- python/branches/py3k/PC/config.c	(original)
+++ python/branches/py3k/PC/config.c	Thu Jun 12 01:38:40 2008
@@ -60,6 +60,8 @@
 extern PyObject* PyInit__ast(void);
 extern PyObject* PyInit__fileio(void);
 extern PyObject* PyInit__bytesio(void);
+extern PyObject* PyInit__stringio(void);
+extern PyObject* PyInit__pickle(void);
 extern PyObject* PyInit_atexit(void);
 extern PyObject* _PyWarnings_Init(void);
 
@@ -150,6 +152,8 @@
 
         {"_fileio", PyInit__fileio},
         {"_bytesio", PyInit__bytesio},
+        {"_stringio", PyInit__stringio},
+        {"_pickle", PyInit__pickle},
         {"atexit", PyInit_atexit},
 
         /* Sentinel */

From python-3000-checkins at python.org  Thu Jun 12 02:23:43 2008
From: python-3000-checkins at python.org (alexandre.vassalotti)
Date: Thu, 12 Jun 2008 02:23:43 +0200 (CEST)
Subject: [Python-3000-checkins] r64157 -
	python/branches/py3k/Lib/test/test_sys.py
Message-ID: <20080612002343.A4B161E4005@bag.python.org>

Author: alexandre.vassalotti
Date: Thu Jun 12 02:23:43 2008
New Revision: 64157

Log:
Fixed test_sys failure due to removal of the unused slots
in PyNumberMethods.


Modified:
   python/branches/py3k/Lib/test/test_sys.py

Modified: python/branches/py3k/Lib/test/test_sys.py
==============================================================================
--- python/branches/py3k/Lib/test/test_sys.py	(original)
+++ python/branches/py3k/Lib/test/test_sys.py	Thu Jun 12 02:23:43 2008
@@ -471,11 +471,16 @@
                 pass
         # type (PyTypeObject + PyNumberMethods + PyMappingMethods +
         #       PySequenceMethods + PyBufferProcs)
-        self.check_sizeof(class_newstyle, h +\
-                          p + 2*l + 15*p + l + 4*p + l + 9*p + l + 11*p +\
-                              self.align(4) +\
-                          16*p + self.align(i) + 20*p +\
-                          10*p + 3*p + 2*p + 2*p);
+        self.check_sizeof(class_newstyle, h +
+                          # PyTypeObject
+                          p + 2*l + 15*p + l + 4*p + l + 9*p + l + 11*p +
+                          self.align(4) +
+                          # PyNumberMethods
+                          16*p + self.align(i) + 17*p +
+                          3*p  + # PyMappingMethods
+                          10*p + # PySequenceMethods
+                          2*p  + # PyBufferProcs
+                          2*p)   # *ht_name and *ht_slots
 
     def test_specialtypes(self):
         i = self.i

From python-3000-checkins at python.org  Thu Jun 12 02:52:33 2008
From: python-3000-checkins at python.org (alexandre.vassalotti)
Date: Thu, 12 Jun 2008 02:52:33 +0200 (CEST)
Subject: [Python-3000-checkins] r64158 - in python/branches/py3k/PC:
	VC6/pythoncore.dsp VS7.1/pythoncore.vcproj
Message-ID: <20080612005233.1958C1E4005@bag.python.org>

Author: alexandre.vassalotti
Date: Thu Jun 12 02:52:32 2008
New Revision: 64158

Log:
Attempt to fix the Windows build for _stringio and _pickle.

I don't have any win32 machine in my reach. So, I can't test this.


Modified:
   python/branches/py3k/PC/VC6/pythoncore.dsp
   python/branches/py3k/PC/VS7.1/pythoncore.vcproj

Modified: python/branches/py3k/PC/VC6/pythoncore.dsp
==============================================================================
--- python/branches/py3k/PC/VC6/pythoncore.dsp	(original)
+++ python/branches/py3k/PC/VC6/pythoncore.dsp	Thu Jun 12 02:52:32 2008
@@ -137,6 +137,18 @@
 # End Source File
 # Begin Source File
 
+SOURCE=..\..\Modules\_bytesio.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\_stringio.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Modules\_pickle.c
+# End Source File
+# Begin Source File
+
 SOURCE=..\..\Modules\_functoolsmodule.c
 # End Source File
 # Begin Source File

Modified: python/branches/py3k/PC/VS7.1/pythoncore.vcproj
==============================================================================
--- python/branches/py3k/PC/VS7.1/pythoncore.vcproj	(original)
+++ python/branches/py3k/PC/VS7.1/pythoncore.vcproj	Thu Jun 12 02:52:32 2008
@@ -371,6 +371,15 @@
 			RelativePath="..\..\Modules\_fileio.c">
 		</File>
 		<File
+			RelativePath="..\..\Modules\_bytesio.c">
+		</File>
+		<File
+			RelativePath="..\..\Modules\_stringio.c">
+		</File>
+		<File
+			RelativePath="..\..\Modules\_pickle.c">
+		</File>
+		<File
 			RelativePath="..\..\Modules\_functoolsmodule.c">
 		</File>
 		<File

From python-3000-checkins at python.org  Thu Jun 12 03:13:54 2008
From: python-3000-checkins at python.org (alexandre.vassalotti)
Date: Thu, 12 Jun 2008 03:13:54 +0200 (CEST)
Subject: [Python-3000-checkins] r64159 - in python/branches/py3k/Lib: io.py
	tempfile.py
Message-ID: <20080612011354.898461E4005@bag.python.org>

Author: alexandre.vassalotti
Date: Thu Jun 12 03:13:54 2008
New Revision: 64159

Log:
Fixed test_tempfile.
Added the encoding, errors, line_buffering attribute to io.StringIO
make more compatible with TextIOWrapper's API.


Modified:
   python/branches/py3k/Lib/io.py
   python/branches/py3k/Lib/tempfile.py

Modified: python/branches/py3k/Lib/io.py
==============================================================================
--- python/branches/py3k/Lib/io.py	(original)
+++ python/branches/py3k/Lib/io.py	Thu Jun 12 03:13:54 2008
@@ -1839,6 +1839,22 @@
             raise UnsupportedOperation("%s.buffer attribute is unsupported" %
                                        self.__class__.__name__)
 
+        # XXX Cruft to support the TextIOWrapper API. This would only
+        # be meaningful if StringIO supported the buffer attribute.
+        # Hopefully, a better solution, than adding these pseudo-attributes,
+        # will be found.
+        @property
+        def encoding(self):
+            return "utf-8"
+
+        @property
+        def errors(self):
+            return "strict"
+
+        @property
+        def line_buffering(self):
+            return False
+
         def _decode_newlines(self, input, final=False):
             # decode input (with the eventual \r from a previous pass)
             if self._pending:

Modified: python/branches/py3k/Lib/tempfile.py
==============================================================================
--- python/branches/py3k/Lib/tempfile.py	(original)
+++ python/branches/py3k/Lib/tempfile.py	Thu Jun 12 03:13:54 2008
@@ -502,7 +502,7 @@
             # Setting newline="\n" avoids newline translation;
             # this is important because otherwise on Windows we'd
             # hget double newline translation upon rollover().
-            self._file = _io.StringIO(encoding=encoding, newline="\n")
+            self._file = _io.StringIO(newline="\n")
         self._max_size = max_size
         self._rolled = False
         self._TemporaryFileArgs = {'mode': mode, 'buffering': buffering,

From python-3000-checkins at python.org  Thu Jun 12 03:50:40 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Thu, 12 Jun 2008 03:50:40 +0200 (CEST)
Subject: [Python-3000-checkins] r64160 -
	python/branches/py3k/Lib/test/test_pyclbr.py
Message-ID: <20080612015040.0482D1E4005@bag.python.org>

Author: benjamin.peterson
Date: Thu Jun 12 03:50:39 2008
New Revision: 64160

Log:
fix test_pyclbr which failed because the new StringIO presented bases it couldn't find


Modified:
   python/branches/py3k/Lib/test/test_pyclbr.py

Modified: python/branches/py3k/Lib/test/test_pyclbr.py
==============================================================================
--- python/branches/py3k/Lib/test/test_pyclbr.py	(original)
+++ python/branches/py3k/Lib/test/test_pyclbr.py	Thu Jun 12 03:50:39 2008
@@ -140,7 +140,7 @@
 
     def test_easy(self):
         self.checkModule('pyclbr')
-        self.checkModule('doctest', ignore=("TestResults",))
+        self.checkModule('doctest', ignore=("TestResults", "_SpoofOut"))
         self.checkModule('rfc822')
         self.checkModule('difflib', ignore=("Match",))
 

From python-3000-checkins at python.org  Thu Jun 12 04:38:52 2008
From: python-3000-checkins at python.org (barry.warsaw)
Date: Thu, 12 Jun 2008 04:38:52 +0200 (CEST)
Subject: [Python-3000-checkins] r64161 - in python/branches/py3k/Lib: cgi.py
	test/test_cgi.py
Message-ID: <20080612023852.50CE71E4005@bag.python.org>

Author: barry.warsaw
Date: Thu Jun 12 04:38:51 2008
New Revision: 64161

Log:
Patch by Humberto Diogenes for issue 2849, removing rfc822 module from
the standard library.  There are still a few cases of it in Demo and
Tools, but that's fine for now.  These should eventually get cleaned
up.  mimetools still has an import of rfc822, but mimetools itself
should go away.


Modified:
   python/branches/py3k/Lib/cgi.py
   python/branches/py3k/Lib/test/test_cgi.py

Modified: python/branches/py3k/Lib/cgi.py
==============================================================================
--- python/branches/py3k/Lib/cgi.py	(original)
+++ python/branches/py3k/Lib/cgi.py	Thu Jun 12 04:38:51 2008
@@ -32,13 +32,12 @@
 # =======
 
 from operator import attrgetter
+from io import StringIO
 import sys
 import os
 import urllib
 import mimetools
-import rfc822
-import collections
-from io import StringIO
+import email.parser
 
 __all__ = ["MiniFieldStorage", "FieldStorage",
            "parse", "parse_qs", "parse_qsl", "parse_multipart",
@@ -404,7 +403,7 @@
 
     disposition_options: dictionary of corresponding options
 
-    headers: a dictionary(-like) object (sometimes rfc822.Message or a
+    headers: a dictionary(-like) object (sometimes email.message.Message or a
         subclass thereof) containing *all* headers
 
     The class is subclassable, mostly for the purpose of overriding
@@ -633,13 +632,17 @@
             raise ValueError('Invalid boundary in multipart form: %r' % (ib,))
         self.list = []
         klass = self.FieldStorageClass or self.__class__
-        part = klass(self.fp, {}, ib,
-                     environ, keep_blank_values, strict_parsing)
-        # Throw first part away
-        while not part.done:
-            headers = rfc822.Message(self.fp)
-            part = klass(self.fp, headers, ib,
-                         environ, keep_blank_values, strict_parsing)
+        parser = email.parser.FeedParser()
+        # Create bogus content-type header for proper multipart parsing
+        parser.feed('Content-Type: %s; boundary=%s\r\n\r\n' % (self.type, ib))
+        parser.feed(self.fp.read())
+        full_msg = parser.close()
+        # Get subparts
+        msgs = full_msg.get_payload()
+        for msg in msgs:
+            fp = StringIO(msg.get_payload())
+            part = klass(fp, msg, ib, environ, keep_blank_values,
+                         strict_parsing)
             self.list.append(part)
         self.skip_lines()
 

Modified: python/branches/py3k/Lib/test/test_cgi.py
==============================================================================
--- python/branches/py3k/Lib/test/test_cgi.py	(original)
+++ python/branches/py3k/Lib/test/test_cgi.py	Thu Jun 12 04:38:51 2008
@@ -234,7 +234,7 @@
         self.assertEquals(len(fs.list), 4)
         expect = [{'name':'id', 'filename':None, 'value':'1234'},
                   {'name':'title', 'filename':None, 'value':''},
-                  {'name':'file', 'filename':'test.txt','value':'Testing 123.\n'},
+                  {'name':'file', 'filename':'test.txt', 'value':'Testing 123.'},
                   {'name':'submit', 'filename':None, 'value':' Add '}]
         for x in range(len(fs.list)):
             for k, exp in expect[x].items():

From python-3000-checkins at python.org  Thu Jun 12 04:42:00 2008
From: python-3000-checkins at python.org (barry.warsaw)
Date: Thu, 12 Jun 2008 04:42:00 +0200 (CEST)
Subject: [Python-3000-checkins] r64162 - in python/branches/py3k/Misc: ACKS
	NEWS
Message-ID: <20080612024200.72C721E4005@bag.python.org>

Author: barry.warsaw
Date: Thu Jun 12 04:42:00 2008
New Revision: 64162

Log:
Update NEWS and ACKS for issue 2849.

Modified:
   python/branches/py3k/Misc/ACKS
   python/branches/py3k/Misc/NEWS

Modified: python/branches/py3k/Misc/ACKS
==============================================================================
--- python/branches/py3k/Misc/ACKS	(original)
+++ python/branches/py3k/Misc/ACKS	Thu Jun 12 04:42:00 2008
@@ -161,6 +161,7 @@
 Raghuram Devarakonda
 Toby Dickenson
 Mark Dickinson
+Humberto Diogenes
 Yves Dionne
 Daniel Dittmar
 Jaromir Dolecek

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Thu Jun 12 04:42:00 2008
@@ -78,6 +78,8 @@
 Library
 -------
 
+- Patch #2849: Remove use of rfc822 module from standard library.
+
 - Added C optimized implementation of io.StringIO.
 
 - The ``pickle`` module is now automatically use an optimized C

From python-3000-checkins at python.org  Thu Jun 12 05:10:05 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Thu, 12 Jun 2008 05:10:05 +0200 (CEST)
Subject: [Python-3000-checkins] r64163 - in python/branches/py3k:
	Lib/pickle.py Lib/pickletools.py Lib/test/pickletester.py
	Lib/test/test_pickle.py Lib/test/test_pickletools.py
	Misc/NEWS Modules/_pickle.c PC/VC6/pythoncore.dsp
	PC/VS7.1/pythoncore.vcproj PC/VS8.0/pythoncore.vcproj
	PC/config.c setup.py
Message-ID: <20080612031005.06E821E4005@bag.python.org>

Author: benjamin.peterson
Date: Thu Jun 12 05:10:02 2008
New Revision: 64163

Log:
revert the addition of _pickle because it was causing havok with 64-bit


Removed:
   python/branches/py3k/Modules/_pickle.c
Modified:
   python/branches/py3k/Lib/pickle.py
   python/branches/py3k/Lib/pickletools.py
   python/branches/py3k/Lib/test/pickletester.py
   python/branches/py3k/Lib/test/test_pickle.py
   python/branches/py3k/Lib/test/test_pickletools.py
   python/branches/py3k/Misc/NEWS
   python/branches/py3k/PC/VC6/pythoncore.dsp
   python/branches/py3k/PC/VS7.1/pythoncore.vcproj
   python/branches/py3k/PC/VS8.0/pythoncore.vcproj
   python/branches/py3k/PC/config.c
   python/branches/py3k/setup.py

Modified: python/branches/py3k/Lib/pickle.py
==============================================================================
--- python/branches/py3k/Lib/pickle.py	(original)
+++ python/branches/py3k/Lib/pickle.py	Thu Jun 12 05:10:02 2008
@@ -174,7 +174,7 @@
 
 # Pickling machinery
 
-class _Pickler:
+class Pickler:
 
     def __init__(self, file, protocol=None):
         """This takes a binary file for writing a pickle data stream.
@@ -182,19 +182,21 @@
         All protocols now read and write bytes.
 
         The optional protocol argument tells the pickler to use the
-        given protocol; supported protocols are 0, 1, 2, 3.  The default
-        protocol is 3; a backward-incompatible protocol designed for
-        Python 3.0.
+        given protocol; supported protocols are 0, 1, 2.  The default
+        protocol is 2; it's been supported for many years now.
+
+        Protocol 1 is more efficient than protocol 0; protocol 2 is
+        more efficient than protocol 1.
 
         Specifying a negative protocol version selects the highest
         protocol version supported.  The higher the protocol used, the
         more recent the version of Python needed to read the pickle
         produced.
 
-        The file argument must have a write() method that accepts a single
-        bytes argument. It can thus be a file object opened for binary
-        writing, a io.BytesIO instance, or any other custom object that
-        meets this interface.
+        The file parameter must have a write() method that accepts a single
+        string argument.  It can thus be an open file object, a StringIO
+        object, or any other custom object that meets this interface.
+
         """
         if protocol is None:
             protocol = DEFAULT_PROTOCOL
@@ -202,10 +204,7 @@
             protocol = HIGHEST_PROTOCOL
         elif not 0 <= protocol <= HIGHEST_PROTOCOL:
             raise ValueError("pickle protocol must be <= %d" % HIGHEST_PROTOCOL)
-        try:
-            self.write = file.write
-        except AttributeError:
-            raise TypeError("file must have a 'write' attribute")
+        self.write = file.write
         self.memo = {}
         self.proto = int(protocol)
         self.bin = protocol >= 1
@@ -271,10 +270,10 @@
 
         return GET + repr(i).encode("ascii") + b'\n'
 
-    def save(self, obj, save_persistent_id=True):
+    def save(self, obj):
         # Check for persistent id (defined by a subclass)
         pid = self.persistent_id(obj)
-        if pid is not None and save_persistent_id:
+        if pid:
             self.save_pers(pid)
             return
 
@@ -342,7 +341,7 @@
     def save_pers(self, pid):
         # Save a persistent id reference
         if self.bin:
-            self.save(pid, save_persistent_id=False)
+            self.save(pid)
             self.write(BINPERSID)
         else:
             self.write(PERSID + str(pid).encode("ascii") + b'\n')
@@ -351,13 +350,13 @@
                     listitems=None, dictitems=None, obj=None):
         # This API is called by some subclasses
 
-        # Assert that args is a tuple
+        # Assert that args is a tuple or None
         if not isinstance(args, tuple):
-            raise PicklingError("args from save_reduce() should be a tuple")
+            raise PicklingError("args from reduce() should be a tuple")
 
         # Assert that func is callable
         if not hasattr(func, '__call__'):
-            raise PicklingError("func from save_reduce() should be callable")
+            raise PicklingError("func from reduce should be callable")
 
         save = self.save
         write = self.write
@@ -439,6 +438,31 @@
             self.write(obj and TRUE or FALSE)
     dispatch[bool] = save_bool
 
+    def save_int(self, obj, pack=struct.pack):
+        if self.bin:
+            # If the int is small enough to fit in a signed 4-byte 2's-comp
+            # format, we can store it more efficiently than the general
+            # case.
+            # First one- and two-byte unsigned ints:
+            if obj >= 0:
+                if obj <= 0xff:
+                    self.write(BININT1 + bytes([obj]))
+                    return
+                if obj <= 0xffff:
+                    self.write(BININT2 + bytes([obj&0xff, obj>>8]))
+                    return
+            # Next check for 4-byte signed ints:
+            high_bits = obj >> 31  # note that Python shift sign-extends
+            if high_bits == 0 or high_bits == -1:
+                # All high bits are copies of bit 2**31, so the value
+                # fits in a 4-byte signed int.
+                self.write(BININT + pack("<i", obj))
+                return
+        # Text pickle, or int too big to fit in signed 4-byte format.
+        self.write(INT + repr(obj).encode("ascii") + b'\n')
+    # XXX save_int is merged into save_long
+    # dispatch[int] = save_int
+
     def save_long(self, obj, pack=struct.pack):
         if self.bin:
             # If the int is small enough to fit in a signed 4-byte 2's-comp
@@ -479,7 +503,7 @@
 
     def save_bytes(self, obj, pack=struct.pack):
         if self.proto < 3:
-            self.save_reduce(bytes, (list(obj),), obj=obj)
+            self.save_reduce(bytes, (list(obj),))
             return
         n = len(obj)
         if n < 256:
@@ -555,6 +579,12 @@
 
     dispatch[tuple] = save_tuple
 
+    # save_empty_tuple() isn't used by anything in Python 2.3.  However, I
+    # found a Pickler subclass in Zope3 that calls it, so it's not harmless
+    # to remove it.
+    def save_empty_tuple(self, obj):
+        self.write(EMPTY_TUPLE)
+
     def save_list(self, obj):
         write = self.write
 
@@ -666,7 +696,7 @@
             module = whichmodule(obj, name)
 
         try:
-            __import__(module, level=0)
+            __import__(module)
             mod = sys.modules[module]
             klass = getattr(mod, name)
         except (ImportError, KeyError, AttributeError):
@@ -690,19 +720,9 @@
                 else:
                     write(EXT4 + pack("<i", code))
                 return
-        # Non-ASCII identifiers are supported only with protocols >= 3.
-        if self.proto >= 3:
-            write(GLOBAL + bytes(module, "utf-8") + b'\n' +
-                  bytes(name, "utf-8") + b'\n')
-        else:
-            try:
-                write(GLOBAL + bytes(module, "ascii") + b'\n' +
-                      bytes(name, "ascii") + b'\n')
-            except UnicodeEncodeError:
-                raise PicklingError(
-                    "can't pickle global identifier '%s.%s' using "
-                    "pickle protocol %i" % (module, name, self.proto))
 
+        write(GLOBAL + bytes(module, "utf-8") + b'\n' +
+              bytes(name, "utf-8") + b'\n')
         self.memoize(obj)
 
     dispatch[FunctionType] = save_global
@@ -761,7 +781,7 @@
 
 # Unpickling machinery
 
-class _Unpickler:
+class Unpickler:
 
     def __init__(self, file, *, encoding="ASCII", errors="strict"):
         """This takes a binary file for reading a pickle data stream.
@@ -821,9 +841,6 @@
         while stack[k] is not mark: k = k-1
         return k
 
-    def persistent_load(self, pid):
-        raise UnpickingError("unsupported persistent id encountered")
-
     dispatch = {}
 
     def load_proto(self):
@@ -833,7 +850,7 @@
     dispatch[PROTO[0]] = load_proto
 
     def load_persid(self):
-        pid = self.readline()[:-1].decode("ascii")
+        pid = self.readline()[:-1]
         self.append(self.persistent_load(pid))
     dispatch[PERSID[0]] = load_persid
 
@@ -862,9 +879,9 @@
             val = True
         else:
             try:
-                val = int(data, 0)
+                val = int(data)
             except ValueError:
-                val = int(data, 0)
+                val = int(data)
         self.append(val)
     dispatch[INT[0]] = load_int
 
@@ -916,8 +933,7 @@
                 break
         else:
             raise ValueError("insecure string pickle: %r" % orig)
-        self.append(codecs.escape_decode(rep)[0]
-                    .decode(self.encoding, self.errors))
+        self.append(codecs.escape_decode(rep)[0])
     dispatch[STRING[0]] = load_string
 
     def load_binstring(self):
@@ -959,7 +975,7 @@
     dispatch[TUPLE[0]] = load_tuple
 
     def load_empty_tuple(self):
-        self.append(())
+        self.stack.append(())
     dispatch[EMPTY_TUPLE[0]] = load_empty_tuple
 
     def load_tuple1(self):
@@ -975,11 +991,11 @@
     dispatch[TUPLE3[0]] = load_tuple3
 
     def load_empty_list(self):
-        self.append([])
+        self.stack.append([])
     dispatch[EMPTY_LIST[0]] = load_empty_list
 
     def load_empty_dictionary(self):
-        self.append({})
+        self.stack.append({})
     dispatch[EMPTY_DICT[0]] = load_empty_dictionary
 
     def load_list(self):
@@ -1006,13 +1022,13 @@
     def _instantiate(self, klass, k):
         args = tuple(self.stack[k+1:])
         del self.stack[k:]
-        instantiated = False
+        instantiated = 0
         if (not args and
                 isinstance(klass, type) and
                 not hasattr(klass, "__getinitargs__")):
             value = _EmptyClass()
             value.__class__ = klass
-            instantiated = True
+            instantiated = 1
         if not instantiated:
             try:
                 value = klass(*args)
@@ -1022,8 +1038,8 @@
         self.append(value)
 
     def load_inst(self):
-        module = self.readline()[:-1].decode("ascii")
-        name = self.readline()[:-1].decode("ascii")
+        module = self.readline()[:-1]
+        name = self.readline()[:-1]
         klass = self.find_class(module, name)
         self._instantiate(klass, self.marker())
     dispatch[INST[0]] = load_inst
@@ -1043,8 +1059,8 @@
     dispatch[NEWOBJ[0]] = load_newobj
 
     def load_global(self):
-        module = self.readline()[:-1].decode("utf-8")
-        name = self.readline()[:-1].decode("utf-8")
+        module = self.readline()[:-1]
+        name = self.readline()[:-1]
         klass = self.find_class(module, name)
         self.append(klass)
     dispatch[GLOBAL[0]] = load_global
@@ -1079,7 +1095,11 @@
 
     def find_class(self, module, name):
         # Subclasses may override this
-        __import__(module, level=0)
+        if isinstance(module, bytes_types):
+            module = module.decode("utf-8")
+        if isinstance(name, bytes_types):
+            name = name.decode("utf-8")
+        __import__(module)
         mod = sys.modules[module]
         klass = getattr(mod, name)
         return klass
@@ -1111,33 +1131,31 @@
     dispatch[DUP[0]] = load_dup
 
     def load_get(self):
-        i = int(self.readline()[:-1])
-        self.append(self.memo[i])
+        self.append(self.memo[self.readline()[:-1].decode("ascii")])
     dispatch[GET[0]] = load_get
 
     def load_binget(self):
-        i = self.read(1)[0]
-        self.append(self.memo[i])
+        i = ord(self.read(1))
+        self.append(self.memo[repr(i)])
     dispatch[BINGET[0]] = load_binget
 
     def load_long_binget(self):
         i = mloads(b'i' + self.read(4))
-        self.append(self.memo[i])
+        self.append(self.memo[repr(i)])
     dispatch[LONG_BINGET[0]] = load_long_binget
 
     def load_put(self):
-        i = int(self.readline()[:-1])
-        self.memo[i] = self.stack[-1]
+        self.memo[self.readline()[:-1].decode("ascii")] = self.stack[-1]
     dispatch[PUT[0]] = load_put
 
     def load_binput(self):
-        i = self.read(1)[0]
-        self.memo[i] = self.stack[-1]
+        i = ord(self.read(1))
+        self.memo[repr(i)] = self.stack[-1]
     dispatch[BINPUT[0]] = load_binput
 
     def load_long_binput(self):
         i = mloads(b'i' + self.read(4))
-        self.memo[i] = self.stack[-1]
+        self.memo[repr(i)] = self.stack[-1]
     dispatch[LONG_BINPUT[0]] = load_long_binput
 
     def load_append(self):
@@ -1303,12 +1321,6 @@
         n -= 1 << (nbytes * 8)
     return n
 
-# Use the faster _pickle if possible
-try:
-    from _pickle import *
-except ImportError:
-    Pickler, Unpickler = _Pickler, _Unpickler
-
 # Shorthands
 
 def dump(obj, file, protocol=None):
@@ -1321,14 +1333,14 @@
     assert isinstance(res, bytes_types)
     return res
 
-def load(file, *, encoding="ASCII", errors="strict"):
-    return Unpickler(file, encoding=encoding, errors=errors).load()
+def load(file):
+    return Unpickler(file).load()
 
-def loads(s, *, encoding="ASCII", errors="strict"):
+def loads(s):
     if isinstance(s, str):
         raise TypeError("Can't load pickle from unicode string")
     file = io.BytesIO(s)
-    return Unpickler(file, encoding=encoding, errors=errors).load()
+    return Unpickler(file).load()
 
 # Doctest
 

Modified: python/branches/py3k/Lib/pickletools.py
==============================================================================
--- python/branches/py3k/Lib/pickletools.py	(original)
+++ python/branches/py3k/Lib/pickletools.py	Thu Jun 12 05:10:02 2008
@@ -2079,12 +2079,11 @@
    70: t        TUPLE      (MARK at 49)
    71: p    PUT        5
    74: R    REDUCE
-   75: p    PUT        6
-   78: V    UNICODE    'def'
-   83: p    PUT        7
-   86: s    SETITEM
-   87: a    APPEND
-   88: .    STOP
+   75: V    UNICODE    'def'
+   80: p    PUT        6
+   83: s    SETITEM
+   84: a    APPEND
+   85: .    STOP
 highest protocol among opcodes = 0
 
 Try again with a "binary" pickle.
@@ -2116,12 +2115,11 @@
    49: t            TUPLE      (MARK at 37)
    50: q        BINPUT     5
    52: R        REDUCE
-   53: q        BINPUT     6
-   55: X        BINUNICODE 'def'
-   63: q        BINPUT     7
-   65: s        SETITEM
-   66: e        APPENDS    (MARK at 3)
-   67: .    STOP
+   53: X        BINUNICODE 'def'
+   61: q        BINPUT     6
+   63: s        SETITEM
+   64: e        APPENDS    (MARK at 3)
+   65: .    STOP
 highest protocol among opcodes = 1
 
 Exercise the INST/OBJ/BUILD family.

Modified: python/branches/py3k/Lib/test/pickletester.py
==============================================================================
--- python/branches/py3k/Lib/test/pickletester.py	(original)
+++ python/branches/py3k/Lib/test/pickletester.py	Thu Jun 12 05:10:02 2008
@@ -362,7 +362,7 @@
     return x
 
 class AbstractPickleTests(unittest.TestCase):
-    # Subclass must define self.dumps, self.loads.
+    # Subclass must define self.dumps, self.loads, self.error.
 
     _testdata = create_data()
 
@@ -463,9 +463,8 @@
             self.assertEqual(list(x[0].attr.keys()), [1])
             self.assert_(x[0].attr[1] is x)
 
-    def test_get(self):
-        self.assertRaises(KeyError, self.loads, b'g0\np0')
-        self.assertEquals(self.loads(b'((Kdtp0\nh\x00l.))'), [(100,), (100,)])
+    def test_garyp(self):
+        self.assertRaises(self.error, self.loads, b'garyp')
 
     def test_insecure_strings(self):
         # XXX Some of these tests are temporarily disabled
@@ -956,7 +955,7 @@
         f = open(TESTFN, "wb")
         try:
             f.close()
-            self.assertRaises(ValueError, pickle.dump, 123, f)
+            self.assertRaises(ValueError, self.module.dump, 123, f)
         finally:
             os.remove(TESTFN)
 
@@ -965,24 +964,24 @@
         f = open(TESTFN, "wb")
         try:
             f.close()
-            self.assertRaises(ValueError, pickle.dump, 123, f)
+            self.assertRaises(ValueError, self.module.dump, 123, f)
         finally:
             os.remove(TESTFN)
 
     def test_highest_protocol(self):
         # Of course this needs to be changed when HIGHEST_PROTOCOL changes.
-        self.assertEqual(pickle.HIGHEST_PROTOCOL, 3)
+        self.assertEqual(self.module.HIGHEST_PROTOCOL, 3)
 
     def test_callapi(self):
         from io import BytesIO
         f = BytesIO()
         # With and without keyword arguments
-        pickle.dump(123, f, -1)
-        pickle.dump(123, file=f, protocol=-1)
-        pickle.dumps(123, -1)
-        pickle.dumps(123, protocol=-1)
-        pickle.Pickler(f, -1)
-        pickle.Pickler(f, protocol=-1)
+        self.module.dump(123, f, -1)
+        self.module.dump(123, file=f, protocol=-1)
+        self.module.dumps(123, -1)
+        self.module.dumps(123, protocol=-1)
+        self.module.Pickler(f, -1)
+        self.module.Pickler(f, protocol=-1)
 
 class AbstractPersistentPicklerTests(unittest.TestCase):
 

Modified: python/branches/py3k/Lib/test/test_pickle.py
==============================================================================
--- python/branches/py3k/Lib/test/test_pickle.py	(original)
+++ python/branches/py3k/Lib/test/test_pickle.py	Thu Jun 12 05:10:02 2008
@@ -7,42 +7,37 @@
 from test.pickletester import AbstractPickleModuleTests
 from test.pickletester import AbstractPersistentPicklerTests
 
-try:
-    import _pickle
-    has_c_implementation = True
-except ImportError:
-    has_c_implementation = False
+class PickleTests(AbstractPickleTests, AbstractPickleModuleTests):
 
+    module = pickle
+    error = KeyError
 
-class PickleTests(AbstractPickleModuleTests):
-    pass
+    def dumps(self, arg, proto=None):
+        return pickle.dumps(arg, proto)
 
+    def loads(self, buf):
+        return pickle.loads(buf)
 
-class PyPicklerTests(AbstractPickleTests):
+class PicklerTests(AbstractPickleTests):
 
-    pickler = pickle._Pickler
-    unpickler = pickle._Unpickler
+    error = KeyError
 
     def dumps(self, arg, proto=None):
         f = io.BytesIO()
-        p = self.pickler(f, proto)
+        p = pickle.Pickler(f, proto)
         p.dump(arg)
         f.seek(0)
         return bytes(f.read())
 
     def loads(self, buf):
         f = io.BytesIO(buf)
-        u = self.unpickler(f)
+        u = pickle.Unpickler(f)
         return u.load()
 
-
-class PyPersPicklerTests(AbstractPersistentPicklerTests):
-
-    pickler = pickle._Pickler
-    unpickler = pickle._Unpickler
+class PersPicklerTests(AbstractPersistentPicklerTests):
 
     def dumps(self, arg, proto=None):
-        class PersPickler(self.pickler):
+        class PersPickler(pickle.Pickler):
             def persistent_id(subself, obj):
                 return self.persistent_id(obj)
         f = io.BytesIO()
@@ -52,29 +47,19 @@
         return f.read()
 
     def loads(self, buf):
-        class PersUnpickler(self.unpickler):
+        class PersUnpickler(pickle.Unpickler):
             def persistent_load(subself, obj):
                 return self.persistent_load(obj)
         f = io.BytesIO(buf)
         u = PersUnpickler(f)
         return u.load()
 
-
-if has_c_implementation:
-    class CPicklerTests(PyPicklerTests):
-        pickler = _pickle.Pickler
-        unpickler = _pickle.Unpickler
-
-    class CPersPicklerTests(PyPersPicklerTests):
-        pickler = _pickle.Pickler
-        unpickler = _pickle.Unpickler
-
-
 def test_main():
-    tests = [PickleTests, PyPicklerTests, PyPersPicklerTests]
-    if has_c_implementation:
-        tests.extend([CPicklerTests, CPersPicklerTests])
-    support.run_unittest(*tests)
+    support.run_unittest(
+        PickleTests,
+        PicklerTests,
+        PersPicklerTests
+    )
     support.run_doctest(pickle)
 
 if __name__ == "__main__":

Modified: python/branches/py3k/Lib/test/test_pickletools.py
==============================================================================
--- python/branches/py3k/Lib/test/test_pickletools.py	(original)
+++ python/branches/py3k/Lib/test/test_pickletools.py	Thu Jun 12 05:10:02 2008
@@ -12,6 +12,8 @@
     def loads(self, buf):
         return pickle.loads(buf)
 
+    module = pickle
+    error = KeyError
 
 def test_main():
     support.run_unittest(OptimizedPickleTests)

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Thu Jun 12 05:10:02 2008
@@ -82,10 +82,6 @@
 
 - Added C optimized implementation of io.StringIO.
 
-- The ``pickle`` module is now automatically use an optimized C
-  implementation of Pickler and Unpickler when available. The
-  ``cPickle`` module is no longer needed.
-
 - Removed the ``htmllib`` and ``sgmllib`` modules.
 
 - The deprecated ``SmartCookie`` and ``SimpleCookie`` classes have

Deleted: python/branches/py3k/Modules/_pickle.c
==============================================================================
--- python/branches/py3k/Modules/_pickle.c	Thu Jun 12 05:10:02 2008
+++ (empty file)
@@ -1,4546 +0,0 @@
-#include "Python.h"
-#include "structmember.h"
-
-PyDoc_STRVAR(pickle_module_doc,
-"Optimized C implementation for the Python pickle module.");
-
-/* Bump this when new opcodes are added to the pickle protocol. */
-enum {
-    HIGHEST_PROTOCOL = 3,
-    DEFAULT_PROTOCOL = 3
-};
-
-
-/* Pickle opcodes. These must be kept updated with pickle.py.
-   Extensive docs are in pickletools.py. */
-enum opcode {
-    MARK            = '(',
-    STOP            = '.',
-    POP             = '0',
-    POP_MARK        = '1',
-    DUP             = '2',
-    FLOAT           = 'F',
-    INT             = 'I',
-    BININT          = 'J',
-    BININT1         = 'K',
-    LONG            = 'L',
-    BININT2         = 'M',
-    NONE            = 'N',
-    PERSID          = 'P',
-    BINPERSID       = 'Q',
-    REDUCE          = 'R',
-    STRING          = 'S',
-    BINSTRING       = 'T',
-    SHORT_BINSTRING = 'U',
-    UNICODE         = 'V',
-    BINUNICODE      = 'X',
-    APPEND          = 'a',
-    BUILD           = 'b',
-    GLOBAL          = 'c',
-    DICT            = 'd',
-    EMPTY_DICT      = '}',
-    APPENDS         = 'e',
-    GET             = 'g',
-    BINGET          = 'h',
-    INST            = 'i',
-    LONG_BINGET     = 'j',
-    LIST            = 'l',
-    EMPTY_LIST      = ']',
-    OBJ             = 'o',
-    PUT             = 'p',
-    BINPUT          = 'q',
-    LONG_BINPUT     = 'r',
-    SETITEM         = 's',
-    TUPLE           = 't',
-    EMPTY_TUPLE     = ')',
-    SETITEMS        = 'u',
-    BINFLOAT        = 'G',
-
-    /* Protocol 2. */
-    PROTO       = '\x80',
-    NEWOBJ      = '\x81',
-    EXT1        = '\x82',
-    EXT2        = '\x83',
-    EXT4        = '\x84',
-    TUPLE1      = '\x85',
-    TUPLE2      = '\x86',
-    TUPLE3      = '\x87',
-    NEWTRUE     = '\x88',
-    NEWFALSE    = '\x89',
-    LONG1       = '\x8a',
-    LONG4       = '\x8b',
-
-    /* Protocol 3 (Python 3.x) */
-    BINBYTES       = 'B',
-    SHORT_BINBYTES = 'C',
-};
-
-/* These aren't opcodes -- they're ways to pickle bools before protocol 2
- * so that unpicklers written before bools were introduced unpickle them
- * as ints, but unpicklers after can recognize that bools were intended.
- * Note that protocol 2 added direct ways to pickle bools.
- */
-#undef TRUE
-#define TRUE  "I01\n"
-#undef FALSE
-#define FALSE "I00\n"
-
-enum {
-   /* Keep in synch with pickle.Pickler._BATCHSIZE.  This is how many elements
-      batch_list/dict() pumps out before doing APPENDS/SETITEMS.  Nothing will
-      break if this gets out of synch with pickle.py, but it's unclear that would
-      help anything either. */
-    BATCHSIZE = 1000,
-
-    /* Nesting limit until Pickler, when running in "fast mode", starts
-       checking for self-referential data-structures. */
-    FAST_NESTING_LIMIT = 50,
-
-    /* Size of the write buffer of Pickler. Higher values will reduce the
-       number of calls to the write() method of the output stream. */
-    WRITE_BUF_SIZE = 256,
-};
-
-/* Exception classes for pickle. These should override the ones defined in
-   pickle.py, when the C-optimized Pickler and Unpickler are used. */
-static PyObject *PickleError;
-static PyObject *PicklingError;
-static PyObject *UnpicklingError;
-
-/* copyreg.dispatch_table, {type_object: pickling_function} */
-static PyObject *dispatch_table;
-/* For EXT[124] opcodes. */
-/* copyreg._extension_registry, {(module_name, function_name): code} */
-static PyObject *extension_registry;
-/* copyreg._inverted_registry, {code: (module_name, function_name)} */
-static PyObject *inverted_registry;
-/* copyreg._extension_cache, {code: object} */
-static PyObject *extension_cache;
-
-/* XXX: Are these really nescessary? */
-/* As the name says, an empty tuple. */
-static PyObject *empty_tuple;
-/* For looking up name pairs in copyreg._extension_registry. */
-static PyObject *two_tuple;
-
-static int
-stack_underflow(void)
-{
-    PyErr_SetString(UnpicklingError, "unpickling stack underflow");
-    return -1;
-}
-
-/* Internal data type used as the unpickling stack. */
-typedef struct {
-    PyObject_HEAD
-    int length;   /* number of initial slots in data currently used */
-    int size;     /* number of slots in data allocated */
-    PyObject **data;
-} Pdata;
-
-static void
-Pdata_dealloc(Pdata *self)
-{
-    int i;
-    PyObject **p;
-
-    for (i = self->length, p = self->data; --i >= 0; p++) {
-        Py_DECREF(*p);
-    }
-    if (self->data)
-        PyMem_Free(self->data);
-    PyObject_Del(self);
-}
-
-static PyTypeObject Pdata_Type = {
-    PyVarObject_HEAD_INIT(NULL, 0)
-    "_pickle.Pdata",              /*tp_name*/
-    sizeof(Pdata),                /*tp_basicsize*/
-    0,                            /*tp_itemsize*/
-    (destructor)Pdata_dealloc,    /*tp_dealloc*/
-};
-
-static PyObject *
-Pdata_New(void)
-{
-    Pdata *self;
-
-    if (!(self = PyObject_New(Pdata, &Pdata_Type)))
-        return NULL;
-    self->size = 8;
-    self->length = 0;
-    self->data = PyMem_Malloc(self->size * sizeof(PyObject *));
-    if (self->data)
-        return (PyObject *)self;
-    Py_DECREF(self);
-    return PyErr_NoMemory();
-}
-
-
-/* Retain only the initial clearto items.  If clearto >= the current
- * number of items, this is a (non-erroneous) NOP.
- */
-static int
-Pdata_clear(Pdata *self, int clearto)
-{
-    int i;
-    PyObject **p;
-
-    if (clearto < 0)
-        return stack_underflow();
-    if (clearto >= self->length)
-        return 0;
-
-    for (i = self->length, p = self->data + clearto; --i >= clearto; p++) {
-        Py_CLEAR(*p);
-    }
-    self->length = clearto;
-
-    return 0;
-}
-
-static int
-Pdata_grow(Pdata *self)
-{
-    int bigger;
-    size_t nbytes;
-    PyObject **tmp;
-
-    bigger = (self->size << 1) + 1;
-    if (bigger <= 0)            /* was 0, or new value overflows */
-        goto nomemory;
-    if ((int)(size_t)bigger != bigger)
-        goto nomemory;
-    nbytes = (size_t)bigger * sizeof(PyObject *);
-    if (nbytes / sizeof(PyObject *) != (size_t)bigger)
-        goto nomemory;
-    tmp = PyMem_Realloc(self->data, nbytes);
-    if (tmp == NULL)
-        goto nomemory;
-    self->data = tmp;
-    self->size = bigger;
-    return 0;
-
-  nomemory:
-    PyErr_NoMemory();
-    return -1;
-}
-
-/* D is a Pdata*.  Pop the topmost element and store it into V, which
- * must be an lvalue holding PyObject*.  On stack underflow, UnpicklingError
- * is raised and V is set to NULL.
- */
-static PyObject *
-Pdata_pop(Pdata *self)
-{
-    if (self->length == 0) {
-        PyErr_SetString(UnpicklingError, "bad pickle data");
-        return NULL;
-    }
-    return self->data[--(self->length)];
-}
-#define PDATA_POP(D, V) do { (V) = Pdata_pop((D)); } while (0)
-
-static int
-Pdata_push(Pdata *self, PyObject *obj)
-{
-    if (self->length == self->size && Pdata_grow(self) < 0) {
-        return -1;
-    }
-    self->data[self->length++] = obj;
-    return 0;
-}
-
-/* Push an object on stack, transferring its ownership to the stack. */
-#define PDATA_PUSH(D, O, ER) do {                               \
-        if (Pdata_push((D), (O)) < 0) return (ER); } while(0)
-
-/* Push an object on stack, adding a new reference to the object. */
-#define PDATA_APPEND(D, O, ER) do {                             \
-        Py_INCREF((O));                                         \
-        if (Pdata_push((D), (O)) < 0) return (ER); } while(0)
-
-static PyObject *
-Pdata_poptuple(Pdata *self, Py_ssize_t start)
-{
-    PyObject *tuple;
-    Py_ssize_t len, i, j;
-
-    len = self->length - start;
-    tuple = PyTuple_New(len);
-    if (tuple == NULL)
-        return NULL;
-    for (i = start, j = 0; j < len; i++, j++)
-        PyTuple_SET_ITEM(tuple, j, self->data[i]);
-
-    self->length = start;
-    return tuple;
-}
-
-static PyObject *
-Pdata_poplist(Pdata *self, Py_ssize_t start)
-{
-    PyObject *list;
-    Py_ssize_t len, i, j;
-
-    len = self->length - start;
-    list = PyList_New(len);
-    if (list == NULL)
-        return NULL;
-    for (i = start, j = 0; j < len; i++, j++)
-        PyList_SET_ITEM(list, j, self->data[i]);
-
-    self->length = start;
-    return list;
-}
-
-typedef struct PicklerObject {
-    PyObject_HEAD
-    PyObject *write;            /* write() method of the output stream */
-    PyObject *memo;             /* Memo dictionary, keep track of the seen
-                                   objects to support self-referential objects
-                                   pickling.  */
-    PyObject *pers_func;        /* persistent_id() method, can be NULL */
-    PyObject *arg;
-    int proto;                  /* Pickle protocol number, >= 0 */
-    int bin;                    /* Boolean, true if proto > 0 */
-    int nesting;                /* Current nesting level, this is to guard
-                                   save() from going into infinite recursion
-                                   and segfaulting. */
-    int buf_size;               /* Size of the current buffered pickle data */
-    char *write_buf;            /* Write buffer, this is to avoid calling the
-                                   write() method of the output stream too
-                                   often. */
-    int fast;                   /* Enable fast mode if set to a true value.
-                                   The fast mode disable the usage of memo,
-                                   therefore speeding the pickling process by
-                                   not generating superfluous PUT opcodes. It
-                                   should not be used if with self-referential
-                                   objects. */
-    int fast_nesting;
-    PyObject *fast_memo;
-} PicklerObject;
-
-typedef struct UnpicklerObject {
-    PyObject_HEAD
-    Pdata *stack;               /* Pickle data stack, store unpickled objects. */
-    PyObject *readline;         /* readline() method of the output stream */
-    PyObject *read;             /* read() method of the output stream */
-    PyObject *memo;             /* Memo dictionary, provide the objects stored
-                                   using the PUT opcodes. */
-    PyObject *arg;
-    PyObject *pers_func;        /* persistent_load() method, can be NULL. */
-    PyObject *last_string;      /* Reference to the last string read by the
-                                   readline() method.  */
-    char *buffer;               /* Reading buffer. */
-    char *encoding;             /* Name of the encoding to be used for
-                                   decoding strings pickled using Python
-                                   2.x. The default value is "ASCII" */
-    char *errors;               /* Name of errors handling scheme to used when
-                                   decoding strings. The default value is
-                                   "strict". */
-    int *marks;                 /* Mark stack, used for unpickling container
-                                   objects. */
-    Py_ssize_t num_marks;       /* Number of marks in the mark stack. */
-    Py_ssize_t marks_size;      /* Current allocated size of the mark stack. */
-} UnpicklerObject;
-
-/* Forward declarations */
-static int save(PicklerObject *, PyObject *, int);
-static int save_reduce(PicklerObject *, PyObject *, PyObject *);
-static PyTypeObject Pickler_Type;
-static PyTypeObject Unpickler_Type;
-
-
-/* Helpers for creating the argument tuple passed to functions. This has the
-   performance advantage of calling PyTuple_New() only once. */
-
-#define ARG_TUP(self, obj) do {                             \
-        if ((self)->arg || ((self)->arg=PyTuple_New(1))) {  \
-            Py_XDECREF(PyTuple_GET_ITEM((self)->arg, 0));   \
-            PyTuple_SET_ITEM((self)->arg, 0, (obj));        \
-        }                                                   \
-        else {                                              \
-            Py_DECREF((obj));                               \
-        }                                                   \
-    } while (0)
-
-#define FREE_ARG_TUP(self) do {                 \
-        if ((self)->arg->ob_refcnt > 1)         \
-            Py_CLEAR((self)->arg);              \
-    } while (0)
-
-/* A temporary cleaner API for fast single argument function call.
-
-   XXX: Does caching the argument tuple provides any real performance benefits?
-
-   A quick benchmark, on a 2.0GHz Athlon64 3200+ running Linux 2.6.24 with
-   glibc 2.7, tells me that it takes roughly 20,000,000 PyTuple_New(1) calls
-   when the tuple is retrieved from the freelist (i.e, call PyTuple_New() then
-   immediately DECREF it) and 1,200,000 calls when allocating brand new tuples
-   (i.e, call PyTuple_New() and store the returned value in an array), to save
-   one second (wall clock time). Either ways, the loading time a pickle stream
-   large enough to generate this number of calls would be massively
-   overwhelmed by other factors, like I/O throughput, the GC traversal and
-   object allocation overhead. So, I really doubt these functions provide any
-   real benefits.
-
-   On the other hand, oprofile reports that pickle spends a lot of time in
-   these functions. But, that is probably more related to the function call
-   overhead, than the argument tuple allocation.
-
-   XXX: And, what is the reference behavior of these? Steal, borrow? At first
-   glance, it seems to steal the reference of 'arg' and borrow the reference
-   of 'func'.
- */
-static PyObject *
-pickler_call(PicklerObject *self, PyObject *func, PyObject *arg)
-{
-    PyObject *result = NULL;
-
-    ARG_TUP(self, arg);
-    if (self->arg) {
-        result = PyObject_Call(func, self->arg, NULL);
-        FREE_ARG_TUP(self);
-    }
-    return result;
-}
-
-static PyObject *
-unpickler_call(UnpicklerObject *self, PyObject *func, PyObject *arg)
-{
-    PyObject *result = NULL;
-
-    ARG_TUP(self, arg);
-    if (self->arg) {
-        result = PyObject_Call(func, self->arg, NULL);
-        FREE_ARG_TUP(self);
-    }
-    return result;
-}
-
-static Py_ssize_t
-pickler_write(PicklerObject *self, const char *s, Py_ssize_t n)
-{
-    PyObject *data, *result;
-
-    if (s == NULL) {
-        if (!(self->buf_size))
-            return 0;
-        data = PyBytes_FromStringAndSize(self->write_buf, self->buf_size);
-        if (data == NULL)
-            return -1;
-    }
-    else {
-        if (self->buf_size && (n + self->buf_size) > WRITE_BUF_SIZE) {
-            if (pickler_write(self, NULL, 0) < 0)
-                return -1;
-        }
-
-        if (n > WRITE_BUF_SIZE) {
-            if (!(data = PyBytes_FromStringAndSize(s, n)))
-                return -1;
-        }
-        else {
-            memcpy(self->write_buf + self->buf_size, s, n);
-            self->buf_size += n;
-            return n;
-        }
-    }
-
-    /* object with write method */
-    result = pickler_call(self, self->write, data);
-    if (result == NULL)
-        return -1;
-
-    Py_DECREF(result);
-    self->buf_size = 0;
-    return n;
-}
-
-/* XXX: These read/readline functions ought to be optimized. Buffered I/O
-   might help a lot, especially with the new (but much slower) io library.
-   On the other hand, the added complexity might not worth it.
- */
-
-/* Read at least n characters from the input stream and set s to the current
-   reading position. */
-static Py_ssize_t
-unpickler_read(UnpicklerObject *self, char **s, Py_ssize_t n)
-{
-    PyObject *len;
-    PyObject *data;
-
-    len = PyLong_FromSsize_t(n);
-    if (len == NULL)
-        return -1;
-
-    data = unpickler_call(self, self->read, len);
-    if (data == NULL)
-        return -1;
-
-    /* XXX: Should bytearray be supported too? */
-    if (!PyBytes_Check(data)) {
-        PyErr_SetString(PyExc_ValueError,
-                        "read() from the underlying stream did not"
-                        "return bytes");
-        return -1;
-    }
-
-    Py_XDECREF(self->last_string);
-    self->last_string = data;
-
-    if (!(*s = PyBytes_AS_STRING(data)))
-        return -1;
-
-    return n;
-}
-
-static Py_ssize_t
-unpickler_readline(UnpicklerObject *self, char **s)
-{
-    PyObject *data;
-
-    data = PyObject_CallObject(self->readline, empty_tuple);
-    if (data == NULL)
-        return -1;
-
-    /* XXX: Should bytearray be supported too? */
-    if (!PyBytes_Check(data)) {
-        PyErr_SetString(PyExc_ValueError,
-                        "readline() from the underlying stream did not"
-                        "return bytes");
-        return -1;
-    }
-
-    Py_XDECREF(self->last_string);
-    self->last_string = data;
-
-    if (!(*s = PyBytes_AS_STRING(data)))
-        return -1;
-
-    return PyBytes_GET_SIZE(data);
-}
-
-/* Generate a GET opcode for an object stored in the memo. The 'key' argument
-   should be the address of the object as returned by PyLong_FromVoidPtr(). */
-static int
-memo_get(PicklerObject *self, PyObject *key)
-{
-    PyObject *value;
-    PyObject *memo_id;
-    long x;
-    char pdata[30];
-    int len;
-
-    value = PyDict_GetItemWithError(self->memo, key);
-    if (value == NULL) {
-        if (!PyErr_Occurred())
-            PyErr_SetObject(PyExc_KeyError, key);
-        return -1;
-    }
-
-    memo_id = PyTuple_GetItem(value, 0);
-    if (memo_id == NULL)
-        return -1;
-
-    if (!PyLong_Check(memo_id)) {
-        PyErr_SetString(PicklingError, "memo id must be an integer");
-        return -1;
-    }
-    x = PyLong_AsLong(memo_id);
-    if (x == -1 && PyErr_Occurred())
-        return -1;
-
-    if (!self->bin) {
-        pdata[0] = GET;
-        PyOS_snprintf(pdata + 1, sizeof(pdata) - 1, "%ld\n", x);
-        len = (int)strlen(pdata);
-    }
-    else {
-        if (x < 256) {
-            pdata[0] = BINGET;
-            pdata[1] = (unsigned char)(x & 0xff);
-            len = 2;
-        }
-        else if (x <= 0xffffffffL) {
-            pdata[0] = LONG_BINGET;
-            pdata[1] = (unsigned char)(x & 0xff);
-            pdata[2] = (unsigned char)((x >> 8) & 0xff);
-            pdata[3] = (unsigned char)((x >> 16) & 0xff);
-            pdata[4] = (unsigned char)((x >> 24) & 0xff);
-            len = 5;
-        }
-        else { /* unlikely */
-            PyErr_SetString(PicklingError,
-                            "memo id too large for LONG_BINGET");
-            return -1;
-        }
-    }
-
-    if (pickler_write(self, pdata, len) < 0)
-        return -1;
-
-    return 0;
-}
-
-/* Store an object in the memo, assign it a new unique ID based on the number
-   of objects currently stored in the memo and generate a PUT opcode. */
-static int
-memo_put(PicklerObject *self, PyObject *obj)
-{
-    PyObject *key = NULL;
-    PyObject *memo_id = NULL;
-    PyObject *tuple = NULL;
-    long x;
-    char pdata[30];
-    int len;
-    int status = 0;
-
-    if (self->fast)
-        return 0;
-
-    key = PyLong_FromVoidPtr(obj);
-    if (key == NULL)
-        goto error;
-    if ((x = PyDict_Size(self->memo)) < 0)
-        goto error;
-    memo_id = PyLong_FromLong(x);
-    if (memo_id == NULL)
-        goto error;
-    tuple = PyTuple_New(2);
-    if (tuple == NULL)
-        goto error;
-
-    Py_INCREF(memo_id);
-    PyTuple_SET_ITEM(tuple, 0, memo_id);
-    Py_INCREF(obj);
-    PyTuple_SET_ITEM(tuple, 1, obj);
-    if (PyDict_SetItem(self->memo, key, tuple) < 0)
-        goto error;
-
-    if (!self->bin) {
-        pdata[0] = PUT;
-        PyOS_snprintf(pdata + 1, sizeof(pdata) - 1, "%ld\n", x);
-        len = strlen(pdata);
-    }
-    else {
-        if (x < 256) {
-            pdata[0] = BINPUT;
-            pdata[1] = x;
-            len = 2;
-        }
-        else if (x <= 0xffffffffL) {
-            pdata[0] = LONG_BINPUT;
-            pdata[1] = (unsigned char)(x & 0xff);
-            pdata[2] = (unsigned char)((x >> 8) & 0xff);
-            pdata[3] = (unsigned char)((x >> 16) & 0xff);
-            pdata[4] = (unsigned char)((x >> 24) & 0xff);
-            len = 5;
-        }
-        else { /* unlikely */
-            PyErr_SetString(PicklingError,
-                            "memo id too large for LONG_BINPUT");
-            return -1;
-        }
-    }
-
-    if (pickler_write(self, pdata, len) < 0)
-        goto error;
-
-    if (0) {
-  error:
-        status = -1;
-    }
-
-    Py_XDECREF(key);
-    Py_XDECREF(memo_id);
-    Py_XDECREF(tuple);
-
-    return status;
-}
-
-static PyObject *
-whichmodule(PyObject *global, PyObject *global_name)
-{
-    Py_ssize_t i, j;
-    static PyObject *module_str = NULL;
-    static PyObject *main_str = NULL;
-    PyObject *module_name;
-    PyObject *modules_dict;
-    PyObject *module;
-    PyObject *obj;
-
-    if (module_str == NULL) {
-        module_str = PyUnicode_InternFromString("__module__");
-        if (module_str == NULL)
-            return NULL;
-        main_str = PyUnicode_InternFromString("__main__");
-        if (main_str == NULL)
-            return NULL;
-    }
-
-    module_name = PyObject_GetAttr(global, module_str);
-
-    /* In some rare cases (e.g., random.getrandbits), __module__ can be
-       None. If it is so, then search sys.modules for the module of
-       global.  */
-    if (module_name == Py_None) {
-        Py_DECREF(module_name);
-        goto search;
-    }
-
-    if (module_name) {
-        return module_name;
-    }
-    if (PyErr_ExceptionMatches(PyExc_AttributeError))
-        PyErr_Clear();
-    else
-        return NULL;
-
-  search:
-    modules_dict = PySys_GetObject("modules");
-    if (modules_dict == NULL)
-        return NULL;
-
-    i = 0;
-    module_name = NULL;
-    while ((j = PyDict_Next(modules_dict, &i, &module_name, &module))) {
-        if (PyObject_Compare(module_name, main_str) == 0)
-            continue;
-
-        obj = PyObject_GetAttr(module, global_name);
-        if (obj == NULL) {
-            if (PyErr_ExceptionMatches(PyExc_AttributeError))
-                PyErr_Clear();
-            else
-                return NULL;
-            continue;
-        }
-
-        if (obj != global) {
-            Py_DECREF(obj);
-            continue;
-        }
-
-        Py_DECREF(obj);
-        break;
-    }
-
-    /* If no module is found, use __main__. */
-    if (!j) {
-        module_name = main_str;
-    }
-
-    Py_INCREF(module_name);
-    return module_name;
-}
-
-/* fast_save_enter() and fast_save_leave() are guards against recursive
-   objects when Pickler is used with the "fast mode" (i.e., with object
-   memoization disabled). If the nesting of a list or dict object exceed
-   FAST_NESTING_LIMIT, these guards will start keeping an internal
-   reference to the seen list or dict objects and check whether these objects
-   are recursive. These are not strictly necessary, since save() has a
-   hard-coded recursion limit, but they give a nicer error message than the
-   typical RuntimeError. */
-static int
-fast_save_enter(PicklerObject *self, PyObject *obj)
-{
-    /* if fast_nesting < 0, we're doing an error exit. */
-    if (++self->fast_nesting >= FAST_NESTING_LIMIT) {
-        PyObject *key = NULL;
-        if (self->fast_memo == NULL) {
-            self->fast_memo = PyDict_New();
-            if (self->fast_memo == NULL) {
-                self->fast_nesting = -1;
-                return 0;
-            }
-        }
-        key = PyLong_FromVoidPtr(obj);
-        if (key == NULL)
-            return 0;
-        if (PyDict_GetItem(self->fast_memo, key)) {
-            Py_DECREF(key);
-            PyErr_Format(PyExc_ValueError,
-                         "fast mode: can't pickle cyclic objects "
-                         "including object type %.200s at %p",
-                         obj->ob_type->tp_name, obj);
-            self->fast_nesting = -1;
-            return 0;
-        }
-        if (PyDict_SetItem(self->fast_memo, key, Py_None) < 0) {
-            Py_DECREF(key);
-            self->fast_nesting = -1;
-            return 0;
-        }
-        Py_DECREF(key);
-    }
-    return 1;
-}
-
-static int
-fast_save_leave(PicklerObject *self, PyObject *obj)
-{
-    if (self->fast_nesting-- >= FAST_NESTING_LIMIT) {
-        PyObject *key = PyLong_FromVoidPtr(obj);
-        if (key == NULL)
-            return 0;
-        if (PyDict_DelItem(self->fast_memo, key) < 0) {
-            Py_DECREF(key);
-            return 0;
-        }
-        Py_DECREF(key);
-    }
-    return 1;
-}
-
-static int
-save_none(PicklerObject *self, PyObject *obj)
-{
-    const char none_op = NONE;
-    if (pickler_write(self, &none_op, 1) < 0)
-        return -1;
-
-    return 0;
-}
-
-static int
-save_bool(PicklerObject *self, PyObject *obj)
-{
-    static const char *buf[2] = { FALSE, TRUE };
-    const char len[2] = {sizeof(FALSE) - 1, sizeof(TRUE) - 1};
-    int p = (obj == Py_True);
-
-    if (self->proto >= 2) {
-        const char bool_op = p ? NEWTRUE : NEWFALSE;
-        if (pickler_write(self, &bool_op, 1) < 0)
-            return -1;
-    }
-    else if (pickler_write(self, buf[p], len[p]) < 0)
-        return -1;
-
-    return 0;
-}
-
-static int
-save_int(PicklerObject *self, long x)
-{
-    char pdata[32];
-    int len = 0;
-
-    if (!self->bin
-#if SIZEOF_LONG > 4
-        || x > 0x7fffffffL || x < -0x80000000L
-#endif
-        ) {
-        /* Text-mode pickle, or long too big to fit in the 4-byte
-         * signed BININT format:  store as a string.
-         */
-        pdata[0] = LONG;        /* use LONG for consistence with pickle.py */
-        PyOS_snprintf(pdata + 1, sizeof(pdata) - 1, "%ld\n", x);
-        if (pickler_write(self, pdata, strlen(pdata)) < 0)
-            return -1;
-    }
-    else {
-        /* Binary pickle and x fits in a signed 4-byte int. */
-        pdata[1] = (unsigned char)(x & 0xff);
-        pdata[2] = (unsigned char)((x >> 8) & 0xff);
-        pdata[3] = (unsigned char)((x >> 16) & 0xff);
-        pdata[4] = (unsigned char)((x >> 24) & 0xff);
-
-        if ((pdata[4] == 0) && (pdata[3] == 0)) {
-            if (pdata[2] == 0) {
-                pdata[0] = BININT1;
-                len = 2;
-            }
-            else {
-                pdata[0] = BININT2;
-                len = 3;
-            }
-        }
-        else {
-            pdata[0] = BININT;
-            len = 5;
-        }
-
-        if (pickler_write(self, pdata, len) < 0)
-            return -1;
-    }
-
-    return 0;
-}
-
-static int
-save_long(PicklerObject *self, PyObject *obj)
-{
-    PyObject *repr = NULL;
-    Py_ssize_t size;
-    long val = PyLong_AsLong(obj);
-    int status = 0;
-
-    const char long_op = LONG;
-
-    if (val == -1 && PyErr_Occurred()) {
-        /* out of range for int pickling */
-        PyErr_Clear();
-    }
-    else
-        return save_int(self, val);
-
-    if (self->proto >= 2) {
-        /* Linear-time pickling. */
-        size_t nbits;
-        size_t nbytes;
-        unsigned char *pdata;
-        char header[5];
-        int i;
-        int sign = _PyLong_Sign(obj);
-
-        if (sign == 0) {
-            header[0] = LONG1;
-            header[1] = 0;      /* It's 0 -- an empty bytestring. */
-            if (pickler_write(self, header, 2) < 0)
-                goto error;
-            return 0;
-        }
-        nbits = _PyLong_NumBits(obj);
-        if (nbits == (size_t)-1 && PyErr_Occurred())
-            goto error;
-        /* How many bytes do we need?  There are nbits >> 3 full
-         * bytes of data, and nbits & 7 leftover bits.  If there
-         * are any leftover bits, then we clearly need another
-         * byte.  Wnat's not so obvious is that we *probably*
-         * need another byte even if there aren't any leftovers:
-         * the most-significant bit of the most-significant byte
-         * acts like a sign bit, and it's usually got a sense
-         * opposite of the one we need.  The exception is longs
-         * of the form -(2**(8*j-1)) for j > 0.  Such a long is
-         * its own 256's-complement, so has the right sign bit
-         * even without the extra byte.  That's a pain to check
-         * for in advance, though, so we always grab an extra
-         * byte at the start, and cut it back later if possible.
-         */
-        nbytes = (nbits >> 3) + 1;
-        if (nbytes > INT_MAX) {
-            PyErr_SetString(PyExc_OverflowError,
-                            "long too large to pickle");
-            goto error;
-        }
-        repr = PyUnicode_FromStringAndSize(NULL, (int)nbytes);
-        if (repr == NULL)
-            goto error;
-        pdata = (unsigned char *)PyUnicode_AsString(repr);
-        i = _PyLong_AsByteArray((PyLongObject *)obj,
-                                pdata, nbytes,
-                                1 /* little endian */ , 1 /* signed */ );
-        if (i < 0)
-            goto error;
-        /* If the long is negative, this may be a byte more than
-         * needed.  This is so iff the MSB is all redundant sign
-         * bits.
-         */
-        if (sign < 0 &&
-            nbytes > 1 && 
-            pdata[nbytes - 1] == 0xff &&
-            (pdata[nbytes - 2] & 0x80) != 0) {
-            nbytes--;
-        }
-
-        if (nbytes < 256) {
-            header[0] = LONG1;
-            header[1] = (unsigned char)nbytes;
-            size = 2;
-        }
-        else {
-            header[0] = LONG4;
-            size = (int)nbytes;
-            for (i = 1; i < 5; i++) {
-                header[i] = (unsigned char)(size & 0xff);
-                size >>= 8;
-            }
-            size = 5;
-        }
-        if (pickler_write(self, header, size) < 0 ||
-            pickler_write(self, (char *)pdata, (int)nbytes) < 0)
-            goto error;
-    }
-    else {
-        char *string;
-
-        /* proto < 2:  write the repr and newline.  This is quadratic-time
-           (in the number of digits), in both directions. */
-
-        repr = PyObject_Repr(obj);
-        if (repr == NULL)
-            goto error;
-
-        string = PyUnicode_AsStringAndSize(repr, &size);
-        if (string == NULL)
-            goto error;
-
-        if (pickler_write(self, &long_op, 1) < 0 ||
-            pickler_write(self, string, size) < 0 ||
-            pickler_write(self, "\n", 1) < 0)
-            goto error;
-    }
-
-    if (0) {
-  error:
-      status = -1;
-    }
-    Py_XDECREF(repr);
-
-    return status;
-}
-
-static int
-save_float(PicklerObject *self, PyObject *obj)
-{
-    double x = PyFloat_AS_DOUBLE((PyFloatObject *)obj);
-
-    if (self->bin) {
-        char pdata[9];
-        pdata[0] = BINFLOAT;
-        if (_PyFloat_Pack8(x, (unsigned char *)&pdata[1], 0) < 0)
-            return -1;
-        if (pickler_write(self, pdata, 9) < 0)
-            return -1;
-    }
-    else {
-        char pdata[250];
-        pdata[0] = FLOAT;
-        PyOS_ascii_formatd(pdata + 1, sizeof(pdata) - 2, "%.17g", x);
-        /* Extend the formatted string with a newline character */
-        strcat(pdata, "\n");
-
-        if (pickler_write(self, pdata, strlen(pdata)) < 0)
-            return -1;
-    }
-
-    return 0;
-}
-
-static int
-save_bytes(PicklerObject *self, PyObject *obj)
-{
-    if (self->proto < 3) {
-        /* Older pickle protocols do not have an opcode for pickling bytes
-           objects. Therefore, we need to fake the copy protocol (i.e.,
-           the __reduce__ method) to permit bytes object unpickling. */
-        PyObject *reduce_value = NULL;
-        PyObject *bytelist = NULL;
-        int status;
-
-        bytelist = PySequence_List(obj);
-        if (bytelist == NULL)
-            return -1;
-
-        reduce_value = Py_BuildValue("(O(O))", (PyObject *)&PyBytes_Type,
-                                     bytelist);
-        if (reduce_value == NULL) {
-            Py_DECREF(bytelist);
-            return -1;
-        }
-
-        /* save_reduce() will memoize the object automatically. */
-        status = save_reduce(self, reduce_value, obj);
-        Py_DECREF(reduce_value);
-        Py_DECREF(bytelist);
-        return status;
-    }
-    else {
-        Py_ssize_t size;
-        char header[5];
-        int len;
-
-        size = PyBytes_Size(obj);
-        if (size < 0)
-            return -1;
-
-        if (size < 256) {
-            header[0] = SHORT_BINBYTES;
-            header[1] = (unsigned char)size;
-            len = 2;
-        }
-        else if (size <= 0xffffffffL) {
-            header[0] = BINBYTES;
-            header[1] = (unsigned char)(size & 0xff);
-            header[2] = (unsigned char)((size >> 8) & 0xff);
-            header[3] = (unsigned char)((size >> 16) & 0xff);
-            header[4] = (unsigned char)((size >> 24) & 0xff);
-            len = 5;
-        }
-        else {
-            return -1;          /* string too large */
-        }
-
-        if (pickler_write(self, header, len) < 0)
-            return -1;
-
-        if (pickler_write(self, PyBytes_AS_STRING(obj), size) < 0)
-            return -1;
-
-        if (memo_put(self, obj) < 0)
-            return -1;
-
-        return 0;
-    }
-}
-
-/* A copy of PyUnicode_EncodeRawUnicodeEscape() that also translates
-   backslash and newline characters to \uXXXX escapes. */
-static PyObject *
-raw_unicode_escape(const Py_UNICODE *s, Py_ssize_t size)
-{
-    PyObject *repr, *result;
-    char *p;
-    char *q;
-
-    static const char *hexdigits = "0123456789abcdef";
-
-#ifdef Py_UNICODE_WIDE
-    repr = PyBytes_FromStringAndSize(NULL, 10 * size);
-#else
-    repr = PyBytes_FromStringAndSize(NULL, 6 * size);
-#endif
-    if (repr == NULL)
-        return NULL;
-    if (size == 0)
-        goto done;
-
-    p = q = PyBytes_AS_STRING(repr);
-    while (size-- > 0) {
-        Py_UNICODE ch = *s++;
-#ifdef Py_UNICODE_WIDE
-        /* Map 32-bit characters to '\Uxxxxxxxx' */
-        if (ch >= 0x10000) {
-            *p++ = '\\';
-            *p++ = 'U';
-            *p++ = hexdigits[(ch >> 28) & 0xf];
-            *p++ = hexdigits[(ch >> 24) & 0xf];
-            *p++ = hexdigits[(ch >> 20) & 0xf];
-            *p++ = hexdigits[(ch >> 16) & 0xf];
-            *p++ = hexdigits[(ch >> 12) & 0xf];
-            *p++ = hexdigits[(ch >> 8) & 0xf];
-            *p++ = hexdigits[(ch >> 4) & 0xf];
-            *p++ = hexdigits[ch & 15];
-        }
-        else
-#endif
-        /* Map 16-bit characters to '\uxxxx' */
-        if (ch >= 256 || ch == '\\' || ch == '\n') {
-            *p++ = '\\';
-            *p++ = 'u';
-            *p++ = hexdigits[(ch >> 12) & 0xf];
-            *p++ = hexdigits[(ch >> 8) & 0xf];
-            *p++ = hexdigits[(ch >> 4) & 0xf];
-            *p++ = hexdigits[ch & 15];
-        }
-	/* Copy everything else as-is */
-        else
-            *p++ = (char) ch;
-    }
-    size = p - q;
-
-  done:
-    result = PyBytes_FromStringAndSize(PyBytes_AS_STRING(repr), size);
-    Py_DECREF(repr);
-    return result;
-}
-
-static int
-save_unicode(PicklerObject *self, PyObject *obj)
-{
-    Py_ssize_t size;
-    PyObject *encoded = NULL;
-
-    if (self->bin) {
-        char pdata[5];
-
-        encoded = PyUnicode_AsUTF8String(obj);
-        if (encoded == NULL)
-            goto error;
-
-        size = PyBytes_GET_SIZE(encoded);
-        if (size < 0 || size > 0xffffffffL)
-            goto error;          /* string too large */
-
-        pdata[0] = BINUNICODE;
-        pdata[1] = (unsigned char)(size & 0xff);
-        pdata[2] = (unsigned char)((size >> 8) & 0xff);
-        pdata[3] = (unsigned char)((size >> 16) & 0xff);
-        pdata[4] = (unsigned char)((size >> 24) & 0xff);
-
-        if (pickler_write(self, pdata, 5) < 0)
-            goto error;
-
-        if (pickler_write(self, PyBytes_AS_STRING(encoded), size) < 0)
-            goto error;
-    }
-    else {
-        const char unicode_op = UNICODE;
-
-        encoded = raw_unicode_escape(PyUnicode_AS_UNICODE(obj),
-                                     PyUnicode_GET_SIZE(obj));
-        if (encoded == NULL)
-            goto error;
-
-        if (pickler_write(self, &unicode_op, 1) < 0)
-            goto error;
-
-        size = PyBytes_GET_SIZE(encoded);
-        if (pickler_write(self, PyBytes_AS_STRING(encoded), size) < 0)
-            goto error;
-
-        if (pickler_write(self, "\n", 1) < 0)
-            goto error;
-    }
-    if (memo_put(self, obj) < 0)
-        goto error;
-
-    Py_DECREF(encoded);
-    return 0;
-
-  error:
-    Py_XDECREF(encoded);
-    return -1;
-}
-
-/* A helper for save_tuple.  Push the len elements in tuple t on the stack. */
-static int
-store_tuple_elements(PicklerObject *self, PyObject *t, int len)
-{
-    int i;
-
-    assert(PyTuple_Size(t) == len);
-
-    for (i = 0; i < len; i++) {
-        PyObject *element = PyTuple_GET_ITEM(t, i);
-
-        if (element == NULL)
-            return -1;
-        if (save(self, element, 0) < 0)
-            return -1;
-    }
-
-    return 0;
-}
-
-/* Tuples are ubiquitous in the pickle protocols, so many techniques are
- * used across protocols to minimize the space needed to pickle them.
- * Tuples are also the only builtin immutable type that can be recursive
- * (a tuple can be reached from itself), and that requires some subtle
- * magic so that it works in all cases.  IOW, this is a long routine.
- */
-static int
-save_tuple(PicklerObject *self, PyObject *obj)
-{
-    PyObject *memo_key = NULL;
-    int len, i;
-    int status = 0;
-
-    const char mark_op = MARK;
-    const char tuple_op = TUPLE;
-    const char pop_op = POP;
-    const char pop_mark_op = POP_MARK;
-    const char len2opcode[] = {EMPTY_TUPLE, TUPLE1, TUPLE2, TUPLE3};
-
-    if ((len = PyTuple_Size(obj)) < 0)
-        return -1;
-
-    if (len == 0) {
-        char pdata[2];
-
-        if (self->proto) {
-            pdata[0] = EMPTY_TUPLE;
-            len = 1;
-        }
-        else {
-            pdata[0] = MARK;
-            pdata[1] = TUPLE;
-            len = 2;
-        }
-        if (pickler_write(self, pdata, len) < 0)
-            return -1;
-        return 0;
-    }
-
-    /* id(tuple) isn't in the memo now.  If it shows up there after
-     * saving the tuple elements, the tuple must be recursive, in
-     * which case we'll pop everything we put on the stack, and fetch
-     * its value from the memo.
-     */
-    memo_key = PyLong_FromVoidPtr(obj);
-    if (memo_key == NULL)
-        return -1;
-
-    if (len <= 3 && self->proto >= 2) {
-        /* Use TUPLE{1,2,3} opcodes. */
-        if (store_tuple_elements(self, obj, len) < 0)
-            goto error;
-
-        if (PyDict_GetItem(self->memo, memo_key)) {
-            /* pop the len elements */
-            for (i = 0; i < len; i++)
-                if (pickler_write(self, &pop_op, 1) < 0)
-                    goto error;
-            /* fetch from memo */
-            if (memo_get(self, memo_key) < 0)
-                goto error;
-
-            Py_DECREF(memo_key);
-            return 0;
-        }
-        else { /* Not recursive. */
-            if (pickler_write(self, len2opcode + len, 1) < 0)
-                goto error;
-        }
-        goto memoize;
-    }
-
-    /* proto < 2 and len > 0, or proto >= 2 and len > 3.
-     * Generate MARK e1 e2 ... TUPLE
-     */
-    if (pickler_write(self, &mark_op, 1) < 0)
-        goto error;
-
-    if (store_tuple_elements(self, obj, len) < 0)
-        goto error;
-
-    if (PyDict_GetItem(self->memo, memo_key)) {
-        /* pop the stack stuff we pushed */
-        if (self->bin) {
-            if (pickler_write(self, &pop_mark_op, 1) < 0)
-                goto error;
-        }
-        else {
-            /* Note that we pop one more than len, to remove
-             * the MARK too.
-             */
-            for (i = 0; i <= len; i++)
-                if (pickler_write(self, &pop_op, 1) < 0)
-                    goto error;
-        }
-        /* fetch from memo */
-        if (memo_get(self, memo_key) < 0)
-            goto error;
-
-        Py_DECREF(memo_key);
-        return 0;
-    }
-    else { /* Not recursive. */
-        if (pickler_write(self, &tuple_op, 1) < 0)
-            goto error;
-    }
-
-  memoize:
-    if (memo_put(self, obj) < 0)
-        goto error;
-
-    if (0) {
-  error:
-        status = -1;
-    }
-
-    Py_DECREF(memo_key);
-    return status;
-}
-
-/* iter is an iterator giving items, and we batch up chunks of
- *     MARK item item ... item APPENDS
- * opcode sequences.  Calling code should have arranged to first create an
- * empty list, or list-like object, for the APPENDS to operate on.
- * Returns 0 on success, <0 on error.
- */
-static int
-batch_list(PicklerObject *self, PyObject *iter)
-{
-    PyObject *obj;
-    PyObject *slice[BATCHSIZE];
-    int i, n;
-
-    const char mark_op = MARK;
-    const char append_op = APPEND;
-    const char appends_op = APPENDS;
-
-    assert(iter != NULL);
-
-    /* XXX: I think this function could be made faster by avoiding the
-       iterator interface and fetching objects directly from list using
-       PyList_GET_ITEM.
-    */
-
-    if (self->proto == 0) {
-        /* APPENDS isn't available; do one at a time. */
-        for (;;) {
-            obj = PyIter_Next(iter);
-            if (obj == NULL) {
-                if (PyErr_Occurred())
-                    return -1;
-                break;
-            }
-            i = save(self, obj, 0);
-            Py_DECREF(obj);
-            if (i < 0)
-                return -1;
-            if (pickler_write(self, &append_op, 1) < 0)
-                return -1;
-        }
-        return 0;
-    }
-
-    /* proto > 0:  write in batches of BATCHSIZE. */
-    do {
-        /* Get next group of (no more than) BATCHSIZE elements. */
-        for (n = 0; n < BATCHSIZE; n++) {
-            obj = PyIter_Next(iter);
-            if (obj == NULL) {
-                if (PyErr_Occurred())
-                    goto error;
-                break;
-            }
-            slice[n] = obj;
-        }
-
-        if (n > 1) {
-            /* Pump out MARK, slice[0:n], APPENDS. */
-            if (pickler_write(self, &mark_op, 1) < 0)
-                goto error;
-            for (i = 0; i < n; i++) {
-                if (save(self, slice[i], 0) < 0)
-                    goto error;
-            }
-            if (pickler_write(self, &appends_op, 1) < 0)
-                goto error;
-        }
-        else if (n == 1) {
-            if (save(self, slice[0], 0) < 0 || 
-                pickler_write(self, &append_op, 1) < 0)
-                goto error;
-        }
-
-        for (i = 0; i < n; i++) {
-            Py_DECREF(slice[i]);
-        }
-    } while (n == BATCHSIZE);
-    return 0;
-
-  error:
-    while (--n >= 0) {
-        Py_DECREF(slice[n]);
-    }
-    return -1;
-}
-
-static int
-save_list(PicklerObject *self, PyObject *obj)
-{
-    PyObject *iter;
-    char header[3];
-    int len;
-    int status = 0;
-
-    if (self->fast && !fast_save_enter(self, obj))
-        goto error;
-
-    /* Create an empty list. */
-    if (self->bin) {
-        header[0] = EMPTY_LIST;
-        len = 1;
-    }
-    else {
-        header[0] = MARK;
-        header[1] = LIST;
-        len = 2;
-    }
-
-    if (pickler_write(self, header, len) < 0)
-        goto error;
-
-    /* Get list length, and bow out early if empty. */
-    if ((len = PyList_Size(obj)) < 0)
-        goto error;
-
-    if (memo_put(self, obj) < 0)
-        goto error;
-
-    if (len != 0) {
-        /* Save the list elements. */
-        iter = PyObject_GetIter(obj);
-        if (iter == NULL)
-            goto error;
-        status = batch_list(self, iter);
-        Py_DECREF(iter);
-    }
-
-    if (0) {
-  error:
-        status = -1;
-    }
-
-    if (self->fast && !fast_save_leave(self, obj))
-        status = -1;
-
-    return status;
-}
-
-/* iter is an iterator giving (key, value) pairs, and we batch up chunks of
- *     MARK key value ... key value SETITEMS
- * opcode sequences.  Calling code should have arranged to first create an
- * empty dict, or dict-like object, for the SETITEMS to operate on.
- * Returns 0 on success, <0 on error.
- *
- * This is very much like batch_list().  The difference between saving
- * elements directly, and picking apart two-tuples, is so long-winded at
- * the C level, though, that attempts to combine these routines were too
- * ugly to bear.
- */
-static int
-batch_dict(PicklerObject *self, PyObject *iter)
-{
-    PyObject *obj;
-    PyObject *slice[BATCHSIZE];
-    int i, n;
-
-    const char mark_op = MARK;
-    const char setitem_op = SETITEM;
-    const char setitems_op = SETITEMS;
-
-    assert(iter != NULL);
-
-    if (self->proto == 0) {
-        /* SETITEMS isn't available; do one at a time. */
-        for (;;) {
-            obj = PyIter_Next(iter);
-            if (obj == NULL) {
-                if (PyErr_Occurred())
-                    return -1;
-                break;
-            }
-            if (!PyTuple_Check(obj) || PyTuple_Size(obj) != 2) {
-                PyErr_SetString(PyExc_TypeError, "dict items "
-                                "iterator must return 2-tuples");
-                return -1;
-            }
-            i = save(self, PyTuple_GET_ITEM(obj, 0), 0);
-            if (i >= 0)
-                i = save(self, PyTuple_GET_ITEM(obj, 1), 0);
-            Py_DECREF(obj);
-            if (i < 0)
-                return -1;
-            if (pickler_write(self, &setitem_op, 1) < 0)
-                return -1;
-        }
-        return 0;
-    }
-
-    /* proto > 0:  write in batches of BATCHSIZE. */
-    do {
-        /* Get next group of (no more than) BATCHSIZE elements. */
-        for (n = 0; n < BATCHSIZE; n++) {
-            obj = PyIter_Next(iter);
-            if (obj == NULL) {
-                if (PyErr_Occurred())
-                    goto error;
-                break;
-            }
-            if (!PyTuple_Check(obj) || PyTuple_Size(obj) != 2) {
-                PyErr_SetString(PyExc_TypeError, "dict items "
-                                "iterator must return 2-tuples");
-                goto error;
-            }
-            slice[n] = obj;
-        }
-
-        if (n > 1) {
-            /* Pump out MARK, slice[0:n], SETITEMS. */
-            if (pickler_write(self, &mark_op, 1) < 0)
-                goto error;
-            for (i = 0; i < n; i++) {
-                obj = slice[i];
-                if (save(self, PyTuple_GET_ITEM(obj, 0), 0) < 0 ||
-                    save(self, PyTuple_GET_ITEM(obj, 1), 0) < 0)
-                    goto error;
-            }
-            if (pickler_write(self, &setitems_op, 1) < 0)
-                goto error;
-        }
-        else if (n == 1) {
-            obj = slice[0];
-            if (save(self, PyTuple_GET_ITEM(obj, 0), 0) < 0 ||
-                save(self, PyTuple_GET_ITEM(obj, 1), 0) < 0 ||
-                pickler_write(self, &setitem_op, 1) < 0)
-                goto error;
-        }
-
-        for (i = 0; i < n; i++) {
-            Py_DECREF(slice[i]);
-        }
-    } while (n == BATCHSIZE);
-    return 0;
-
-  error:
-    while (--n >= 0) {
-        Py_DECREF(slice[n]);
-    }
-    return -1;
-}
-
-static int
-save_dict(PicklerObject *self, PyObject *obj)
-{
-    PyObject *items, *iter;
-    char header[3];
-    int len;
-    int status = 0;
-
-    if (self->fast && !fast_save_enter(self, obj))
-        goto error;
-
-    /* Create an empty dict. */
-    if (self->bin) {
-        header[0] = EMPTY_DICT;
-        len = 1;
-    }
-    else {
-        header[0] = MARK;
-        header[1] = DICT;
-        len = 2;
-    }
-
-    if (pickler_write(self, header, len) < 0)
-        goto error;
-
-    /* Get dict size, and bow out early if empty. */
-    if ((len = PyDict_Size(obj)) < 0)
-        goto error;
-
-    if (memo_put(self, obj) < 0)
-        goto error;
-
-    if (len != 0) {
-        /* Save the dict items. */
-        items = PyObject_CallMethod(obj, "items", "()");
-        if (items == NULL)
-            goto error;
-        iter = PyObject_GetIter(items);
-        Py_DECREF(items);
-        if (iter == NULL)
-            goto error;
-        status = batch_dict(self, iter);
-        Py_DECREF(iter);
-    }
-
-    if (0) {
-  error:
-        status = -1;
-    }
-
-    if (self->fast && !fast_save_leave(self, obj))
-        status = -1;
-
-    return status;
-}
-
-static int
-save_global(PicklerObject *self, PyObject *obj, PyObject *name)
-{
-    static PyObject *name_str = NULL;
-    PyObject *global_name = NULL;
-    PyObject *module_name = NULL;
-    PyObject *module = NULL;
-    PyObject *cls;
-    int status = 0;
-
-    const char global_op = GLOBAL;
-
-    if (name_str == NULL) {
-        name_str = PyUnicode_InternFromString("__name__");
-        if (name_str == NULL)
-            goto error;
-    }
-
-    if (name) {
-        global_name = name;
-        Py_INCREF(global_name);
-    }
-    else {
-        global_name = PyObject_GetAttr(obj, name_str);
-        if (global_name == NULL)
-            goto error;
-    }
-
-    module_name = whichmodule(obj, global_name);
-    if (module_name == NULL)
-        goto error;
-
-    /* XXX: Change to use the import C API directly with level=0 to disallow
-       relative imports.
-
-       XXX: PyImport_ImportModuleLevel could be used. However, this bypasses
-       builtins.__import__. Therefore, _pickle, unlike pickle.py, will ignore
-       custom import functions (IMHO, this would be a nice security
-       feature). The import C API would need to be extended to support the
-       extra parameters of __import__ to fix that. */
-    module = PyImport_Import(module_name);
-    if (module == NULL) {
-        PyErr_Format(PicklingError,
-                     "Can't pickle %R: import of module %R failed",
-                     obj, module_name);
-        goto error;
-    }
-    cls = PyObject_GetAttr(module, global_name);
-    if (cls == NULL) {
-        PyErr_Format(PicklingError,
-                     "Can't pickle %R: attribute lookup %S.%S failed",
-                     obj, module_name, global_name);
-        goto error;
-    }
-    if (cls != obj) {
-        Py_DECREF(cls);
-        PyErr_Format(PicklingError,
-                     "Can't pickle %R: it's not the same object as %S.%S",
-                     obj, module_name, global_name);
-        goto error;
-    }
-    Py_DECREF(cls);
-
-    if (self->proto >= 2) {
-        /* See whether this is in the extension registry, and if
-         * so generate an EXT opcode.
-         */
-        PyObject *code_obj;      /* extension code as Python object */
-        long code;               /* extension code as C value */
-        char pdata[5];
-        int n;
-
-        PyTuple_SET_ITEM(two_tuple, 0, module_name);
-        PyTuple_SET_ITEM(two_tuple, 1, global_name);
-        code_obj = PyDict_GetItem(extension_registry, two_tuple);
-        /* The object is not registered in the extension registry.
-           This is the most likely code path. */
-        if (code_obj == NULL)
-            goto gen_global;
-
-        /* XXX: pickle.py doesn't check neither the type, nor the range
-           of the value returned by the extension_registry. It should for
-           consistency. */
-
-        /* Verify code_obj has the right type and value. */
-        if (!PyLong_Check(code_obj)) {
-            PyErr_Format(PicklingError,
-                         "Can't pickle %R: extension code %R isn't an integer",
-                         obj, code_obj);
-            goto error;
-        }
-        code = PyLong_AS_LONG(code_obj);
-        if (code <= 0 || code > 0x7fffffffL) {
-            PyErr_Format(PicklingError,
-                         "Can't pickle %R: extension code %ld is out of range",
-                         obj, code);
-            goto error;
-        }
-
-        /* Generate an EXT opcode. */
-        if (code <= 0xff) {
-            pdata[0] = EXT1;
-            pdata[1] = (unsigned char)code;
-            n = 2;
-        }
-        else if (code <= 0xffff) {
-            pdata[0] = EXT2;
-            pdata[1] = (unsigned char)(code & 0xff);
-            pdata[2] = (unsigned char)((code >> 8) & 0xff);
-            n = 3;
-        }
-        else {
-            pdata[0] = EXT4;
-            pdata[1] = (unsigned char)(code & 0xff);
-            pdata[2] = (unsigned char)((code >> 8) & 0xff);
-            pdata[3] = (unsigned char)((code >> 16) & 0xff);
-            pdata[4] = (unsigned char)((code >> 24) & 0xff);
-            n = 5;
-        }
-
-        if (pickler_write(self, pdata, n) < 0)
-            goto error;
-    }
-    else {
-        /* Generate a normal global opcode if we are using a pickle
-           protocol <= 2, or if the object is not registered in the
-           extension registry. */
-        PyObject *encoded;
-        PyObject *(*unicode_encoder)(PyObject *);
-
-  gen_global:
-        if (pickler_write(self, &global_op, 1) < 0)
-            goto error;
-
-        /* Since Python 3.0 now supports non-ASCII identifiers, we encode both
-           the module name and the global name using UTF-8. We do so only when
-           we are using the pickle protocol newer than version 3. This is to
-           ensure compatibility with older Unpickler running on Python 2.x. */
-        if (self->proto >= 3) {
-            unicode_encoder = PyUnicode_AsUTF8String;
-        }
-        else {
-            unicode_encoder = PyUnicode_AsASCIIString;
-        }
-
-        /* Save the name of the module. */
-        encoded = unicode_encoder(module_name);
-        if (encoded == NULL) {
-            if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError))
-                PyErr_Format(PicklingError,
-                             "can't pickle module identifier '%S' using "
-                             "pickle protocol %i", module_name, self->proto);
-            goto error;
-        }
-        if (pickler_write(self, PyBytes_AS_STRING(encoded),
-                          PyBytes_GET_SIZE(encoded)) < 0) {
-            Py_DECREF(encoded);
-            goto error;
-        }
-        Py_DECREF(encoded);
-        if(pickler_write(self, "\n", 1) < 0)
-            goto error;
-
-        /* Save the name of the module. */
-        encoded = unicode_encoder(global_name);
-        if (encoded == NULL) {
-            if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError))
-                PyErr_Format(PicklingError,
-                             "can't pickle global identifier '%S' using "
-                             "pickle protocol %i", global_name, self->proto);
-            goto error;
-        }
-        if (pickler_write(self, PyBytes_AS_STRING(encoded),
-                          PyBytes_GET_SIZE(encoded)) < 0) {
-            Py_DECREF(encoded);
-            goto error;
-        }
-        Py_DECREF(encoded);
-        if(pickler_write(self, "\n", 1) < 0)
-            goto error;
-
-        /* Memoize the object. */
-        if (memo_put(self, obj) < 0)
-            goto error;
-    }
-
-    if (0) {
-  error:
-        status = -1;
-    }
-    Py_XDECREF(module_name);
-    Py_XDECREF(global_name);
-    Py_XDECREF(module);
-
-    return status;
-}
-
-static int
-save_pers(PicklerObject *self, PyObject *obj, PyObject *func)
-{
-    PyObject *pid = NULL;
-    int status = 0;
-
-    const char persid_op = PERSID;
-    const char binpersid_op = BINPERSID;
-
-    Py_INCREF(obj);
-    pid = pickler_call(self, func, obj);
-    if (pid == NULL)
-        return -1;
-
-    if (pid != Py_None) {
-        if (self->bin) {
-            if (save(self, pid, 1) < 0 ||
-                pickler_write(self, &binpersid_op, 1) < 0)
-                goto error;
-        }
-        else {
-            PyObject *pid_str = NULL;
-            char *pid_ascii_bytes;
-            Py_ssize_t size;
-
-            pid_str = PyObject_Str(pid);
-            if (pid_str == NULL)
-                goto error;
-
-            /* XXX: Should it check whether the persistent id only contains
-               ASCII characters? And what if the pid contains embedded
-               newlines? */
-            pid_ascii_bytes = PyUnicode_AsStringAndSize(pid_str, &size);
-            Py_DECREF(pid_str);
-            if (pid_ascii_bytes == NULL)
-                goto error;
-
-            if (pickler_write(self, &persid_op, 1) < 0 ||
-                pickler_write(self, pid_ascii_bytes, size) < 0 ||
-                pickler_write(self, "\n", 1) < 0)
-                goto error;
-        }
-        status = 1;
-    }
-
-    if (0) {
-  error:
-        status = -1;
-    }
-    Py_XDECREF(pid);
-
-    return status;
-}
-
-/* We're saving obj, and args is the 2-thru-5 tuple returned by the
- * appropriate __reduce__ method for obj.
- */
-static int
-save_reduce(PicklerObject *self, PyObject *args, PyObject *obj)
-{
-    PyObject *callable;
-    PyObject *argtup;
-    PyObject *state = NULL;
-    PyObject *listitems = NULL;
-    PyObject *dictitems = NULL;
-
-    int use_newobj = self->proto >= 2;
-
-    const char reduce_op = REDUCE;
-    const char build_op = BUILD;
-    const char newobj_op = NEWOBJ;
-
-    if (!PyArg_UnpackTuple(args, "save_reduce", 2, 5,
-                           &callable, &argtup, &state, &listitems, &dictitems))
-        return -1;
-
-    if (!PyCallable_Check(callable)) {
-        PyErr_SetString(PicklingError,
-                        "first argument of save_reduce() must be callable");
-        return -1;
-    }
-    if (!PyTuple_Check(argtup)) {
-        PyErr_SetString(PicklingError,
-                        "second argument of save_reduce() must be a tuple");
-        return -1;
-    }
-
-    if (state == Py_None)
-        state = NULL;
-    if (listitems == Py_None)
-        listitems = NULL;
-    if (dictitems == Py_None)
-        dictitems = NULL;
-
-    /* Protocol 2 special case: if callable's name is __newobj__, use
-       NEWOBJ. */
-    if (use_newobj) {
-        static PyObject *newobj_str = NULL;
-        PyObject *name_str;
-
-        if (newobj_str == NULL) {
-            newobj_str = PyUnicode_InternFromString("__newobj__");
-        }
-
-        name_str = PyObject_GetAttrString(callable, "__name__");
-        if (name_str == NULL) {
-            if (PyErr_ExceptionMatches(PyExc_AttributeError))
-                PyErr_Clear();
-            else
-                return -1;
-            use_newobj = 0;
-        }
-        else {
-            use_newobj = PyUnicode_Check(name_str) && 
-                PyUnicode_Compare(name_str, newobj_str) == 0;
-            Py_DECREF(name_str);
-        }
-    }
-    if (use_newobj) {
-        PyObject *cls;
-        PyObject *newargtup;
-        PyObject *obj_class;
-        int p;
-
-        /* Sanity checks. */
-        if (Py_SIZE(argtup) < 1) {
-            PyErr_SetString(PicklingError, "__newobj__ arglist is empty");
-            return -1;
-        }
-
-        cls = PyTuple_GET_ITEM(argtup, 0);
-        if (!PyObject_HasAttrString(cls, "__new__")) {
-            PyErr_SetString(PicklingError, "args[0] from "
-                            "__newobj__ args has no __new__");
-            return -1;
-        }
-
-        if (obj != NULL) {
-            obj_class = PyObject_GetAttrString(obj, "__class__");
-            if (obj_class == NULL) {
-                if (PyErr_ExceptionMatches(PyExc_AttributeError))
-                    PyErr_Clear();
-                else
-                    return -1;
-            }
-            p = obj_class != cls;    /* true iff a problem */
-            Py_DECREF(obj_class);
-            if (p) {
-                PyErr_SetString(PicklingError, "args[0] from "
-                                "__newobj__ args has the wrong class");
-                return -1;
-            }
-        }
-        /* XXX: These calls save() are prone to infinite recursion. Imagine
-           what happen if the value returned by the __reduce__() method of
-           some extension type contains another object of the same type. Ouch!
-
-           Here is a quick example, that I ran into, to illustrate what I
-           mean:
-
-             >>> import pickle, copyreg
-             >>> copyreg.dispatch_table.pop(complex)
-             >>> pickle.dumps(1+2j)
-             Traceback (most recent call last):
-               ...
-             RuntimeError: maximum recursion depth exceeded
-
-           Removing the complex class from copyreg.dispatch_table made the
-           __reduce_ex__() method emit another complex object:
-
-             >>> (1+1j).__reduce_ex__(2)
-             (<function __newobj__ at 0xb7b71c3c>,
-               (<class 'complex'>, (1+1j)), None, None, None)
-
-           Thus when save() was called on newargstup (the 2nd item) recursion
-           ensued. Of course, the bug was in the complex class which had a
-           broken __getnewargs__() that emitted another complex object. But,
-           the point, here, is it is quite easy to end up with a broken reduce
-           function. */
-
-        /* Save the class and its __new__ arguments. */
-        if (save(self, cls, 0) < 0)
-            return -1;
-
-        newargtup = PyTuple_GetSlice(argtup, 1, Py_SIZE(argtup));
-        if (newargtup == NULL)
-            return -1;
-
-        p = save(self, newargtup, 0);
-        Py_DECREF(newargtup);
-        if (p < 0)
-            return -1;
-
-        /* Add NEWOBJ opcode. */
-        if (pickler_write(self, &newobj_op, 1) < 0)
-            return -1;
-    }
-    else { /* Not using NEWOBJ. */
-        if (save(self, callable, 0) < 0 ||
-            save(self, argtup, 0) < 0 ||
-            pickler_write(self, &reduce_op, 1) < 0)
-            return -1;
-    }
-
-    /* obj can be NULL when save_reduce() is used directly. A NULL obj means
-       the caller do not want to memoize the object. Not particularly useful,
-       but that is to mimic the behavior save_reduce() in pickle.py when
-       obj is None. */
-    if (obj && memo_put(self, obj) < 0)
-        return -1;
-
-    if (listitems && batch_list(self, listitems) < 0)
-        return -1;
-
-    if (dictitems && batch_dict(self, dictitems) < 0)
-        return -1;
-
-    if (state) {
-        if (save(self, state, 0) < 0 || 
-            pickler_write(self, &build_op, 1) < 0)
-            return -1;
-    }
-
-    return 0;
-}
-
-static int
-save(PicklerObject *self, PyObject *obj, int pers_save)
-{
-    PyTypeObject *type;
-    PyObject *reduce_func = NULL;
-    PyObject *reduce_value = NULL;
-    PyObject *memo_key = NULL;
-    int status = 0;
-
-    /* XXX: Use Py_EnterRecursiveCall()? */
-    if (++self->nesting > Py_GetRecursionLimit()) {
-        PyErr_SetString(PyExc_RuntimeError,
-                        "maximum recursion depth exceeded");
-        goto error;
-    }
-
-    /* The extra pers_save argument is necessary to avoid calling save_pers()
-       on its returned object. */
-    if (!pers_save && self->pers_func) {
-        /* save_pers() returns:
-            -1   to signal an error;
-             0   if it did nothing successfully;
-             1   if a persistent id was saved.
-         */
-        if ((status = save_pers(self, obj, self->pers_func)) != 0)
-            goto done;
-    }
-
-    type = Py_TYPE(obj);
-
-    /* XXX: The old cPickle had an optimization that used switch-case
-       statement dispatching on the first letter of the type name. It was
-       probably not a bad idea after all. If benchmarks shows that particular
-       optimization had some real benefits, it would be nice to add it
-       back. */
-
-    /* Atom types; these aren't memoized, so don't check the memo. */
-
-    if (obj == Py_None) {
-        status = save_none(self, obj);
-        goto done;
-    }
-    else if (obj == Py_False || obj == Py_True) {
-        status = save_bool(self, obj);
-        goto done;
-    }
-    else if (type == &PyLong_Type) {
-        status = save_long(self, obj);
-        goto done;
-    }
-    else if (type == &PyFloat_Type) {
-        status = save_float(self, obj);
-        goto done;
-    }
-
-    /* Check the memo to see if it has the object. If so, generate
-       a GET (or BINGET) opcode, instead of pickling the object
-       once again. */
-    memo_key = PyLong_FromVoidPtr(obj);
-    if (memo_key == NULL)
-        goto error;
-    if (PyDict_GetItem(self->memo, memo_key)) {
-        if (memo_get(self, memo_key) < 0)
-            goto error;
-        goto done;
-    }
-
-    if (type == &PyBytes_Type) {
-        status = save_bytes(self, obj);
-        goto done;
-    }
-    else if (type == &PyUnicode_Type) {
-        status = save_unicode(self, obj);
-        goto done;
-    }
-    else if (type == &PyDict_Type) {
-        status = save_dict(self, obj);
-        goto done;
-    }
-    else if (type == &PyList_Type) {
-        status = save_list(self, obj);
-        goto done;
-    }
-    else if (type == &PyTuple_Type) {
-        status = save_tuple(self, obj);
-        goto done;
-    }
-    else if (type == &PyType_Type) {
-        status = save_global(self, obj, NULL);
-        goto done;
-    }
-    else if (type == &PyFunction_Type) {
-        status = save_global(self, obj, NULL);
-        if (status < 0 && PyErr_ExceptionMatches(PickleError)) {
-            /* fall back to reduce */
-            PyErr_Clear();
-        }
-        else {
-            goto done;
-        }
-    }
-    else if (type == &PyCFunction_Type) {
-        status = save_global(self, obj, NULL);
-        goto done;
-    }
-    else if (PyType_IsSubtype(type, &PyType_Type)) {
-        status = save_global(self, obj, NULL);
-        goto done;
-    }
-
-    /* XXX: This part needs some unit tests. */
-
-    /* Get a reduction callable, and call it.  This may come from
-     * copyreg.dispatch_table, the object's __reduce_ex__ method,
-     * or the object's __reduce__ method.
-     */
-    reduce_func = PyDict_GetItem(dispatch_table, (PyObject *)type);
-    if (reduce_func != NULL) {
-        /* Here, the reference count of the reduce_func object returned by
-           PyDict_GetItem needs to be increased to be consistent with the one
-           returned by PyObject_GetAttr. This is allow us to blindly DECREF
-           reduce_func at the end of the save() routine.
-        */
-        Py_INCREF(reduce_func);
-        Py_INCREF(obj);
-        reduce_value = pickler_call(self, reduce_func, obj);
-    }
-    else {
-        static PyObject *reduce_str = NULL;
-        static PyObject *reduce_ex_str = NULL;
-
-        /* Cache the name of the reduce methods. */
-        if (reduce_str == NULL) {
-            reduce_str = PyUnicode_InternFromString("__reduce__");
-            if (reduce_str == NULL)
-                goto error;
-            reduce_ex_str = PyUnicode_InternFromString("__reduce_ex__");
-            if (reduce_ex_str == NULL)
-                goto error;
-        }
-
-        /* XXX: If the __reduce__ method is defined, __reduce_ex__ is
-           automatically defined as __reduce__. While this is convenient, this
-           make it impossible to know which method was actually called. Of
-           course, this is not a big deal. But still, it would be nice to let
-           the user know which method was called when something go
-           wrong. Incidentally, this means if __reduce_ex__ is not defined, we
-           don't actually have to check for a __reduce__ method. */
-
-        /* Check for a __reduce_ex__ method. */
-        reduce_func = PyObject_GetAttr(obj, reduce_ex_str);
-        if (reduce_func != NULL) {
-            PyObject *proto;
-            proto = PyLong_FromLong(self->proto);
-            if (proto != NULL) {
-                reduce_value = pickler_call(self, reduce_func, proto);
-            }
-        }
-        else {
-            if (PyErr_ExceptionMatches(PyExc_AttributeError))
-                PyErr_Clear();
-            else
-                goto error;
-            /* Check for a __reduce__ method. */
-            reduce_func = PyObject_GetAttr(obj, reduce_str);
-            if (reduce_func != NULL) {
-                reduce_value = PyObject_Call(reduce_func, empty_tuple, NULL);
-            }
-            else {
-                PyErr_Format(PicklingError, "can't pickle '%.200s' object: %R",
-                             type->tp_name, obj);
-                goto error;
-            }
-        }
-    }
-
-    if (reduce_value == NULL)
-        goto error;
-
-    if (PyUnicode_Check(reduce_value)) {
-        status = save_global(self, obj, reduce_value);
-        goto done;
-    }
-
-    if (!PyTuple_Check(reduce_value)) {
-        PyErr_SetString(PicklingError,
-                        "__reduce__ must return a string or tuple");
-        goto error;
-    }
-    if (Py_SIZE(reduce_value) < 2 || Py_SIZE(reduce_value) > 5) {
-        PyErr_SetString(PicklingError, "tuple returned by __reduce__ "
-                        "must contain 2 through 5 elements");
-        goto error;
-    }
-    if (!PyTuple_Check(PyTuple_GET_ITEM(reduce_value, 1))) {
-        PyErr_SetString(PicklingError, "second item of the tuple "
-                        "returned by __reduce__ must be a tuple");
-        goto error;
-    }
-
-    status = save_reduce(self, reduce_value, obj);
-
-    if (0) {
-  error:
-        status = -1;
-    }
-  done:
-    self->nesting--;
-    Py_XDECREF(memo_key);
-    Py_XDECREF(reduce_func);
-    Py_XDECREF(reduce_value);
-
-    return status;
-}
-
-static int
-dump(PicklerObject *self, PyObject *obj)
-{
-    const char stop_op = STOP;
-
-    if (self->proto >= 2) {
-        char header[2];
-
-        header[0] = PROTO;
-        assert(self->proto >= 0 && self->proto < 256);
-        header[1] = (unsigned char)self->proto;
-        if (pickler_write(self, header, 2) < 0)
-            return -1;
-    }
-
-    if (save(self, obj, 0) < 0 ||
-        pickler_write(self, &stop_op, 1) < 0 ||
-        pickler_write(self, NULL, 0) < 0)
-        return -1;
-
-    return 0;
-}
-
-PyDoc_STRVAR(Pickler_clear_memo_doc,
-"clear_memo() -> None. Clears the pickler's \"memo\"."
-"\n"
-"The memo is the data structure that remembers which objects the\n"
-"pickler has already seen, so that shared or recursive objects are\n"
-"pickled by reference and not by value.  This method is useful when\n"
-"re-using picklers.");
-
-static PyObject *
-Pickler_clear_memo(PicklerObject *self)
-{
-    if (self->memo)
-        PyDict_Clear(self->memo);
-
-    Py_RETURN_NONE;
-}
-
-PyDoc_STRVAR(Pickler_dump_doc,
-"dump(obj) -> None. Write a pickled representation of obj to the open file.");
-
-static PyObject *
-Pickler_dump(PicklerObject *self, PyObject *args)
-{
-    PyObject *obj;
-
-    if (!PyArg_ParseTuple(args, "O:dump", &obj))
-        return NULL;
-
-    if (dump(self, obj) < 0)
-        return NULL;
-
-    Py_RETURN_NONE;
-}
-
-static struct PyMethodDef Pickler_methods[] = {
-    {"dump", (PyCFunction)Pickler_dump, METH_VARARGS,
-     Pickler_dump_doc},
-    {"clear_memo", (PyCFunction)Pickler_clear_memo, METH_NOARGS,
-     Pickler_clear_memo_doc},
-    {NULL, NULL}                /* sentinel */
-};
-
-static void
-Pickler_dealloc(PicklerObject *self)
-{
-    PyObject_GC_UnTrack(self);
-
-    Py_XDECREF(self->write);
-    Py_XDECREF(self->memo);
-    Py_XDECREF(self->pers_func);
-    Py_XDECREF(self->arg);
-    Py_XDECREF(self->fast_memo);
-
-    PyMem_Free(self->write_buf);
-
-    Py_TYPE(self)->tp_free((PyObject *)self);
-}
-
-static int
-Pickler_traverse(PicklerObject *self, visitproc visit, void *arg)
-{
-    Py_VISIT(self->write);
-    Py_VISIT(self->memo);
-    Py_VISIT(self->pers_func);
-    Py_VISIT(self->arg);
-    Py_VISIT(self->fast_memo);
-    return 0;
-}
-
-static int
-Pickler_clear(PicklerObject *self)
-{
-    Py_CLEAR(self->write);
-    Py_CLEAR(self->memo);
-    Py_CLEAR(self->pers_func);
-    Py_CLEAR(self->arg);
-    Py_CLEAR(self->fast_memo);
-
-    PyMem_Free(self->write_buf);
-    self->write_buf = NULL;
-
-    return 0;
-}
-
-PyDoc_STRVAR(Pickler_doc,
-"Pickler(file, protocol=None)"
-"\n"
-"This takes a binary file for writing a pickle data stream.\n"
-"\n"
-"The optional protocol argument tells the pickler to use the\n"
-"given protocol; supported protocols are 0, 1, 2, 3.  The default\n"
-"protocol is 3; a backward-incompatible protocol designed for\n"
-"Python 3.0.\n"
-"\n"
-"Specifying a negative protocol version selects the highest\n"
-"protocol version supported.  The higher the protocol used, the\n"
-"more recent the version of Python needed to read the pickle\n"
-"produced.\n"
-"\n"
-"The file argument must have a write() method that accepts a single\n"
-"bytes argument. It can thus be a file object opened for binary\n"
-"writing, a io.BytesIO instance, or any other custom object that\n"
-"meets this interface.\n");
-
-static int
-Pickler_init(PicklerObject *self, PyObject *args, PyObject *kwds)
-{
-    static char *kwlist[] = {"file", "protocol", 0};
-    PyObject *file;
-    PyObject *proto_obj = NULL;
-    long proto = 0;
-
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:Pickler",
-                                     kwlist, &file, &proto_obj))
-        return -1;
-
-    /* In case of multiple __init__() calls, clear previous content. */
-    if (self->write != NULL)
-        (void)Pickler_clear(self);
-
-    if (proto_obj == NULL || proto_obj == Py_None)
-        proto = DEFAULT_PROTOCOL;
-    else
-        proto = PyLong_AsLong(proto_obj);
-
-    if (proto < 0)
-        proto = HIGHEST_PROTOCOL;
-    if (proto > HIGHEST_PROTOCOL) {
-        PyErr_Format(PyExc_ValueError, "pickle protocol must be <= %d",
-                     HIGHEST_PROTOCOL);
-        return -1;
-    }
-
-	self->proto = proto;
-	self->bin = proto > 0;
-	self->arg = NULL;
-    self->nesting = 0;
-	self->fast = 0;
-	self->fast_nesting = 0;
-	self->fast_memo = NULL;
-
-    if (!PyObject_HasAttrString(file, "write")) {
-        PyErr_SetString(PyExc_TypeError,
-                        "file must have a 'write' attribute");
-        return -1;
-    }
-    self->write = PyObject_GetAttrString(file, "write");
-    if (self->write == NULL)
-        return -1;
-	self->buf_size = 0;
-    self->write_buf = (char *)PyMem_Malloc(WRITE_BUF_SIZE);
-    if (self->write_buf == NULL) {
-        PyErr_NoMemory();
-        return -1;
-    }
-    self->pers_func = NULL;
-    if (PyObject_HasAttrString((PyObject *)self, "persistent_id")) {
-        self->pers_func = PyObject_GetAttrString((PyObject *)self,
-                                                 "persistent_id");
-        if (self->pers_func == NULL)
-            return -1;
-    }
-    self->memo = PyDict_New();
-    if (self->memo == NULL)
-        return -1;
-
-    return 0;
-}
-
-static PyObject *
-Pickler_get_memo(PicklerObject *self)
-{
-    if (self->memo == NULL)
-        PyErr_SetString(PyExc_AttributeError, "memo");
-    else
-        Py_INCREF(self->memo);
-    return self->memo;
-}
-
-static int
-Pickler_set_memo(PicklerObject *self, PyObject *value)
-{
-    PyObject *tmp;
-
-    if (value == NULL) {
-        PyErr_SetString(PyExc_TypeError,
-                        "attribute deletion is not supported");
-        return -1;
-    }
-    if (!PyDict_Check(value)) {
-        PyErr_SetString(PyExc_TypeError, "memo must be a dictionary");
-        return -1;
-    }
-
-    tmp = self->memo;
-    Py_INCREF(value);
-    self->memo = value;
-    Py_XDECREF(tmp);
-
-    return 0;
-}
-
-static PyObject *
-Pickler_get_persid(PicklerObject *self)
-{
-    if (self->pers_func == NULL)
-        PyErr_SetString(PyExc_AttributeError, "persistent_id");
-    else
-        Py_INCREF(self->pers_func);
-    return self->pers_func;
-}
-
-static int
-Pickler_set_persid(PicklerObject *self, PyObject *value)
-{
-    PyObject *tmp;
-
-    if (value == NULL) {
-        PyErr_SetString(PyExc_TypeError,
-                        "attribute deletion is not supported");
-        return -1;
-    }
-    if (!PyCallable_Check(value)) {
-        PyErr_SetString(PyExc_TypeError,
-                        "persistent_id must be a callable taking one argument");
-        return -1;
-    }
-
-    tmp = self->pers_func;
-    Py_INCREF(value);
-    self->pers_func = value;
-    Py_XDECREF(tmp);      /* self->pers_func can be NULL, so be careful. */
-
-    return 0;
-}
-
-static PyMemberDef Pickler_members[] = {
-    {"bin", T_INT, offsetof(PicklerObject, bin)},
-    {"fast", T_INT, offsetof(PicklerObject, fast)},
-    {NULL}
-};
-
-static PyGetSetDef Pickler_getsets[] = {
-    {"memo",          (getter)Pickler_get_memo,
-                      (setter)Pickler_set_memo},
-    {"persistent_id", (getter)Pickler_get_persid,
-                      (setter)Pickler_set_persid},
-    {NULL}
-};
-
-static PyTypeObject Pickler_Type = {
-    PyVarObject_HEAD_INIT(NULL, 0)
-    "_pickle.Pickler"  ,                /*tp_name*/
-    sizeof(PicklerObject),              /*tp_basicsize*/
-    0,                                  /*tp_itemsize*/
-    (destructor)Pickler_dealloc,        /*tp_dealloc*/
-    0,                                  /*tp_print*/
-    0,                                  /*tp_getattr*/
-    0,                                  /*tp_setattr*/
-    0,                                  /*tp_compare*/
-    0,                                  /*tp_repr*/
-    0,                                  /*tp_as_number*/
-    0,                                  /*tp_as_sequence*/
-    0,                                  /*tp_as_mapping*/
-    0,                                  /*tp_hash*/
-    0,                                  /*tp_call*/
-    0,                                  /*tp_str*/
-    0,                                  /*tp_getattro*/
-    0,                                  /*tp_setattro*/
-    0,                                  /*tp_as_buffer*/
-    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
-    Pickler_doc,                        /*tp_doc*/
-    (traverseproc)Pickler_traverse,     /*tp_traverse*/
-    (inquiry)Pickler_clear,             /*tp_clear*/
-    0,                                  /*tp_richcompare*/
-    0,                                  /*tp_weaklistoffset*/
-    0,                                  /*tp_iter*/
-    0,                                  /*tp_iternext*/
-    Pickler_methods,                    /*tp_methods*/
-    Pickler_members,                    /*tp_members*/
-    Pickler_getsets,                    /*tp_getset*/
-    0,                                  /*tp_base*/
-    0,                                  /*tp_dict*/
-    0,                                  /*tp_descr_get*/
-    0,                                  /*tp_descr_set*/
-    0,                                  /*tp_dictoffset*/
-    (initproc)Pickler_init,             /*tp_init*/
-    PyType_GenericAlloc,                /*tp_alloc*/
-    PyType_GenericNew,                  /*tp_new*/
-    PyObject_GC_Del,                    /*tp_free*/
-    0,                                  /*tp_is_gc*/
-};
-
-/* Temporary helper for calling self.find_class(). 
-
-   XXX: It would be nice to able to avoid Python function call overhead, by
-   using directly the C version of find_class(), when find_class() is not
-   overridden by a subclass. Although, this could become rather hackish. A
-   simpler optimization would be to call the C function when self is not a
-   subclass instance. */
-static PyObject *
-find_class(UnpicklerObject *self, PyObject *module_name, PyObject *global_name)
-{
-    return PyObject_CallMethod((PyObject *)self, "find_class", "OO",
-                               module_name, global_name);
-}
-
-static int
-marker(UnpicklerObject *self)
-{
-    if (self->num_marks < 1) {
-        PyErr_SetString(UnpicklingError, "could not find MARK");
-        return -1;
-    }
-
-    return self->marks[--self->num_marks];
-}
-
-static int
-load_none(UnpicklerObject *self)
-{
-    PDATA_APPEND(self->stack, Py_None, -1);
-    return 0;
-}
-
-static int
-bad_readline(void)
-{
-    PyErr_SetString(UnpicklingError, "pickle data was truncated");
-    return -1;
-}
-
-static int
-load_int(UnpicklerObject *self)
-{
-    PyObject *value;
-    char *endptr, *s;
-    Py_ssize_t len;
-    long x;
-
-    if ((len = unpickler_readline(self, &s)) < 0)
-        return -1;
-    if (len < 2)
-        return bad_readline();
-
-    errno = 0;
-    /* XXX: Should the base argument of strtol() be explicitly set to 10? */
-    x = strtol(s, &endptr, 0);
-
-    if (errno || (*endptr != '\n') || (endptr[1] != '\0')) {
-        /* Hm, maybe we've got something long.  Let's try reading
-         * it as a Python long object. */
-        errno = 0;
-        /* XXX: Same thing about the base here. */
-        value = PyLong_FromString(s, NULL, 0); 
-        if (value == NULL) {
-            PyErr_SetString(PyExc_ValueError,
-                            "could not convert string to int");
-            return -1;
-        }
-    }
-    else {
-        if (len == 3 && (x == 0 || x == 1)) {
-            if ((value = PyBool_FromLong(x)) == NULL)
-                return -1;
-        }
-        else {
-            if ((value = PyLong_FromLong(x)) == NULL)
-                return -1;
-        }
-    }
-
-    PDATA_PUSH(self->stack, value, -1);
-    return 0;
-}
-
-static int
-load_bool(UnpicklerObject *self, PyObject *boolean)
-{
-    assert(boolean == Py_True || boolean == Py_False);
-    PDATA_APPEND(self->stack, boolean, -1);
-    return 0;
-}
-
-/* s contains x bytes of a little-endian integer.  Return its value as a
- * C int.  Obscure:  when x is 1 or 2, this is an unsigned little-endian
- * int, but when x is 4 it's a signed one.  This is an historical source
- * of x-platform bugs.
- */
-static long
-calc_binint(char *s, int size)
-{
-    unsigned char c;
-    int i;
-    long x = 0L;
-
-    for (i = 0; i < size; i++) {
-        c = (unsigned char)s[i];
-        x |= (long)c << (i * 8);
-    }
-#if SIZEOF_LONG > 4
-    /* Unlike BININT1 and BININT2, BININT (more accurately BININT4)
-     * is signed, so on a box with longs bigger than 4 bytes we need
-     * to extend a BININT's sign bit to the full width.
-     */
-    if (x == 4 && x & (1L << 31))
-        x |= (~0L) << 32;
-#endif
-    return x;
-}
-
-static int
-load_binintx(UnpicklerObject *self, char *s, int size)
-{
-    PyObject *value;
-    long x;
-
-    x = calc_binint(s, size);
-
-    if ((value = PyLong_FromLong(x)) == NULL)
-        return -1;
-
-    PDATA_PUSH(self->stack, value, -1);
-    return 0;
-}
-
-static int
-load_binint(UnpicklerObject *self)
-{
-    char *s;
-
-    if (unpickler_read(self, &s, 4) < 0)
-        return -1;
-
-    return load_binintx(self, s, 4);
-}
-
-static int
-load_binint1(UnpicklerObject *self)
-{
-    char *s;
-
-    if (unpickler_read(self, &s, 1) < 0)
-        return -1;
-
-    return load_binintx(self, s, 1);
-}
-
-static int
-load_binint2(UnpicklerObject *self)
-{
-    char *s;
-
-    if (unpickler_read(self, &s, 2) < 0)
-        return -1;
-
-    return load_binintx(self, s, 2);
-}
-
-static int
-load_long(UnpicklerObject *self)
-{
-    PyObject *value;
-    char *s;
-    Py_ssize_t len;
-
-    if ((len = unpickler_readline(self, &s)) < 0)
-        return -1;
-    if (len < 2)
-        return bad_readline();
-
-    /* XXX: Should the base argument explicitly set to 10? */
-    if ((value = PyLong_FromString(s, NULL, 0)) == NULL)
-        return -1;
-
-    PDATA_PUSH(self->stack, value, -1);
-    return 0;
-}
-
-/* 'size' bytes contain the # of bytes of little-endian 256's-complement
- * data following.
- */
-static int
-load_counted_long(UnpicklerObject *self, int size)
-{
-    PyObject *value;
-    char *nbytes;
-    char *pdata;
-
-    assert(size == 1 || size == 4);
-    if (unpickler_read(self, &nbytes, size) < 0)
-        return -1;
-
-    size = calc_binint(nbytes, size);
-    if (size < 0) {
-        /* Corrupt or hostile pickle -- we never write one like this */
-        PyErr_SetString(UnpicklingError,
-                        "LONG pickle has negative byte count");
-        return -1;
-    }
-
-    if (size == 0)
-        value = PyLong_FromLong(0L);
-    else {
-        /* Read the raw little-endian bytes and convert. */
-        if (unpickler_read(self, &pdata, size) < 0)
-            return -1;
-        value = _PyLong_FromByteArray((unsigned char *)pdata, (size_t)size,
-                                      1 /* little endian */ , 1 /* signed */ );
-    }
-    if (value == NULL)
-        return -1;
-    PDATA_PUSH(self->stack, value, -1);
-    return 0;
-}
-
-static int
-load_float(UnpicklerObject *self)
-{
-    PyObject *value;
-    char *endptr, *s;
-    Py_ssize_t len;
-    double d;
-
-    if ((len = unpickler_readline(self, &s)) < 0)
-        return -1;
-    if (len < 2)
-        return bad_readline();
-
-    errno = 0;
-    d = PyOS_ascii_strtod(s, &endptr);
-
-    if (errno || (endptr[0] != '\n') || (endptr[1] != '\0')) {
-        PyErr_SetString(PyExc_ValueError, "could not convert string to float");
-        return -1;
-    }
-
-    if ((value = PyFloat_FromDouble(d)) == NULL)
-        return -1;
-
-    PDATA_PUSH(self->stack, value, -1);
-    return 0;
-}
-
-static int
-load_binfloat(UnpicklerObject *self)
-{
-    PyObject *value;
-    double x;
-    char *s;
-
-    if (unpickler_read(self, &s, 8) < 0)
-        return -1;
-
-    x = _PyFloat_Unpack8((unsigned char *)s, 0);
-    if (x == -1.0 && PyErr_Occurred())
-        return -1;
-
-    if ((value = PyFloat_FromDouble(x)) == NULL)
-        return -1;
-
-    PDATA_PUSH(self->stack, value, -1);
-    return 0;
-}
-
-static int
-load_string(UnpicklerObject *self)
-{
-    PyObject *bytes;
-    PyObject *str = NULL;
-    Py_ssize_t len;
-    char *s, *p;
-
-    if ((len = unpickler_readline(self, &s)) < 0)
-        return -1;
-    if (len < 3)
-        return bad_readline();
-    if ((s = strdup(s)) == NULL) {
-        PyErr_NoMemory();
-        return -1;
-    }
-
-    /* Strip outermost quotes */
-    while (s[len - 1] <= ' ')
-        len--;
-    if (s[0] == '"' && s[len - 1] == '"') {
-        s[len - 1] = '\0';
-        p = s + 1;
-        len -= 2;
-    }
-    else if (s[0] == '\'' && s[len - 1] == '\'') {
-        s[len - 1] = '\0';
-        p = s + 1;
-        len -= 2;
-    }
-    else {
-        free(s);
-        PyErr_SetString(PyExc_ValueError, "insecure string pickle");
-        return -1;
-    }
-
-    /* Use the PyBytes API to decode the string, since that is what is used
-       to encode, and then coerce the result to Unicode. */
-    bytes = PyBytes_DecodeEscape(p, len, NULL, 0, NULL);
-    free(s);
-    if (bytes == NULL)
-        return -1;
-    str = PyUnicode_FromEncodedObject(bytes, self->encoding, self->errors);
-    Py_DECREF(bytes);
-    if (str == NULL)
-        return -1;
-
-    PDATA_PUSH(self->stack, str, -1);
-    return 0;
-}
-
-static int
-load_binbytes(UnpicklerObject *self)
-{
-    PyObject *bytes;
-    long x;
-    char *s;
-
-    if (unpickler_read(self, &s, 4) < 0)
-        return -1;
-
-    x = calc_binint(s, 4);
-    if (x < 0) {
-        PyErr_SetString(UnpicklingError, 
-                        "BINBYTES pickle has negative byte count");
-        return -1;
-    }
-
-    if (unpickler_read(self, &s, x) < 0)
-        return -1;
-    bytes = PyBytes_FromStringAndSize(s, x);
-    if (bytes == NULL)
-        return -1;
-
-    PDATA_PUSH(self->stack, bytes, -1);
-    return 0;
-}
-
-static int
-load_short_binbytes(UnpicklerObject *self)
-{
-    PyObject *bytes;
-    unsigned char x;
-    char *s;
-
-    if (unpickler_read(self, &s, 1) < 0)
-        return -1;
-
-    x = (unsigned char)s[0];
-
-    if (unpickler_read(self, &s, x) < 0)
-        return -1;
-
-    bytes = PyBytes_FromStringAndSize(s, x);
-    if (bytes == NULL)
-        return -1;
-
-    PDATA_PUSH(self->stack, bytes, -1);
-    return 0;
-}
-
-static int
-load_binstring(UnpicklerObject *self)
-{
-    PyObject *str;
-    long x;
-    char *s;
-
-    if (unpickler_read(self, &s, 4) < 0)
-        return -1;
-
-    x = calc_binint(s, 4);
-    if (x < 0) {
-        PyErr_SetString(UnpicklingError, 
-                        "BINSTRING pickle has negative byte count");
-        return -1;
-    }
-
-    if (unpickler_read(self, &s, x) < 0)
-        return -1;
-
-    /* Convert Python 2.x strings to unicode. */
-    str = PyUnicode_Decode(s, x, self->encoding, self->errors);
-    if (str == NULL)
-        return -1;
-
-    PDATA_PUSH(self->stack, str, -1);
-    return 0;
-}
-
-static int
-load_short_binstring(UnpicklerObject *self)
-{
-    PyObject *str;
-    unsigned char x;
-    char *s;
-
-    if (unpickler_read(self, &s, 1) < 0)
-        return -1;
-
-    x = (unsigned char)s[0];
-
-    if (unpickler_read(self, &s, x) < 0)
-        return -1;
-
-    /* Convert Python 2.x strings to unicode. */
-    str = PyUnicode_Decode(s, x, self->encoding, self->errors);
-    if (str == NULL)
-        return -1;
-
-    PDATA_PUSH(self->stack, str, -1);
-    return 0;
-}
-
-static int
-load_unicode(UnpicklerObject *self)
-{
-    PyObject *str;
-    Py_ssize_t len;
-    char *s;
-
-    if ((len = unpickler_readline(self, &s)) < 0)
-        return -1;
-    if (len < 1)
-        return bad_readline();
-
-    str = PyUnicode_DecodeRawUnicodeEscape(s, len - 1, NULL);
-    if (str == NULL)
-        return -1;
-
-    PDATA_PUSH(self->stack, str, -1);
-    return 0;
-}
-
-static int
-load_binunicode(UnpicklerObject *self)
-{
-    PyObject *str;
-    long size;
-    char *s;
-
-    if (unpickler_read(self, &s, 4) < 0)
-        return -1;
-
-    size = calc_binint(s, 4);
-    if (size < 0) {
-        PyErr_SetString(UnpicklingError, 
-                        "BINUNICODE pickle has negative byte count");
-        return -1;
-    }
-
-    if (unpickler_read(self, &s, size) < 0)
-        return -1;
-
-    str = PyUnicode_DecodeUTF8(s, size, NULL);
-    if (str == NULL)
-        return -1;
-
-    PDATA_PUSH(self->stack, str, -1);
-    return 0;
-}
-
-static int
-load_tuple(UnpicklerObject *self)
-{
-    PyObject *tuple;
-    int i;
-
-    if ((i = marker(self)) < 0)
-        return -1;
-
-    tuple = Pdata_poptuple(self->stack, i);
-    if (tuple == NULL)
-        return -1;
-    PDATA_PUSH(self->stack, tuple, -1);
-    return 0;
-}
-
-static int
-load_counted_tuple(UnpicklerObject *self, int len)
-{
-    PyObject *tuple;
-
-    tuple = PyTuple_New(len);
-    if (tuple == NULL)
-        return -1;
-
-    while (--len >= 0) {
-        PyObject *item;
-
-        PDATA_POP(self->stack, item);
-        if (item == NULL)
-            return -1;
-        PyTuple_SET_ITEM(tuple, len, item);
-    }
-    PDATA_PUSH(self->stack, tuple, -1);
-    return 0;
-}
-
-static int
-load_empty_list(UnpicklerObject *self)
-{
-    PyObject *list;
-
-    if ((list = PyList_New(0)) == NULL)
-        return -1;
-    PDATA_PUSH(self->stack, list, -1);
-    return 0;
-}
-
-static int
-load_empty_dict(UnpicklerObject *self)
-{
-    PyObject *dict;
-
-    if ((dict = PyDict_New()) == NULL)
-        return -1;
-    PDATA_PUSH(self->stack, dict, -1);
-    return 0;
-}
-
-static int
-load_list(UnpicklerObject *self)
-{
-    PyObject *list;
-    int i;
-
-    if ((i = marker(self)) < 0)
-        return -1;
-
-    list = Pdata_poplist(self->stack, i);
-    if (list == NULL)
-        return -1;
-    PDATA_PUSH(self->stack, list, -1);
-    return 0;
-}
-
-static int
-load_dict(UnpicklerObject *self)
-{
-    PyObject *dict, *key, *value;
-    int i, j, k;
-
-    if ((i = marker(self)) < 0)
-        return -1;
-    j = self->stack->length;
-
-    if ((dict = PyDict_New()) == NULL)
-        return -1;
-
-    for (k = i + 1; k < j; k += 2) {
-        key = self->stack->data[k - 1];
-        value = self->stack->data[k];
-        if (PyDict_SetItem(dict, key, value) < 0) {
-            Py_DECREF(dict);
-            return -1;
-        }
-    }
-    Pdata_clear(self->stack, i);
-    PDATA_PUSH(self->stack, dict, -1);
-    return 0;
-}
-
-static PyObject *
-instantiate(PyObject *cls, PyObject *args)
-{
-    PyObject *r = NULL;
-
-    /* XXX: The pickle.py module does not create instances this way when the
-       args tuple is empty. See Unpickler._instantiate(). */
-    if ((r = PyObject_CallObject(cls, args)))
-        return r;
-
-    /* XXX: Is this still nescessary? */
-    {
-        PyObject *tp, *v, *tb, *tmp_value;
-
-        PyErr_Fetch(&tp, &v, &tb);
-        tmp_value = v;
-        /* NULL occurs when there was a KeyboardInterrupt */
-        if (tmp_value == NULL)
-            tmp_value = Py_None;
-        if ((r = PyTuple_Pack(3, tmp_value, cls, args))) {
-            Py_XDECREF(v);
-            v = r;
-        }
-        PyErr_Restore(tp, v, tb);
-    }
-    return NULL;
-}
-
-static int
-load_obj(UnpicklerObject *self)
-{
-    PyObject *cls, *args, *obj = NULL;
-    int i;
-
-    if ((i = marker(self)) < 0)
-        return -1;
-
-    args = Pdata_poptuple(self->stack, i + 1);
-    if (args == NULL)
-        return -1;
-
-    PDATA_POP(self->stack, cls);
-    if (cls) {
-        obj = instantiate(cls, args);
-        Py_DECREF(cls);
-    }
-    Py_DECREF(args);
-    if (obj == NULL)
-        return -1;
-
-    PDATA_PUSH(self->stack, obj, -1);
-    return 0;
-}
-
-static int
-load_inst(UnpicklerObject *self)
-{
-    PyObject *cls = NULL;
-    PyObject *args = NULL;
-    PyObject *obj = NULL;
-    PyObject *module_name;
-    PyObject *class_name;
-    Py_ssize_t len;
-    int i;
-    char *s;
-
-    if ((i = marker(self)) < 0)
-        return -1;
-    if ((len = unpickler_readline(self, &s)) < 0)
-        return -1;
-    if (len < 2)
-        return bad_readline();
-
-    /* Here it is safe to use PyUnicode_DecodeASCII(), even though non-ASCII
-       identifiers are permitted in Python 3.0, since the INST opcode is only
-       supported by older protocols on Python 2.x. */
-    module_name = PyUnicode_DecodeASCII(s, len - 1, "strict");
-    if (module_name == NULL)
-        return -1;
-
-    if ((len = unpickler_readline(self, &s)) >= 0) {
-        if (len < 2)
-            return bad_readline();
-        class_name = PyUnicode_DecodeASCII(s, len - 1, "strict");
-        if (class_name == NULL) {
-            cls = find_class(self, module_name, class_name);
-            Py_DECREF(class_name);
-        }
-    }
-    Py_DECREF(module_name);
-
-    if (cls == NULL)
-        return -1;
-
-    if ((args = Pdata_poptuple(self->stack, i)) != NULL) {
-        obj = instantiate(cls, args);
-        Py_DECREF(args);
-    }
-    Py_DECREF(cls);
-
-    if (obj == NULL)
-        return -1;
-
-    PDATA_PUSH(self->stack, obj, -1);
-    return 0;
-}
-
-static int
-load_newobj(UnpicklerObject *self)
-{
-    PyObject *args = NULL;
-    PyObject *clsraw = NULL;
-    PyTypeObject *cls;          /* clsraw cast to its true type */
-    PyObject *obj;
-
-    /* Stack is ... cls argtuple, and we want to call
-     * cls.__new__(cls, *argtuple).
-     */
-    PDATA_POP(self->stack, args);
-    if (args == NULL)
-        goto error;
-    if (!PyTuple_Check(args)) {
-        PyErr_SetString(UnpicklingError, "NEWOBJ expected an arg " "tuple.");
-        goto error;
-    }
-
-    PDATA_POP(self->stack, clsraw);
-    cls = (PyTypeObject *)clsraw;
-    if (cls == NULL)
-        goto error;
-    if (!PyType_Check(cls)) {
-        PyErr_SetString(UnpicklingError, "NEWOBJ class argument "
-                        "isn't a type object");
-        goto error;
-    }
-    if (cls->tp_new == NULL) {
-        PyErr_SetString(UnpicklingError, "NEWOBJ class argument "
-                        "has NULL tp_new");
-        goto error;
-    }
-
-    /* Call __new__. */
-    obj = cls->tp_new(cls, args, NULL);
-    if (obj == NULL)
-        goto error;
-
-    Py_DECREF(args);
-    Py_DECREF(clsraw);
-    PDATA_PUSH(self->stack, obj, -1);
-    return 0;
-
-  error:
-    Py_XDECREF(args);
-    Py_XDECREF(clsraw);
-    return -1;
-}
-
-static int
-load_global(UnpicklerObject *self)
-{
-    PyObject *global = NULL;
-    PyObject *module_name;
-    PyObject *global_name;
-    Py_ssize_t len;
-    char *s;
-
-    if ((len = unpickler_readline(self, &s)) < 0)
-        return -1;
-    if (len < 2)
-        return bad_readline();
-    module_name = PyUnicode_DecodeUTF8(s, len - 1, "strict");
-    if (!module_name)
-        return -1;
-
-    if ((len = unpickler_readline(self, &s)) >= 0) {
-        if (len < 2) {
-            Py_DECREF(module_name);
-            return bad_readline();
-        }
-        global_name = PyUnicode_DecodeUTF8(s, len - 1, "strict");
-        if (global_name) {
-            global = find_class(self, module_name, global_name);
-            Py_DECREF(global_name);
-        }
-    }
-    Py_DECREF(module_name);
-
-    if (global == NULL)
-        return -1;
-    PDATA_PUSH(self->stack, global, -1);
-    return 0;
-}
-
-static int
-load_persid(UnpicklerObject *self)
-{
-    PyObject *pid;
-    Py_ssize_t len;
-    char *s;
-
-    if (self->pers_func) {
-        if ((len = unpickler_readline(self, &s)) < 0)
-            return -1;
-        if (len < 2)
-            return bad_readline();
-
-        pid = PyBytes_FromStringAndSize(s, len - 1);
-        if (pid == NULL)
-            return -1;
-
-        /* Ugh... this does not leak since unpickler_call() steals the
-           reference to pid first. */
-        pid = unpickler_call(self, self->pers_func, pid);
-        if (pid == NULL)
-            return -1;
-
-        PDATA_PUSH(self->stack, pid, -1);
-        return 0;
-    }
-    else {
-        PyErr_SetString(UnpicklingError,
-                        "A load persistent id instruction was encountered,\n"
-                        "but no persistent_load function was specified.");
-        return -1;
-    }
-}
-
-static int
-load_binpersid(UnpicklerObject *self)
-{
-    PyObject *pid;
-
-    if (self->pers_func) {
-        PDATA_POP(self->stack, pid);
-        if (pid == NULL)
-            return -1;
-
-        /* Ugh... this does not leak since unpickler_call() steals the
-           reference to pid first. */
-        pid = unpickler_call(self, self->pers_func, pid);
-        if (pid == NULL)
-            return -1;
-
-        PDATA_PUSH(self->stack, pid, -1);
-        return 0;
-    }
-    else {
-        PyErr_SetString(UnpicklingError,
-                        "A load persistent id instruction was encountered,\n"
-                        "but no persistent_load function was specified.");
-        return -1;
-    }
-}
-
-static int
-load_pop(UnpicklerObject *self)
-{
-    int len;
-
-    if ((len = self->stack->length) <= 0)
-        return stack_underflow();
-
-    /* Note that we split the (pickle.py) stack into two stacks,
-     * an object stack and a mark stack. We have to be clever and
-     * pop the right one. We do this by looking at the top of the
-     * mark stack.
-     */
-
-    if ((self->num_marks > 0) && (self->marks[self->num_marks - 1] == len))
-        self->num_marks--;
-    else {
-        len--;
-        Py_DECREF(self->stack->data[len]);
-        self->stack->length = len;
-    }
-
-    return 0;
-}
-
-static int
-load_pop_mark(UnpicklerObject *self)
-{
-    int i;
-
-    if ((i = marker(self)) < 0)
-        return -1;
-
-    Pdata_clear(self->stack, i);
-
-    return 0;
-}
-
-static int
-load_dup(UnpicklerObject *self)
-{
-    PyObject *last;
-    int len;
-
-    if ((len = self->stack->length) <= 0)
-        return stack_underflow();
-    last = self->stack->data[len - 1];
-    PDATA_APPEND(self->stack, last, -1);
-    return 0;
-}
-
-static int
-load_get(UnpicklerObject *self)
-{
-    PyObject *key, *value;
-    Py_ssize_t len;
-    char *s;
-
-    if ((len = unpickler_readline(self, &s)) < 0)
-        return -1;
-    if (len < 2)
-        return bad_readline();
-
-    key = PyLong_FromString(s, NULL, 10);
-    if (key == NULL)
-        return -1;
-
-    value = PyDict_GetItemWithError(self->memo, key);
-    if (value == NULL) {
-        if (!PyErr_Occurred())
-            PyErr_SetObject(PyExc_KeyError, key);
-        Py_DECREF(key);
-        return -1;
-    }
-    Py_DECREF(key);
-
-    PDATA_APPEND(self->stack, value, -1);
-    return 0;
-}
-
-static int
-load_binget(UnpicklerObject *self)
-{
-    PyObject *key, *value;
-    char *s;
-
-    if (unpickler_read(self, &s, 1) < 0)
-        return -1;
-
-    /* Here, the unsigned cast is necessary to avoid negative values. */
-    key = PyLong_FromLong((long)(unsigned char)s[0]);
-    if (key == NULL)
-        return -1;
-
-    value = PyDict_GetItemWithError(self->memo, key);
-    if (value == NULL) {
-        if (!PyErr_Occurred())
-            PyErr_SetObject(PyExc_KeyError, key);
-        Py_DECREF(key);
-        return -1;
-    }
-    Py_DECREF(key);
-
-    PDATA_APPEND(self->stack, value, -1);
-    return 0;
-}
-
-static int
-load_long_binget(UnpicklerObject *self)
-{
-    PyObject *key, *value;
-    char *s;
-    long k;
-
-    if (unpickler_read(self, &s, 4) < 0)
-        return -1;
-
-    k = (long)(unsigned char)s[0];
-    k |= (long)(unsigned char)s[1] << 8;
-    k |= (long)(unsigned char)s[2] << 16;
-    k |= (long)(unsigned char)s[3] << 24;
-
-    key = PyLong_FromLong(k);
-    if (key == NULL)
-        return -1;
-
-    value = PyDict_GetItemWithError(self->memo, key);
-    if (value == NULL) {
-        if (!PyErr_Occurred())
-            PyErr_SetObject(PyExc_KeyError, key);
-        Py_DECREF(key);
-        return -1;
-    }
-    Py_DECREF(key);
-
-    PDATA_APPEND(self->stack, value, -1);
-    return 0;
-}
-
-/* Push an object from the extension registry (EXT[124]).  nbytes is
- * the number of bytes following the opcode, holding the index (code) value.
- */
-static int
-load_extension(UnpicklerObject *self, int nbytes)
-{
-    char *codebytes;            /* the nbytes bytes after the opcode */
-    long code;                  /* calc_binint returns long */
-    PyObject *py_code;          /* code as a Python int */
-    PyObject *obj;              /* the object to push */
-    PyObject *pair;             /* (module_name, class_name) */
-    PyObject *module_name, *class_name;
-
-    assert(nbytes == 1 || nbytes == 2 || nbytes == 4);
-    if (unpickler_read(self, &codebytes, nbytes) < 0)
-        return -1;
-    code = calc_binint(codebytes, nbytes);
-    if (code <= 0) {            /* note that 0 is forbidden */
-        /* Corrupt or hostile pickle. */
-        PyErr_SetString(UnpicklingError, "EXT specifies code <= 0");
-        return -1;
-    }
-
-    /* Look for the code in the cache. */
-    py_code = PyLong_FromLong(code);
-    if (py_code == NULL)
-        return -1;
-    obj = PyDict_GetItem(extension_cache, py_code);
-    if (obj != NULL) {
-        /* Bingo. */
-        Py_DECREF(py_code);
-        PDATA_APPEND(self->stack, obj, -1);
-        return 0;
-    }
-
-    /* Look up the (module_name, class_name) pair. */
-    pair = PyDict_GetItem(inverted_registry, py_code);
-    if (pair == NULL) {
-        Py_DECREF(py_code);
-        PyErr_Format(PyExc_ValueError, "unregistered extension "
-                     "code %ld", code);
-        return -1;
-    }
-    /* Since the extension registry is manipulable via Python code,
-     * confirm that pair is really a 2-tuple of strings.
-     */
-    if (!PyTuple_Check(pair) || PyTuple_Size(pair) != 2 ||
-        !PyUnicode_Check(module_name = PyTuple_GET_ITEM(pair, 0)) ||
-        !PyUnicode_Check(class_name = PyTuple_GET_ITEM(pair, 1))) {
-        Py_DECREF(py_code);
-        PyErr_Format(PyExc_ValueError, "_inverted_registry[%ld] "
-                     "isn't a 2-tuple of strings", code);
-        return -1;
-    }
-    /* Load the object. */
-    obj = find_class(self, module_name, class_name);
-    if (obj == NULL) {
-        Py_DECREF(py_code);
-        return -1;
-    }
-    /* Cache code -> obj. */
-    code = PyDict_SetItem(extension_cache, py_code, obj);
-    Py_DECREF(py_code);
-    if (code < 0) {
-        Py_DECREF(obj);
-        return -1;
-    }
-    PDATA_PUSH(self->stack, obj, -1);
-    return 0;
-}
-
-static int
-load_put(UnpicklerObject *self)
-{
-    PyObject *key, *value;
-    Py_ssize_t len;
-    char *s;
-    int x;
-
-    if ((len = unpickler_readline(self, &s)) < 0)
-        return -1;
-    if (len < 2)
-        return bad_readline();
-    if ((x = self->stack->length) <= 0)
-        return stack_underflow();
-
-    key = PyLong_FromString(s, NULL, 10);
-    if (key == NULL)
-        return -1;
-    value = self->stack->data[x - 1];
-
-    x = PyDict_SetItem(self->memo, key, value);
-    Py_DECREF(key);
-    return x;
-}
-
-static int
-load_binput(UnpicklerObject *self)
-{
-    PyObject *key, *value;
-    char *s;
-    int x;
-
-    if (unpickler_read(self, &s, 1) < 0)
-        return -1;
-    if ((x = self->stack->length) <= 0)
-        return stack_underflow();
-
-    key = PyLong_FromLong((long)(unsigned char)s[0]);
-    if (key == NULL)
-        return -1;
-    value = self->stack->data[x - 1];
-
-    x = PyDict_SetItem(self->memo, key, value);
-    Py_DECREF(key);
-    return x;
-}
-
-static int
-load_long_binput(UnpicklerObject *self)
-{
-    PyObject *key, *value;
-    long k;
-    char *s;
-    int x;
-
-    if (unpickler_read(self, &s, 4) < 0)
-        return -1;
-    if ((x = self->stack->length) <= 0)
-        return stack_underflow();
-
-    k = (long)(unsigned char)s[0];
-    k |= (long)(unsigned char)s[1] << 8;
-    k |= (long)(unsigned char)s[2] << 16;
-    k |= (long)(unsigned char)s[3] << 24;
-
-    key = PyLong_FromLong(k);
-    if (key == NULL)
-        return -1;
-    value = self->stack->data[x - 1];
-
-    x = PyDict_SetItem(self->memo, key, value);
-    Py_DECREF(key);
-    return x;
-}
-
-static int
-do_append(UnpicklerObject *self, int x)
-{
-    PyObject *value;
-    PyObject *list;
-    int len, i;
-
-    len = self->stack->length;
-    if (x > len || x <= 0)
-        return stack_underflow();
-    if (len == x)  /* nothing to do */
-        return 0;
-
-    list = self->stack->data[x - 1];
-
-    if (PyList_Check(list)) {
-        PyObject *slice;
-        Py_ssize_t list_len;
-
-        slice = Pdata_poplist(self->stack, x);
-        if (!slice)
-            return -1;
-        list_len = PyList_GET_SIZE(list);
-        i = PyList_SetSlice(list, list_len, list_len, slice);
-        Py_DECREF(slice);
-        return i;
-    }
-    else {
-        PyObject *append_func;
-
-        append_func = PyObject_GetAttrString(list, "append");
-        if (append_func == NULL)
-            return -1;
-        for (i = x; i < len; i++) {
-            PyObject *result;
-
-            value = self->stack->data[i];
-            result = unpickler_call(self, append_func, value);
-            if (result == NULL) {
-                Pdata_clear(self->stack, i + 1);
-                self->stack->length = x;
-                return -1;
-            }
-            Py_DECREF(result);
-        }
-        self->stack->length = x;
-    }
-
-    return 0;
-}
-
-static int
-load_append(UnpicklerObject *self)
-{
-    return do_append(self, self->stack->length - 1);
-}
-
-static int
-load_appends(UnpicklerObject *self)
-{
-    return do_append(self, marker(self));
-}
-
-static int
-do_setitems(UnpicklerObject *self, int x)
-{
-    PyObject *value, *key;
-    PyObject *dict;
-    int len, i;
-    int status = 0;
-
-    len = self->stack->length;
-    if (x > len || x <= 0)
-        return stack_underflow();
-    if (len == x)  /* nothing to do */
-        return 0;
-    if ((len - x) % 2 != 0) { 
-        /* Currupt or hostile pickle -- we never write one like this. */
-        PyErr_SetString(UnpicklingError, "odd number of items for SETITEMS");
-        return -1;
-    }
-
-    /* Here, dict does not actually need to be a PyDict; it could be anything
-       that supports the __setitem__ attribute. */
-    dict = self->stack->data[x - 1];
-
-    for (i = x + 1; i < len; i += 2) {
-        key = self->stack->data[i - 1];
-        value = self->stack->data[i];
-        if (PyObject_SetItem(dict, key, value) < 0) {
-            status = -1;
-            break;
-        }
-    }
-
-    Pdata_clear(self->stack, x);
-    return status;
-}
-
-static int
-load_setitem(UnpicklerObject *self)
-{
-    return do_setitems(self, self->stack->length - 2);
-}
-
-static int
-load_setitems(UnpicklerObject *self)
-{
-    return do_setitems(self, marker(self));
-}
-
-static int
-load_build(UnpicklerObject *self)
-{
-    PyObject *state, *inst, *slotstate;
-    PyObject *setstate;
-    int status = 0;
-
-    /* Stack is ... instance, state.  We want to leave instance at
-     * the stack top, possibly mutated via instance.__setstate__(state).
-     */
-    if (self->stack->length < 2)
-        return stack_underflow();
-
-    PDATA_POP(self->stack, state);
-    if (state == NULL)
-        return -1;
-
-    inst = self->stack->data[self->stack->length - 1];
-
-    setstate = PyObject_GetAttrString(inst, "__setstate__");
-    if (setstate == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) {
-        PyErr_Clear();
-    }
-    else {
-        PyObject *result;
-
-        /* The explicit __setstate__ is responsible for everything. */
-        result = unpickler_call(self, setstate, state);
-        Py_DECREF(setstate);
-        if (result == NULL)
-            return -1;
-        Py_DECREF(result);
-        return 0;
-    }
-
-    /* A default __setstate__.  First see whether state embeds a
-     * slot state dict too (a proto 2 addition).
-     */
-    if (PyTuple_Check(state) && Py_SIZE(state) == 2) {
-        PyObject *tmp = state;
-
-        state = PyTuple_GET_ITEM(tmp, 0);
-        slotstate = PyTuple_GET_ITEM(tmp, 1);
-        Py_INCREF(state);
-        Py_INCREF(slotstate);
-        Py_DECREF(tmp);
-    }
-    else
-        slotstate = NULL;
-
-    /* Set inst.__dict__ from the state dict (if any). */
-    if (state != Py_None) {
-        PyObject *dict;
-
-        if (!PyDict_Check(state)) {
-            PyErr_SetString(UnpicklingError, "state is not a dictionary");
-            goto error;
-        }
-        dict = PyObject_GetAttrString(inst, "__dict__");
-        if (dict == NULL)
-            goto error;
-
-        PyDict_Update(dict, state);
-        Py_DECREF(dict);
-    }
-
-    /* Also set instance attributes from the slotstate dict (if any). */
-    if (slotstate != NULL) {
-        PyObject *d_key, *d_value;
-        Py_ssize_t i;
-
-        if (!PyDict_Check(slotstate)) {
-            PyErr_SetString(UnpicklingError,
-                            "slot state is not a dictionary");
-            goto error;
-        }
-        i = 0;
-        while (PyDict_Next(slotstate, &i, &d_key, &d_value)) {
-            if (PyObject_SetAttr(inst, d_key, d_value) < 0)
-                goto error;
-        }
-    }
-
-    if (0) {
-  error:
-        status = -1;
-    }
-
-    Py_DECREF(state);
-    Py_XDECREF(slotstate);
-    return status;
-}
-
-static int
-load_mark(UnpicklerObject *self)
-{
-
-    /* Note that we split the (pickle.py) stack into two stacks, an
-     * object stack and a mark stack. Here we push a mark onto the
-     * mark stack.
-     */
-
-    if ((self->num_marks + 1) >= self->marks_size) {
-        size_t alloc;
-        int *marks;
-
-        /* Use the size_t type to check for overflow. */
-        alloc = ((size_t)self->num_marks << 1) + 20;
-        if (alloc > PY_SSIZE_T_MAX || alloc <= (self->num_marks + 1)) {
-            PyErr_NoMemory();
-            return -1;
-        }
-
-        if (self->marks == NULL)
-            marks = (int *)PyMem_Malloc(alloc * sizeof(int));
-        else
-            marks = (int *)PyMem_Realloc(self->marks, alloc * sizeof(int));
-        if (marks == NULL) {
-            PyErr_NoMemory();
-            return -1;
-        }
-        self->marks = marks;
-        self->marks_size = (Py_ssize_t)alloc;
-    }
-
-    self->marks[self->num_marks++] = self->stack->length;
-
-    return 0;
-}
-
-static int
-load_reduce(UnpicklerObject *self)
-{
-    PyObject *callable = NULL;
-    PyObject *argtup = NULL;
-    PyObject *obj = NULL;
-
-    PDATA_POP(self->stack, argtup);
-    if (argtup == NULL)
-        return -1;
-    PDATA_POP(self->stack, callable);
-    if (callable) {
-        obj = instantiate(callable, argtup);
-        Py_DECREF(callable);
-    }
-    Py_DECREF(argtup);
-
-    if (obj == NULL)
-        return -1;
-
-    PDATA_PUSH(self->stack, obj, -1);
-    return 0;
-}
-
-/* Just raises an error if we don't know the protocol specified.  PROTO
- * is the first opcode for protocols >= 2.
- */
-static int
-load_proto(UnpicklerObject *self)
-{
-    char *s;
-    int i;
-
-    if (unpickler_read(self, &s, 1) < 0)
-        return -1;
-
-    i = (unsigned char)s[0];
-    if (i <= HIGHEST_PROTOCOL)
-        return 0;
-
-    PyErr_Format(PyExc_ValueError, "unsupported pickle protocol: %d", i);
-    return -1;
-}
-
-static PyObject *
-load(UnpicklerObject *self)
-{
-    PyObject *err;
-    PyObject *value = NULL;
-    char *s;
-
-    self->num_marks = 0;
-    if (self->stack->length)
-        Pdata_clear(self->stack, 0);
-
-    /* Convenient macros for the dispatch while-switch loop just below. */
-#define OP(opcode, load_func) \
-    case opcode: if (load_func(self) < 0) break; continue;
-
-#define OP_ARG(opcode, load_func, arg) \
-    case opcode: if (load_func(self, (arg)) < 0) break; continue;
-
-    while (1) {
-        if (unpickler_read(self, &s, 1) < 0)
-            break;
-
-        switch ((enum opcode)s[0]) {
-        OP(NONE, load_none)
-        OP(BININT, load_binint)
-        OP(BININT1, load_binint1)
-        OP(BININT2, load_binint2)
-        OP(INT, load_int)
-        OP(LONG, load_long)
-        OP_ARG(LONG1, load_counted_long, 1)
-        OP_ARG(LONG4, load_counted_long, 4)
-        OP(FLOAT, load_float)
-        OP(BINFLOAT, load_binfloat)
-        OP(BINBYTES, load_binbytes)
-        OP(SHORT_BINBYTES, load_short_binbytes)
-        OP(BINSTRING, load_binstring)
-        OP(SHORT_BINSTRING, load_short_binstring)
-        OP(STRING, load_string)
-        OP(UNICODE, load_unicode)
-        OP(BINUNICODE, load_binunicode)
-        OP_ARG(EMPTY_TUPLE, load_counted_tuple, 0)
-        OP_ARG(TUPLE1, load_counted_tuple, 1)
-        OP_ARG(TUPLE2, load_counted_tuple, 2)
-        OP_ARG(TUPLE3, load_counted_tuple, 3)
-        OP(TUPLE, load_tuple)
-        OP(EMPTY_LIST, load_empty_list)
-        OP(LIST, load_list)
-        OP(EMPTY_DICT, load_empty_dict)
-        OP(DICT, load_dict)
-        OP(OBJ, load_obj)
-        OP(INST, load_inst)
-        OP(NEWOBJ, load_newobj)
-        OP(GLOBAL, load_global)
-        OP(APPEND, load_append)
-        OP(APPENDS, load_appends)
-        OP(BUILD, load_build)
-        OP(DUP, load_dup)
-        OP(BINGET, load_binget)
-        OP(LONG_BINGET, load_long_binget)
-        OP(GET, load_get)
-        OP(MARK, load_mark)
-        OP(BINPUT, load_binput)
-        OP(LONG_BINPUT, load_long_binput)
-        OP(PUT, load_put)
-        OP(POP, load_pop)
-        OP(POP_MARK, load_pop_mark)
-        OP(SETITEM, load_setitem)
-        OP(SETITEMS, load_setitems)
-        OP(PERSID, load_persid)
-        OP(BINPERSID, load_binpersid)
-        OP(REDUCE, load_reduce)
-        OP(PROTO, load_proto)
-        OP_ARG(EXT1, load_extension, 1)
-        OP_ARG(EXT2, load_extension, 2)
-        OP_ARG(EXT4, load_extension, 4)
-        OP_ARG(NEWTRUE, load_bool, Py_True)
-        OP_ARG(NEWFALSE, load_bool, Py_False)
-
-        case STOP:
-            break;
-
-        case '\0':
-            PyErr_SetNone(PyExc_EOFError);
-            return NULL;
-
-        default:
-            PyErr_Format(UnpicklingError,
-                         "invalid load key, '%c'.", s[0]);
-            return NULL;
-        }
-
-        break;                  /* and we are done! */
-    }
-
-    /* XXX: It is not clear what this is actually for. */
-    if ((err = PyErr_Occurred())) {
-        if (err == PyExc_EOFError) {
-            PyErr_SetNone(PyExc_EOFError);
-        }
-        return NULL;
-    }
-
-    PDATA_POP(self->stack, value);
-    return value;
-}
-
-PyDoc_STRVAR(Unpickler_load_doc,
-"load() -> object. Load a pickle."
-"\n"
-"Read a pickled object representation from the open file object given in\n"
-"the constructor, and return the reconstituted object hierarchy specified\n"
-"therein.\n");
-
-static PyObject *
-Unpickler_load(UnpicklerObject *self)
-{
-    /* Check whether the Unpickler was initialized correctly. This prevents
-       segfaulting if a subclass overridden __init__ with a function that does
-       not call Unpickler.__init__(). Here, we simply ensure that self->read
-       is not NULL. */
-    if (self->read == NULL) {
-        PyErr_Format(UnpicklingError, 
-                     "Unpickler.__init__() was not called by %s.__init__()",
-                     Py_TYPE(self)->tp_name);
-        return NULL;
-    }
-
-    return load(self);
-}
-
-/* The name of find_class() is misleading. In newer pickle protocols, this
-   function is used for loading any global (i.e., functions), not just
-   classes. The name is kept only for backward compatibility. */
-
-PyDoc_STRVAR(Unpickler_find_class_doc,
-"find_class(module_name, global_name) -> object.\n"
-"\n"
-"Return an object from a specified module, importing the module if\n"
-"necessary.  Subclasses may override this method (e.g. to restrict\n"
-"unpickling of arbitrary classes and functions).\n"
-"\n"
-"This method is called whenever a class or a function object is\n"
-"needed.  Both arguments passed are str objects.\n");
-
-static PyObject *
-Unpickler_find_class(UnpicklerObject *self, PyObject *args)
-{
-    PyObject *global;
-    PyObject *modules_dict;
-    PyObject *module;
-    PyObject *module_name, *global_name;
-
-    if (!PyArg_UnpackTuple(args, "find_class", 2, 2,
-                           &module_name, &global_name))
-        return NULL;
-
-    modules_dict = PySys_GetObject("modules");
-    if (modules_dict == NULL)
-        return NULL;
-
-    module = PyDict_GetItem(modules_dict, module_name);
-    if (module == NULL) {
-        module = PyImport_Import(module_name);
-        if (module == NULL)
-            return NULL;
-        global = PyObject_GetAttr(module, global_name);
-        Py_DECREF(module);
-    }
-    else { 
-        global = PyObject_GetAttr(module, global_name);
-    }
-    return global;
-}
-
-static struct PyMethodDef Unpickler_methods[] = {
-    {"load", (PyCFunction)Unpickler_load, METH_NOARGS,
-     Unpickler_load_doc},
-    {"find_class", (PyCFunction)Unpickler_find_class, METH_VARARGS,
-     Unpickler_find_class_doc},
-    {NULL, NULL}                /* sentinel */
-};
-
-static void
-Unpickler_dealloc(UnpicklerObject *self)
-{
-    PyObject_GC_UnTrack((PyObject *)self);
-    Py_XDECREF(self->readline);
-    Py_XDECREF(self->read);
-    Py_XDECREF(self->memo);
-    Py_XDECREF(self->stack);
-    Py_XDECREF(self->pers_func);
-    Py_XDECREF(self->arg);
-    Py_XDECREF(self->last_string);
-
-    PyMem_Free(self->marks);
-    free(self->encoding);
-    free(self->errors);
-
-    Py_TYPE(self)->tp_free((PyObject *)self);
-}
-
-static int
-Unpickler_traverse(UnpicklerObject *self, visitproc visit, void *arg)
-{
-    Py_VISIT(self->readline);
-    Py_VISIT(self->read);
-    Py_VISIT(self->memo);
-    Py_VISIT(self->stack);
-    Py_VISIT(self->pers_func);
-    Py_VISIT(self->arg);
-    Py_VISIT(self->last_string);
-    return 0;
-}
-
-static int
-Unpickler_clear(UnpicklerObject *self)
-{
-    Py_CLEAR(self->readline);
-    Py_CLEAR(self->read);
-    Py_CLEAR(self->memo);
-    Py_CLEAR(self->stack);
-    Py_CLEAR(self->pers_func);
-    Py_CLEAR(self->arg);
-    Py_CLEAR(self->last_string);
-
-    PyMem_Free(self->marks);
-    self->marks = NULL;
-    free(self->encoding);
-    self->encoding = NULL;
-    free(self->errors);
-    self->errors = NULL;
-
-    return 0;
-}
-
-PyDoc_STRVAR(Unpickler_doc,
-"Unpickler(file, *, encoding='ASCII', errors='strict')"
-"\n"
-"This takes a binary file for reading a pickle data stream.\n"
-"\n"
-"The protocol version of the pickle is detected automatically, so no\n"
-"proto argument is needed.\n"
-"\n"
-"The file-like object must have two methods, a read() method\n"
-"that takes an integer argument, and a readline() method that\n"
-"requires no arguments.  Both methods should return bytes.\n"
-"Thus file-like object can be a binary file object opened for\n"
-"reading, a BytesIO object, or any other custom object that\n"
-"meets this interface.\n"
-"\n"
-"Optional keyword arguments are encoding and errors, which are\n"
-"used to decode 8-bit string instances pickled by Python 2.x.\n"
-"These default to 'ASCII' and 'strict', respectively.\n");
-
-static int
-Unpickler_init(UnpicklerObject *self, PyObject *args, PyObject *kwds)
-{
-    static char *kwlist[] = {"file", "encoding", "errors", 0};
-    PyObject *file;
-    char *encoding = NULL;
-    char *errors = NULL;
-
-    /* XXX: That is an horrible error message. But, I don't know how to do
-       better... */
-    if (Py_SIZE(args) != 1) {
-        PyErr_Format(PyExc_TypeError,
-                     "%s takes exactly one positional argument (%zd given)",
-                     Py_TYPE(self)->tp_name, Py_SIZE(args));
-        return -1;
-    }
-
-    /* Arguments parsing needs to be done in the __init__() method to allow
-       subclasses to define their own __init__() method, which may (or may
-       not) support Unpickler arguments. However, this means we need to be
-       extra careful in the other Unpickler methods, since a subclass could
-       forget to call Unpickler.__init__() thus breaking our internal
-       invariants. */
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|ss:Unpickler", kwlist,
-                                     &file, &encoding, &errors))
-        return -1;
-
-    /* In case of multiple __init__() calls, clear previous content. */
-    if (self->read != NULL)
-        (void)Unpickler_clear(self);
-
-    self->read = PyObject_GetAttrString(file, "read");
-    self->readline = PyObject_GetAttrString(file, "readline");
-    if (self->readline == NULL || self->read == NULL)
-        return -1;
-
-    if (encoding == NULL)
-        encoding = "ASCII";
-    if (errors == NULL)
-        errors = "strict";
-
-    self->encoding = strdup(encoding);
-    self->errors = strdup(errors);
-    if (self->encoding == NULL || self->errors == NULL) {
-        PyErr_NoMemory();
-        return -1;
-    }
-
-    if (PyObject_HasAttrString((PyObject *)self, "persistent_load")) {
-        self->pers_func = PyObject_GetAttrString((PyObject *)self,
-                                                 "persistent_load");
-        if (self->pers_func == NULL)
-            return -1;
-    }
-    else {
-        self->pers_func = NULL;
-    }
-
-    self->stack = (Pdata *)Pdata_New();
-    if (self->stack == NULL)
-        return -1;
-
-    self->memo = PyDict_New();
-    if (self->memo == NULL)
-        return -1;
-
-    return 0;
-}
-
-static PyObject *
-Unpickler_get_memo(UnpicklerObject *self)
-{
-    if (self->memo == NULL)
-        PyErr_SetString(PyExc_AttributeError, "memo");
-    else
-        Py_INCREF(self->memo);
-    return self->memo;
-}
-
-static int
-Unpickler_set_memo(UnpicklerObject *self, PyObject *value)
-{
-    PyObject *tmp;
-
-    if (value == NULL) {
-        PyErr_SetString(PyExc_TypeError,
-                        "attribute deletion is not supported");
-        return -1;
-    }
-    if (!PyDict_Check(value)) {
-        PyErr_SetString(PyExc_TypeError, "memo must be a dictionary");
-        return -1;
-    }
-
-    tmp = self->memo;
-    Py_INCREF(value);
-    self->memo = value;
-    Py_XDECREF(tmp);
-
-    return 0;
-}
-
-static PyObject *
-Unpickler_get_persload(UnpicklerObject *self)
-{
-    if (self->pers_func == NULL)
-        PyErr_SetString(PyExc_AttributeError, "persistent_load");
-    else
-        Py_INCREF(self->pers_func);
-    return self->pers_func;
-}
-
-static int
-Unpickler_set_persload(UnpicklerObject *self, PyObject *value)
-{
-    PyObject *tmp;
-
-    if (value == NULL) {
-        PyErr_SetString(PyExc_TypeError,
-                        "attribute deletion is not supported");
-        return -1;
-    }
-    if (!PyCallable_Check(value)) {
-        PyErr_SetString(PyExc_TypeError,
-                        "persistent_load must be a callable taking "
-                        "one argument");
-        return -1;
-    }
-
-    tmp = self->pers_func;
-    Py_INCREF(value);
-    self->pers_func = value;
-    Py_XDECREF(tmp);      /* self->pers_func can be NULL, so be careful. */
-
-    return 0;
-}
-
-static PyGetSetDef Unpickler_getsets[] = {
-    {"memo", (getter)Unpickler_get_memo, (setter)Unpickler_set_memo},
-    {"persistent_load", (getter)Unpickler_get_persload,
-                        (setter)Unpickler_set_persload},
-    {NULL}
-};
-
-static PyTypeObject Unpickler_Type = {
-    PyVarObject_HEAD_INIT(NULL, 0)
-    "_pickle.Unpickler",                /*tp_name*/
-    sizeof(UnpicklerObject),            /*tp_basicsize*/
-    0,                                  /*tp_itemsize*/
-    (destructor)Unpickler_dealloc,      /*tp_dealloc*/
-    0,                                  /*tp_print*/
-    0,                                  /*tp_getattr*/
-    0,	                                /*tp_setattr*/
-    0,                                  /*tp_compare*/
-    0,                                  /*tp_repr*/
-    0,                                  /*tp_as_number*/
-    0,                                  /*tp_as_sequence*/
-    0,                                  /*tp_as_mapping*/
-    0,                                  /*tp_hash*/
-    0,                                  /*tp_call*/
-    0,                                  /*tp_str*/
-    0,                                  /*tp_getattro*/
-    0,                                  /*tp_setattro*/
-    0,                                  /*tp_as_buffer*/
-    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
-    Unpickler_doc,                      /*tp_doc*/
-    (traverseproc)Unpickler_traverse,   /*tp_traverse*/
-    (inquiry)Unpickler_clear,           /*tp_clear*/
-    0,                                  /*tp_richcompare*/
-    0,                                  /*tp_weaklistoffset*/
-    0,                                  /*tp_iter*/
-    0,                                  /*tp_iternext*/
-    Unpickler_methods,                  /*tp_methods*/
-    0,                                  /*tp_members*/
-    Unpickler_getsets,                  /*tp_getset*/
-    0,                                  /*tp_base*/
-    0,                                  /*tp_dict*/
-    0,                                  /*tp_descr_get*/
-    0,                                  /*tp_descr_set*/
-    0,                                  /*tp_dictoffset*/
-    (initproc)Unpickler_init,           /*tp_init*/
-    PyType_GenericAlloc,                /*tp_alloc*/
-    PyType_GenericNew,                  /*tp_new*/
-    PyObject_GC_Del,                    /*tp_free*/
-    0,                                  /*tp_is_gc*/
-};
-
-static int
-init_stuff(void)
-{
-    PyObject *copyreg;
-
-    copyreg = PyImport_ImportModule("copyreg");
-    if (!copyreg)
-        return -1;
-
-    dispatch_table = PyObject_GetAttrString(copyreg, "dispatch_table");
-    if (!dispatch_table)
-        goto error;
-
-    extension_registry = \
-        PyObject_GetAttrString(copyreg, "_extension_registry");
-    if (!extension_registry)
-        goto error;
-
-    inverted_registry = PyObject_GetAttrString(copyreg, "_inverted_registry");
-    if (!inverted_registry)
-        goto error;
-
-    extension_cache = PyObject_GetAttrString(copyreg, "_extension_cache");
-    if (!extension_cache)
-        goto error;
-
-    Py_DECREF(copyreg);
-
-    empty_tuple = PyTuple_New(0);
-    if (empty_tuple == NULL)
-        return -1;
-
-    two_tuple = PyTuple_New(2);
-    if (two_tuple == NULL)
-        return -1;
-    /* We use this temp container with no regard to refcounts, or to
-     * keeping containees alive.  Exempt from GC, because we don't
-     * want anything looking at two_tuple() by magic.
-     */
-    PyObject_GC_UnTrack(two_tuple);
-
-    return 0;
-
-  error:
-    Py_DECREF(copyreg);
-    return -1;
-}
-
-static struct PyModuleDef _picklemodule = {
-    PyModuleDef_HEAD_INIT,
-    "_pickle",
-    pickle_module_doc,
-    -1,
-    NULL,
-    NULL,
-    NULL,
-    NULL,
-    NULL
-};
-
-PyMODINIT_FUNC
-PyInit__pickle(void)
-{
-    PyObject *m;
-
-    if (PyType_Ready(&Unpickler_Type) < 0)
-        return NULL;
-    if (PyType_Ready(&Pickler_Type) < 0)
-        return NULL;
-    if (PyType_Ready(&Pdata_Type) < 0)
-        return NULL;
-
-    /* Create the module and add the functions. */
-    m = PyModule_Create(&_picklemodule);
-    if (m == NULL)
-        return NULL;
-
-    if (PyModule_AddObject(m, "Pickler", (PyObject *)&Pickler_Type) < 0)
-        return NULL;
-    if (PyModule_AddObject(m, "Unpickler", (PyObject *)&Unpickler_Type) < 0)
-        return NULL;
-
-    /* Initialize the exceptions. */
-    PickleError = PyErr_NewException("_pickle.PickleError", NULL, NULL);
-    if (PickleError == NULL)
-        return NULL;
-    PicklingError = \
-        PyErr_NewException("_pickle.PicklingError", PickleError, NULL);
-    if (PicklingError == NULL)
-        return NULL;
-    UnpicklingError = \
-        PyErr_NewException("_pickle.UnpicklingError", PickleError, NULL);
-    if (UnpicklingError == NULL)
-        return NULL;
-
-    if (PyModule_AddObject(m, "PickleError", PickleError) < 0)
-        return NULL;
-    if (PyModule_AddObject(m, "PicklingError", PicklingError) < 0)
-        return NULL;
-    if (PyModule_AddObject(m, "UnpicklingError", UnpicklingError) < 0)
-        return NULL;
-
-    if (init_stuff() < 0)
-        return NULL;
-
-    return m;
-}

Modified: python/branches/py3k/PC/VC6/pythoncore.dsp
==============================================================================
--- python/branches/py3k/PC/VC6/pythoncore.dsp	(original)
+++ python/branches/py3k/PC/VC6/pythoncore.dsp	Thu Jun 12 05:10:02 2008
@@ -145,10 +145,6 @@
 # End Source File
 # Begin Source File
 
-SOURCE=..\..\Modules\_pickle.c
-# End Source File
-# Begin Source File
-
 SOURCE=..\..\Modules\_functoolsmodule.c
 # End Source File
 # Begin Source File

Modified: python/branches/py3k/PC/VS7.1/pythoncore.vcproj
==============================================================================
--- python/branches/py3k/PC/VS7.1/pythoncore.vcproj	(original)
+++ python/branches/py3k/PC/VS7.1/pythoncore.vcproj	Thu Jun 12 05:10:02 2008
@@ -377,9 +377,6 @@
 			RelativePath="..\..\Modules\_stringio.c">
 		</File>
 		<File
-			RelativePath="..\..\Modules\_pickle.c">
-		</File>
-		<File
 			RelativePath="..\..\Modules\_functoolsmodule.c">
 		</File>
 		<File

Modified: python/branches/py3k/PC/VS8.0/pythoncore.vcproj
==============================================================================
--- python/branches/py3k/PC/VS8.0/pythoncore.vcproj	(original)
+++ python/branches/py3k/PC/VS8.0/pythoncore.vcproj	Thu Jun 12 05:10:02 2008
@@ -995,10 +995,6 @@
 				>
 			</File>
 			<File
-				RelativePath="..\..\Modules\_pickle.c"
-				>
-			</File>
-			<File
 				RelativePath="..\..\Modules\_functoolsmodule.c"
 				>
 			</File>

Modified: python/branches/py3k/PC/config.c
==============================================================================
--- python/branches/py3k/PC/config.c	(original)
+++ python/branches/py3k/PC/config.c	Thu Jun 12 05:10:02 2008
@@ -153,7 +153,6 @@
         {"_fileio", PyInit__fileio},
         {"_bytesio", PyInit__bytesio},
         {"_stringio", PyInit__stringio},
-        {"_pickle", PyInit__pickle},
         {"atexit", PyInit_atexit},
 
         /* Sentinel */

Modified: python/branches/py3k/setup.py
==============================================================================
--- python/branches/py3k/setup.py	(original)
+++ python/branches/py3k/setup.py	Thu Jun 12 05:10:02 2008
@@ -422,9 +422,6 @@
         exts.append( Extension("_functools", ["_functoolsmodule.c"]) )
         # Memory-based IO accelerator modules
         exts.append( Extension("_bytesio", ["_bytesio.c"]) )
-        exts.append( Extension("_stringio", ["_stringio.c"]) )
-        # C-optimized pickle replacement
-        exts.append( Extension("_pickle", ["_pickle.c"]) )
         # atexit
         exts.append( Extension("atexit", ["atexitmodule.c"]) )
         # _json speedups

From python-3000-checkins at python.org  Thu Jun 12 06:06:47 2008
From: python-3000-checkins at python.org (barry.warsaw)
Date: Thu, 12 Jun 2008 06:06:47 +0200 (CEST)
Subject: [Python-3000-checkins] r64164 - in python/branches/py3k:
	Demo/scripts/mboxconvert.py Lib/cgi.py Lib/email/parser.py
	Lib/email/utils.py Lib/http/client.py Lib/http/cookiejar.py
	Lib/http/server.py Lib/pydoc.py Lib/smtpd.py
	Lib/test/test_http_cookiejar.py Lib/test/test_httpservers.py
	Lib/test/test_ssl.py Lib/test/test_urllib.py
	Lib/test/test_urllib2.py Lib/test/test_urllib2_localnet.py
	Lib/test/test_urllib2net.py Lib/test/test_urllibnet.py
	Lib/test/test_xmlrpc.py Lib/urllib.py Lib/urllib2.py
	Lib/wsgiref/simple_server.py Tools/scripts/mailerdaemon.py
	Tools/versioncheck/pyversioncheck.py
Message-ID: <20080612040647.78F3A1E4005@bag.python.org>

Author: barry.warsaw
Date: Thu Jun 12 06:06:45 2008
New Revision: 64164

Log:
Patch for issue 2848, mostly by Humberto Diogenes, with a couple of
small fixes by Barry.  This removes mimetools from the stdlib.


Modified:
   python/branches/py3k/Demo/scripts/mboxconvert.py
   python/branches/py3k/Lib/cgi.py
   python/branches/py3k/Lib/email/parser.py
   python/branches/py3k/Lib/email/utils.py
   python/branches/py3k/Lib/http/client.py
   python/branches/py3k/Lib/http/cookiejar.py
   python/branches/py3k/Lib/http/server.py
   python/branches/py3k/Lib/pydoc.py
   python/branches/py3k/Lib/smtpd.py
   python/branches/py3k/Lib/test/test_http_cookiejar.py
   python/branches/py3k/Lib/test/test_httpservers.py
   python/branches/py3k/Lib/test/test_ssl.py
   python/branches/py3k/Lib/test/test_urllib.py
   python/branches/py3k/Lib/test/test_urllib2.py
   python/branches/py3k/Lib/test/test_urllib2_localnet.py
   python/branches/py3k/Lib/test/test_urllib2net.py
   python/branches/py3k/Lib/test/test_urllibnet.py
   python/branches/py3k/Lib/test/test_xmlrpc.py
   python/branches/py3k/Lib/urllib.py
   python/branches/py3k/Lib/urllib2.py
   python/branches/py3k/Lib/wsgiref/simple_server.py
   python/branches/py3k/Tools/scripts/mailerdaemon.py
   python/branches/py3k/Tools/versioncheck/pyversioncheck.py

Modified: python/branches/py3k/Demo/scripts/mboxconvert.py
==============================================================================
--- python/branches/py3k/Demo/scripts/mboxconvert.py	(original)
+++ python/branches/py3k/Demo/scripts/mboxconvert.py	Thu Jun 12 06:06:45 2008
@@ -89,7 +89,7 @@
         t = time.mktime(tt)
     else:
         sys.stderr.write(
-                'Unparseable date: %r\n' % (m.getheader('Date'),))
+                'Unparseable date: %r\n' % (m.get('Date'),))
         t = os.fstat(f.fileno())[stat.ST_MTIME]
     print('From', email, time.ctime(t))
     # Copy RFC822 header

Modified: python/branches/py3k/Lib/cgi.py
==============================================================================
--- python/branches/py3k/Lib/cgi.py	(original)
+++ python/branches/py3k/Lib/cgi.py	Thu Jun 12 06:06:45 2008
@@ -249,6 +249,8 @@
     since it can call parse_multipart().
 
     """
+    import http.client
+
     boundary = ""
     if 'boundary' in pdict:
         boundary = pdict['boundary']
@@ -266,8 +268,8 @@
         data = None
         if terminator:
             # At start of next part.  Read headers first.
-            headers = mimetools.Message(fp)
-            clength = headers.getheader('content-length')
+            headers = http.client.parse_headers(fp)
+            clength = headers.get('content-length')
             if clength:
                 try:
                     bytes = int(clength)

Modified: python/branches/py3k/Lib/email/parser.py
==============================================================================
--- python/branches/py3k/Lib/email/parser.py	(original)
+++ python/branches/py3k/Lib/email/parser.py	Thu Jun 12 06:06:45 2008
@@ -68,11 +68,7 @@
             data = fp.read(8192)
             if not data:
                 break
-            # XXX When Guido fixes TextIOWrapper.read() to act just like
-            # .readlines(), this...
-            feedparser.feed(str(data))
-            # ...gets reverted back to
-            #feedparser.feed(data)
+            feedparser.feed(data)
         return feedparser.close()
 
     def parsestr(self, text, headersonly=False):

Modified: python/branches/py3k/Lib/email/utils.py
==============================================================================
--- python/branches/py3k/Lib/email/utils.py	(original)
+++ python/branches/py3k/Lib/email/utils.py	Thu Jun 12 06:06:45 2008
@@ -25,7 +25,6 @@
 import base64
 import random
 import socket
-import urllib
 import warnings
 from io import StringIO
 
@@ -235,6 +234,7 @@
 
     params is a sequence of 2-tuples containing (param name, string value).
     """
+    import urllib
     # Copy params so we don't mess with the original
     params = params[:]
     new_params = []

Modified: python/branches/py3k/Lib/http/client.py
==============================================================================
--- python/branches/py3k/Lib/http/client.py	(original)
+++ python/branches/py3k/Lib/http/client.py	Thu Jun 12 06:06:45 2008
@@ -67,8 +67,9 @@
 """
 
 import io
-import mimetools
 import socket
+import email.parser
+import email.message
 from urlparse import urlsplit
 import warnings
 
@@ -201,110 +202,52 @@
 # maximal amount of data to read at one time in _safe_read
 MAXAMOUNT = 1048576
 
-class HTTPMessage(mimetools.Message):
+class HTTPMessage(email.message.Message):
+    def getallmatchingheaders(self, name):
+        """Find all header lines matching a given header name.
+
+        Look through the list of headers and find all lines matching a given
+        header name (and their continuation lines).  A list of the lines is
+        returned, without interpretation.  If the header does not occur, an
+        empty list is returned.  If the header occurs multiple times, all
+        occurrences are returned.  Case is not important in the header name.
 
-    def addheader(self, key, value):
-        """Add header for field key handling repeats."""
-        prev = self.dict.get(key)
-        if prev is None:
-            self.dict[key] = value
-        else:
-            combined = ", ".join((prev, value))
-            self.dict[key] = combined
-
-    def addcontinue(self, key, more):
-        """Add more field data from a continuation line."""
-        prev = self.dict[key]
-        self.dict[key] = prev + "\n " + more
-
-    def readheaders(self):
-        """Read header lines.
-
-        Read header lines up to the entirely blank line that terminates them.
-        The (normally blank) line that ends the headers is skipped, but not
-        included in the returned list.  If a non-header line ends the headers,
-        (which is an error), an attempt is made to backspace over it; it is
-        never included in the returned list.
-
-        The variable self.status is set to the empty string if all went well,
-        otherwise it is an error message.  The variable self.headers is a
-        completely uninterpreted list of lines contained in the header (so
-        printing them will reproduce the header exactly as it appears in the
-        file).
-
-        If multiple header fields with the same name occur, they are combined
-        according to the rules in RFC 2616 sec 4.2:
-
-        Appending each subsequent field-value to the first, each separated
-        by a comma. The order in which header fields with the same field-name
-        are received is significant to the interpretation of the combined
-        field value.
         """
-        # XXX The implementation overrides the readheaders() method of
-        # rfc822.Message.  The base class design isn't amenable to
-        # customized behavior here so the method here is a copy of the
-        # base class code with a few small changes.
-
-        self.dict = {}
-        self.unixfrom = ''
-        self.headers = hlist = []
-        self.status = ''
-        headerseen = ""
-        firstline = 1
-        startofline = unread = tell = None
-        if hasattr(self.fp, 'unread'):
-            unread = self.fp.unread
-        elif self.seekable:
-            tell = self.fp.tell
-        while True:
-            if tell:
-                try:
-                    startofline = tell()
-                except IOError:
-                    startofline = tell = None
-                    self.seekable = 0
-            line = str(self.fp.readline(), "iso-8859-1")
-            if not line:
-                self.status = 'EOF in headers'
-                break
-            # Skip unix From name time lines
-            if firstline and line.startswith('From '):
-                self.unixfrom = self.unixfrom + line
-                continue
-            firstline = 0
-            if headerseen and line[0] in ' \t':
-                # XXX Not sure if continuation lines are handled properly
-                # for http and/or for repeating headers
-                # It's a continuation line.
-                hlist.append(line)
-                self.addcontinue(headerseen, line.strip())
-                continue
-            elif self.iscomment(line):
-                # It's a comment.  Ignore it.
-                continue
-            elif self.islast(line):
-                # Note! No pushback here!  The delimiter line gets eaten.
-                break
-            headerseen = self.isheader(line)
-            if headerseen:
-                # It's a legal header line, save it.
-                hlist.append(line)
-                self.addheader(headerseen, line[len(headerseen)+1:].strip())
-                continue
-            else:
-                # It's not a header line; throw it back and stop here.
-                if not self.dict:
-                    self.status = 'No headers'
-                else:
-                    self.status = 'Non-header line where header expected'
-                # Try to undo the read.
-                if unread:
-                    unread(line)
-                elif tell:
-                    self.fp.seek(startofline)
-                else:
-                    self.status = self.status + '; bad seek'
-                break
+        # XXX: copied from rfc822.Message for compatibility
+        name = name.lower() + ':'
+        n = len(name)
+        lst = []
+        hit = 0
+        for line in self.keys():
+            if line[:n].lower() == name:
+                hit = 1
+            elif not line[:1].isspace():
+                hit = 0
+            if hit:
+                lst.append(line)
+        return lst
+
+def parse_headers(fp):
+    """Parses only RFC2822 headers from a file pointer.
+
+    email Parser wants to see strings rather than bytes.
+    But a TextIOWrapper around self.rfile would buffer too many bytes
+    from the stream, bytes which we later need to read as bytes.
+    So we read the correct bytes here, as bytes, for email Parser
+    to parse.
+
+    """
+    # XXX: Copied from http.server.BaseHTTPRequestHandler.parse_request,
+    # maybe we can just call this function from there.
+    headers = []
+    while True:
+        line = fp.readline()
+        headers.append(line)
+        if line in (b'\r\n', b'\n', b''):
+            break
+    hstring = b''.join(headers).decode('iso-8859-1')
+
+    return email.parser.Parser(_class=HTTPMessage).parsestr(hstring)
 
 class HTTPResponse:
 
@@ -418,19 +361,17 @@
             self.length = None
             self.chunked = 0
             self.will_close = 1
-            self.msg = HTTPMessage(io.BytesIO())
+            self.msg = email.message_from_string('')
             return
 
-        self.msg = HTTPMessage(self.fp, 0)
+        self.msg = parse_headers(self.fp)
+
         if self.debuglevel > 0:
-            for hdr in self.msg.headers:
+            for hdr in self.msg:
                 print("header:", hdr, end=" ")
 
-        # don't let the msg keep an fp
-        self.msg.fp = None
-
         # are we using the chunked-style of transfer encoding?
-        tr_enc = self.msg.getheader("transfer-encoding")
+        tr_enc = self.msg.get("transfer-encoding")
         if tr_enc and tr_enc.lower() == "chunked":
             self.chunked = 1
             self.chunk_left = None
@@ -443,7 +384,10 @@
         # do we have a Content-Length?
         # NOTE: RFC 2616, S4.4, #3 says we ignore this if tr_enc is "chunked"
         self.length = None
-        length = self.msg.getheader("content-length")
+        length = self.msg.get("content-length")
+
+         # are we using the chunked-style of transfer encoding?
+        tr_enc = self.msg.get("transfer-encoding")
         if length and not self.chunked:
             try:
                 self.length = int(length)
@@ -470,11 +414,11 @@
             self.will_close = 1
 
     def _check_close(self):
-        conn = self.msg.getheader("connection")
+        conn = self.msg.get("connection")
         if self.version == 11:
             # An HTTP/1.1 proxy is assumed to stay open unless
             # explicitly closed.
-            conn = self.msg.getheader("connection")
+            conn = self.msg.get("connection")
             if conn and "close" in conn.lower():
                 return True
             return False
@@ -483,7 +427,7 @@
         # connections, using rules different than HTTP/1.1.
 
         # For older HTTP, Keep-Alive indicates persistent connection.
-        if self.msg.getheader("keep-alive"):
+        if self.msg.get("keep-alive"):
             return False
 
         # At least Akamai returns a "Connection: Keep-Alive" header,
@@ -492,7 +436,7 @@
             return False
 
         # Proxy-Connection is a netscape hack.
-        pconn = self.msg.getheader("proxy-connection")
+        pconn = self.msg.get("proxy-connection")
         if pconn and "keep-alive" in pconn.lower():
             return False
 
@@ -644,7 +588,7 @@
     def getheader(self, name, default=None):
         if self.msg is None:
             raise ResponseNotReady()
-        return self.msg.getheader(name, default)
+        return ', '.join(self.msg.get_all(name, default))
 
     def getheaders(self):
         """Return list of (header, value) tuples."""

Modified: python/branches/py3k/Lib/http/cookiejar.py
==============================================================================
--- python/branches/py3k/Lib/http/cookiejar.py	(original)
+++ python/branches/py3k/Lib/http/cookiejar.py	Thu Jun 12 06:06:45 2008
@@ -1547,8 +1547,8 @@
         """Return sequence of Cookie objects extracted from response object."""
         # get cookie-attributes for RFC 2965 and Netscape protocols
         headers = response.info()
-        rfc2965_hdrs = headers.getheaders("Set-Cookie2")
-        ns_hdrs = headers.getheaders("Set-Cookie")
+        rfc2965_hdrs = headers.get_all("Set-Cookie2", [])
+        ns_hdrs = headers.get_all("Set-Cookie", [])
 
         rfc2965 = self._policy.rfc2965
         netscape = self._policy.netscape

Modified: python/branches/py3k/Lib/http/server.py
==============================================================================
--- python/branches/py3k/Lib/http/server.py	(original)
+++ python/branches/py3k/Lib/http/server.py	Thu Jun 12 06:06:45 2008
@@ -95,10 +95,11 @@
 import shutil
 import urllib
 import select
-import mimetools
 import mimetypes
 import posixpath
 import socketserver
+import email.message
+import email.parser
 
 # Default error message template
 DEFAULT_ERROR_MESSAGE = """\
@@ -211,7 +212,7 @@
 
     - command, path and version are the broken-down request line;
 
-    - headers is an instance of mimetools.Message (or a derived
+    - headers is an instance of email.message.Message (or a derived
     class) containing the header information;
 
     - rfile is a file object open for reading positioned at the
@@ -326,7 +327,7 @@
             if line in (b'\r\n', b'\n', b''):
                 break
         hfile = io.StringIO(b''.join(headers).decode('iso-8859-1'))
-        self.headers = self.MessageClass(hfile)
+        self.headers = email.parser.Parser(_class=self.MessageClass).parse(hfile)
 
         conntype = self.headers.get('Connection', "")
         if conntype.lower() == 'close':
@@ -524,8 +525,9 @@
     # Set this to HTTP/1.1 to enable automatic keepalive
     protocol_version = "HTTP/1.0"
 
-    # The Message-like class used to parse headers
-    MessageClass = mimetools.Message
+    # MessageClass used to parse headers
+    import http.client
+    MessageClass = http.client.HTTPMessage
 
     # Table mapping response codes to messages; entries have the
     # form {code: (shortmessage, longmessage)}.
@@ -955,7 +957,7 @@
         if host != self.client_address[0]:
             env['REMOTE_HOST'] = host
         env['REMOTE_ADDR'] = self.client_address[0]
-        authorization = self.headers.getheader("authorization")
+        authorization = self.headers.get("authorization")
         if authorization:
             authorization = authorization.split()
             if len(authorization) == 2:
@@ -973,14 +975,14 @@
                         if len(authorization) == 2:
                             env['REMOTE_USER'] = authorization[0]
         # XXX REMOTE_IDENT
-        if self.headers.typeheader is None:
-            env['CONTENT_TYPE'] = self.headers.type
+        if self.headers.get('content-type') is None:
+            env['CONTENT_TYPE'] = self.headers.get_content_type()
         else:
-            env['CONTENT_TYPE'] = self.headers.typeheader
-        length = self.headers.getheader('content-length')
+            env['CONTENT_TYPE'] = self.headers['content-type']
+        length = self.headers.get('content-length')
         if length:
             env['CONTENT_LENGTH'] = length
-        referer = self.headers.getheader('referer')
+        referer = self.headers.get('referer')
         if referer:
             env['HTTP_REFERER'] = referer
         accept = []
@@ -990,10 +992,10 @@
             else:
                 accept = accept + line[7:].split(',')
         env['HTTP_ACCEPT'] = ','.join(accept)
-        ua = self.headers.getheader('user-agent')
+        ua = self.headers.get('user-agent')
         if ua:
             env['HTTP_USER_AGENT'] = ua
-        co = filter(None, self.headers.getheaders('cookie'))
+        co = filter(None, self.headers.get_all('cookie', []))
         if co:
             env['HTTP_COOKIE'] = ', '.join(co)
         # XXX Other HTTP_* headers

Modified: python/branches/py3k/Lib/pydoc.py
==============================================================================
--- python/branches/py3k/Lib/pydoc.py	(original)
+++ python/branches/py3k/Lib/pydoc.py	Thu Jun 12 06:06:45 2008
@@ -1910,8 +1910,8 @@
         def __init__(self, fp, seekable=1):
             Message = self.__class__
             Message.__bases__[0].__bases__[0].__init__(self, fp, seekable)
-            self.encodingheader = self.getheader('content-transfer-encoding')
-            self.typeheader = self.getheader('content-type')
+            self.encodingheader = self.get('content-transfer-encoding')
+            self.typeheader = self.get('content-type')
             self.parsetype()
             self.parseplist()
 

Modified: python/branches/py3k/Lib/smtpd.py
==============================================================================
--- python/branches/py3k/Lib/smtpd.py	(original)
+++ python/branches/py3k/Lib/smtpd.py	Thu Jun 12 06:06:45 2008
@@ -421,9 +421,9 @@
         # These headers are required for the proper execution of Mailman.  All
         # MTAs in existance seem to add these if the original message doesn't
         # have them.
-        if not msg.getheader('from'):
+        if not msg.get('from'):
             msg['From'] = mailfrom
-        if not msg.getheader('date'):
+        if not msg.get('date'):
             msg['Date'] = time.ctime(time.time())
         for rcpt, listname, command in listnames:
             print('sending message to', rcpt, file=DEBUGSTREAM)

Modified: python/branches/py3k/Lib/test/test_http_cookiejar.py
==============================================================================
--- python/branches/py3k/Lib/test/test_http_cookiejar.py	(original)
+++ python/branches/py3k/Lib/test/test_http_cookiejar.py	Thu Jun 12 06:06:45 2008
@@ -193,9 +193,8 @@
         """
         headers: list of RFC822-style 'Key: value' strings
         """
-        import mimetools, io
-        f = io.StringIO("\n".join(headers))
-        self._headers = mimetools.Message(f)
+        import email
+        self._headers = email.message_from_string("\n".join(headers))
         self._url = url
     def info(self): return self._headers
 

Modified: python/branches/py3k/Lib/test/test_httpservers.py
==============================================================================
--- python/branches/py3k/Lib/test/test_httpservers.py	(original)
+++ python/branches/py3k/Lib/test/test_httpservers.py	Thu Jun 12 06:06:45 2008
@@ -19,12 +19,14 @@
 import unittest
 from test import support
 
-
 class NoLogRequestHandler:
     def log_message(self, *args):
         # don't write log messages to stderr
         pass
 
+    def read(self, n=None):
+        return ''
+
 
 class TestServerThread(threading.Thread):
     def __init__(self, test_object, request_handler):

Modified: python/branches/py3k/Lib/test/test_ssl.py
==============================================================================
--- python/branches/py3k/Lib/test/test_ssl.py	(original)
+++ python/branches/py3k/Lib/test/test_ssl.py	Thu Jun 12 06:06:45 2008
@@ -944,7 +944,7 @@
                 url = 'https://%s:%d/%s' % (
                     HOST, server.port, os.path.split(CERTFILE)[1])
                 f = urllib.urlopen(url)
-                dlen = f.info().getheader("content-length")
+                dlen = f.info().get("content-length")
                 if dlen and (int(dlen) > 0):
                     d2 = f.read(int(dlen))
                     if support.verbose:

Modified: python/branches/py3k/Lib/test/test_urllib.py
==============================================================================
--- python/branches/py3k/Lib/test/test_urllib.py	(original)
+++ python/branches/py3k/Lib/test/test_urllib.py	Thu Jun 12 06:06:45 2008
@@ -2,11 +2,11 @@
 
 import urllib
 import http.client
+import email.message
 import io
 import unittest
 from test import support
 import os
-import mimetools
 import tempfile
 
 def hexescape(char):
@@ -78,7 +78,7 @@
         self.returned_obj.close()
 
     def test_info(self):
-        self.assert_(isinstance(self.returned_obj.info(), mimetools.Message))
+        self.assert_(isinstance(self.returned_obj.info(), email.message.Message))
 
     def test_geturl(self):
         self.assertEqual(self.returned_obj.geturl(), self.pathname)
@@ -206,8 +206,8 @@
         # a headers value is returned.
         result = urllib.urlretrieve("file:%s" % support.TESTFN)
         self.assertEqual(result[0], support.TESTFN)
-        self.assert_(isinstance(result[1], mimetools.Message),
-                     "did not get a mimetools.Message instance as second "
+        self.assert_(isinstance(result[1], email.message.Message),
+                     "did not get a email.message.Message instance as second "
                      "returned value")
 
     def test_copy(self):

Modified: python/branches/py3k/Lib/test/test_urllib2.py
==============================================================================
--- python/branches/py3k/Lib/test/test_urllib2.py	(original)
+++ python/branches/py3k/Lib/test/test_urllib2.py	Thu Jun 12 06:06:45 2008
@@ -349,18 +349,18 @@
         self._count = 0
         self.requests = []
     def http_open(self, req):
-        import mimetools, http.client, copy
+        import email, http.client, copy
         from io import StringIO
         self.requests.append(copy.deepcopy(req))
         if self._count == 0:
             self._count = self._count + 1
             name = http.client.responses[self.code]
-            msg = mimetools.Message(StringIO(self.headers))
+            msg = email.message_from_string(self.headers)
             return self.parent.error(
                 "http", req, MockFile(), self.code, name, msg)
         else:
             self.req = req
-            msg = mimetools.Message(StringIO("\r\n\r\n"))
+            msg = email.message_from_string("\r\n\r\n")
             return MockResponse(200, "OK", msg, "", req.get_full_url())
 
 class MockPasswordManager:

Modified: python/branches/py3k/Lib/test/test_urllib2_localnet.py
==============================================================================
--- python/branches/py3k/Lib/test/test_urllib2_localnet.py	(original)
+++ python/branches/py3k/Lib/test/test_urllib2_localnet.py	Thu Jun 12 06:06:45 2008
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 
-import mimetools
+import email
 import threading
 import urlparse
 import urllib2
@@ -443,10 +443,10 @@
         try:
             open_url = urllib2.urlopen("http://localhost:%s" % handler.port)
             info_obj = open_url.info()
-            self.assert_(isinstance(info_obj, mimetools.Message),
+            self.assert_(isinstance(info_obj, email.message.Message),
                          "object returned by 'info' is not an instance of "
-                         "mimetools.Message")
-            self.assertEqual(info_obj.getsubtype(), "plain")
+                         "email.message.Message")
+            self.assertEqual(info_obj.get_content_subtype(), "plain")
         finally:
             self.server.stop()
 

Modified: python/branches/py3k/Lib/test/test_urllib2net.py
==============================================================================
--- python/branches/py3k/Lib/test/test_urllib2net.py	(original)
+++ python/branches/py3k/Lib/test/test_urllib2net.py	Thu Jun 12 06:06:45 2008
@@ -8,7 +8,6 @@
 import urllib2
 import sys
 import os
-import mimetools
 
 
 def _retry_thrice(func, exc, *args, **kwargs):

Modified: python/branches/py3k/Lib/test/test_urllibnet.py
==============================================================================
--- python/branches/py3k/Lib/test/test_urllibnet.py	(original)
+++ python/branches/py3k/Lib/test/test_urllibnet.py	Thu Jun 12 06:06:45 2008
@@ -7,7 +7,7 @@
 import urllib
 import sys
 import os
-import mimetools
+import email.message
 
 
 def _open_with_retry(func, host, *args, **kwargs):
@@ -87,10 +87,10 @@
             info_obj = open_url.info()
         finally:
             open_url.close()
-            self.assert_(isinstance(info_obj, mimetools.Message),
+            self.assert_(isinstance(info_obj, email.message.Message),
                          "object returned by 'info' is not an instance of "
-                         "mimetools.Message")
-            self.assertEqual(info_obj.getsubtype(), "html")
+                         "email.message.Message")
+            self.assertEqual(info_obj.get_content_subtype(), "html")
 
     def test_geturl(self):
         # Make sure same URL as opened is returned by geturl.
@@ -180,8 +180,8 @@
         # Make sure header returned as 2nd value from urlretrieve is good.
         file_location, header = self.urlretrieve("http://www.python.org/")
         os.unlink(file_location)
-        self.assert_(isinstance(header, mimetools.Message),
-                     "header is not an instance of mimetools.Message")
+        self.assert_(isinstance(header, email.message.Message),
+                     "header is not an instance of email.message.Message")
 
 
 

Modified: python/branches/py3k/Lib/test/test_xmlrpc.py
==============================================================================
--- python/branches/py3k/Lib/test/test_xmlrpc.py	(original)
+++ python/branches/py3k/Lib/test/test_xmlrpc.py	Thu Jun 12 06:06:45 2008
@@ -6,7 +6,6 @@
 import xmlrpc.client as xmlrpclib
 import xmlrpc.server
 import threading
-import mimetools
 import http.client
 import socket
 import os
@@ -452,12 +451,12 @@
 
 # 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):
+class FailingMessageClass(http.client.HTTPMessage):
+    def get(self, key, failobj=None):
         key = key.lower()
         if key == 'content-length':
             return 'I am broken'
-        return mimetools.Message.__getitem__(self, key)
+        return super().get(key, failobj)
 
 
 class FailingServerTestCase(unittest.TestCase):
@@ -477,7 +476,8 @@
         # reset flag
         xmlrpc.server.SimpleXMLRPCServer._send_traceback_header = False
         # reset message class
-        xmlrpc.server.SimpleXMLRPCRequestHandler.MessageClass = mimetools.Message
+        default_class = http.client.HTTPMessage
+        xmlrpc.server.SimpleXMLRPCRequestHandler.MessageClass = default_class
 
     def test_basic(self):
         # check that flag is false by default
@@ -529,8 +529,8 @@
             if not is_unavailable_exception(e) and hasattr(e, "headers"):
                 # 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)
+                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')
 

Modified: python/branches/py3k/Lib/urllib.py
==============================================================================
--- python/branches/py3k/Lib/urllib.py	(original)
+++ python/branches/py3k/Lib/urllib.py	Thu Jun 12 06:06:45 2008
@@ -17,12 +17,14 @@
 protocol.  All you know is that is has methods read(), readline(),
 readlines(), fileno(), close() and info().  The read*(), fileno()
 and close() methods work like those of open files.
-The info() method returns a mimetools.Message object which can be
+The info() method returns a email.message.Message object which can be
 used to query various info about the object, if available.
-(mimetools.Message objects are queried with the getheader() method.)
+(email.message.Message objects provide a dict-like interface.)
 """
 
 import http.client
+import email.message
+import email
 import os
 import socket
 import sys
@@ -414,8 +416,7 @@
 
     def open_local_file(self, url):
         """Use local file."""
-        import mimetypes, mimetools, email.utils
-        from io import StringIO
+        import mimetypes, email.utils
         host, file = splithost(url)
         localname = url2pathname(file)
         try:
@@ -425,9 +426,9 @@
         size = stats.st_size
         modified = email.utils.formatdate(stats.st_mtime, usegmt=True)
         mtype = mimetypes.guess_type(url)[0]
-        headers = mimetools.Message(StringIO(
+        headers = email.message_from_string(
             'Content-Type: %s\nContent-Length: %d\nLast-modified: %s\n' %
-            (mtype or 'text/plain', size, modified)))
+            (mtype or 'text/plain', size, modified))
         if not host:
             urlfile = file
             if file[:1] == '/':
@@ -448,8 +449,7 @@
         """Use FTP protocol."""
         if not isinstance(url, str):
             raise IOError('ftp error', 'proxy support for ftp protocol currently not implemented')
-        import mimetypes, mimetools
-        from io import StringIO
+        import mimetypes
         host, path = splithost(url)
         if not host: raise IOError('ftp error', 'no host given')
         host, port = splitport(host)
@@ -498,7 +498,7 @@
                 headers += "Content-Type: %s\n" % mtype
             if retrlen is not None and retrlen >= 0:
                 headers += "Content-Length: %d\n" % retrlen
-            headers = mimetools.Message(StringIO(headers))
+            headers = email.message_from_string(headers)
             return addinfourl(fp, headers, "ftp:" + url)
         except ftperrors() as msg:
             raise IOError('ftp error', msg).with_traceback(sys.exc_info()[2])
@@ -514,7 +514,6 @@
         # mediatype := [ type "/" subtype ] *( ";" parameter )
         # data      := *urlchar
         # parameter := attribute "=" value
-        import mimetools
         from io import StringIO
         try:
             [type, data] = url.split(',', 1)
@@ -541,8 +540,8 @@
         msg.append('')
         msg.append(data)
         msg = '\n'.join(msg)
+        headers = email.message_from_string(msg)
         f = StringIO(msg)
-        headers = mimetools.Message(f, 0)
         #f.fileno = None     # needed for addinfourl
         return addinfourl(f, headers, url)
 
@@ -761,13 +760,10 @@
 
 _noheaders = None
 def noheaders():
-    """Return an empty mimetools.Message object."""
+    """Return an empty email.message.Message object."""
     global _noheaders
     if _noheaders is None:
-        import mimetools
-        from io import StringIO
-        _noheaders = mimetools.Message(StringIO(), 0)
-        _noheaders.fp.close()   # Recycle file descriptor
+        _noheaders = email.message.Message()
     return _noheaders
 
 

Modified: python/branches/py3k/Lib/urllib2.py
==============================================================================
--- python/branches/py3k/Lib/urllib2.py	(original)
+++ python/branches/py3k/Lib/urllib2.py	Thu Jun 12 06:06:45 2008
@@ -91,7 +91,7 @@
 import hashlib
 import http.client
 import io
-import mimetools
+import email
 import os
 import posixpath
 import random
@@ -549,9 +549,9 @@
         # Some servers (incorrectly) return multiple Location headers
         # (so probably same goes for URI).  Use first header.
         if 'location' in headers:
-            newurl = headers.getheaders('location')[0]
+            newurl = headers['location']
         elif 'uri' in headers:
-            newurl = headers.getheaders('uri')[0]
+            newurl = headers['uri']
         else:
             return
         newurl = urlparse.urljoin(req.get_full_url(), newurl)
@@ -1050,7 +1050,7 @@
         http_class must implement the HTTPConnection API from http.client.
         The addinfourl return value is a file-like object.  It also
         has methods and attributes including:
-            - info(): return a mimetools.Message object for the headers
+            - info(): return a email.message.Message object for the headers
             - geturl(): return the original request URL
             - code: HTTP status code
         """
@@ -1140,6 +1140,10 @@
     """Parse list of key=value strings where keys are not duplicated."""
     parsed = {}
     for elt in l:
+        # Because of a trailing comma in the auth string, elt could be the
+        # empty string.
+        if not elt:
+            continue
         k, v = elt.split('=', 1)
         if v[0] == '"' and v[-1] == '"':
             v = v[1:-1]
@@ -1222,9 +1226,9 @@
             size = stats.st_size
             modified = email.utils.formatdate(stats.st_mtime, usegmt=True)
             mtype = mimetypes.guess_type(file)[0]
-            headers = mimetools.Message(StringIO(
+            headers = email.message_from_string(
                 'Content-type: %s\nContent-length: %d\nLast-modified: %s\n' %
-                (mtype or 'text/plain', size, modified)))
+                (mtype or 'text/plain', size, modified))
             if host:
                 host, port = splitport(host)
             if not host or \
@@ -1290,8 +1294,8 @@
                 headers += "Content-type: %s\n" % mtype
             if retrlen is not None and retrlen >= 0:
                 headers += "Content-length: %d\n" % retrlen
+            headers = email.message_from_string(headers)
             sf = StringIO(headers)
-            headers = mimetools.Message(sf)
             return addinfourl(fp, headers, req.get_full_url())
         except ftplib.all_errors as msg:
             raise URLError('ftp error: %s' % msg).with_traceback(sys.exc_info()[2])

Modified: python/branches/py3k/Lib/wsgiref/simple_server.py
==============================================================================
--- python/branches/py3k/Lib/wsgiref/simple_server.py	(original)
+++ python/branches/py3k/Lib/wsgiref/simple_server.py	Thu Jun 12 06:06:45 2008
@@ -101,16 +101,16 @@
             env['REMOTE_HOST'] = host
         env['REMOTE_ADDR'] = self.client_address[0]
 
-        if self.headers.typeheader is None:
-            env['CONTENT_TYPE'] = self.headers.type
+        if self.headers.get('content-type') is None:
+            env['CONTENT_TYPE'] = self.headers.get_content_type()
         else:
-            env['CONTENT_TYPE'] = self.headers.typeheader
+            env['CONTENT_TYPE'] = self.headers['content-type']
 
-        length = self.headers.getheader('content-length')
+        length = self.headers.get('content-length')
         if length:
             env['CONTENT_LENGTH'] = length
 
-        for h in self.headers.headers:
+        for h in self.headers:
             k,v = h.split(':',1)
             k=k.replace('-','_').upper(); v=v.strip()
             if k in env:

Modified: python/branches/py3k/Tools/scripts/mailerdaemon.py
==============================================================================
--- python/branches/py3k/Tools/scripts/mailerdaemon.py	(original)
+++ python/branches/py3k/Tools/scripts/mailerdaemon.py	Thu Jun 12 06:06:45 2008
@@ -14,7 +14,7 @@
         self.sub = ''
 
     def is_warning(self):
-        sub = self.getheader('Subject')
+        sub = self.get('Subject')
         if not sub:
             return 0
         sub = sub.lower()

Modified: python/branches/py3k/Tools/versioncheck/pyversioncheck.py
==============================================================================
--- python/branches/py3k/Tools/versioncheck/pyversioncheck.py	(original)
+++ python/branches/py3k/Tools/versioncheck/pyversioncheck.py	Thu Jun 12 06:06:45 2008
@@ -53,7 +53,7 @@
             print('    Cannot open:', arg)
         return -1, None, None
     msg = rfc822.Message(fp, seekable=0)
-    newversion = msg.getheader('current-version')
+    newversion = msg.get('current-version')
     if not newversion:
         if verbose >= VERBOSE_EACHFILE:
             print('    No "Current-Version:" header in URL or URL not found')

From guido at python.org  Thu Jun 12 06:08:35 2008
From: guido at python.org (Guido van Rossum)
Date: Wed, 11 Jun 2008 21:08:35 -0700
Subject: [Python-3000-checkins] r64163 - in python/branches/py3k:
	Lib/pickle.py Lib/pickletools.py Lib/test/pickletester.py
	Lib/test/test_pickle.py Lib/test/test_pickletools.py
	Misc/NEWS Modules/_pickle.c PC/VC6/pythoncore.dsp
	PC/VS7.1/pythoncore.vcproj P
Message-ID: <ca471dc20806112108g2f66848by349f35cf3dfc4aab@mail.gmail.com>

Whoa, I object. This seems to be rolling back functionality that was
pretty stable for several alphas, and (if I may believe the docstring
change) you're even dropping protocol 3. Isn't there a more elegant
way? This seems way too drastic a change so close to the beta release.

On Wed, Jun 11, 2008 at 8:10 PM, benjamin.peterson
<python-3000-checkins at python.org> wrote:
> Author: benjamin.peterson
> Date: Thu Jun 12 05:10:02 2008
> New Revision: 64163
>
> Log:
> revert the addition of _pickle because it was causing havok with 64-bit
>
>
> Removed:
>   python/branches/py3k/Modules/_pickle.c
> Modified:
>   python/branches/py3k/Lib/pickle.py
>   python/branches/py3k/Lib/pickletools.py
>   python/branches/py3k/Lib/test/pickletester.py
>   python/branches/py3k/Lib/test/test_pickle.py
>   python/branches/py3k/Lib/test/test_pickletools.py
>   python/branches/py3k/Misc/NEWS
>   python/branches/py3k/PC/VC6/pythoncore.dsp
>   python/branches/py3k/PC/VS7.1/pythoncore.vcproj
>   python/branches/py3k/PC/VS8.0/pythoncore.vcproj
>   python/branches/py3k/PC/config.c
>   python/branches/py3k/setup.py
>
> Modified: python/branches/py3k/Lib/pickle.py
> ==============================================================================
> --- python/branches/py3k/Lib/pickle.py  (original)
> +++ python/branches/py3k/Lib/pickle.py  Thu Jun 12 05:10:02 2008
> @@ -174,7 +174,7 @@
>
>  # Pickling machinery
>
> -class _Pickler:
> +class Pickler:
>
>     def __init__(self, file, protocol=None):
>         """This takes a binary file for writing a pickle data stream.
> @@ -182,19 +182,21 @@
>         All protocols now read and write bytes.
>
>         The optional protocol argument tells the pickler to use the
> -        given protocol; supported protocols are 0, 1, 2, 3.  The default
> -        protocol is 3; a backward-incompatible protocol designed for
> -        Python 3.0.
> +        given protocol; supported protocols are 0, 1, 2.  The default
> +        protocol is 2; it's been supported for many years now.
> +
> +        Protocol 1 is more efficient than protocol 0; protocol 2 is
> +        more efficient than protocol 1.
>
>         Specifying a negative protocol version selects the highest
>         protocol version supported.  The higher the protocol used, the
>         more recent the version of Python needed to read the pickle
>         produced.
>
> -        The file argument must have a write() method that accepts a single
> -        bytes argument. It can thus be a file object opened for binary
> -        writing, a io.BytesIO instance, or any other custom object that
> -        meets this interface.
> +        The file parameter must have a write() method that accepts a single
> +        string argument.  It can thus be an open file object, a StringIO
> +        object, or any other custom object that meets this interface.
> +
>         """
>         if protocol is None:
>             protocol = DEFAULT_PROTOCOL
> @@ -202,10 +204,7 @@
>             protocol = HIGHEST_PROTOCOL
>         elif not 0 <= protocol <= HIGHEST_PROTOCOL:
>             raise ValueError("pickle protocol must be <= %d" % HIGHEST_PROTOCOL)
> -        try:
> -            self.write = file.write
> -        except AttributeError:
> -            raise TypeError("file must have a 'write' attribute")
> +        self.write = file.write
>         self.memo = {}
>         self.proto = int(protocol)
>         self.bin = protocol >= 1
> @@ -271,10 +270,10 @@
>
>         return GET + repr(i).encode("ascii") + b'\n'
>
> -    def save(self, obj, save_persistent_id=True):
> +    def save(self, obj):
>         # Check for persistent id (defined by a subclass)
>         pid = self.persistent_id(obj)
> -        if pid is not None and save_persistent_id:
> +        if pid:
>             self.save_pers(pid)
>             return
>
> @@ -342,7 +341,7 @@
>     def save_pers(self, pid):
>         # Save a persistent id reference
>         if self.bin:
> -            self.save(pid, save_persistent_id=False)
> +            self.save(pid)
>             self.write(BINPERSID)
>         else:
>             self.write(PERSID + str(pid).encode("ascii") + b'\n')
> @@ -351,13 +350,13 @@
>                     listitems=None, dictitems=None, obj=None):
>         # This API is called by some subclasses
>
> -        # Assert that args is a tuple
> +        # Assert that args is a tuple or None
>         if not isinstance(args, tuple):
> -            raise PicklingError("args from save_reduce() should be a tuple")
> +            raise PicklingError("args from reduce() should be a tuple")
>
>         # Assert that func is callable
>         if not hasattr(func, '__call__'):
> -            raise PicklingError("func from save_reduce() should be callable")
> +            raise PicklingError("func from reduce should be callable")
>
>         save = self.save
>         write = self.write
> @@ -439,6 +438,31 @@
>             self.write(obj and TRUE or FALSE)
>     dispatch[bool] = save_bool
>
> +    def save_int(self, obj, pack=struct.pack):
> +        if self.bin:
> +            # If the int is small enough to fit in a signed 4-byte 2's-comp
> +            # format, we can store it more efficiently than the general
> +            # case.
> +            # First one- and two-byte unsigned ints:
> +            if obj >= 0:
> +                if obj <= 0xff:
> +                    self.write(BININT1 + bytes([obj]))
> +                    return
> +                if obj <= 0xffff:
> +                    self.write(BININT2 + bytes([obj&0xff, obj>>8]))
> +                    return
> +            # Next check for 4-byte signed ints:
> +            high_bits = obj >> 31  # note that Python shift sign-extends
> +            if high_bits == 0 or high_bits == -1:
> +                # All high bits are copies of bit 2**31, so the value
> +                # fits in a 4-byte signed int.
> +                self.write(BININT + pack("<i", obj))
> +                return
> +        # Text pickle, or int too big to fit in signed 4-byte format.
> +        self.write(INT + repr(obj).encode("ascii") + b'\n')
> +    # XXX save_int is merged into save_long
> +    # dispatch[int] = save_int
> +
>     def save_long(self, obj, pack=struct.pack):
>         if self.bin:
>             # If the int is small enough to fit in a signed 4-byte 2's-comp
> @@ -479,7 +503,7 @@
>
>     def save_bytes(self, obj, pack=struct.pack):
>         if self.proto < 3:
> -            self.save_reduce(bytes, (list(obj),), obj=obj)
> +            self.save_reduce(bytes, (list(obj),))
>             return
>         n = len(obj)
>         if n < 256:
> @@ -555,6 +579,12 @@
>
>     dispatch[tuple] = save_tuple
>
> +    # save_empty_tuple() isn't used by anything in Python 2.3.  However, I
> +    # found a Pickler subclass in Zope3 that calls it, so it's not harmless
> +    # to remove it.
> +    def save_empty_tuple(self, obj):
> +        self.write(EMPTY_TUPLE)
> +
>     def save_list(self, obj):
>         write = self.write
>
> @@ -666,7 +696,7 @@
>             module = whichmodule(obj, name)
>
>         try:
> -            __import__(module, level=0)
> +            __import__(module)
>             mod = sys.modules[module]
>             klass = getattr(mod, name)
>         except (ImportError, KeyError, AttributeError):
> @@ -690,19 +720,9 @@
>                 else:
>                     write(EXT4 + pack("<i", code))
>                 return
> -        # Non-ASCII identifiers are supported only with protocols >= 3.
> -        if self.proto >= 3:
> -            write(GLOBAL + bytes(module, "utf-8") + b'\n' +
> -                  bytes(name, "utf-8") + b'\n')
> -        else:
> -            try:
> -                write(GLOBAL + bytes(module, "ascii") + b'\n' +
> -                      bytes(name, "ascii") + b'\n')
> -            except UnicodeEncodeError:
> -                raise PicklingError(
> -                    "can't pickle global identifier '%s.%s' using "
> -                    "pickle protocol %i" % (module, name, self.proto))
>
> +        write(GLOBAL + bytes(module, "utf-8") + b'\n' +
> +              bytes(name, "utf-8") + b'\n')
>         self.memoize(obj)
>
>     dispatch[FunctionType] = save_global
> @@ -761,7 +781,7 @@
>
>  # Unpickling machinery
>
> -class _Unpickler:
> +class Unpickler:
>
>     def __init__(self, file, *, encoding="ASCII", errors="strict"):
>         """This takes a binary file for reading a pickle data stream.
> @@ -821,9 +841,6 @@
>         while stack[k] is not mark: k = k-1
>         return k
>
> -    def persistent_load(self, pid):
> -        raise UnpickingError("unsupported persistent id encountered")
> -
>     dispatch = {}
>
>     def load_proto(self):
> @@ -833,7 +850,7 @@
>     dispatch[PROTO[0]] = load_proto
>
>     def load_persid(self):
> -        pid = self.readline()[:-1].decode("ascii")
> +        pid = self.readline()[:-1]
>         self.append(self.persistent_load(pid))
>     dispatch[PERSID[0]] = load_persid
>
> @@ -862,9 +879,9 @@
>             val = True
>         else:
>             try:
> -                val = int(data, 0)
> +                val = int(data)
>             except ValueError:
> -                val = int(data, 0)
> +                val = int(data)
>         self.append(val)
>     dispatch[INT[0]] = load_int
>
> @@ -916,8 +933,7 @@
>                 break
>         else:
>             raise ValueError("insecure string pickle: %r" % orig)
> -        self.append(codecs.escape_decode(rep)[0]
> -                    .decode(self.encoding, self.errors))
> +        self.append(codecs.escape_decode(rep)[0])
>     dispatch[STRING[0]] = load_string
>
>     def load_binstring(self):
> @@ -959,7 +975,7 @@
>     dispatch[TUPLE[0]] = load_tuple
>
>     def load_empty_tuple(self):
> -        self.append(())
> +        self.stack.append(())
>     dispatch[EMPTY_TUPLE[0]] = load_empty_tuple
>
>     def load_tuple1(self):
> @@ -975,11 +991,11 @@
>     dispatch[TUPLE3[0]] = load_tuple3
>
>     def load_empty_list(self):
> -        self.append([])
> +        self.stack.append([])
>     dispatch[EMPTY_LIST[0]] = load_empty_list
>
>     def load_empty_dictionary(self):
> -        self.append({})
> +        self.stack.append({})
>     dispatch[EMPTY_DICT[0]] = load_empty_dictionary
>
>     def load_list(self):
> @@ -1006,13 +1022,13 @@
>     def _instantiate(self, klass, k):
>         args = tuple(self.stack[k+1:])
>         del self.stack[k:]
> -        instantiated = False
> +        instantiated = 0
>         if (not args and
>                 isinstance(klass, type) and
>                 not hasattr(klass, "__getinitargs__")):
>             value = _EmptyClass()
>             value.__class__ = klass
> -            instantiated = True
> +            instantiated = 1
>         if not instantiated:
>             try:
>                 value = klass(*args)
> @@ -1022,8 +1038,8 @@
>         self.append(value)
>
>     def load_inst(self):
> -        module = self.readline()[:-1].decode("ascii")
> -        name = self.readline()[:-1].decode("ascii")
> +        module = self.readline()[:-1]
> +        name = self.readline()[:-1]
>         klass = self.find_class(module, name)
>         self._instantiate(klass, self.marker())
>     dispatch[INST[0]] = load_inst
> @@ -1043,8 +1059,8 @@
>     dispatch[NEWOBJ[0]] = load_newobj
>
>     def load_global(self):
> -        module = self.readline()[:-1].decode("utf-8")
> -        name = self.readline()[:-1].decode("utf-8")
> +        module = self.readline()[:-1]
> +        name = self.readline()[:-1]
>         klass = self.find_class(module, name)
>         self.append(klass)
>     dispatch[GLOBAL[0]] = load_global
> @@ -1079,7 +1095,11 @@
>
>     def find_class(self, module, name):
>         # Subclasses may override this
> -        __import__(module, level=0)
> +        if isinstance(module, bytes_types):
> +            module = module.decode("utf-8")
> +        if isinstance(name, bytes_types):
> +            name = name.decode("utf-8")
> +        __import__(module)
>         mod = sys.modules[module]
>         klass = getattr(mod, name)
>         return klass
> @@ -1111,33 +1131,31 @@
>     dispatch[DUP[0]] = load_dup
>
>     def load_get(self):
> -        i = int(self.readline()[:-1])
> -        self.append(self.memo[i])
> +        self.append(self.memo[self.readline()[:-1].decode("ascii")])
>     dispatch[GET[0]] = load_get
>
>     def load_binget(self):
> -        i = self.read(1)[0]
> -        self.append(self.memo[i])
> +        i = ord(self.read(1))
> +        self.append(self.memo[repr(i)])
>     dispatch[BINGET[0]] = load_binget
>
>     def load_long_binget(self):
>         i = mloads(b'i' + self.read(4))
> -        self.append(self.memo[i])
> +        self.append(self.memo[repr(i)])
>     dispatch[LONG_BINGET[0]] = load_long_binget
>
>     def load_put(self):
> -        i = int(self.readline()[:-1])
> -        self.memo[i] = self.stack[-1]
> +        self.memo[self.readline()[:-1].decode("ascii")] = self.stack[-1]
>     dispatch[PUT[0]] = load_put
>
>     def load_binput(self):
> -        i = self.read(1)[0]
> -        self.memo[i] = self.stack[-1]
> +        i = ord(self.read(1))
> +        self.memo[repr(i)] = self.stack[-1]
>     dispatch[BINPUT[0]] = load_binput
>
>     def load_long_binput(self):
>         i = mloads(b'i' + self.read(4))
> -        self.memo[i] = self.stack[-1]
> +        self.memo[repr(i)] = self.stack[-1]
>     dispatch[LONG_BINPUT[0]] = load_long_binput
>
>     def load_append(self):
> @@ -1303,12 +1321,6 @@
>         n -= 1 << (nbytes * 8)
>     return n
>
> -# Use the faster _pickle if possible
> -try:
> -    from _pickle import *
> -except ImportError:
> -    Pickler, Unpickler = _Pickler, _Unpickler
> -
>  # Shorthands
>
>  def dump(obj, file, protocol=None):
> @@ -1321,14 +1333,14 @@
>     assert isinstance(res, bytes_types)
>     return res
>
> -def load(file, *, encoding="ASCII", errors="strict"):
> -    return Unpickler(file, encoding=encoding, errors=errors).load()
> +def load(file):
> +    return Unpickler(file).load()
>
> -def loads(s, *, encoding="ASCII", errors="strict"):
> +def loads(s):
>     if isinstance(s, str):
>         raise TypeError("Can't load pickle from unicode string")
>     file = io.BytesIO(s)
> -    return Unpickler(file, encoding=encoding, errors=errors).load()
> +    return Unpickler(file).load()
>
>  # Doctest
>
>
> Modified: python/branches/py3k/Lib/pickletools.py
> ==============================================================================
> --- python/branches/py3k/Lib/pickletools.py     (original)
> +++ python/branches/py3k/Lib/pickletools.py     Thu Jun 12 05:10:02 2008
> @@ -2079,12 +2079,11 @@
>    70: t        TUPLE      (MARK at 49)
>    71: p    PUT        5
>    74: R    REDUCE
> -   75: p    PUT        6
> -   78: V    UNICODE    'def'
> -   83: p    PUT        7
> -   86: s    SETITEM
> -   87: a    APPEND
> -   88: .    STOP
> +   75: V    UNICODE    'def'
> +   80: p    PUT        6
> +   83: s    SETITEM
> +   84: a    APPEND
> +   85: .    STOP
>  highest protocol among opcodes = 0
>
>  Try again with a "binary" pickle.
> @@ -2116,12 +2115,11 @@
>    49: t            TUPLE      (MARK at 37)
>    50: q        BINPUT     5
>    52: R        REDUCE
> -   53: q        BINPUT     6
> -   55: X        BINUNICODE 'def'
> -   63: q        BINPUT     7
> -   65: s        SETITEM
> -   66: e        APPENDS    (MARK at 3)
> -   67: .    STOP
> +   53: X        BINUNICODE 'def'
> +   61: q        BINPUT     6
> +   63: s        SETITEM
> +   64: e        APPENDS    (MARK at 3)
> +   65: .    STOP
>  highest protocol among opcodes = 1
>
>  Exercise the INST/OBJ/BUILD family.
>
> Modified: python/branches/py3k/Lib/test/pickletester.py
> ==============================================================================
> --- python/branches/py3k/Lib/test/pickletester.py       (original)
> +++ python/branches/py3k/Lib/test/pickletester.py       Thu Jun 12 05:10:02 2008
> @@ -362,7 +362,7 @@
>     return x
>
>  class AbstractPickleTests(unittest.TestCase):
> -    # Subclass must define self.dumps, self.loads.
> +    # Subclass must define self.dumps, self.loads, self.error.
>
>     _testdata = create_data()
>
> @@ -463,9 +463,8 @@
>             self.assertEqual(list(x[0].attr.keys()), [1])
>             self.assert_(x[0].attr[1] is x)
>
> -    def test_get(self):
> -        self.assertRaises(KeyError, self.loads, b'g0\np0')
> -        self.assertEquals(self.loads(b'((Kdtp0\nh\x00l.))'), [(100,), (100,)])
> +    def test_garyp(self):
> +        self.assertRaises(self.error, self.loads, b'garyp')
>
>     def test_insecure_strings(self):
>         # XXX Some of these tests are temporarily disabled
> @@ -956,7 +955,7 @@
>         f = open(TESTFN, "wb")
>         try:
>             f.close()
> -            self.assertRaises(ValueError, pickle.dump, 123, f)
> +            self.assertRaises(ValueError, self.module.dump, 123, f)
>         finally:
>             os.remove(TESTFN)
>
> @@ -965,24 +964,24 @@
>         f = open(TESTFN, "wb")
>         try:
>             f.close()
> -            self.assertRaises(ValueError, pickle.dump, 123, f)
> +            self.assertRaises(ValueError, self.module.dump, 123, f)
>         finally:
>             os.remove(TESTFN)
>
>     def test_highest_protocol(self):
>         # Of course this needs to be changed when HIGHEST_PROTOCOL changes.
> -        self.assertEqual(pickle.HIGHEST_PROTOCOL, 3)
> +        self.assertEqual(self.module.HIGHEST_PROTOCOL, 3)
>
>     def test_callapi(self):
>         from io import BytesIO
>         f = BytesIO()
>         # With and without keyword arguments
> -        pickle.dump(123, f, -1)
> -        pickle.dump(123, file=f, protocol=-1)
> -        pickle.dumps(123, -1)
> -        pickle.dumps(123, protocol=-1)
> -        pickle.Pickler(f, -1)
> -        pickle.Pickler(f, protocol=-1)
> +        self.module.dump(123, f, -1)
> +        self.module.dump(123, file=f, protocol=-1)
> +        self.module.dumps(123, -1)
> +        self.module.dumps(123, protocol=-1)
> +        self.module.Pickler(f, -1)
> +        self.module.Pickler(f, protocol=-1)
>
>  class AbstractPersistentPicklerTests(unittest.TestCase):
>
>
> Modified: python/branches/py3k/Lib/test/test_pickle.py
> ==============================================================================
> --- python/branches/py3k/Lib/test/test_pickle.py        (original)
> +++ python/branches/py3k/Lib/test/test_pickle.py        Thu Jun 12 05:10:02 2008
> @@ -7,42 +7,37 @@
>  from test.pickletester import AbstractPickleModuleTests
>  from test.pickletester import AbstractPersistentPicklerTests
>
> -try:
> -    import _pickle
> -    has_c_implementation = True
> -except ImportError:
> -    has_c_implementation = False
> +class PickleTests(AbstractPickleTests, AbstractPickleModuleTests):
>
> +    module = pickle
> +    error = KeyError
>
> -class PickleTests(AbstractPickleModuleTests):
> -    pass
> +    def dumps(self, arg, proto=None):
> +        return pickle.dumps(arg, proto)
>
> +    def loads(self, buf):
> +        return pickle.loads(buf)
>
> -class PyPicklerTests(AbstractPickleTests):
> +class PicklerTests(AbstractPickleTests):
>
> -    pickler = pickle._Pickler
> -    unpickler = pickle._Unpickler
> +    error = KeyError
>
>     def dumps(self, arg, proto=None):
>         f = io.BytesIO()
> -        p = self.pickler(f, proto)
> +        p = pickle.Pickler(f, proto)
>         p.dump(arg)
>         f.seek(0)
>         return bytes(f.read())
>
>     def loads(self, buf):
>         f = io.BytesIO(buf)
> -        u = self.unpickler(f)
> +        u = pickle.Unpickler(f)
>         return u.load()
>
> -
> -class PyPersPicklerTests(AbstractPersistentPicklerTests):
> -
> -    pickler = pickle._Pickler
> -    unpickler = pickle._Unpickler
> +class PersPicklerTests(AbstractPersistentPicklerTests):
>
>     def dumps(self, arg, proto=None):
> -        class PersPickler(self.pickler):
> +        class PersPickler(pickle.Pickler):
>             def persistent_id(subself, obj):
>                 return self.persistent_id(obj)
>         f = io.BytesIO()
> @@ -52,29 +47,19 @@
>         return f.read()
>
>     def loads(self, buf):
> -        class PersUnpickler(self.unpickler):
> +        class PersUnpickler(pickle.Unpickler):
>             def persistent_load(subself, obj):
>                 return self.persistent_load(obj)
>         f = io.BytesIO(buf)
>         u = PersUnpickler(f)
>         return u.load()
>
> -
> -if has_c_implementation:
> -    class CPicklerTests(PyPicklerTests):
> -        pickler = _pickle.Pickler
> -        unpickler = _pickle.Unpickler
> -
> -    class CPersPicklerTests(PyPersPicklerTests):
> -        pickler = _pickle.Pickler
> -        unpickler = _pickle.Unpickler
> -
> -
>  def test_main():
> -    tests = [PickleTests, PyPicklerTests, PyPersPicklerTests]
> -    if has_c_implementation:
> -        tests.extend([CPicklerTests, CPersPicklerTests])
> -    support.run_unittest(*tests)
> +    support.run_unittest(
> +        PickleTests,
> +        PicklerTests,
> +        PersPicklerTests
> +    )
>     support.run_doctest(pickle)
>
>  if __name__ == "__main__":
>
> Modified: python/branches/py3k/Lib/test/test_pickletools.py
> ==============================================================================
> --- python/branches/py3k/Lib/test/test_pickletools.py   (original)
> +++ python/branches/py3k/Lib/test/test_pickletools.py   Thu Jun 12 05:10:02 2008
> @@ -12,6 +12,8 @@
>     def loads(self, buf):
>         return pickle.loads(buf)
>
> +    module = pickle
> +    error = KeyError
>
>  def test_main():
>     support.run_unittest(OptimizedPickleTests)
>
> Modified: python/branches/py3k/Misc/NEWS
> ==============================================================================
> --- python/branches/py3k/Misc/NEWS      (original)
> +++ python/branches/py3k/Misc/NEWS      Thu Jun 12 05:10:02 2008
> @@ -82,10 +82,6 @@
>
>  - Added C optimized implementation of io.StringIO.
>
> -- The ``pickle`` module is now automatically use an optimized C
> -  implementation of Pickler and Unpickler when available. The
> -  ``cPickle`` module is no longer needed.
> -
>  - Removed the ``htmllib`` and ``sgmllib`` modules.
>
>  - The deprecated ``SmartCookie`` and ``SimpleCookie`` classes have
>
> Deleted: python/branches/py3k/Modules/_pickle.c
> ==============================================================================
> --- python/branches/py3k/Modules/_pickle.c      Thu Jun 12 05:10:02 2008
> +++ (empty file)
> @@ -1,4546 +0,0 @@
> -#include "Python.h"
> -#include "structmember.h"
> -
> -PyDoc_STRVAR(pickle_module_doc,
> -"Optimized C implementation for the Python pickle module.");
> -
> -/* Bump this when new opcodes are added to the pickle protocol. */
> -enum {
> -    HIGHEST_PROTOCOL = 3,
> -    DEFAULT_PROTOCOL = 3
> -};
> -
> -
> -/* Pickle opcodes. These must be kept updated with pickle.py.
> -   Extensive docs are in pickletools.py. */
> -enum opcode {
> -    MARK            = '(',
> -    STOP            = '.',
> -    POP             = '0',
> -    POP_MARK        = '1',
> -    DUP             = '2',
> -    FLOAT           = 'F',
> -    INT             = 'I',
> -    BININT          = 'J',
> -    BININT1         = 'K',
> -    LONG            = 'L',
> -    BININT2         = 'M',
> -    NONE            = 'N',
> -    PERSID          = 'P',
> -    BINPERSID       = 'Q',
> -    REDUCE          = 'R',
> -    STRING          = 'S',
> -    BINSTRING       = 'T',
> -    SHORT_BINSTRING = 'U',
> -    UNICODE         = 'V',
> -    BINUNICODE      = 'X',
> -    APPEND          = 'a',
> -    BUILD           = 'b',
> -    GLOBAL          = 'c',
> -    DICT            = 'd',
> -    EMPTY_DICT      = '}',
> -    APPENDS         = 'e',
> -    GET             = 'g',
> -    BINGET          = 'h',
> -    INST            = 'i',
> -    LONG_BINGET     = 'j',
> -    LIST            = 'l',
> -    EMPTY_LIST      = ']',
> -    OBJ             = 'o',
> -    PUT             = 'p',
> -    BINPUT          = 'q',
> -    LONG_BINPUT     = 'r',
> -    SETITEM         = 's',
> -    TUPLE           = 't',
> -    EMPTY_TUPLE     = ')',
> -    SETITEMS        = 'u',
> -    BINFLOAT        = 'G',
> -
> -    /* Protocol 2. */
> -    PROTO       = '\x80',
> -    NEWOBJ      = '\x81',
> -    EXT1        = '\x82',
> -    EXT2        = '\x83',
> -    EXT4        = '\x84',
> -    TUPLE1      = '\x85',
> -    TUPLE2      = '\x86',
> -    TUPLE3      = '\x87',
> -    NEWTRUE     = '\x88',
> -    NEWFALSE    = '\x89',
> -    LONG1       = '\x8a',
> -    LONG4       = '\x8b',
> -
> -    /* Protocol 3 (Python 3.x) */
> -    BINBYTES       = 'B',
> -    SHORT_BINBYTES = 'C',
> -};
> -
> -/* These aren't opcodes -- they're ways to pickle bools before protocol 2
> - * so that unpicklers written before bools were introduced unpickle them
> - * as ints, but unpicklers after can recognize that bools were intended.
> - * Note that protocol 2 added direct ways to pickle bools.
> - */
> -#undef TRUE
> -#define TRUE  "I01\n"
> -#undef FALSE
> -#define FALSE "I00\n"
> -
> -enum {
> -   /* Keep in synch with pickle.Pickler._BATCHSIZE.  This is how many elements
> -      batch_list/dict() pumps out before doing APPENDS/SETITEMS.  Nothing will
> -      break if this gets out of synch with pickle.py, but it's unclear that would
> -      help anything either. */
> -    BATCHSIZE = 1000,
> -
> -    /* Nesting limit until Pickler, when running in "fast mode", starts
> -       checking for self-referential data-structures. */
> -    FAST_NESTING_LIMIT = 50,
> -
> -    /* Size of the write buffer of Pickler. Higher values will reduce the
> -       number of calls to the write() method of the output stream. */
> -    WRITE_BUF_SIZE = 256,
> -};
> -
> -/* Exception classes for pickle. These should override the ones defined in
> -   pickle.py, when the C-optimized Pickler and Unpickler are used. */
> -static PyObject *PickleError;
> -static PyObject *PicklingError;
> -static PyObject *UnpicklingError;
> -
> -/* copyreg.dispatch_table, {type_object: pickling_function} */
> -static PyObject *dispatch_table;
> -/* For EXT[124] opcodes. */
> -/* copyreg._extension_registry, {(module_name, function_name): code} */
> -static PyObject *extension_registry;
> -/* copyreg._inverted_registry, {code: (module_name, function_name)} */
> -static PyObject *inverted_registry;
> -/* copyreg._extension_cache, {code: object} */
> -static PyObject *extension_cache;
> -
> -/* XXX: Are these really nescessary? */
> -/* As the name says, an empty tuple. */
> -static PyObject *empty_tuple;
> -/* For looking up name pairs in copyreg._extension_registry. */
> -static PyObject *two_tuple;
> -
> -static int
> -stack_underflow(void)
> -{
> -    PyErr_SetString(UnpicklingError, "unpickling stack underflow");
> -    return -1;
> -}
> -
> -/* Internal data type used as the unpickling stack. */
> -typedef struct {
> -    PyObject_HEAD
> -    int length;   /* number of initial slots in data currently used */
> -    int size;     /* number of slots in data allocated */
> -    PyObject **data;
> -} Pdata;
> -
> -static void
> -Pdata_dealloc(Pdata *self)
> -{
> -    int i;
> -    PyObject **p;
> -
> -    for (i = self->length, p = self->data; --i >= 0; p++) {
> -        Py_DECREF(*p);
> -    }
> -    if (self->data)
> -        PyMem_Free(self->data);
> -    PyObject_Del(self);
> -}
> -
> -static PyTypeObject Pdata_Type = {
> -    PyVarObject_HEAD_INIT(NULL, 0)
> -    "_pickle.Pdata",              /*tp_name*/
> -    sizeof(Pdata),                /*tp_basicsize*/
> -    0,                            /*tp_itemsize*/
> -    (destructor)Pdata_dealloc,    /*tp_dealloc*/
> -};
> -
> -static PyObject *
> -Pdata_New(void)
> -{
> -    Pdata *self;
> -
> -    if (!(self = PyObject_New(Pdata, &Pdata_Type)))
> -        return NULL;
> -    self->size = 8;
> -    self->length = 0;
> -    self->data = PyMem_Malloc(self->size * sizeof(PyObject *));
> -    if (self->data)
> -        return (PyObject *)self;
> -    Py_DECREF(self);
> -    return PyErr_NoMemory();
> -}
> -
> -
> -/* Retain only the initial clearto items.  If clearto >= the current
> - * number of items, this is a (non-erroneous) NOP.
> - */
> -static int
> -Pdata_clear(Pdata *self, int clearto)
> -{
> -    int i;
> -    PyObject **p;
> -
> -    if (clearto < 0)
> -        return stack_underflow();
> -    if (clearto >= self->length)
> -        return 0;
> -
> -    for (i = self->length, p = self->data + clearto; --i >= clearto; p++) {
> -        Py_CLEAR(*p);
> -    }
> -    self->length = clearto;
> -
> -    return 0;
> -}
> -
> -static int
> -Pdata_grow(Pdata *self)
> -{
> -    int bigger;
> -    size_t nbytes;
> -    PyObject **tmp;
> -
> -    bigger = (self->size << 1) + 1;
> -    if (bigger <= 0)            /* was 0, or new value overflows */
> -        goto nomemory;
> -    if ((int)(size_t)bigger != bigger)
> -        goto nomemory;
> -    nbytes = (size_t)bigger * sizeof(PyObject *);
> -    if (nbytes / sizeof(PyObject *) != (size_t)bigger)
> -        goto nomemory;
> -    tmp = PyMem_Realloc(self->data, nbytes);
> -    if (tmp == NULL)
> -        goto nomemory;
> -    self->data = tmp;
> -    self->size = bigger;
> -    return 0;
> -
> -  nomemory:
> -    PyErr_NoMemory();
> -    return -1;
> -}
> -
> -/* D is a Pdata*.  Pop the topmost element and store it into V, which
> - * must be an lvalue holding PyObject*.  On stack underflow, UnpicklingError
> - * is raised and V is set to NULL.
> - */
> -static PyObject *
> -Pdata_pop(Pdata *self)
> -{
> -    if (self->length == 0) {
> -        PyErr_SetString(UnpicklingError, "bad pickle data");
> -        return NULL;
> -    }
> -    return self->data[--(self->length)];
> -}
> -#define PDATA_POP(D, V) do { (V) = Pdata_pop((D)); } while (0)
> -
> -static int
> -Pdata_push(Pdata *self, PyObject *obj)
> -{
> -    if (self->length == self->size && Pdata_grow(self) < 0) {
> -        return -1;
> -    }
> -    self->data[self->length++] = obj;
> -    return 0;
> -}
> -
> -/* Push an object on stack, transferring its ownership to the stack. */
> -#define PDATA_PUSH(D, O, ER) do {                               \
> -        if (Pdata_push((D), (O)) < 0) return (ER); } while(0)
> -
> -/* Push an object on stack, adding a new reference to the object. */
> -#define PDATA_APPEND(D, O, ER) do {                             \
> -        Py_INCREF((O));                                         \
> -        if (Pdata_push((D), (O)) < 0) return (ER); } while(0)
> -
> -static PyObject *
> -Pdata_poptuple(Pdata *self, Py_ssize_t start)
> -{
> -    PyObject *tuple;
> -    Py_ssize_t len, i, j;
> -
> -    len = self->length - start;
> -    tuple = PyTuple_New(len);
> -    if (tuple == NULL)
> -        return NULL;
> -    for (i = start, j = 0; j < len; i++, j++)
> -        PyTuple_SET_ITEM(tuple, j, self->data[i]);
> -
> -    self->length = start;
> -    return tuple;
> -}
> -
> -static PyObject *
> -Pdata_poplist(Pdata *self, Py_ssize_t start)
> -{
> -    PyObject *list;
> -    Py_ssize_t len, i, j;
> -
> -    len = self->length - start;
> -    list = PyList_New(len);
> -    if (list == NULL)
> -        return NULL;
> -    for (i = start, j = 0; j < len; i++, j++)
> -        PyList_SET_ITEM(list, j, self->data[i]);
> -
> -    self->length = start;
> -    return list;
> -}
> -
> -typedef struct PicklerObject {
> -    PyObject_HEAD
> -    PyObject *write;            /* write() method of the output stream */
> -    PyObject *memo;             /* Memo dictionary, keep track of the seen
> -                                   objects to support self-referential objects
> -                                   pickling.  */
> -    PyObject *pers_func;        /* persistent_id() method, can be NULL */
> -    PyObject *arg;
> -    int proto;                  /* Pickle protocol number, >= 0 */
> -    int bin;                    /* Boolean, true if proto > 0 */
> -    int nesting;                /* Current nesting level, this is to guard
> -                                   save() from going into infinite recursion
> -                                   and segfaulting. */
> -    int buf_size;               /* Size of the current buffered pickle data */
> -    char *write_buf;            /* Write buffer, this is to avoid calling the
> -                                   write() method of the output stream too
> -                                   often. */
> -    int fast;                   /* Enable fast mode if set to a true value.
> -                                   The fast mode disable the usage of memo,
> -                                   therefore speeding the pickling process by
> -                                   not generating superfluous PUT opcodes. It
> -                                   should not be used if with self-referential
> -                                   objects. */
> -    int fast_nesting;
> -    PyObject *fast_memo;
> -} PicklerObject;
> -
> -typedef struct UnpicklerObject {
> -    PyObject_HEAD
> -    Pdata *stack;               /* Pickle data stack, store unpickled objects. */
> -    PyObject *readline;         /* readline() method of the output stream */
> -    PyObject *read;             /* read() method of the output stream */
> -    PyObject *memo;             /* Memo dictionary, provide the objects stored
> -                                   using the PUT opcodes. */
> -    PyObject *arg;
> -    PyObject *pers_func;        /* persistent_load() method, can be NULL. */
> -    PyObject *last_string;      /* Reference to the last string read by the
> -                                   readline() method.  */
> -    char *buffer;               /* Reading buffer. */
> -    char *encoding;             /* Name of the encoding to be used for
> -                                   decoding strings pickled using Python
> -                                   2.x. The default value is "ASCII" */
> -    char *errors;               /* Name of errors handling scheme to used when
> -                                   decoding strings. The default value is
> -                                   "strict". */
> -    int *marks;                 /* Mark stack, used for unpickling container
> -                                   objects. */
> -    Py_ssize_t num_marks;       /* Number of marks in the mark stack. */
> -    Py_ssize_t marks_size;      /* Current allocated size of the mark stack. */
> -} UnpicklerObject;
> -
> -/* Forward declarations */
> -static int save(PicklerObject *, PyObject *, int);
> -static int save_reduce(PicklerObject *, PyObject *, PyObject *);
> -static PyTypeObject Pickler_Type;
> -static PyTypeObject Unpickler_Type;
> -
> -
> -/* Helpers for creating the argument tuple passed to functions. This has the
> -   performance advantage of calling PyTuple_New() only once. */
> -
> -#define ARG_TUP(self, obj) do {                             \
> -        if ((self)->arg || ((self)->arg=PyTuple_New(1))) {  \
> -            Py_XDECREF(PyTuple_GET_ITEM((self)->arg, 0));   \
> -            PyTuple_SET_ITEM((self)->arg, 0, (obj));        \
> -        }                                                   \
> -        else {                                              \
> -            Py_DECREF((obj));                               \
> -        }                                                   \
> -    } while (0)
> -
> -#define FREE_ARG_TUP(self) do {                 \
> -        if ((self)->arg->ob_refcnt > 1)         \
> -            Py_CLEAR((self)->arg);              \
> -    } while (0)
> -
> -/* A temporary cleaner API for fast single argument function call.
> -
> -   XXX: Does caching the argument tuple provides any real performance benefits?
> -
> -   A quick benchmark, on a 2.0GHz Athlon64 3200+ running Linux 2.6.24 with
> -   glibc 2.7, tells me that it takes roughly 20,000,000 PyTuple_New(1) calls
> -   when the tuple is retrieved from the freelist (i.e, call PyTuple_New() then
> -   immediately DECREF it) and 1,200,000 calls when allocating brand new tuples
> -   (i.e, call PyTuple_New() and store the returned value in an array), to save
> -   one second (wall clock time). Either ways, the loading time a pickle stream
> -   large enough to generate this number of calls would be massively
> -   overwhelmed by other factors, like I/O throughput, the GC traversal and
> -   object allocation overhead. So, I really doubt these functions provide any
> -   real benefits.
> -
> -   On the other hand, oprofile reports that pickle spends a lot of time in
> -   these functions. But, that is probably more related to the function call
> -   overhead, than the argument tuple allocation.
> -
> -   XXX: And, what is the reference behavior of these? Steal, borrow? At first
> -   glance, it seems to steal the reference of 'arg' and borrow the reference
> -   of 'func'.
> - */
> -static PyObject *
> -pickler_call(PicklerObject *self, PyObject *func, PyObject *arg)
> -{
> -    PyObject *result = NULL;
> -
> -    ARG_TUP(self, arg);
> -    if (self->arg) {
> -        result = PyObject_Call(func, self->arg, NULL);
> -        FREE_ARG_TUP(self);
> -    }
> -    return result;
> -}
> -
> -static PyObject *
> -unpickler_call(UnpicklerObject *self, PyObject *func, PyObject *arg)
> -{
> -    PyObject *result = NULL;
> -
> -    ARG_TUP(self, arg);
> -    if (self->arg) {
> -        result = PyObject_Call(func, self->arg, NULL);
> -        FREE_ARG_TUP(self);
> -    }
> -    return result;
> -}
> -
> -static Py_ssize_t
> -pickler_write(PicklerObject *self, const char *s, Py_ssize_t n)
> -{
> -    PyObject *data, *result;
> -
> -    if (s == NULL) {
> -        if (!(self->buf_size))
> -            return 0;
> -        data = PyBytes_FromStringAndSize(self->write_buf, self->buf_size);
> -        if (data == NULL)
> -            return -1;
> -    }
> -    else {
> -        if (self->buf_size && (n + self->buf_size) > WRITE_BUF_SIZE) {
> -            if (pickler_write(self, NULL, 0) < 0)
> -                return -1;
> -        }
> -
> -        if (n > WRITE_BUF_SIZE) {
> -            if (!(data = PyBytes_FromStringAndSize(s, n)))
> -                return -1;
> -        }
> -        else {
> -            memcpy(self->write_buf + self->buf_size, s, n);
> -            self->buf_size += n;
> -            return n;
> -        }
> -    }
> -
> -    /* object with write method */
> -    result = pickler_call(self, self->write, data);
> -    if (result == NULL)
> -        return -1;
> -
> -    Py_DECREF(result);
> -    self->buf_size = 0;
> -    return n;
> -}
> -
> -/* XXX: These read/readline functions ought to be optimized. Buffered I/O
> -   might help a lot, especially with the new (but much slower) io library.
> -   On the other hand, the added complexity might not worth it.
> - */
> -
> -/* Read at least n characters from the input stream and set s to the current
> -   reading position. */
> -static Py_ssize_t
> -unpickler_read(UnpicklerObject *self, char **s, Py_ssize_t n)
> -{
> -    PyObject *len;
> -    PyObject *data;
> -
> -    len = PyLong_FromSsize_t(n);
> -    if (len == NULL)
> -        return -1;
> -
> -    data = unpickler_call(self, self->read, len);
> -    if (data == NULL)
> -        return -1;
> -
> -    /* XXX: Should bytearray be supported too? */
> -    if (!PyBytes_Check(data)) {
> -        PyErr_SetString(PyExc_ValueError,
> -                        "read() from the underlying stream did not"
> -                        "return bytes");
> -        return -1;
> -    }
> -
> -    Py_XDECREF(self->last_string);
> -    self->last_string = data;
> -
> -    if (!(*s = PyBytes_AS_STRING(data)))
> -        return -1;
> -
> -    return n;
> -}
> -
> -static Py_ssize_t
> -unpickler_readline(UnpicklerObject *self, char **s)
> -{
> -    PyObject *data;
> -
> -    data = PyObject_CallObject(self->readline, empty_tuple);
> -    if (data == NULL)
> -        return -1;
> -
> -    /* XXX: Should bytearray be supported too? */
> -    if (!PyBytes_Check(data)) {
> -        PyErr_SetString(PyExc_ValueError,
> -                        "readline() from the underlying stream did not"
> -                        "return bytes");
> -        return -1;
> -    }
> -
> -    Py_XDECREF(self->last_string);
> -    self->last_string = data;
> -
> -    if (!(*s = PyBytes_AS_STRING(data)))
> -        return -1;
> -
> -    return PyBytes_GET_SIZE(data);
> -}
> -
> -/* Generate a GET opcode for an object stored in the memo. The 'key' argument
> -   should be the address of the object as returned by PyLong_FromVoidPtr(). */
> -static int
> -memo_get(PicklerObject *self, PyObject *key)
> -{
> -    PyObject *value;
> -    PyObject *memo_id;
> -    long x;
> -    char pdata[30];
> -    int len;
> -
> -    value = PyDict_GetItemWithError(self->memo, key);
> -    if (value == NULL) {
> -        if (!PyErr_Occurred())
> -            PyErr_SetObject(PyExc_KeyError, key);
> -        return -1;
> -    }
> -
> -    memo_id = PyTuple_GetItem(value, 0);
> -    if (memo_id == NULL)
> -        return -1;
> -
> -    if (!PyLong_Check(memo_id)) {
> -        PyErr_SetString(PicklingError, "memo id must be an integer");
> -        return -1;
> -    }
> -    x = PyLong_AsLong(memo_id);
> -    if (x == -1 && PyErr_Occurred())
> -        return -1;
> -
> -    if (!self->bin) {
> -        pdata[0] = GET;
> -        PyOS_snprintf(pdata + 1, sizeof(pdata) - 1, "%ld\n", x);
> -        len = (int)strlen(pdata);
> -    }
> -    else {
> -        if (x < 256) {
> -            pdata[0] = BINGET;
> -            pdata[1] = (unsigned char)(x & 0xff);
> -            len = 2;
> -        }
> -        else if (x <= 0xffffffffL) {
> -            pdata[0] = LONG_BINGET;
> -            pdata[1] = (unsigned char)(x & 0xff);
> -            pdata[2] = (unsigned char)((x >> 8) & 0xff);
> -            pdata[3] = (unsigned char)((x >> 16) & 0xff);
> -            pdata[4] = (unsigned char)((x >> 24) & 0xff);
> -            len = 5;
> -        }
> -        else { /* unlikely */
> -            PyErr_SetString(PicklingError,
> -                            "memo id too large for LONG_BINGET");
> -            return -1;
> -        }
> -    }
> -
> -    if (pickler_write(self, pdata, len) < 0)
> -        return -1;
> -
> -    return 0;
> -}
> -
> -/* Store an object in the memo, assign it a new unique ID based on the number
> -   of objects currently stored in the memo and generate a PUT opcode. */
> -static int
> -memo_put(PicklerObject *self, PyObject *obj)
> -{
> -    PyObject *key = NULL;
> -    PyObject *memo_id = NULL;
> -    PyObject *tuple = NULL;
> -    long x;
> -    char pdata[30];
> -    int len;
> -    int status = 0;
> -
> -    if (self->fast)
> -        return 0;
> -
> -    key = PyLong_FromVoidPtr(obj);
> -    if (key == NULL)
> -        goto error;
> -    if ((x = PyDict_Size(self->memo)) < 0)
> -        goto error;
> -    memo_id = PyLong_FromLong(x);
> -    if (memo_id == NULL)
> -        goto error;
> -    tuple = PyTuple_New(2);
> -    if (tuple == NULL)
> -        goto error;
> -
> -    Py_INCREF(memo_id);
> -    PyTuple_SET_ITEM(tuple, 0, memo_id);
> -    Py_INCREF(obj);
> -    PyTuple_SET_ITEM(tuple, 1, obj);
> -    if (PyDict_SetItem(self->memo, key, tuple) < 0)
> -        goto error;
> -
> -    if (!self->bin) {
> -        pdata[0] = PUT;
> -        PyOS_snprintf(pdata + 1, sizeof(pdata) - 1, "%ld\n", x);
> -        len = strlen(pdata);
> -    }
> -    else {
> -        if (x < 256) {
> -            pdata[0] = BINPUT;
> -            pdata[1] = x;
> -            len = 2;
> -        }
> -        else if (x <= 0xffffffffL) {
> -            pdata[0] = LONG_BINPUT;
> -            pdata[1] = (unsigned char)(x & 0xff);
> -            pdata[2] = (unsigned char)((x >> 8) & 0xff);
> -            pdata[3] = (unsigned char)((x >> 16) & 0xff);
> -            pdata[4] = (unsigned char)((x >> 24) & 0xff);
> -            len = 5;
> -        }
> -        else { /* unlikely */
> -            PyErr_SetString(PicklingError,
> -                            "memo id too large for LONG_BINPUT");
> -            return -1;
> -        }
> -    }
> -
> -    if (pickler_write(self, pdata, len) < 0)
> -        goto error;
> -
> -    if (0) {
> -  error:
> -        status = -1;
> -    }
> -
> -    Py_XDECREF(key);
> -    Py_XDECREF(memo_id);
> -    Py_XDECREF(tuple);
> -
> -    return status;
> -}
> -
> -static PyObject *
> -whichmodule(PyObject *global, PyObject *global_name)
> -{
> -    Py_ssize_t i, j;
> -    static PyObject *module_str = NULL;
> -    static PyObject *main_str = NULL;
> -    PyObject *module_name;
> -    PyObject *modules_dict;
> -    PyObject *module;
> -    PyObject *obj;
> -
> -    if (module_str == NULL) {
> -        module_str = PyUnicode_InternFromString("__module__");
> -        if (module_str == NULL)
> -            return NULL;
> -        main_str = PyUnicode_InternFromString("__main__");
> -        if (main_str == NULL)
> -            return NULL;
> -    }
> -
> -    module_name = PyObject_GetAttr(global, module_str);
> -
> -    /* In some rare cases (e.g., random.getrandbits), __module__ can be
> -       None. If it is so, then search sys.modules for the module of
> -       global.  */
> -    if (module_name == Py_None) {
> -        Py_DECREF(module_name);
> -        goto search;
> -    }
> -
> -    if (module_name) {
> -        return module_name;
> -    }
> -    if (PyErr_ExceptionMatches(PyExc_AttributeError))
> -        PyErr_Clear();
> -    else
> -        return NULL;
> -
> -  search:
> -    modules_dict = PySys_GetObject("modules");
> -    if (modules_dict == NULL)
> -        return NULL;
> -
> -    i = 0;
> -    module_name = NULL;
> -    while ((j = PyDict_Next(modules_dict, &i, &module_name, &module))) {
> -        if (PyObject_Compare(module_name, main_str) == 0)
> -            continue;
> -
> -        obj = PyObject_GetAttr(module, global_name);
> -        if (obj == NULL) {
> -            if (PyErr_ExceptionMatches(PyExc_AttributeError))
> -                PyErr_Clear();
> -            else
> -                return NULL;
> -            continue;
> -        }
> -
> -        if (obj != global) {
> -            Py_DECREF(obj);
> -            continue;
> -        }
> -
> -        Py_DECREF(obj);
> -        break;
> -    }
> -
> -    /* If no module is found, use __main__. */
> -    if (!j) {
> -        module_name = main_str;
> -    }
> -
> -    Py_INCREF(module_name);
> -    return module_name;
> -}
> -
> -/* fast_save_enter() and fast_save_leave() are guards against recursive
> -   objects when Pickler is used with the "fast mode" (i.e., with object
> -   memoization disabled). If the nesting of a list or dict object exceed
> -   FAST_NESTING_LIMIT, these guards will start keeping an internal
> -   reference to the seen list or dict objects and check whether these objects
> -   are recursive. These are not strictly necessary, since save() has a
> -   hard-coded recursion limit, but they give a nicer error message than the
> -   typical RuntimeError. */
> -static int
> -fast_save_enter(PicklerObject *self, PyObject *obj)
> -{
> -    /* if fast_nesting < 0, we're doing an error exit. */
> -    if (++self->fast_nesting >= FAST_NESTING_LIMIT) {
> -        PyObject *key = NULL;
> -        if (self->fast_memo == NULL) {
> -            self->fast_memo = PyDict_New();
> -            if (self->fast_memo == NULL) {
> -                self->fast_nesting = -1;
> -                return 0;
> -            }
> -        }
> -        key = PyLong_FromVoidPtr(obj);
> -        if (key == NULL)
> -            return 0;
> -        if (PyDict_GetItem(self->fast_memo, key)) {
> -            Py_DECREF(key);
> -            PyErr_Format(PyExc_ValueError,
> -                         "fast mode: can't pickle cyclic objects "
> -                         "including object type %.200s at %p",
> -                         obj->ob_type->tp_name, obj);
> -            self->fast_nesting = -1;
> -            return 0;
> -        }
> -        if (PyDict_SetItem(self->fast_memo, key, Py_None) < 0) {
> -            Py_DECREF(key);
> -            self->fast_nesting = -1;
> -            return 0;
> -        }
> -        Py_DECREF(key);
> -    }
> -    return 1;
> -}
> -
> -static int
> -fast_save_leave(PicklerObject *self, PyObject *obj)
> -{
> -    if (self->fast_nesting-- >= FAST_NESTING_LIMIT) {
> -        PyObject *key = PyLong_FromVoidPtr(obj);
> -        if (key == NULL)
> -            return 0;
> -        if (PyDict_DelItem(self->fast_memo, key) < 0) {
> -            Py_DECREF(key);
> -            return 0;
> -        }
> -        Py_DECREF(key);
> -    }
> -    return 1;
> -}
> -
> -static int
> -save_none(PicklerObject *self, PyObject *obj)
> -{
> -    const char none_op = NONE;
> -    if (pickler_write(self, &none_op, 1) < 0)
> -        return -1;
> -
> -    return 0;
> -}
> -
> -static int
> -save_bool(PicklerObject *self, PyObject *obj)
> -{
> -    static const char *buf[2] = { FALSE, TRUE };
> -    const char len[2] = {sizeof(FALSE) - 1, sizeof(TRUE) - 1};
> -    int p = (obj == Py_True);
> -
> -    if (self->proto >= 2) {
> -        const char bool_op = p ? NEWTRUE : NEWFALSE;
> -        if (pickler_write(self, &bool_op, 1) < 0)
> -            return -1;
> -    }
> -    else if (pickler_write(self, buf[p], len[p]) < 0)
> -        return -1;
> -
> -    return 0;
> -}
> -
> -static int
> -save_int(PicklerObject *self, long x)
> -{
> -    char pdata[32];
> -    int len = 0;
> -
> -    if (!self->bin
> -#if SIZEOF_LONG > 4
> -        || x > 0x7fffffffL || x < -0x80000000L
> -#endif
> -        ) {
> -        /* Text-mode pickle, or long too big to fit in the 4-byte
> -         * signed BININT format:  store as a string.
> -         */
> -        pdata[0] = LONG;        /* use LONG for consistence with pickle.py */
> -        PyOS_snprintf(pdata + 1, sizeof(pdata) - 1, "%ld\n", x);
> -        if (pickler_write(self, pdata, strlen(pdata)) < 0)
> -            return -1;
> -    }
> -    else {
> -        /* Binary pickle and x fits in a signed 4-byte int. */
> -        pdata[1] = (unsigned char)(x & 0xff);
> -        pdata[2] = (unsigned char)((x >> 8) & 0xff);
> -        pdata[3] = (unsigned char)((x >> 16) & 0xff);
> -        pdata[4] = (unsigned char)((x >> 24) & 0xff);
> -
> -        if ((pdata[4] == 0) && (pdata[3] == 0)) {
> -            if (pdata[2] == 0) {
> -                pdata[0] = BININT1;
> -                len = 2;
> -            }
> -            else {
> -                pdata[0] = BININT2;
> -                len = 3;
> -            }
> -        }
> -        else {
> -            pdata[0] = BININT;
> -            len = 5;
> -        }
> -
> -        if (pickler_write(self, pdata, len) < 0)
> -            return -1;
> -    }
> -
> -    return 0;
> -}
> -
> -static int
> -save_long(PicklerObject *self, PyObject *obj)
> -{
> -    PyObject *repr = NULL;
> -    Py_ssize_t size;
> -    long val = PyLong_AsLong(obj);
> -    int status = 0;
> -
> -    const char long_op = LONG;
> -
> -    if (val == -1 && PyErr_Occurred()) {
> -        /* out of range for int pickling */
> -        PyErr_Clear();
> -    }
> -    else
> -        return save_int(self, val);
> -
> -    if (self->proto >= 2) {
> -        /* Linear-time pickling. */
> -        size_t nbits;
> -        size_t nbytes;
> -        unsigned char *pdata;
> -        char header[5];
> -        int i;
> -        int sign = _PyLong_Sign(obj);
> -
> -        if (sign == 0) {
> -            header[0] = LONG1;
> -            header[1] = 0;      /* It's 0 -- an empty bytestring. */
> -            if (pickler_write(self, header, 2) < 0)
> -                goto error;
> -            return 0;
> -        }
> -        nbits = _PyLong_NumBits(obj);
> -        if (nbits == (size_t)-1 && PyErr_Occurred())
> -            goto error;
> -        /* How many bytes do we need?  There are nbits >> 3 full
> -         * bytes of data, and nbits & 7 leftover bits.  If there
> -         * are any leftover bits, then we clearly need another
> -         * byte.  Wnat's not so obvious is that we *probably*
> -         * need another byte even if there aren't any leftovers:
> -         * the most-significant bit of the most-significant byte
> -         * acts like a sign bit, and it's usually got a sense
> -         * opposite of the one we need.  The exception is longs
> -         * of the form -(2**(8*j-1)) for j > 0.  Such a long is
> -         * its own 256's-complement, so has the right sign bit
> -         * even without the extra byte.  That's a pain to check
> -         * for in advance, though, so we always grab an extra
> -         * byte at the start, and cut it back later if possible.
> -         */
> -        nbytes = (nbits >> 3) + 1;
> -        if (nbytes > INT_MAX) {
> -            PyErr_SetString(PyExc_OverflowError,
> -                            "long too large to pickle");
> -            goto error;
> -        }
> -        repr = PyUnicode_FromStringAndSize(NULL, (int)nbytes);
> -        if (repr == NULL)
> -            goto error;
> -        pdata = (unsigned char *)PyUnicode_AsString(repr);
> -        i = _PyLong_AsByteArray((PyLongObject *)obj,
> -                                pdata, nbytes,
> -                                1 /* little endian */ , 1 /* signed */ );
> -        if (i < 0)
> -            goto error;
> -        /* If the long is negative, this may be a byte more than
> -         * needed.  This is so iff the MSB is all redundant sign
> -         * bits.
> -         */
> -        if (sign < 0 &&
> -            nbytes > 1 &&
> -            pdata[nbytes - 1] == 0xff &&
> -            (pdata[nbytes - 2] & 0x80) != 0) {
> -            nbytes--;
> -        }
> -
> -        if (nbytes < 256) {
> -            header[0] = LONG1;
> -            header[1] = (unsigned char)nbytes;
> -            size = 2;
> -        }
> -        else {
> -            header[0] = LONG4;
> -            size = (int)nbytes;
> -            for (i = 1; i < 5; i++) {
> -                header[i] = (unsigned char)(size & 0xff);
> -                size >>= 8;
> -            }
> -            size = 5;
> -        }
> -        if (pickler_write(self, header, size) < 0 ||
> -            pickler_write(self, (char *)pdata, (int)nbytes) < 0)
> -            goto error;
> -    }
> -    else {
> -        char *string;
> -
> -        /* proto < 2:  write the repr and newline.  This is quadratic-time
> -           (in the number of digits), in both directions. */
> -
> -        repr = PyObject_Repr(obj);
> -        if (repr == NULL)
> -            goto error;
> -
> -        string = PyUnicode_AsStringAndSize(repr, &size);
> -        if (string == NULL)
> -            goto error;
> -
> -        if (pickler_write(self, &long_op, 1) < 0 ||
> -            pickler_write(self, string, size) < 0 ||
> -            pickler_write(self, "\n", 1) < 0)
> -            goto error;
> -    }
> -
> -    if (0) {
> -  error:
> -      status = -1;
> -    }
> -    Py_XDECREF(repr);
> -
> -    return status;
> -}
> -
> -static int
> -save_float(PicklerObject *self, PyObject *obj)
> -{
> -    double x = PyFloat_AS_DOUBLE((PyFloatObject *)obj);
> -
> -    if (self->bin) {
> -        char pdata[9];
> -        pdata[0] = BINFLOAT;
> -        if (_PyFloat_Pack8(x, (unsigned char *)&pdata[1], 0) < 0)
> -            return -1;
> -        if (pickler_write(self, pdata, 9) < 0)
> -            return -1;
> -    }
> -    else {
> -        char pdata[250];
> -        pdata[0] = FLOAT;
> -        PyOS_ascii_formatd(pdata + 1, sizeof(pdata) - 2, "%.17g", x);
> -        /* Extend the formatted string with a newline character */
> -        strcat(pdata, "\n");
> -
> -        if (pickler_write(self, pdata, strlen(pdata)) < 0)
> -            return -1;
> -    }
> -
> -    return 0;
> -}
> -
> -static int
> -save_bytes(PicklerObject *self, PyObject *obj)
> -{
> -    if (self->proto < 3) {
> -        /* Older pickle protocols do not have an opcode for pickling bytes
> -           objects. Therefore, we need to fake the copy protocol (i.e.,
> -           the __reduce__ method) to permit bytes object unpickling. */
> -        PyObject *reduce_value = NULL;
> -        PyObject *bytelist = NULL;
> -        int status;
> -
> -        bytelist = PySequence_List(obj);
> -        if (bytelist == NULL)
> -            return -1;
> -
> -        reduce_value = Py_BuildValue("(O(O))", (PyObject *)&PyBytes_Type,
> -                                     bytelist);
> -        if (reduce_value == NULL) {
> -            Py_DECREF(bytelist);
> -            return -1;
> -        }
> -
> -        /* save_reduce() will memoize the object automatically. */
> -        status = save_reduce(self, reduce_value, obj);
> -        Py_DECREF(reduce_value);
> -        Py_DECREF(bytelist);
> -        return status;
> -    }
> -    else {
> -        Py_ssize_t size;
> -        char header[5];
> -        int len;
> -
> -        size = PyBytes_Size(obj);
> -        if (size < 0)
> -            return -1;
> -
> -        if (size < 256) {
> -            header[0] = SHORT_BINBYTES;
> -            header[1] = (unsigned char)size;
> -            len = 2;
> -        }
> -        else if (size <= 0xffffffffL) {
> -            header[0] = BINBYTES;
> -            header[1] = (unsigned char)(size & 0xff);
> -            header[2] = (unsigned char)((size >> 8) & 0xff);
> -            header[3] = (unsigned char)((size >> 16) & 0xff);
> -            header[4] = (unsigned char)((size >> 24) & 0xff);
> -            len = 5;
> -        }
> -        else {
> -            return -1;          /* string too large */
> -        }
> -
> -        if (pickler_write(self, header, len) < 0)
> -            return -1;
> -
> -        if (pickler_write(self, PyBytes_AS_STRING(obj), size) < 0)
> -            return -1;
> -
> -        if (memo_put(self, obj) < 0)
> -            return -1;
> -
> -        return 0;
> -    }
> -}
> -
> -/* A copy of PyUnicode_EncodeRawUnicodeEscape() that also translates
> -   backslash and newline characters to \uXXXX escapes. */
> -static PyObject *
> -raw_unicode_escape(const Py_UNICODE *s, Py_ssize_t size)
> -{
> -    PyObject *repr, *result;
> -    char *p;
> -    char *q;
> -
> -    static const char *hexdigits = "0123456789abcdef";
> -
> -#ifdef Py_UNICODE_WIDE
> -    repr = PyBytes_FromStringAndSize(NULL, 10 * size);
> -#else
> -    repr = PyBytes_FromStringAndSize(NULL, 6 * size);
> -#endif
> -    if (repr == NULL)
> -        return NULL;
> -    if (size == 0)
> -        goto done;
> -
> -    p = q = PyBytes_AS_STRING(repr);
> -    while (size-- > 0) {
> -        Py_UNICODE ch = *s++;
> -#ifdef Py_UNICODE_WIDE
> -        /* Map 32-bit characters to '\Uxxxxxxxx' */
> -        if (ch >= 0x10000) {
> -            *p++ = '\\';
> -            *p++ = 'U';
> -            *p++ = hexdigits[(ch >> 28) & 0xf];
> -            *p++ = hexdigits[(ch >> 24) & 0xf];
> -            *p++ = hexdigits[(ch >> 20) & 0xf];
> -            *p++ = hexdigits[(ch >> 16) & 0xf];
> -            *p++ = hexdigits[(ch >> 12) & 0xf];
> -            *p++ = hexdigits[(ch >> 8) & 0xf];
> -            *p++ = hexdigits[(ch >> 4) & 0xf];
> -            *p++ = hexdigits[ch & 15];
> -        }
> -        else
> -#endif
> -        /* Map 16-bit characters to '\uxxxx' */
> -        if (ch >= 256 || ch == '\\' || ch == '\n') {
> -            *p++ = '\\';
> -            *p++ = 'u';
> -            *p++ = hexdigits[(ch >> 12) & 0xf];
> -            *p++ = hexdigits[(ch >> 8) & 0xf];
> -            *p++ = hexdigits[(ch >> 4) & 0xf];
> -            *p++ = hexdigits[ch & 15];
> -        }
> -       /* Copy everything else as-is */
> -        else
> -            *p++ = (char) ch;
> -    }
> -    size = p - q;
> -
> -  done:
> -    result = PyBytes_FromStringAndSize(PyBytes_AS_STRING(repr), size);
> -    Py_DECREF(repr);
> -    return result;
> -}
> -
> -static int
> -save_unicode(PicklerObject *self, PyObject *obj)
> -{
> -    Py_ssize_t size;
> -    PyObject *encoded = NULL;
> -
> -    if (self->bin) {
> -        char pdata[5];
> -
> -        encoded = PyUnicode_AsUTF8String(obj);
> -        if (encoded == NULL)
> -            goto error;
> -
> -        size = PyBytes_GET_SIZE(encoded);
> -        if (size < 0 || size > 0xffffffffL)
> -            goto error;          /* string too large */
> -
> -        pdata[0] = BINUNICODE;
> -        pdata[1] = (unsigned char)(size & 0xff);
> -        pdata[2] = (unsigned char)((size >> 8) & 0xff);
> -        pdata[3] = (unsigned char)((size >> 16) & 0xff);
> -        pdata[4] = (unsigned char)((size >> 24) & 0xff);
> -
> -        if (pickler_write(self, pdata, 5) < 0)
> -            goto error;
> -
> -        if (pickler_write(self, PyBytes_AS_STRING(encoded), size) < 0)
> -            goto error;
> -    }
> -    else {
> -        const char unicode_op = UNICODE;
> -
> -        encoded = raw_unicode_escape(PyUnicode_AS_UNICODE(obj),
> -                                     PyUnicode_GET_SIZE(obj));
> -        if (encoded == NULL)
> -            goto error;
> -
> -        if (pickler_write(self, &unicode_op, 1) < 0)
> -            goto error;
> -
> -        size = PyBytes_GET_SIZE(encoded);
> -        if (pickler_write(self, PyBytes_AS_STRING(encoded), size) < 0)
> -            goto error;
> -
> -        if (pickler_write(self, "\n", 1) < 0)
> -            goto error;
> -    }
> -    if (memo_put(self, obj) < 0)
> -        goto error;
> -
> -    Py_DECREF(encoded);
> -    return 0;
> -
> -  error:
> -    Py_XDECREF(encoded);
> -    return -1;
> -}
> -
> -/* A helper for save_tuple.  Push the len elements in tuple t on the stack. */
> -static int
> -store_tuple_elements(PicklerObject *self, PyObject *t, int len)
> -{
> -    int i;
> -
> -    assert(PyTuple_Size(t) == len);
> -
> -    for (i = 0; i < len; i++) {
> -        PyObject *element = PyTuple_GET_ITEM(t, i);
> -
> -        if (element == NULL)
> -            return -1;
> -        if (save(self, element, 0) < 0)
> -            return -1;
> -    }
> -
> -    return 0;
> -}
> -
> -/* Tuples are ubiquitous in the pickle protocols, so many techniques are
> - * used across protocols to minimize the space needed to pickle them.
> - * Tuples are also the only builtin immutable type that can be recursive
> - * (a tuple can be reached from itself), and that requires some subtle
> - * magic so that it works in all cases.  IOW, this is a long routine.
> - */
> -static int
> -save_tuple(PicklerObject *self, PyObject *obj)
> -{
> -    PyObject *memo_key = NULL;
> -    int len, i;
> -    int status = 0;
> -
> -    const char mark_op = MARK;
> -    const char tuple_op = TUPLE;
> -    const char pop_op = POP;
> -    const char pop_mark_op = POP_MARK;
> -    const char len2opcode[] = {EMPTY_TUPLE, TUPLE1, TUPLE2, TUPLE3};
> -
> -    if ((len = PyTuple_Size(obj)) < 0)
> -        return -1;
> -
> -    if (len == 0) {
> -        char pdata[2];
> -
> -        if (self->proto) {
> -            pdata[0] = EMPTY_TUPLE;
> -            len = 1;
> -        }
> -        else {
> -            pdata[0] = MARK;
> -            pdata[1] = TUPLE;
> -            len = 2;
> -        }
> -        if (pickler_write(self, pdata, len) < 0)
> -            return -1;
> -        return 0;
> -    }
> -
> -    /* id(tuple) isn't in the memo now.  If it shows up there after
> -     * saving the tuple elements, the tuple must be recursive, in
> -     * which case we'll pop everything we put on the stack, and fetch
> -     * its value from the memo.
> -     */
> -    memo_key = PyLong_FromVoidPtr(obj);
> -    if (memo_key == NULL)
> -        return -1;
> -
> -    if (len <= 3 && self->proto >= 2) {
> -        /* Use TUPLE{1,2,3} opcodes. */
> -        if (store_tuple_elements(self, obj, len) < 0)
> -            goto error;
> -
> -        if (PyDict_GetItem(self->memo, memo_key)) {
> -            /* pop the len elements */
> -            for (i = 0; i < len; i++)
> -                if (pickler_write(self, &pop_op, 1) < 0)
> -                    goto error;
> -            /* fetch from memo */
> -            if (memo_get(self, memo_key) < 0)
> -                goto error;
> -
> -            Py_DECREF(memo_key);
> -            return 0;
> -        }
> -        else { /* Not recursive. */
> -            if (pickler_write(self, len2opcode + len, 1) < 0)
> -                goto error;
> -        }
> -        goto memoize;
> -    }
> -
> -    /* proto < 2 and len > 0, or proto >= 2 and len > 3.
> -     * Generate MARK e1 e2 ... TUPLE
> -     */
> -    if (pickler_write(self, &mark_op, 1) < 0)
> -        goto error;
> -
> -    if (store_tuple_elements(self, obj, len) < 0)
> -        goto error;
> -
> -    if (PyDict_GetItem(self->memo, memo_key)) {
> -        /* pop the stack stuff we pushed */
> -        if (self->bin) {
> -            if (pickler_write(self, &pop_mark_op, 1) < 0)
> -                goto error;
> -        }
> -        else {
> -            /* Note that we pop one more than len, to remove
> -             * the MARK too.
> -             */
> -            for (i = 0; i <= len; i++)
> -                if (pickler_write(self, &pop_op, 1) < 0)
> -                    goto error;
> -        }
> -        /* fetch from memo */
> -        if (memo_get(self, memo_key) < 0)
> -            goto error;
> -
> -        Py_DECREF(memo_key);
> -        return 0;
> -    }
> -    else { /* Not recursive. */
> -        if (pickler_write(self, &tuple_op, 1) < 0)
> -            goto error;
> -    }
> -
> -  memoize:
> -    if (memo_put(self, obj) < 0)
> -        goto error;
> -
> -    if (0) {
> -  error:
> -        status = -1;
> -    }
> -
> -    Py_DECREF(memo_key);
> -    return status;
> -}
> -
> -/* iter is an iterator giving items, and we batch up chunks of
> - *     MARK item item ... item APPENDS
> - * opcode sequences.  Calling code should have arranged to first create an
> - * empty list, or list-like object, for the APPENDS to operate on.
> - * Returns 0 on success, <0 on error.
> - */
> -static int
> -batch_list(PicklerObject *self, PyObject *iter)
> -{
> -    PyObject *obj;
> -    PyObject *slice[BATCHSIZE];
> -    int i, n;
> -
> -    const char mark_op = MARK;
> -    const char append_op = APPEND;
> -    const char appends_op = APPENDS;
> -
> -    assert(iter != NULL);
> -
> -    /* XXX: I think this function could be made faster by avoiding the
> -       iterator interface and fetching objects directly from list using
> -       PyList_GET_ITEM.
> -    */
> -
> -    if (self->proto == 0) {
> -        /* APPENDS isn't available; do one at a time. */
> -        for (;;) {
> -            obj = PyIter_Next(iter);
> -            if (obj == NULL) {
> -                if (PyErr_Occurred())
> -                    return -1;
> -                break;
> -            }
> -            i = save(self, obj, 0);
> -            Py_DECREF(obj);
> -            if (i < 0)
> -                return -1;
> -            if (pickler_write(self, &append_op, 1) < 0)
> -                return -1;
> -        }
> -        return 0;
> -    }
> -
> -    /* proto > 0:  write in batches of BATCHSIZE. */
> -    do {
> -        /* Get next group of (no more than) BATCHSIZE elements. */
> -        for (n = 0; n < BATCHSIZE; n++) {
> -            obj = PyIter_Next(iter);
> -            if (obj == NULL) {
> -                if (PyErr_Occurred())
> -                    goto error;
> -                break;
> -            }
> -            slice[n] = obj;
> -        }
> -
> -        if (n > 1) {
> -            /* Pump out MARK, slice[0:n], APPENDS. */
> -            if (pickler_write(self, &mark_op, 1) < 0)
> -                goto error;
> -            for (i = 0; i < n; i++) {
> -                if (save(self, slice[i], 0) < 0)
> -                    goto error;
> -            }
> -            if (pickler_write(self, &appends_op, 1) < 0)
> -                goto error;
> -        }
> -        else if (n == 1) {
> -            if (save(self, slice[0], 0) < 0 ||
> -                pickler_write(self, &append_op, 1) < 0)
> -                goto error;
> -        }
> -
> -        for (i = 0; i < n; i++) {
> -            Py_DECREF(slice[i]);
> -        }
> -    } while (n == BATCHSIZE);
> -    return 0;
> -
> -  error:
> -    while (--n >= 0) {
> -        Py_DECREF(slice[n]);
> -    }
> -    return -1;
> -}
> -
> -static int
> -save_list(PicklerObject *self, PyObject *obj)
> -{
> -    PyObject *iter;
> -    char header[3];
> -    int len;
> -    int status = 0;
> -
> -    if (self->fast && !fast_save_enter(self, obj))
> -        goto error;
> -
> -    /* Create an empty list. */
> -    if (self->bin) {
> -        header[0] = EMPTY_LIST;
> -        len = 1;
> -    }
> -    else {
> -        header[0] = MARK;
> -        header[1] = LIST;
> -        len = 2;
> -    }
> -
> -    if (pickler_write(self, header, len) < 0)
> -        goto error;
> -
> -    /* Get list length, and bow out early if empty. */
> -    if ((len = PyList_Size(obj)) < 0)
> -        goto error;
> -
> -    if (memo_put(self, obj) < 0)
> -        goto error;
> -
> -    if (len != 0) {
> -        /* Save the list elements. */
> -        iter = PyObject_GetIter(obj);
> -        if (iter == NULL)
> -            goto error;
> -        status = batch_list(self, iter);
> -        Py_DECREF(iter);
> -    }
> -
> -    if (0) {
> -  error:
> -        status = -1;
> -    }
> -
> -    if (self->fast && !fast_save_leave(self, obj))
> -        status = -1;
> -
> -    return status;
> -}
> -
> -/* iter is an iterator giving (key, value) pairs, and we batch up chunks of
> - *     MARK key value ... key value SETITEMS
> - * opcode sequences.  Calling code should have arranged to first create an
> - * empty dict, or dict-like object, for the SETITEMS to operate on.
> - * Returns 0 on success, <0 on error.
> - *
> - * This is very much like batch_list().  The difference between saving
> - * elements directly, and picking apart two-tuples, is so long-winded at
> - * the C level, though, that attempts to combine these routines were too
> - * ugly to bear.
> - */
> -static int
> -batch_dict(PicklerObject *self, PyObject *iter)
> -{
> -    PyObject *obj;
> -    PyObject *slice[BATCHSIZE];
> -    int i, n;
> -
> -    const char mark_op = MARK;
> -    const char setitem_op = SETITEM;
> -    const char setitems_op = SETITEMS;
> -
> -    assert(iter != NULL);
> -
> -    if (self->proto == 0) {
> -        /* SETITEMS isn't available; do one at a time. */
> -        for (;;) {
> -            obj = PyIter_Next(iter);
> -            if (obj == NULL) {
> -                if (PyErr_Occurred())
> -                    return -1;
> -                break;
> -            }
> -            if (!PyTuple_Check(obj) || PyTuple_Size(obj) != 2) {
> -                PyErr_SetString(PyExc_TypeError, "dict items "
> -                                "iterator must return 2-tuples");
> -                return -1;
> -            }
> -            i = save(self, PyTuple_GET_ITEM(obj, 0), 0);
> -            if (i >= 0)
> -                i = save(self, PyTuple_GET_ITEM(obj, 1), 0);
> -            Py_DECREF(obj);
> -            if (i < 0)
> -                return -1;
> -            if (pickler_write(self, &setitem_op, 1) < 0)
> -                return -1;
> -        }
> -        return 0;
> -    }
> -
> -    /* proto > 0:  write in batches of BATCHSIZE. */
> -    do {
> -        /* Get next group of (no more than) BATCHSIZE elements. */
> -        for (n = 0; n < BATCHSIZE; n++) {
> -            obj = PyIter_Next(iter);
> -            if (obj == NULL) {
> -                if (PyErr_Occurred())
> -                    goto error;
> -                break;
> -            }
> -            if (!PyTuple_Check(obj) || PyTuple_Size(obj) != 2) {
> -                PyErr_SetString(PyExc_TypeError, "dict items "
> -                                "iterator must return 2-tuples");
> -                goto error;
> -            }
> -            slice[n] = obj;
> -        }
> -
> -        if (n > 1) {
> -            /* Pump out MARK, slice[0:n], SETITEMS. */
> -            if (pickler_write(self, &mark_op, 1) < 0)
> -                goto error;
> -            for (i = 0; i < n; i++) {
> -                obj = slice[i];
> -                if (save(self, PyTuple_GET_ITEM(obj, 0), 0) < 0 ||
> -                    save(self, PyTuple_GET_ITEM(obj, 1), 0) < 0)
> -                    goto error;
> -            }
> -            if (pickler_write(self, &setitems_op, 1) < 0)
> -                goto error;
> -        }
> -        else if (n == 1) {
> -            obj = slice[0];
> -            if (save(self, PyTuple_GET_ITEM(obj, 0), 0) < 0 ||
> -                save(self, PyTuple_GET_ITEM(obj, 1), 0) < 0 ||
> -                pickler_write(self, &setitem_op, 1) < 0)
> -                goto error;
> -        }
> -
> -        for (i = 0; i < n; i++) {
> -            Py_DECREF(slice[i]);
> -        }
> -    } while (n == BATCHSIZE);
> -    return 0;
> -
> -  error:
> -    while (--n >= 0) {
> -        Py_DECREF(slice[n]);
> -    }
> -    return -1;
> -}
> -
> -static int
> -save_dict(PicklerObject *self, PyObject *obj)
> -{
> -    PyObject *items, *iter;
> -    char header[3];
> -    int len;
> -    int status = 0;
> -
> -    if (self->fast && !fast_save_enter(self, obj))
> -        goto error;
> -
> -    /* Create an empty dict. */
> -    if (self->bin) {
> -        header[0] = EMPTY_DICT;
> -        len = 1;
> -    }
> -    else {
> -        header[0] = MARK;
> -        header[1] = DICT;
> -        len = 2;
> -    }
> -
> -    if (pickler_write(self, header, len) < 0)
> -        goto error;
> -
> -    /* Get dict size, and bow out early if empty. */
> -    if ((len = PyDict_Size(obj)) < 0)
> -        goto error;
> -
> -    if (memo_put(self, obj) < 0)
> -        goto error;
> -
> -    if (len != 0) {
> -        /* Save the dict items. */
> -        items = PyObject_CallMethod(obj, "items", "()");
> -        if (items == NULL)
> -            goto error;
> -        iter = PyObject_GetIter(items);
> -        Py_DECREF(items);
> -        if (iter == NULL)
> -            goto error;
> -        status = batch_dict(self, iter);
> -        Py_DECREF(iter);
> -    }
> -
> -    if (0) {
> -  error:
> -        status = -1;
> -    }
> -
> -    if (self->fast && !fast_save_leave(self, obj))
> -        status = -1;
> -
> -    return status;
> -}
> -
> -static int
> -save_global(PicklerObject *self, PyObject *obj, PyObject *name)
> -{
> -    static PyObject *name_str = NULL;
> -    PyObject *global_name = NULL;
> -    PyObject *module_name = NULL;
> -    PyObject *module = NULL;
> -    PyObject *cls;
> -    int status = 0;
> -
> -    const char global_op = GLOBAL;
> -
> -    if (name_str == NULL) {
> -        name_str = PyUnicode_InternFromString("__name__");
> -        if (name_str == NULL)
> -            goto error;
> -    }
> -
> -    if (name) {
> -        global_name = name;
> -        Py_INCREF(global_name);
> -    }
> -    else {
> -        global_name = PyObject_GetAttr(obj, name_str);
> -        if (global_name == NULL)
> -            goto error;
> -    }
> -
> -    module_name = whichmodule(obj, global_name);
> -    if (module_name == NULL)
> -        goto error;
> -
> -    /* XXX: Change to use the import C API directly with level=0 to disallow
> -       relative imports.
> -
> -       XXX: PyImport_ImportModuleLevel could be used. However, this bypasses
> -       builtins.__import__. Therefore, _pickle, unlike pickle.py, will ignore
> -       custom import functions (IMHO, this would be a nice security
> -       feature). The import C API would need to be extended to support the
> -       extra parameters of __import__ to fix that. */
> -    module = PyImport_Import(module_name);
> -    if (module == NULL) {
> -        PyErr_Format(PicklingError,
> -                     "Can't pickle %R: import of module %R failed",
> -                     obj, module_name);
> -        goto error;
> -    }
> -    cls = PyObject_GetAttr(module, global_name);
> -    if (cls == NULL) {
> -        PyErr_Format(PicklingError,
> -                     "Can't pickle %R: attribute lookup %S.%S failed",
> -                     obj, module_name, global_name);
> -        goto error;
> -    }
> -    if (cls != obj) {
> -        Py_DECREF(cls);
> -        PyErr_Format(PicklingError,
> -                     "Can't pickle %R: it's not the same object as %S.%S",
> -                     obj, module_name, global_name);
> -        goto error;
> -    }
> -    Py_DECREF(cls);
> -
> -    if (self->proto >= 2) {
> -        /* See whether this is in the extension registry, and if
> -         * so generate an EXT opcode.
> -         */
> -        PyObject *code_obj;      /* extension code as Python object */
> -        long code;               /* extension code as C value */
> -        char pdata[5];
> -        int n;
> -
> -        PyTuple_SET_ITEM(two_tuple, 0, module_name);
> -        PyTuple_SET_ITEM(two_tuple, 1, global_name);
> -        code_obj = PyDict_GetItem(extension_registry, two_tuple);
> -        /* The object is not registered in the extension registry.
> -           This is the most likely code path. */
> -        if (code_obj == NULL)
> -            goto gen_global;
> -
> -        /* XXX: pickle.py doesn't check neither the type, nor the range
> -           of the value returned by the extension_registry. It should for
> -           consistency. */
> -
> -        /* Verify code_obj has the right type and value. */
> -        if (!PyLong_Check(code_obj)) {
> -            PyErr_Format(PicklingError,
> -                         "Can't pickle %R: extension code %R isn't an integer",
> -                         obj, code_obj);
> -            goto error;
> -        }
> -        code = PyLong_AS_LONG(code_obj);
> -        if (code <= 0 || code > 0x7fffffffL) {
> -            PyErr_Format(PicklingError,
> -                         "Can't pickle %R: extension code %ld is out of range",
> -                         obj, code);
> -            goto error;
> -        }
> -
> -        /* Generate an EXT opcode. */
> -        if (code <= 0xff) {
> -            pdata[0] = EXT1;
> -            pdata[1] = (unsigned char)code;
> -            n = 2;
> -        }
> -        else if (code <= 0xffff) {
> -            pdata[0] = EXT2;
> -            pdata[1] = (unsigned char)(code & 0xff);
> -            pdata[2] = (unsigned char)((code >> 8) & 0xff);
> -            n = 3;
> -        }
> -        else {
> -            pdata[0] = EXT4;
> -            pdata[1] = (unsigned char)(code & 0xff);
> -            pdata[2] = (unsigned char)((code >> 8) & 0xff);
> -            pdata[3] = (unsigned char)((code >> 16) & 0xff);
> -            pdata[4] = (unsigned char)((code >> 24) & 0xff);
> -            n = 5;
> -        }
> -
> -        if (pickler_write(self, pdata, n) < 0)
> -            goto error;
> -    }
> -    else {
> -        /* Generate a normal global opcode if we are using a pickle
> -           protocol <= 2, or if the object is not registered in the
> -           extension registry. */
> -        PyObject *encoded;
> -        PyObject *(*unicode_encoder)(PyObject *);
> -
> -  gen_global:
> -        if (pickler_write(self, &global_op, 1) < 0)
> -            goto error;
> -
> -        /* Since Python 3.0 now supports non-ASCII identifiers, we encode both
> -           the module name and the global name using UTF-8. We do so only when
> -           we are using the pickle protocol newer than version 3. This is to
> -           ensure compatibility with older Unpickler running on Python 2.x. */
> -        if (self->proto >= 3) {
> -            unicode_encoder = PyUnicode_AsUTF8String;
> -        }
> -        else {
> -            unicode_encoder = PyUnicode_AsASCIIString;
> -        }
> -
> -        /* Save the name of the module. */
> -        encoded = unicode_encoder(module_name);
> -        if (encoded == NULL) {
> -            if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError))
> -                PyErr_Format(PicklingError,
> -                             "can't pickle module identifier '%S' using "
> -                             "pickle protocol %i", module_name, self->proto);
> -            goto error;
> -        }
> -        if (pickler_write(self, PyBytes_AS_STRING(encoded),
> -                          PyBytes_GET_SIZE(encoded)) < 0) {
> -            Py_DECREF(encoded);
> -            goto error;
> -        }
> -        Py_DECREF(encoded);
> -        if(pickler_write(self, "\n", 1) < 0)
> -            goto error;
> -
> -        /* Save the name of the module. */
> -        encoded = unicode_encoder(global_name);
> -        if (encoded == NULL) {
> -            if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError))
> -                PyErr_Format(PicklingError,
> -                             "can't pickle global identifier '%S' using "
> -                             "pickle protocol %i", global_name, self->proto);
> -            goto error;
> -        }
> -        if (pickler_write(self, PyBytes_AS_STRING(encoded),
> -                          PyBytes_GET_SIZE(encoded)) < 0) {
> -            Py_DECREF(encoded);
> -            goto error;
> -        }
> -        Py_DECREF(encoded);
> -        if(pickler_write(self, "\n", 1) < 0)
> -            goto error;
> -
> -        /* Memoize the object. */
> -        if (memo_put(self, obj) < 0)
> -            goto error;
> -    }
> -
> -    if (0) {
> -  error:
> -        status = -1;
> -    }
> -    Py_XDECREF(module_name);
> -    Py_XDECREF(global_name);
> -    Py_XDECREF(module);
> -
> -    return status;
> -}
> -
> -static int
> -save_pers(PicklerObject *self, PyObject *obj, PyObject *func)
> -{
> -    PyObject *pid = NULL;
> -    int status = 0;
> -
> -    const char persid_op = PERSID;
> -    const char binpersid_op = BINPERSID;
> -
> -    Py_INCREF(obj);
> -    pid = pickler_call(self, func, obj);
> -    if (pid == NULL)
> -        return -1;
> -
> -    if (pid != Py_None) {
> -        if (self->bin) {
> -            if (save(self, pid, 1) < 0 ||
> -                pickler_write(self, &binpersid_op, 1) < 0)
> -                goto error;
> -        }
> -        else {
> -            PyObject *pid_str = NULL;
> -            char *pid_ascii_bytes;
> -            Py_ssize_t size;
> -
> -            pid_str = PyObject_Str(pid);
> -            if (pid_str == NULL)
> -                goto error;
> -
> -            /* XXX: Should it check whether the persistent id only contains
> -               ASCII characters? And what if the pid contains embedded
> -               newlines? */
> -            pid_ascii_bytes = PyUnicode_AsStringAndSize(pid_str, &size);
> -            Py_DECREF(pid_str);
> -            if (pid_ascii_bytes == NULL)
> -                goto error;
> -
> -            if (pickler_write(self, &persid_op, 1) < 0 ||
> -                pickler_write(self, pid_ascii_bytes, size) < 0 ||
> -                pickler_write(self, "\n", 1) < 0)
> -                goto error;
> -        }
> -        status = 1;
> -    }
> -
> -    if (0) {
> -  error:
> -        status = -1;
> -    }
> -    Py_XDECREF(pid);
> -
> -    return status;
> -}
> -
> -/* We're saving obj, and args is the 2-thru-5 tuple returned by the
> - * appropriate __reduce__ method for obj.
> - */
> -static int
> -save_reduce(PicklerObject *self, PyObject *args, PyObject *obj)
> -{
> -    PyObject *callable;
> -    PyObject *argtup;
> -    PyObject *state = NULL;
> -    PyObject *listitems = NULL;
> -    PyObject *dictitems = NULL;
> -
> -    int use_newobj = self->proto >= 2;
> -
> -    const char reduce_op = REDUCE;
> -    const char build_op = BUILD;
> -    const char newobj_op = NEWOBJ;
> -
> -    if (!PyArg_UnpackTuple(args, "save_reduce", 2, 5,
> -                           &callable, &argtup, &state, &listitems, &dictitems))
> -        return -1;
> -
> -    if (!PyCallable_Check(callable)) {
> -        PyErr_SetString(PicklingError,
> -                        "first argument of save_reduce() must be callable");
> -        return -1;
> -    }
> -    if (!PyTuple_Check(argtup)) {
> -        PyErr_SetString(PicklingError,
> -                        "second argument of save_reduce() must be a tuple");
> -        return -1;
> -    }
> -
> -    if (state == Py_None)
> -        state = NULL;
> -    if (listitems == Py_None)
> -        listitems = NULL;
> -    if (dictitems == Py_None)
> -        dictitems = NULL;
> -
> -    /* Protocol 2 special case: if callable's name is __newobj__, use
> -       NEWOBJ. */
> -    if (use_newobj) {
> -        static PyObject *newobj_str = NULL;
> -        PyObject *name_str;
> -
> -        if (newobj_str == NULL) {
> -            newobj_str = PyUnicode_InternFromString("__newobj__");
> -        }
> -
> -        name_str = PyObject_GetAttrString(callable, "__name__");
> -        if (name_str == NULL) {
> -            if (PyErr_ExceptionMatches(PyExc_AttributeError))
> -                PyErr_Clear();
> -            else
> -                return -1;
> -            use_newobj = 0;
> -        }
> -        else {
> -            use_newobj = PyUnicode_Check(name_str) &&
> -                PyUnicode_Compare(name_str, newobj_str) == 0;
> -            Py_DECREF(name_str);
> -        }
> -    }
> -    if (use_newobj) {
> -        PyObject *cls;
> -        PyObject *newargtup;
> -        PyObject *obj_class;
> -        int p;
> -
> -        /* Sanity checks. */
> -        if (Py_SIZE(argtup) < 1) {
> -            PyErr_SetString(PicklingError, "__newobj__ arglist is empty");
> -            return -1;
> -        }
> -
> -        cls = PyTuple_GET_ITEM(argtup, 0);
> -        if (!PyObject_HasAttrString(cls, "__new__")) {
> -            PyErr_SetString(PicklingError, "args[0] from "
> -                            "__newobj__ args has no __new__");
> -            return -1;
> -        }
> -
> -        if (obj != NULL) {
> -            obj_class = PyObject_GetAttrString(obj, "__class__");
> -            if (obj_class == NULL) {
> -                if (PyErr_ExceptionMatches(PyExc_AttributeError))
> -                    PyErr_Clear();
> -                else
> -                    return -1;
> -            }
> -            p = obj_class != cls;    /* true iff a problem */
> -            Py_DECREF(obj_class);
> -            if (p) {
> -                PyErr_SetString(PicklingError, "args[0] from "
> -                                "__newobj__ args has the wrong class");
> -                return -1;
> -            }
> -        }
> -        /* XXX: These calls save() are prone to infinite recursion. Imagine
> -           what happen if the value returned by the __reduce__() method of
> -           some extension type contains another object of the same type. Ouch!
> -
> -           Here is a quick example, that I ran into, to illustrate what I
> -           mean:
> -
> -             >>> import pickle, copyreg
> -             >>> copyreg.dispatch_table.pop(complex)
> -             >>> pickle.dumps(1+2j)
> -             Traceback (most recent call last):
> -               ...
> -             RuntimeError: maximum recursion depth exceeded
> -
> -           Removing the complex class from copyreg.dispatch_table made the
> -           __reduce_ex__() method emit another complex object:
> -
> -             >>> (1+1j).__reduce_ex__(2)
> -             (<function __newobj__ at 0xb7b71c3c>,
> -               (<class 'complex'>, (1+1j)), None, None, None)
> -
> -           Thus when save() was called on newargstup (the 2nd item) recursion
> -           ensued. Of course, the bug was in the complex class which had a
> -           broken __getnewargs__() that emitted another complex object. But,
> -           the point, here, is it is quite easy to end up with a broken reduce
> -           function. */
> -
> -        /* Save the class and its __new__ arguments. */
> -        if (save(self, cls, 0) < 0)
> -            return -1;
> -
> -        newargtup = PyTuple_GetSlice(argtup, 1, Py_SIZE(argtup));
> -        if (newargtup == NULL)
> -            return -1;
> -
> -        p = save(self, newargtup, 0);
> -        Py_DECREF(newargtup);
> -        if (p < 0)
> -            return -1;
> -
> -        /* Add NEWOBJ opcode. */
> -        if (pickler_write(self, &newobj_op, 1) < 0)
> -            return -1;
> -    }
> -    else { /* Not using NEWOBJ. */
> -        if (save(self, callable, 0) < 0 ||
> -            save(self, argtup, 0) < 0 ||
> -            pickler_write(self, &reduce_op, 1) < 0)
> -            return -1;
> -    }
> -
> -    /* obj can be NULL when save_reduce() is used directly. A NULL obj means
> -       the caller do not want to memoize the object. Not particularly useful,
> -       but that is to mimic the behavior save_reduce() in pickle.py when
> -       obj is None. */
> -    if (obj && memo_put(self, obj) < 0)
> -        return -1;
> -
> -    if (listitems && batch_list(self, listitems) < 0)
> -        return -1;
> -
> -    if (dictitems && batch_dict(self, dictitems) < 0)
> -        return -1;
> -
> -    if (state) {
> -        if (save(self, state, 0) < 0 ||
> -            pickler_write(self, &build_op, 1) < 0)
> -            return -1;
> -    }
> -
> -    return 0;
> -}
> -
> -static int
> -save(PicklerObject *self, PyObject *obj, int pers_save)
> -{
> -    PyTypeObject *type;
> -    PyObject *reduce_func = NULL;
> -    PyObject *reduce_value = NULL;
> -    PyObject *memo_key = NULL;
> -    int status = 0;
> -
> -    /* XXX: Use Py_EnterRecursiveCall()? */
> -    if (++self->nesting > Py_GetRecursionLimit()) {
> -        PyErr_SetString(PyExc_RuntimeError,
> -                        "maximum recursion depth exceeded");
> -        goto error;
> -    }
> -
> -    /* The extra pers_save argument is necessary to avoid calling save_pers()
> -       on its returned object. */
> -    if (!pers_save && self->pers_func) {
> -        /* save_pers() returns:
> -            -1   to signal an error;
> -             0   if it did nothing successfully;
> -             1   if a persistent id was saved.
> -         */
> -        if ((status = save_pers(self, obj, self->pers_func)) != 0)
> -            goto done;
> -    }
> -
> -    type = Py_TYPE(obj);
> -
> -    /* XXX: The old cPickle had an optimization that used switch-case
> -       statement dispatching on the first letter of the type name. It was
> -       probably not a bad idea after all. If benchmarks shows that particular
> -       optimization had some real benefits, it would be nice to add it
> -       back. */
> -
> -    /* Atom types; these aren't memoized, so don't check the memo. */
> -
> -    if (obj == Py_None) {
> -        status = save_none(self, obj);
> -        goto done;
> -    }
> -    else if (obj == Py_False || obj == Py_True) {
> -        status = save_bool(self, obj);
> -        goto done;
> -    }
> -    else if (type == &PyLong_Type) {
> -        status = save_long(self, obj);
> -        goto done;
> -    }
> -    else if (type == &PyFloat_Type) {
> -        status = save_float(self, obj);
> -        goto done;
> -    }
> -
> -    /* Check the memo to see if it has the object. If so, generate
> -       a GET (or BINGET) opcode, instead of pickling the object
> -       once again. */
> -    memo_key = PyLong_FromVoidPtr(obj);
> -    if (memo_key == NULL)
> -        goto error;
> -    if (PyDict_GetItem(self->memo, memo_key)) {
> -        if (memo_get(self, memo_key) < 0)
> -            goto error;
> -        goto done;
> -    }
> -
> -    if (type == &PyBytes_Type) {
> -        status = save_bytes(self, obj);
> -        goto done;
> -    }
> -    else if (type == &PyUnicode_Type) {
> -        status = save_unicode(self, obj);
> -        goto done;
> -    }
> -    else if (type == &PyDict_Type) {
> -        status = save_dict(self, obj);
> -        goto done;
> -    }
> -    else if (type == &PyList_Type) {
> -        status = save_list(self, obj);
> -        goto done;
> -    }
> -    else if (type == &PyTuple_Type) {
> -        status = save_tuple(self, obj);
> -        goto done;
> -    }
> -    else if (type == &PyType_Type) {
> -        status = save_global(self, obj, NULL);
> -        goto done;
> -    }
> -    else if (type == &PyFunction_Type) {
> -        status = save_global(self, obj, NULL);
> -        if (status < 0 && PyErr_ExceptionMatches(PickleError)) {
> -            /* fall back to reduce */
> -            PyErr_Clear();
> -        }
> -        else {
> -            goto done;
> -        }
> -    }
> -    else if (type == &PyCFunction_Type) {
> -        status = save_global(self, obj, NULL);
> -        goto done;
> -    }
> -    else if (PyType_IsSubtype(type, &PyType_Type)) {
> -        status = save_global(self, obj, NULL);
> -        goto done;
> -    }
> -
> -    /* XXX: This part needs some unit tests. */
> -
> -    /* Get a reduction callable, and call it.  This may come from
> -     * copyreg.dispatch_table, the object's __reduce_ex__ method,
> -     * or the object's __reduce__ method.
> -     */
> -    reduce_func = PyDict_GetItem(dispatch_table, (PyObject *)type);
> -    if (reduce_func != NULL) {
> -        /* Here, the reference count of the reduce_func object returned by
> -           PyDict_GetItem needs to be increased to be consistent with the one
> -           returned by PyObject_GetAttr. This is allow us to blindly DECREF
> -           reduce_func at the end of the save() routine.
> -        */
> -        Py_INCREF(reduce_func);
> -        Py_INCREF(obj);
> -        reduce_value = pickler_call(self, reduce_func, obj);
> -    }
> -    else {
> -        static PyObject *reduce_str = NULL;
> -        static PyObject *reduce_ex_str = NULL;
> -
> -        /* Cache the name of the reduce methods. */
> -        if (reduce_str == NULL) {
> -            reduce_str = PyUnicode_InternFromString("__reduce__");
> -            if (reduce_str == NULL)
> -                goto error;
> -            reduce_ex_str = PyUnicode_InternFromString("__reduce_ex__");
> -            if (reduce_ex_str == NULL)
> -                goto error;
> -        }
> -
> -        /* XXX: If the __reduce__ method is defined, __reduce_ex__ is
> -           automatically defined as __reduce__. While this is convenient, this
> -           make it impossible to know which method was actually called. Of
> -           course, this is not a big deal. But still, it would be nice to let
> -           the user know which method was called when something go
> -           wrong. Incidentally, this means if __reduce_ex__ is not defined, we
> -           don't actually have to check for a __reduce__ method. */
> -
> -        /* Check for a __reduce_ex__ method. */
> -        reduce_func = PyObject_GetAttr(obj, reduce_ex_str);
> -        if (reduce_func != NULL) {
> -            PyObject *proto;
> -            proto = PyLong_FromLong(self->proto);
> -            if (proto != NULL) {
> -                reduce_value = pickler_call(self, reduce_func, proto);
> -            }
> -        }
> -        else {
> -            if (PyErr_ExceptionMatches(PyExc_AttributeError))
> -                PyErr_Clear();
> -            else
> -                goto error;
> -            /* Check for a __reduce__ method. */
> -            reduce_func = PyObject_GetAttr(obj, reduce_str);
> -            if (reduce_func != NULL) {
> -                reduce_value = PyObject_Call(reduce_func, empty_tuple, NULL);
> -            }
> -            else {
> -                PyErr_Format(PicklingError, "can't pickle '%.200s' object: %R",
> -                             type->tp_name, obj);
> -                goto error;
> -            }
> -        }
> -    }
> -
> -    if (reduce_value == NULL)
> -        goto error;
> -
> -    if (PyUnicode_Check(reduce_value)) {
> -        status = save_global(self, obj, reduce_value);
> -        goto done;
> -    }
> -
> -    if (!PyTuple_Check(reduce_value)) {
> -        PyErr_SetString(PicklingError,
> -                        "__reduce__ must return a string or tuple");
> -        goto error;
> -    }
> -    if (Py_SIZE(reduce_value) < 2 || Py_SIZE(reduce_value) > 5) {
> -        PyErr_SetString(PicklingError, "tuple returned by __reduce__ "
> -                        "must contain 2 through 5 elements");
> -        goto error;
> -    }
> -    if (!PyTuple_Check(PyTuple_GET_ITEM(reduce_value, 1))) {
> -        PyErr_SetString(PicklingError, "second item of the tuple "
> -                        "returned by __reduce__ must be a tuple");
> -        goto error;
> -    }
> -
> -    status = save_reduce(self, reduce_value, obj);
> -
> -    if (0) {
> -  error:
> -        status = -1;
> -    }
> -  done:
> -    self->nesting--;
> -    Py_XDECREF(memo_key);
> -    Py_XDECREF(reduce_func);
> -    Py_XDECREF(reduce_value);
> -
> -    return status;
> -}
> -
> -static int
> -dump(PicklerObject *self, PyObject *obj)
> -{
> -    const char stop_op = STOP;
> -
> -    if (self->proto >= 2) {
> -        char header[2];
> -
> -        header[0] = PROTO;
> -        assert(self->proto >= 0 && self->proto < 256);
> -        header[1] = (unsigned char)self->proto;
> -        if (pickler_write(self, header, 2) < 0)
> -            return -1;
> -    }
> -
> -    if (save(self, obj, 0) < 0 ||
> -        pickler_write(self, &stop_op, 1) < 0 ||
> -        pickler_write(self, NULL, 0) < 0)
> -        return -1;
> -
> -    return 0;
> -}
> -
> -PyDoc_STRVAR(Pickler_clear_memo_doc,
> -"clear_memo() -> None. Clears the pickler's \"memo\"."
> -"\n"
> -"The memo is the data structure that remembers which objects the\n"
> -"pickler has already seen, so that shared or recursive objects are\n"
> -"pickled by reference and not by value.  This method is useful when\n"
> -"re-using picklers.");
> -
> -static PyObject *
> -Pickler_clear_memo(PicklerObject *self)
> -{
> -    if (self->memo)
> -        PyDict_Clear(self->memo);
> -
> -    Py_RETURN_NONE;
> -}
> -
> -PyDoc_STRVAR(Pickler_dump_doc,
> -"dump(obj) -> None. Write a pickled representation of obj to the open file.");
> -
> -static PyObject *
> -Pickler_dump(PicklerObject *self, PyObject *args)
> -{
> -    PyObject *obj;
> -
> -    if (!PyArg_ParseTuple(args, "O:dump", &obj))
> -        return NULL;
> -
> -    if (dump(self, obj) < 0)
> -        return NULL;
> -
> -    Py_RETURN_NONE;
> -}
> -
> -static struct PyMethodDef Pickler_methods[] = {
> -    {"dump", (PyCFunction)Pickler_dump, METH_VARARGS,
> -     Pickler_dump_doc},
> -    {"clear_memo", (PyCFunction)Pickler_clear_memo, METH_NOARGS,
> -     Pickler_clear_memo_doc},
> -    {NULL, NULL}                /* sentinel */
> -};
> -
> -static void
> -Pickler_dealloc(PicklerObject *self)
> -{
> -    PyObject_GC_UnTrack(self);
> -
> -    Py_XDECREF(self->write);
> -    Py_XDECREF(self->memo);
> -    Py_XDECREF(self->pers_func);
> -    Py_XDECREF(self->arg);
> -    Py_XDECREF(self->fast_memo);
> -
> -    PyMem_Free(self->write_buf);
> -
> -    Py_TYPE(self)->tp_free((PyObject *)self);
> -}
> -
> -static int
> -Pickler_traverse(PicklerObject *self, visitproc visit, void *arg)
> -{
> -    Py_VISIT(self->write);
> -    Py_VISIT(self->memo);
> -    Py_VISIT(self->pers_func);
> -    Py_VISIT(self->arg);
> -    Py_VISIT(self->fast_memo);
> -    return 0;
> -}
> -
> -static int
> -Pickler_clear(PicklerObject *self)
> -{
> -    Py_CLEAR(self->write);
> -    Py_CLEAR(self->memo);
> -    Py_CLEAR(self->pers_func);
> -    Py_CLEAR(self->arg);
> -    Py_CLEAR(self->fast_memo);
> -
> -    PyMem_Free(self->write_buf);
> -    self->write_buf = NULL;
> -
> -    return 0;
> -}
> -
> -PyDoc_STRVAR(Pickler_doc,
> -"Pickler(file, protocol=None)"
> -"\n"
> -"This takes a binary file for writing a pickle data stream.\n"
> -"\n"
> -"The optional protocol argument tells the pickler to use the\n"
> -"given protocol; supported protocols are 0, 1, 2, 3.  The default\n"
> -"protocol is 3; a backward-incompatible protocol designed for\n"
> -"Python 3.0.\n"
> -"\n"
> -"Specifying a negative protocol version selects the highest\n"
> -"protocol version supported.  The higher the protocol used, the\n"
> -"more recent the version of Python needed to read the pickle\n"
> -"produced.\n"
> -"\n"
> -"The file argument must have a write() method that accepts a single\n"
> -"bytes argument. It can thus be a file object opened for binary\n"
> -"writing, a io.BytesIO instance, or any other custom object that\n"
> -"meets this interface.\n");
> -
> -static int
> -Pickler_init(PicklerObject *self, PyObject *args, PyObject *kwds)
> -{
> -    static char *kwlist[] = {"file", "protocol", 0};
> -    PyObject *file;
> -    PyObject *proto_obj = NULL;
> -    long proto = 0;
> -
> -    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:Pickler",
> -                                     kwlist, &file, &proto_obj))
> -        return -1;
> -
> -    /* In case of multiple __init__() calls, clear previous content. */
> -    if (self->write != NULL)
> -        (void)Pickler_clear(self);
> -
> -    if (proto_obj == NULL || proto_obj == Py_None)
> -        proto = DEFAULT_PROTOCOL;
> -    else
> -        proto = PyLong_AsLong(proto_obj);
> -
> -    if (proto < 0)
> -        proto = HIGHEST_PROTOCOL;
> -    if (proto > HIGHEST_PROTOCOL) {
> -        PyErr_Format(PyExc_ValueError, "pickle protocol must be <= %d",
> -                     HIGHEST_PROTOCOL);
> -        return -1;
> -    }
> -
> -       self->proto = proto;
> -       self->bin = proto > 0;
> -       self->arg = NULL;
> -    self->nesting = 0;
> -       self->fast = 0;
> -       self->fast_nesting = 0;
> -       self->fast_memo = NULL;
> -
> -    if (!PyObject_HasAttrString(file, "write")) {
> -        PyErr_SetString(PyExc_TypeError,
> -                        "file must have a 'write' attribute");
> -        return -1;
> -    }
> -    self->write = PyObject_GetAttrString(file, "write");
> -    if (self->write == NULL)
> -        return -1;
> -       self->buf_size = 0;
> -    self->write_buf = (char *)PyMem_Malloc(WRITE_BUF_SIZE);
> -    if (self->write_buf == NULL) {
> -        PyErr_NoMemory();
> -        return -1;
> -    }
> -    self->pers_func = NULL;
> -    if (PyObject_HasAttrString((PyObject *)self, "persistent_id")) {
> -        self->pers_func = PyObject_GetAttrString((PyObject *)self,
> -                                                 "persistent_id");
> -        if (self->pers_func == NULL)
> -            return -1;
> -    }
> -    self->memo = PyDict_New();
> -    if (self->memo == NULL)
> -        return -1;
> -
> -    return 0;
> -}
> -
> -static PyObject *
> -Pickler_get_memo(PicklerObject *self)
> -{
> -    if (self->memo == NULL)
> -        PyErr_SetString(PyExc_AttributeError, "memo");
> -    else
> -        Py_INCREF(self->memo);
> -    return self->memo;
> -}
> -
> -static int
> -Pickler_set_memo(PicklerObject *self, PyObject *value)
> -{
> -    PyObject *tmp;
> -
> -    if (value == NULL) {
> -        PyErr_SetString(PyExc_TypeError,
> -                        "attribute deletion is not supported");
> -        return -1;
> -    }
> -    if (!PyDict_Check(value)) {
> -        PyErr_SetString(PyExc_TypeError, "memo must be a dictionary");
> -        return -1;
> -    }
> -
> -    tmp = self->memo;
> -    Py_INCREF(value);
> -    self->memo = value;
> -    Py_XDECREF(tmp);
> -
> -    return 0;
> -}
> -
> -static PyObject *
> -Pickler_get_persid(PicklerObject *self)
> -{
> -    if (self->pers_func == NULL)
> -        PyErr_SetString(PyExc_AttributeError, "persistent_id");
> -    else
> -        Py_INCREF(self->pers_func);
> -    return self->pers_func;
> -}
> -
> -static int
> -Pickler_set_persid(PicklerObject *self, PyObject *value)
> -{
> -    PyObject *tmp;
> -
> -    if (value == NULL) {
> -        PyErr_SetString(PyExc_TypeError,
> -                        "attribute deletion is not supported");
> -        return -1;
> -    }
> -    if (!PyCallable_Check(value)) {
> -        PyErr_SetString(PyExc_TypeError,
> -                        "persistent_id must be a callable taking one argument");
> -        return -1;
> -    }
> -
> -    tmp = self->pers_func;
> -    Py_INCREF(value);
> -    self->pers_func = value;
> -    Py_XDECREF(tmp);      /* self->pers_func can be NULL, so be careful. */
> -
> -    return 0;
> -}
> -
> -static PyMemberDef Pickler_members[] = {
> -    {"bin", T_INT, offsetof(PicklerObject, bin)},
> -    {"fast", T_INT, offsetof(PicklerObject, fast)},
> -    {NULL}
> -};
> -
> -static PyGetSetDef Pickler_getsets[] = {
> -    {"memo",          (getter)Pickler_get_memo,
> -                      (setter)Pickler_set_memo},
> -    {"persistent_id", (getter)Pickler_get_persid,
> -                      (setter)Pickler_set_persid},
> -    {NULL}
> -};
> -
> -static PyTypeObject Pickler_Type = {
> -    PyVarObject_HEAD_INIT(NULL, 0)
> -    "_pickle.Pickler"  ,                /*tp_name*/
> -    sizeof(PicklerObject),              /*tp_basicsize*/
> -    0,                                  /*tp_itemsize*/
> -    (destructor)Pickler_dealloc,        /*tp_dealloc*/
> -    0,                                  /*tp_print*/
> -    0,                                  /*tp_getattr*/
> -    0,                                  /*tp_setattr*/
> -    0,                                  /*tp_compare*/
> -    0,                                  /*tp_repr*/
> -    0,                                  /*tp_as_number*/
> -    0,                                  /*tp_as_sequence*/
> -    0,                                  /*tp_as_mapping*/
> -    0,                                  /*tp_hash*/
> -    0,                                  /*tp_call*/
> -    0,                                  /*tp_str*/
> -    0,                                  /*tp_getattro*/
> -    0,                                  /*tp_setattro*/
> -    0,                                  /*tp_as_buffer*/
> -    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
> -    Pickler_doc,                        /*tp_doc*/
> -    (traverseproc)Pickler_traverse,     /*tp_traverse*/
> -    (inquiry)Pickler_clear,             /*tp_clear*/
> -    0,                                  /*tp_richcompare*/
> -    0,                                  /*tp_weaklistoffset*/
> -    0,                                  /*tp_iter*/
> -    0,                                  /*tp_iternext*/
> -    Pickler_methods,                    /*tp_methods*/
> -    Pickler_members,                    /*tp_members*/
> -    Pickler_getsets,                    /*tp_getset*/
> -    0,                                  /*tp_base*/
> -    0,                                  /*tp_dict*/
> -    0,                                  /*tp_descr_get*/
> -    0,                                  /*tp_descr_set*/
> -    0,                                  /*tp_dictoffset*/
> -    (initproc)Pickler_init,             /*tp_init*/
> -    PyType_GenericAlloc,                /*tp_alloc*/
> -    PyType_GenericNew,                  /*tp_new*/
> -    PyObject_GC_Del,                    /*tp_free*/
> -    0,                                  /*tp_is_gc*/
> -};
> -
> -/* Temporary helper for calling self.find_class().
> -
> -   XXX: It would be nice to able to avoid Python function call overhead, by
> -   using directly the C version of find_class(), when find_class() is not
> -   overridden by a subclass. Although, this could become rather hackish. A
> -   simpler optimization would be to call the C function when self is not a
> -   subclass instance. */
> -static PyObject *
> -find_class(UnpicklerObject *self, PyObject *module_name, PyObject *global_name)
> -{
> -    return PyObject_CallMethod((PyObject *)self, "find_class", "OO",
> -                               module_name, global_name);
> -}
> -
> -static int
> -marker(UnpicklerObject *self)
> -{
> -    if (self->num_marks < 1) {
> -        PyErr_SetString(UnpicklingError, "could not find MARK");
> -        return -1;
> -    }
> -
> -    return self->marks[--self->num_marks];
> -}
> -
> -static int
> -load_none(UnpicklerObject *self)
> -{
> -    PDATA_APPEND(self->stack, Py_None, -1);
> -    return 0;
> -}
> -
> -static int
> -bad_readline(void)
> -{
> -    PyErr_SetString(UnpicklingError, "pickle data was truncated");
> -    return -1;
> -}
> -
> -static int
> -load_int(UnpicklerObject *self)
> -{
> -    PyObject *value;
> -    char *endptr, *s;
> -    Py_ssize_t len;
> -    long x;
> -
> -    if ((len = unpickler_readline(self, &s)) < 0)
> -        return -1;
> -    if (len < 2)
> -        return bad_readline();
> -
> -    errno = 0;
> -    /* XXX: Should the base argument of strtol() be explicitly set to 10? */
> -    x = strtol(s, &endptr, 0);
> -
> -    if (errno || (*endptr != '\n') || (endptr[1] != '\0')) {
> -        /* Hm, maybe we've got something long.  Let's try reading
> -         * it as a Python long object. */
> -        errno = 0;
> -        /* XXX: Same thing about the base here. */
> -        value = PyLong_FromString(s, NULL, 0);
> -        if (value == NULL) {
> -            PyErr_SetString(PyExc_ValueError,
> -                            "could not convert string to int");
> -            return -1;
> -        }
> -    }
> -    else {
> -        if (len == 3 && (x == 0 || x == 1)) {
> -            if ((value = PyBool_FromLong(x)) == NULL)
> -                retur...
>
> [Message clipped]



-- 
--Guido van Rossum (home page: http://www.python.org/~guido/)

From g.brandl at gmx.net  Thu Jun 12 09:16:12 2008
From: g.brandl at gmx.net (Georg Brandl)
Date: Thu, 12 Jun 2008 09:16:12 +0200
Subject: [Python-3000-checkins] r64163 - in python/branches/py3k:
 Lib/pickle.py Lib/pickletools.py Lib/test/pickletester.py
 Lib/test/test_pickle.py Lib/test/test_pickletools.py Misc/NEWS
 Modules/_pickle.c PC/VC6/pythoncore.dsp PC/VS7.1/pythoncore.vcproj P
In-Reply-To: <ca471dc20806112108g2f66848by349f35cf3dfc4aab@mail.gmail.com>
References: <ca471dc20806112108g2f66848by349f35cf3dfc4aab@mail.gmail.com>
Message-ID: <g2qig0$btu$1@ger.gmane.org>

Guido van Rossum schrieb:
> Whoa, I object. This seems to be rolling back functionality that was
> pretty stable for several alphas, and (if I may believe the docstring
> change) you're even dropping protocol 3. Isn't there a more elegant
> way? This seems way too drastic a change so close to the beta release.

No, this is only a rollback of r64152 and further fixes after that.

That the docstring doesn't mention protocol 3 any more is because it
didn't do so until that point -- Alexandre's patch to add a C pickle
speedup also fixed quite a few things in pickle.py.

Georg


From barry at python.org  Thu Jun 12 13:24:29 2008
From: barry at python.org (Barry Warsaw)
Date: Thu, 12 Jun 2008 07:24:29 -0400
Subject: [Python-3000-checkins] r64163 - in python/branches/py3k:
	Lib/pickle.py Lib/pickletools.py Lib/test/pickletester.py
	Lib/test/test_pickle.py Lib/test/test_pickletools.py
	Misc/NEWS Modules/_pickle.c PC/VC6/pythoncore.dsp
	PC/VS7.1/pythoncore.vcproj P
In-Reply-To: <g2qig0$btu$1@ger.gmane.org>
References: <ca471dc20806112108g2f66848by349f35cf3dfc4aab@mail.gmail.com>
	<g2qig0$btu$1@ger.gmane.org>
Message-ID: <51F78BD2-BF3E-4CA6-A681-C3B1C05DFEE8@python.org>

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Jun 12, 2008, at 3:16 AM, Georg Brandl wrote:

> Guido van Rossum schrieb:
>> Whoa, I object. This seems to be rolling back functionality that was
>> pretty stable for several alphas, and (if I may believe the docstring
>> change) you're even dropping protocol 3. Isn't there a more elegant
>> way? This seems way too drastic a change so close to the beta  
>> release.
>
> No, this is only a rollback of r64152 and further fixes after that.
>
> That the docstring doesn't mention protocol 3 any more is because it
> didn't do so until that point -- Alexandre's patch to add a C pickle
> speedup also fixed quite a few things in pickle.py.

Given the instability of the 3.0 branch, there's time to get this back  
in... and fix the other problems with 3.0!

- -Barry

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (Darwin)

iQCUAwUBSFEHbnEjvBPtnXfVAQKrhwP4oPw02BcgVoDHGM2zW7nedUVFBV3gcoMl
lorFOk/NhNZhUD85M4D6QSzrZu/LF4wXekSXH/xNAY8+KPPDkdv0DktIf5vGkTGC
Wn8WGroLQMI0ojWrlWrGPoeKqbUfCDTIZ0mF4DN32ts8+wUOUdtzRoaya7oB2x5n
+HbUWCmXtw==
=C+Kt
-----END PGP SIGNATURE-----

From python-3000-checkins at python.org  Thu Jun 12 15:16:38 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Thu, 12 Jun 2008 15:16:38 +0200 (CEST)
Subject: [Python-3000-checkins] r64166 -
	python/branches/py3k/Modules/_gestalt.c
Message-ID: <20080612131638.AB3781E401F@bag.python.org>

Author: benjamin.peterson
Date: Thu Jun 12 15:16:38 2008
New Revision: 64166

Log:
fix compiler warning


Modified:
   python/branches/py3k/Modules/_gestalt.c

Modified: python/branches/py3k/Modules/_gestalt.c
==============================================================================
--- python/branches/py3k/Modules/_gestalt.c	(original)
+++ python/branches/py3k/Modules/_gestalt.c	Thu Jun 12 15:16:38 2008
@@ -77,7 +77,7 @@
 	NULL
 };
 
-void
+PyMODINIT_FUNC
 PyInit__gestalt(void)
 {
 	return PyModule_Create(&gestaltmodule);

From python-3000-checkins at python.org  Thu Jun 12 16:07:16 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Thu, 12 Jun 2008 16:07:16 +0200 (CEST)
Subject: [Python-3000-checkins] r64167 - in python/branches/py3k:
	Doc/library/mimetools.rst Doc/library/netdata.rst
	Lib/mimetools.py Lib/test/test_mimetools.py Misc/NEWS
Message-ID: <20080612140716.827B61E4022@bag.python.org>

Author: benjamin.peterson
Date: Thu Jun 12 16:06:57 2008
New Revision: 64167

Log:
actually remove the mimetools module


Removed:
   python/branches/py3k/Doc/library/mimetools.rst
   python/branches/py3k/Lib/mimetools.py
   python/branches/py3k/Lib/test/test_mimetools.py
Modified:
   python/branches/py3k/Doc/library/netdata.rst
   python/branches/py3k/Misc/NEWS

Deleted: python/branches/py3k/Doc/library/mimetools.rst
==============================================================================
--- python/branches/py3k/Doc/library/mimetools.rst	Thu Jun 12 16:06:57 2008
+++ (empty file)
@@ -1,131 +0,0 @@
-
-:mod:`mimetools` --- Tools for parsing MIME messages
-====================================================
-
-.. module:: mimetools
-   :synopsis: Tools for parsing MIME-style message bodies.
-   :deprecated:
-
-
-.. deprecated:: 2.3
-   The :mod:`email` package should be used in preference to the :mod:`mimetools`
-   module.  This module is present only to maintain backward compatibility.
-
-.. index:: module: rfc822
-
-This module defines a subclass of the :mod:`rfc822` module's :class:`Message`
-class and a number of utility functions that are useful for the manipulation for
-MIME multipart or encoded message.
-
-It defines the following items:
-
-
-.. class:: Message(fp[, seekable])
-
-   Return a new instance of the :class:`Message` class.  This is a subclass of the
-   :class:`rfc822.Message` class, with some additional methods (see below).  The
-   *seekable* argument has the same meaning as for :class:`rfc822.Message`.
-
-
-.. function:: choose_boundary()
-
-   Return a unique string that has a high likelihood of being usable as a part
-   boundary.  The string has the form ``'hostipaddr.uid.pid.timestamp.random'``.
-
-
-.. function:: decode(input, output, encoding)
-
-   Read data encoded using the allowed MIME *encoding* from open file object
-   *input* and write the decoded data to open file object *output*.  Valid values
-   for *encoding* include ``'base64'``, ``'quoted-printable'``, ``'uuencode'``,
-   ``'x-uuencode'``, ``'uue'``, ``'x-uue'``, ``'7bit'``, and  ``'8bit'``.  Decoding
-   messages encoded in ``'7bit'`` or ``'8bit'`` has no effect.  The input is simply
-   copied to the output.
-
-
-.. function:: encode(input, output, encoding)
-
-   Read data from open file object *input* and write it encoded using the allowed
-   MIME *encoding* to open file object *output*. Valid values for *encoding* are
-   the same as for :meth:`decode`.
-
-
-.. function:: copyliteral(input, output)
-
-   Read lines from open file *input* until EOF and write them to open file
-   *output*.
-
-
-.. function:: copybinary(input, output)
-
-   Read blocks until EOF from open file *input* and write them to open file
-   *output*.  The block size is currently fixed at 8192.
-
-
-.. seealso::
-
-   Module :mod:`email`
-      Comprehensive email handling package; supersedes the :mod:`mimetools` module.
-
-   Module :mod:`rfc822`
-      Provides the base class for :class:`mimetools.Message`.
-
-   Module :mod:`multifile`
-      Support for reading files which contain distinct parts, such as MIME data.
-
-   http://faqs.cs.uu.nl/na-dir/mail/mime-faq/.html
-      The MIME Frequently Asked Questions document.  For an overview of MIME, see the
-      answer to question 1.1 in Part 1 of this document.
-
-
-.. _mimetools-message-objects:
-
-Additional Methods of Message Objects
--------------------------------------
-
-The :class:`Message` class defines the following methods in addition to the
-:class:`rfc822.Message` methods:
-
-
-.. method:: Message.getplist()
-
-   Return the parameter list of the :mailheader:`Content-Type` header. This is a
-   list of strings.  For parameters of the form ``key=value``, *key* is converted
-   to lower case but *value* is not.  For example, if the message contains the
-   header ``Content-type: text/html; spam=1; Spam=2; Spam`` then :meth:`getplist`
-   will return the Python list ``['spam=1', 'spam=2', 'Spam']``.
-
-
-.. method:: Message.getparam(name)
-
-   Return the *value* of the first parameter (as returned by :meth:`getplist`) of
-   the form ``name=value`` for the given *name*.  If *value* is surrounded by
-   quotes of the form '``<``...\ ``>``' or '``"``...\ ``"``', these are removed.
-
-
-.. method:: Message.getencoding()
-
-   Return the encoding specified in the :mailheader:`Content-Transfer-Encoding`
-   message header.  If no such header exists, return ``'7bit'``.  The encoding is
-   converted to lower case.
-
-
-.. method:: Message.gettype()
-
-   Return the message type (of the form ``type/subtype``) as specified in the
-   :mailheader:`Content-Type` header.  If no such header exists, return
-   ``'text/plain'``.  The type is converted to lower case.
-
-
-.. method:: Message.getmaintype()
-
-   Return the main type as specified in the :mailheader:`Content-Type` header.  If
-   no such header exists, return ``'text'``.  The main type is converted to lower
-   case.
-
-
-.. method:: Message.getsubtype()
-
-   Return the subtype as specified in the :mailheader:`Content-Type` header.  If no
-   such header exists, return ``'plain'``.  The subtype is converted to lower case.
-

Modified: python/branches/py3k/Doc/library/netdata.rst
==============================================================================
--- python/branches/py3k/Doc/library/netdata.rst	(original)
+++ python/branches/py3k/Doc/library/netdata.rst	Thu Jun 12 16:06:57 2008
@@ -15,7 +15,6 @@
    json.rst
    mailcap.rst
    mailbox.rst
-   mimetools.rst
    mimetypes.rst
    rfc822.rst
    base64.rst

Deleted: python/branches/py3k/Lib/mimetools.py
==============================================================================
--- python/branches/py3k/Lib/mimetools.py	Thu Jun 12 16:06:57 2008
+++ (empty file)
@@ -1,240 +0,0 @@
-"""Various tools used by MIME-reading or MIME-writing programs."""
-
-
-import os
-import rfc822
-import tempfile
-
-__all__ = ["Message","choose_boundary","encode","decode","copyliteral",
-           "copybinary"]
-
-class Message(rfc822.Message):
-    """A derived class of rfc822.Message that knows about MIME headers and
-    contains some hooks for decoding encoded and multipart messages."""
-
-    def __init__(self, fp, seekable = 1):
-        rfc822.Message.__init__(self, fp, seekable)
-        self.encodingheader = \
-                self.getheader('content-transfer-encoding')
-        self.typeheader = \
-                self.getheader('content-type')
-        self.parsetype()
-        self.parseplist()
-
-    def parsetype(self):
-        str = self.typeheader
-        if str is None:
-            str = 'text/plain'
-        if ';' in str:
-            i = str.index(';')
-            self.plisttext = str[i:]
-            str = str[:i]
-        else:
-            self.plisttext = ''
-        fields = str.split('/')
-        for i in range(len(fields)):
-            fields[i] = fields[i].strip().lower()
-        self.type = '/'.join(fields)
-        self.maintype = fields[0]
-        self.subtype = '/'.join(fields[1:])
-
-    def parseplist(self):
-        str = self.plisttext
-        self.plist = []
-        while str[:1] == ';':
-            str = str[1:]
-            if ';' in str:
-                # XXX Should parse quotes!
-                end = str.index(';')
-            else:
-                end = len(str)
-            f = str[:end]
-            if '=' in f:
-                i = f.index('=')
-                f = f[:i].strip().lower() + \
-                        '=' + f[i+1:].strip()
-            self.plist.append(f.strip())
-            str = str[end:]
-
-    def getplist(self):
-        return self.plist
-
-    def getparam(self, name):
-        name = name.lower() + '='
-        n = len(name)
-        for p in self.plist:
-            if p[:n] == name:
-                return rfc822.unquote(p[n:])
-        return None
-
-    def getparamnames(self):
-        result = []
-        for p in self.plist:
-            i = p.find('=')
-            if i >= 0:
-                result.append(p[:i].lower())
-        return result
-
-    def getencoding(self):
-        if self.encodingheader is None:
-            return '7bit'
-        return self.encodingheader.lower()
-
-    def gettype(self):
-        return self.type
-
-    def getmaintype(self):
-        return self.maintype
-
-    def getsubtype(self):
-        return self.subtype
-
-
-
-
-# Utility functions
-# -----------------
-
-try:
-    import _thread
-except ImportError:
-    import _dummy_thread as _thread
-_counter_lock = _thread.allocate_lock()
-del _thread
-
-_counter = 0
-def _get_next_counter():
-    global _counter
-    _counter_lock.acquire()
-    _counter += 1
-    result = _counter
-    _counter_lock.release()
-    return result
-
-_prefix = None
-
-def choose_boundary():
-    """Return a string usable as a multipart boundary.
-
-    The string chosen is unique within a single program run, and
-    incorporates the user id (if available), process id (if available),
-    and current time.  So it's very unlikely the returned string appears
-    in message text, but there's no guarantee.
-
-    The boundary contains dots so you have to quote it in the header."""
-
-    global _prefix
-    import time
-    if _prefix is None:
-        import socket
-        try:
-            hostid = socket.gethostbyname(socket.gethostname())
-        except socket.gaierror:
-            hostid = '127.0.0.1'
-        try:
-            uid = repr(os.getuid())
-        except AttributeError:
-            uid = '1'
-        try:
-            pid = repr(os.getpid())
-        except AttributeError:
-            pid = '1'
-        _prefix = hostid + '.' + uid + '.' + pid
-    return "%s.%.3f.%d" % (_prefix, time.time(), _get_next_counter())
-
-
-# Subroutines for decoding some common content-transfer-types
-# Input and output must be files opened in binary mode
-
-def decode(input, output, encoding):
-    """Decode common content-transfer-encodings (base64, quopri, uuencode)."""
-    if encoding == 'base64':
-        import base64
-        return base64.decode(input, output)
-    if encoding == 'quoted-printable':
-        import quopri
-        return quopri.decode(input, output)
-    if encoding in ('uuencode', 'x-uuencode', 'uue', 'x-uue'):
-        import uu
-        return uu.decode(input, output)
-    if encoding in ('7bit', '8bit'):
-        return output.write(input.read())
-    if encoding in decodetab:
-        pipethrough(input, decodetab[encoding], output)
-    else:
-        raise ValueError('unknown Content-Transfer-Encoding: %s' % encoding)
-
-def encode(input, output, encoding):
-    """Encode common content-transfer-encodings (base64, quopri, uuencode)."""
-    if encoding == 'base64':
-        import base64
-        return base64.encode(input, output)
-    if encoding == 'quoted-printable':
-        import quopri
-        return quopri.encode(input, output, 0)
-    if encoding in ('uuencode', 'x-uuencode', 'uue', 'x-uue'):
-        import uu
-        return uu.encode(input, output)
-    if encoding in ('7bit', '8bit'):
-        return output.write(input.read())
-    if encoding in encodetab:
-        pipethrough(input, encodetab[encoding], output)
-    else:
-        raise ValueError('unknown Content-Transfer-Encoding: %s' % encoding)
-
-# The following is no longer used for standard encodings
-
-# XXX This requires that uudecode and mmencode are in $PATH
-
-uudecode_pipe = '''(
-TEMP=/tmp/@uu.$$
-sed "s%^begin [0-7][0-7]* .*%begin 600 $TEMP%" | uudecode
-cat $TEMP
-rm $TEMP
-)'''
-
-decodetab = {
-        'uuencode':             uudecode_pipe,
-        'x-uuencode':           uudecode_pipe,
-        'uue':                  uudecode_pipe,
-        'x-uue':                uudecode_pipe,
-        'quoted-printable':     'mmencode -u -q',
-        'base64':               'mmencode -u -b',
-}
-
-encodetab = {
-        'x-uuencode':           'uuencode tempfile',
-        'uuencode':             'uuencode tempfile',
-        'x-uue':                'uuencode tempfile',
-        'uue':                  'uuencode tempfile',
-        'quoted-printable':     'mmencode -q',
-        'base64':               'mmencode -b',
-}
-
-def pipeto(input, command):
-    pipe = os.popen(command, 'w')
-    copyliteral(input, pipe)
-    pipe.close()
-
-def pipethrough(input, command, output):
-    (fd, tempname) = tempfile.mkstemp()
-    temp = os.fdopen(fd, 'w')
-    copyliteral(input, temp)
-    temp.close()
-    pipe = os.popen(command + ' <' + tempname, 'r')
-    copybinary(pipe, output)
-    pipe.close()
-    os.unlink(tempname)
-
-def copyliteral(input, output):
-    while 1:
-        line = input.readline()
-        if not line: break
-        output.write(line)
-
-def copybinary(input, output):
-    BUFSIZE = 8192
-    while 1:
-        line = input.read(BUFSIZE)
-        if not line: break
-        output.write(line)

Deleted: python/branches/py3k/Lib/test/test_mimetools.py
==============================================================================
--- python/branches/py3k/Lib/test/test_mimetools.py	Thu Jun 12 16:06:57 2008
+++ (empty file)
@@ -1,76 +0,0 @@
-import unittest
-from test import support
-
-import string, mimetools
-import io
-
-msgtext1 = mimetools.Message(io.StringIO(
-"""Content-Type: text/plain; charset=iso-8859-1; format=flowed
-Content-Transfer-Encoding: 8bit
-
-Foo!
-"""))
-
-sample = bytes(string.ascii_letters + "=" + string.digits + "\n", "ASCII")
-
-class MimeToolsTest(unittest.TestCase):
-
-    def decode_encode_test(self, enc):
-        i = io.BytesIO(sample)
-        o = io.BytesIO()
-        mimetools.encode(i, o, enc)
-        i = io.BytesIO(o.getvalue())
-        o = io.BytesIO()
-        mimetools.decode(i, o, enc)
-        self.assertEqual(o.getvalue(), sample)
-
-    # Separate tests for better diagnostics
-
-    def test_7bit(self):
-        self.decode_encode_test('7bit')
-
-    def test_8bit(self):
-        self.decode_encode_test('8bit')
-
-    def test_base64(self):
-        self.decode_encode_test('base64')
-
-    def test_quoted_printable(self):
-        self.decode_encode_test('quoted-printable')
-
-    def test_uuencode(self):
-        self.decode_encode_test('uuencode')
-
-    def test_x_uuencode(self):
-        self.decode_encode_test('x-uuencode')
-
-    def test_uue(self):
-        self.decode_encode_test('uue')
-
-    def test_x_uue(self):
-        self.decode_encode_test('x-uue')
-
-    def test_boundary(self):
-        s = set([""])
-        for i in range(100):
-            nb = mimetools.choose_boundary()
-            self.assert_(nb not in s)
-            s.add(nb)
-
-    def test_message(self):
-        msg = mimetools.Message(io.StringIO(str(msgtext1)))
-        self.assertEqual(msg.gettype(), "text/plain")
-        self.assertEqual(msg.getmaintype(), "text")
-        self.assertEqual(msg.getsubtype(), "plain")
-        self.assertEqual(msg.getplist(), ["charset=iso-8859-1", "format=flowed"])
-        self.assertEqual(msg.getparamnames(), ["charset", "format"])
-        self.assertEqual(msg.getparam("charset"), "iso-8859-1")
-        self.assertEqual(msg.getparam("format"), "flowed")
-        self.assertEqual(msg.getparam("spam"), None)
-        self.assertEqual(msg.getencoding(), "8bit")
-
-def test_main():
-    support.run_unittest(MimeToolsTest)
-
-if __name__=="__main__":
-    test_main()

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Thu Jun 12 16:06:57 2008
@@ -78,6 +78,8 @@
 Library
 -------
 
+- mimetools has been removed in favor of the email package
+
 - Patch #2849: Remove use of rfc822 module from standard library.
 
 - Added C optimized implementation of io.StringIO.

From python-3000-checkins at python.org  Thu Jun 12 16:11:44 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Thu, 12 Jun 2008 16:11:44 +0200 (CEST)
Subject: [Python-3000-checkins] r64168 - python/branches/py3k/Misc/NEWS
Message-ID: <20080612141144.02E311E4006@bag.python.org>

Author: benjamin.peterson
Date: Thu Jun 12 16:11:35 2008
New Revision: 64168

Log:
add a period


Modified:
   python/branches/py3k/Misc/NEWS

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Thu Jun 12 16:11:35 2008
@@ -78,7 +78,7 @@
 Library
 -------
 
-- mimetools has been removed in favor of the email package
+- mimetools has been removed in favor of the email package.
 
 - Patch #2849: Remove use of rfc822 module from standard library.
 

From python-3000-checkins at python.org  Thu Jun 12 16:26:32 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Thu, 12 Jun 2008 16:26:32 +0200 (CEST)
Subject: [Python-3000-checkins] r64171 - python/branches/py3k
Message-ID: <20080612142632.9243E1E402A@bag.python.org>

Author: benjamin.peterson
Date: Thu Jun 12 16:26:32 2008
New Revision: 64171

Log:
Blocked revisions 64169 via svnmerge

........
  r64169 | benjamin.peterson | 2008-06-12 09:23:49 -0500 (Thu, 12 Jun 2008) | 1 line
  
  deprecated mimetools
........


Modified:
   python/branches/py3k/   (props changed)

From alexandre at peadrop.com  Thu Jun 12 18:53:45 2008
From: alexandre at peadrop.com (Alexandre Vassalotti)
Date: Thu, 12 Jun 2008 12:53:45 -0400
Subject: [Python-3000-checkins] r64163 - in python/branches/py3k:
	Lib/pickle.py Lib/pickletools.py Lib/test/pickletester.py
	Lib/test/test_pickle.py Lib/test/test_pickletools.py
	Misc/NEWS Modules/_pickle.c PC/VC6/pythoncore.dsp
	PC/VS7.1/pythoncore.vcproj P
In-Reply-To: <ca471dc20806112108g2f66848by349f35cf3dfc4aab@mail.gmail.com>
References: <ca471dc20806112108g2f66848by349f35cf3dfc4aab@mail.gmail.com>
Message-ID: <acd65fa20806120953l892b01fu6bd5234ebf81e133@mail.gmail.com>

On Thu, Jun 12, 2008 at 12:08 AM, Guido van Rossum <guido at python.org> wrote:
> Whoa, I object. This seems to be rolling back functionality that was
> pretty stable for several alphas, and (if I may believe the docstring
> change) you're even dropping protocol 3. Isn't there a more elegant
> way? This seems way too drastic a change so close to the beta release.

Benjamin had my approval do the revert if necessary. I had to quit
early yesterday, so I could do it myself.

Anyway, I just installed a 64bit OS on my development machine. So, I
will be able to fix the new _pickle module.

-- Alexandre

From python-3000-checkins at python.org  Thu Jun 12 19:02:51 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Thu, 12 Jun 2008 19:02:51 +0200 (CEST)
Subject: [Python-3000-checkins] r64176 -
	python/branches/py3k/Lib/multiprocessing/managers.py
Message-ID: <20080612170251.A4C851E4006@bag.python.org>

Author: benjamin.peterson
Date: Thu Jun 12 19:02:47 2008
New Revision: 64176

Log:
attempt to fix multiprocessing

Modified:
   python/branches/py3k/Lib/multiprocessing/managers.py

Modified: python/branches/py3k/Lib/multiprocessing/managers.py
==============================================================================
--- python/branches/py3k/Lib/multiprocessing/managers.py	(original)
+++ python/branches/py3k/Lib/multiprocessing/managers.py	Thu Jun 12 19:02:47 2008
@@ -968,7 +968,6 @@
 
 
 class ConditionProxy(AcquirerProxy):
-    # XXX will Condition.notfyAll() name be available in Py3.0?
     _exposed_ = ('acquire', 'release', 'wait', 'notify', 'notify_all')
     def wait(self, timeout=None):
         return self._callmethod('wait', (timeout,))
@@ -978,10 +977,9 @@
         return self._callmethod('notify_all')
 
 class EventProxy(BaseProxy):
-    # XXX will Event.isSet name be available in Py3.0?
-    _exposed_ = ('isSet', 'set', 'clear', 'wait')
+    _exposed_ = ('is_set', 'set', 'clear', 'wait')
     def is_set(self):
-        return self._callmethod('isSet')
+        return self._callmethod('is_set')
     def set(self):
         return self._callmethod('set')
     def clear(self):

From python-3000-checkins at python.org  Thu Jun 12 19:36:10 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Thu, 12 Jun 2008 19:36:10 +0200 (CEST)
Subject: [Python-3000-checkins] r64177 - python/branches/py3k/Lib/cgi.py
Message-ID: <20080612173610.C38F71E4006@bag.python.org>

Author: benjamin.peterson
Date: Thu Jun 12 19:36:10 2008
New Revision: 64177

Log:
remove a mimetools import

Modified:
   python/branches/py3k/Lib/cgi.py

Modified: python/branches/py3k/Lib/cgi.py
==============================================================================
--- python/branches/py3k/Lib/cgi.py	(original)
+++ python/branches/py3k/Lib/cgi.py	Thu Jun 12 19:36:10 2008
@@ -36,7 +36,6 @@
 import sys
 import os
 import urllib
-import mimetools
 import email.parser
 
 __all__ = ["MiniFieldStorage", "FieldStorage",

From python-3000-checkins at python.org  Thu Jun 12 20:02:10 2008
From: python-3000-checkins at python.org (alexandre.vassalotti)
Date: Thu, 12 Jun 2008 20:02:10 +0200 (CEST)
Subject: [Python-3000-checkins] r64179 - python/branches/py3k/Lib/urllib2.py
Message-ID: <20080612180210.E1F861E400A@bag.python.org>

Author: alexandre.vassalotti
Date: Thu Jun 12 20:02:10 2008
New Revision: 64179

Log:
Fixed test_urllib2 by coercing Message object to str
before passing it to io.StringIO.write().


Modified:
   python/branches/py3k/Lib/urllib2.py

Modified: python/branches/py3k/Lib/urllib2.py
==============================================================================
--- python/branches/py3k/Lib/urllib2.py	(original)
+++ python/branches/py3k/Lib/urllib2.py	Thu Jun 12 20:02:10 2008
@@ -1295,7 +1295,7 @@
             if retrlen is not None and retrlen >= 0:
                 headers += "Content-length: %d\n" % retrlen
             headers = email.message_from_string(headers)
-            sf = StringIO(headers)
+            sf = StringIO(str(headers))
             return addinfourl(fp, headers, req.get_full_url())
         except ftplib.all_errors as msg:
             raise URLError('ftp error: %s' % msg).with_traceback(sys.exc_info()[2])

From python-3000-checkins at python.org  Thu Jun 12 20:26:05 2008
From: python-3000-checkins at python.org (alexandre.vassalotti)
Date: Thu, 12 Jun 2008 20:26:05 +0200 (CEST)
Subject: [Python-3000-checkins] r64180 - in python/branches/py3k:
	Lib/pickle.py Lib/pickletools.py Lib/test/pickletester.py
	Lib/test/test_pickle.py Lib/test/test_pickletools.py
	Misc/NEWS Modules/_pickle.c setup.py
Message-ID: <20080612182605.D4EEB1E400D@bag.python.org>

Author: alexandre.vassalotti
Date: Thu Jun 12 20:26:05 2008
New Revision: 64180

Log:
Restore _pickle module accelerator module.
Removed temporary Windows support.
64bit bug with integer unpickling is now fixed. 


Added:
   python/branches/py3k/Modules/_pickle.c
      - copied, changed from r64162, /python/branches/py3k/Modules/_pickle.c
Modified:
   python/branches/py3k/Lib/pickle.py
   python/branches/py3k/Lib/pickletools.py
   python/branches/py3k/Lib/test/pickletester.py
   python/branches/py3k/Lib/test/test_pickle.py
   python/branches/py3k/Lib/test/test_pickletools.py
   python/branches/py3k/Misc/NEWS
   python/branches/py3k/setup.py

Modified: python/branches/py3k/Lib/pickle.py
==============================================================================
--- python/branches/py3k/Lib/pickle.py	(original)
+++ python/branches/py3k/Lib/pickle.py	Thu Jun 12 20:26:05 2008
@@ -174,7 +174,7 @@
 
 # Pickling machinery
 
-class Pickler:
+class _Pickler:
 
     def __init__(self, file, protocol=None):
         """This takes a binary file for writing a pickle data stream.
@@ -182,21 +182,19 @@
         All protocols now read and write bytes.
 
         The optional protocol argument tells the pickler to use the
-        given protocol; supported protocols are 0, 1, 2.  The default
-        protocol is 2; it's been supported for many years now.
-
-        Protocol 1 is more efficient than protocol 0; protocol 2 is
-        more efficient than protocol 1.
+        given protocol; supported protocols are 0, 1, 2, 3.  The default
+        protocol is 3; a backward-incompatible protocol designed for
+        Python 3.0.
 
         Specifying a negative protocol version selects the highest
         protocol version supported.  The higher the protocol used, the
         more recent the version of Python needed to read the pickle
         produced.
 
-        The file parameter must have a write() method that accepts a single
-        string argument.  It can thus be an open file object, a StringIO
-        object, or any other custom object that meets this interface.
-
+        The file argument must have a write() method that accepts a single
+        bytes argument. It can thus be a file object opened for binary
+        writing, a io.BytesIO instance, or any other custom object that
+        meets this interface.
         """
         if protocol is None:
             protocol = DEFAULT_PROTOCOL
@@ -204,7 +202,10 @@
             protocol = HIGHEST_PROTOCOL
         elif not 0 <= protocol <= HIGHEST_PROTOCOL:
             raise ValueError("pickle protocol must be <= %d" % HIGHEST_PROTOCOL)
-        self.write = file.write
+        try:
+            self.write = file.write
+        except AttributeError:
+            raise TypeError("file must have a 'write' attribute")
         self.memo = {}
         self.proto = int(protocol)
         self.bin = protocol >= 1
@@ -270,10 +271,10 @@
 
         return GET + repr(i).encode("ascii") + b'\n'
 
-    def save(self, obj):
+    def save(self, obj, save_persistent_id=True):
         # Check for persistent id (defined by a subclass)
         pid = self.persistent_id(obj)
-        if pid:
+        if pid is not None and save_persistent_id:
             self.save_pers(pid)
             return
 
@@ -341,7 +342,7 @@
     def save_pers(self, pid):
         # Save a persistent id reference
         if self.bin:
-            self.save(pid)
+            self.save(pid, save_persistent_id=False)
             self.write(BINPERSID)
         else:
             self.write(PERSID + str(pid).encode("ascii") + b'\n')
@@ -350,13 +351,13 @@
                     listitems=None, dictitems=None, obj=None):
         # This API is called by some subclasses
 
-        # Assert that args is a tuple or None
+        # Assert that args is a tuple
         if not isinstance(args, tuple):
-            raise PicklingError("args from reduce() should be a tuple")
+            raise PicklingError("args from save_reduce() should be a tuple")
 
         # Assert that func is callable
         if not hasattr(func, '__call__'):
-            raise PicklingError("func from reduce should be callable")
+            raise PicklingError("func from save_reduce() should be callable")
 
         save = self.save
         write = self.write
@@ -438,31 +439,6 @@
             self.write(obj and TRUE or FALSE)
     dispatch[bool] = save_bool
 
-    def save_int(self, obj, pack=struct.pack):
-        if self.bin:
-            # If the int is small enough to fit in a signed 4-byte 2's-comp
-            # format, we can store it more efficiently than the general
-            # case.
-            # First one- and two-byte unsigned ints:
-            if obj >= 0:
-                if obj <= 0xff:
-                    self.write(BININT1 + bytes([obj]))
-                    return
-                if obj <= 0xffff:
-                    self.write(BININT2 + bytes([obj&0xff, obj>>8]))
-                    return
-            # Next check for 4-byte signed ints:
-            high_bits = obj >> 31  # note that Python shift sign-extends
-            if high_bits == 0 or high_bits == -1:
-                # All high bits are copies of bit 2**31, so the value
-                # fits in a 4-byte signed int.
-                self.write(BININT + pack("<i", obj))
-                return
-        # Text pickle, or int too big to fit in signed 4-byte format.
-        self.write(INT + repr(obj).encode("ascii") + b'\n')
-    # XXX save_int is merged into save_long
-    # dispatch[int] = save_int
-
     def save_long(self, obj, pack=struct.pack):
         if self.bin:
             # If the int is small enough to fit in a signed 4-byte 2's-comp
@@ -503,7 +479,7 @@
 
     def save_bytes(self, obj, pack=struct.pack):
         if self.proto < 3:
-            self.save_reduce(bytes, (list(obj),))
+            self.save_reduce(bytes, (list(obj),), obj=obj)
             return
         n = len(obj)
         if n < 256:
@@ -579,12 +555,6 @@
 
     dispatch[tuple] = save_tuple
 
-    # save_empty_tuple() isn't used by anything in Python 2.3.  However, I
-    # found a Pickler subclass in Zope3 that calls it, so it's not harmless
-    # to remove it.
-    def save_empty_tuple(self, obj):
-        self.write(EMPTY_TUPLE)
-
     def save_list(self, obj):
         write = self.write
 
@@ -696,7 +666,7 @@
             module = whichmodule(obj, name)
 
         try:
-            __import__(module)
+            __import__(module, level=0)
             mod = sys.modules[module]
             klass = getattr(mod, name)
         except (ImportError, KeyError, AttributeError):
@@ -720,9 +690,19 @@
                 else:
                     write(EXT4 + pack("<i", code))
                 return
+        # Non-ASCII identifiers are supported only with protocols >= 3.
+        if self.proto >= 3:
+            write(GLOBAL + bytes(module, "utf-8") + b'\n' +
+                  bytes(name, "utf-8") + b'\n')
+        else:
+            try:
+                write(GLOBAL + bytes(module, "ascii") + b'\n' +
+                      bytes(name, "ascii") + b'\n')
+            except UnicodeEncodeError:
+                raise PicklingError(
+                    "can't pickle global identifier '%s.%s' using "
+                    "pickle protocol %i" % (module, name, self.proto))
 
-        write(GLOBAL + bytes(module, "utf-8") + b'\n' +
-              bytes(name, "utf-8") + b'\n')
         self.memoize(obj)
 
     dispatch[FunctionType] = save_global
@@ -781,7 +761,7 @@
 
 # Unpickling machinery
 
-class Unpickler:
+class _Unpickler:
 
     def __init__(self, file, *, encoding="ASCII", errors="strict"):
         """This takes a binary file for reading a pickle data stream.
@@ -841,6 +821,9 @@
         while stack[k] is not mark: k = k-1
         return k
 
+    def persistent_load(self, pid):
+        raise UnpickingError("unsupported persistent id encountered")
+
     dispatch = {}
 
     def load_proto(self):
@@ -850,7 +833,7 @@
     dispatch[PROTO[0]] = load_proto
 
     def load_persid(self):
-        pid = self.readline()[:-1]
+        pid = self.readline()[:-1].decode("ascii")
         self.append(self.persistent_load(pid))
     dispatch[PERSID[0]] = load_persid
 
@@ -879,9 +862,9 @@
             val = True
         else:
             try:
-                val = int(data)
+                val = int(data, 0)
             except ValueError:
-                val = int(data)
+                val = int(data, 0)
         self.append(val)
     dispatch[INT[0]] = load_int
 
@@ -933,7 +916,8 @@
                 break
         else:
             raise ValueError("insecure string pickle: %r" % orig)
-        self.append(codecs.escape_decode(rep)[0])
+        self.append(codecs.escape_decode(rep)[0]
+                    .decode(self.encoding, self.errors))
     dispatch[STRING[0]] = load_string
 
     def load_binstring(self):
@@ -975,7 +959,7 @@
     dispatch[TUPLE[0]] = load_tuple
 
     def load_empty_tuple(self):
-        self.stack.append(())
+        self.append(())
     dispatch[EMPTY_TUPLE[0]] = load_empty_tuple
 
     def load_tuple1(self):
@@ -991,11 +975,11 @@
     dispatch[TUPLE3[0]] = load_tuple3
 
     def load_empty_list(self):
-        self.stack.append([])
+        self.append([])
     dispatch[EMPTY_LIST[0]] = load_empty_list
 
     def load_empty_dictionary(self):
-        self.stack.append({})
+        self.append({})
     dispatch[EMPTY_DICT[0]] = load_empty_dictionary
 
     def load_list(self):
@@ -1022,13 +1006,13 @@
     def _instantiate(self, klass, k):
         args = tuple(self.stack[k+1:])
         del self.stack[k:]
-        instantiated = 0
+        instantiated = False
         if (not args and
                 isinstance(klass, type) and
                 not hasattr(klass, "__getinitargs__")):
             value = _EmptyClass()
             value.__class__ = klass
-            instantiated = 1
+            instantiated = True
         if not instantiated:
             try:
                 value = klass(*args)
@@ -1038,8 +1022,8 @@
         self.append(value)
 
     def load_inst(self):
-        module = self.readline()[:-1]
-        name = self.readline()[:-1]
+        module = self.readline()[:-1].decode("ascii")
+        name = self.readline()[:-1].decode("ascii")
         klass = self.find_class(module, name)
         self._instantiate(klass, self.marker())
     dispatch[INST[0]] = load_inst
@@ -1059,8 +1043,8 @@
     dispatch[NEWOBJ[0]] = load_newobj
 
     def load_global(self):
-        module = self.readline()[:-1]
-        name = self.readline()[:-1]
+        module = self.readline()[:-1].decode("utf-8")
+        name = self.readline()[:-1].decode("utf-8")
         klass = self.find_class(module, name)
         self.append(klass)
     dispatch[GLOBAL[0]] = load_global
@@ -1095,11 +1079,7 @@
 
     def find_class(self, module, name):
         # Subclasses may override this
-        if isinstance(module, bytes_types):
-            module = module.decode("utf-8")
-        if isinstance(name, bytes_types):
-            name = name.decode("utf-8")
-        __import__(module)
+        __import__(module, level=0)
         mod = sys.modules[module]
         klass = getattr(mod, name)
         return klass
@@ -1131,31 +1111,33 @@
     dispatch[DUP[0]] = load_dup
 
     def load_get(self):
-        self.append(self.memo[self.readline()[:-1].decode("ascii")])
+        i = int(self.readline()[:-1])
+        self.append(self.memo[i])
     dispatch[GET[0]] = load_get
 
     def load_binget(self):
-        i = ord(self.read(1))
-        self.append(self.memo[repr(i)])
+        i = self.read(1)[0]
+        self.append(self.memo[i])
     dispatch[BINGET[0]] = load_binget
 
     def load_long_binget(self):
         i = mloads(b'i' + self.read(4))
-        self.append(self.memo[repr(i)])
+        self.append(self.memo[i])
     dispatch[LONG_BINGET[0]] = load_long_binget
 
     def load_put(self):
-        self.memo[self.readline()[:-1].decode("ascii")] = self.stack[-1]
+        i = int(self.readline()[:-1])
+        self.memo[i] = self.stack[-1]
     dispatch[PUT[0]] = load_put
 
     def load_binput(self):
-        i = ord(self.read(1))
-        self.memo[repr(i)] = self.stack[-1]
+        i = self.read(1)[0]
+        self.memo[i] = self.stack[-1]
     dispatch[BINPUT[0]] = load_binput
 
     def load_long_binput(self):
         i = mloads(b'i' + self.read(4))
-        self.memo[repr(i)] = self.stack[-1]
+        self.memo[i] = self.stack[-1]
     dispatch[LONG_BINPUT[0]] = load_long_binput
 
     def load_append(self):
@@ -1321,6 +1303,12 @@
         n -= 1 << (nbytes * 8)
     return n
 
+# Use the faster _pickle if possible
+try:
+    from _pickle import *
+except ImportError:
+    Pickler, Unpickler = _Pickler, _Unpickler
+
 # Shorthands
 
 def dump(obj, file, protocol=None):
@@ -1333,14 +1321,14 @@
     assert isinstance(res, bytes_types)
     return res
 
-def load(file):
-    return Unpickler(file).load()
+def load(file, *, encoding="ASCII", errors="strict"):
+    return Unpickler(file, encoding=encoding, errors=errors).load()
 
-def loads(s):
+def loads(s, *, encoding="ASCII", errors="strict"):
     if isinstance(s, str):
         raise TypeError("Can't load pickle from unicode string")
     file = io.BytesIO(s)
-    return Unpickler(file).load()
+    return Unpickler(file, encoding=encoding, errors=errors).load()
 
 # Doctest
 

Modified: python/branches/py3k/Lib/pickletools.py
==============================================================================
--- python/branches/py3k/Lib/pickletools.py	(original)
+++ python/branches/py3k/Lib/pickletools.py	Thu Jun 12 20:26:05 2008
@@ -2079,11 +2079,12 @@
    70: t        TUPLE      (MARK at 49)
    71: p    PUT        5
    74: R    REDUCE
-   75: V    UNICODE    'def'
-   80: p    PUT        6
-   83: s    SETITEM
-   84: a    APPEND
-   85: .    STOP
+   75: p    PUT        6
+   78: V    UNICODE    'def'
+   83: p    PUT        7
+   86: s    SETITEM
+   87: a    APPEND
+   88: .    STOP
 highest protocol among opcodes = 0
 
 Try again with a "binary" pickle.
@@ -2115,11 +2116,12 @@
    49: t            TUPLE      (MARK at 37)
    50: q        BINPUT     5
    52: R        REDUCE
-   53: X        BINUNICODE 'def'
-   61: q        BINPUT     6
-   63: s        SETITEM
-   64: e        APPENDS    (MARK at 3)
-   65: .    STOP
+   53: q        BINPUT     6
+   55: X        BINUNICODE 'def'
+   63: q        BINPUT     7
+   65: s        SETITEM
+   66: e        APPENDS    (MARK at 3)
+   67: .    STOP
 highest protocol among opcodes = 1
 
 Exercise the INST/OBJ/BUILD family.

Modified: python/branches/py3k/Lib/test/pickletester.py
==============================================================================
--- python/branches/py3k/Lib/test/pickletester.py	(original)
+++ python/branches/py3k/Lib/test/pickletester.py	Thu Jun 12 20:26:05 2008
@@ -362,7 +362,7 @@
     return x
 
 class AbstractPickleTests(unittest.TestCase):
-    # Subclass must define self.dumps, self.loads, self.error.
+    # Subclass must define self.dumps, self.loads.
 
     _testdata = create_data()
 
@@ -463,8 +463,9 @@
             self.assertEqual(list(x[0].attr.keys()), [1])
             self.assert_(x[0].attr[1] is x)
 
-    def test_garyp(self):
-        self.assertRaises(self.error, self.loads, b'garyp')
+    def test_get(self):
+        self.assertRaises(KeyError, self.loads, b'g0\np0')
+        self.assertEquals(self.loads(b'((Kdtp0\nh\x00l.))'), [(100,), (100,)])
 
     def test_insecure_strings(self):
         # XXX Some of these tests are temporarily disabled
@@ -955,7 +956,7 @@
         f = open(TESTFN, "wb")
         try:
             f.close()
-            self.assertRaises(ValueError, self.module.dump, 123, f)
+            self.assertRaises(ValueError, pickle.dump, 123, f)
         finally:
             os.remove(TESTFN)
 
@@ -964,24 +965,24 @@
         f = open(TESTFN, "wb")
         try:
             f.close()
-            self.assertRaises(ValueError, self.module.dump, 123, f)
+            self.assertRaises(ValueError, pickle.dump, 123, f)
         finally:
             os.remove(TESTFN)
 
     def test_highest_protocol(self):
         # Of course this needs to be changed when HIGHEST_PROTOCOL changes.
-        self.assertEqual(self.module.HIGHEST_PROTOCOL, 3)
+        self.assertEqual(pickle.HIGHEST_PROTOCOL, 3)
 
     def test_callapi(self):
         from io import BytesIO
         f = BytesIO()
         # With and without keyword arguments
-        self.module.dump(123, f, -1)
-        self.module.dump(123, file=f, protocol=-1)
-        self.module.dumps(123, -1)
-        self.module.dumps(123, protocol=-1)
-        self.module.Pickler(f, -1)
-        self.module.Pickler(f, protocol=-1)
+        pickle.dump(123, f, -1)
+        pickle.dump(123, file=f, protocol=-1)
+        pickle.dumps(123, -1)
+        pickle.dumps(123, protocol=-1)
+        pickle.Pickler(f, -1)
+        pickle.Pickler(f, protocol=-1)
 
 class AbstractPersistentPicklerTests(unittest.TestCase):
 

Modified: python/branches/py3k/Lib/test/test_pickle.py
==============================================================================
--- python/branches/py3k/Lib/test/test_pickle.py	(original)
+++ python/branches/py3k/Lib/test/test_pickle.py	Thu Jun 12 20:26:05 2008
@@ -7,37 +7,42 @@
 from test.pickletester import AbstractPickleModuleTests
 from test.pickletester import AbstractPersistentPicklerTests
 
-class PickleTests(AbstractPickleTests, AbstractPickleModuleTests):
+try:
+    import _pickle
+    has_c_implementation = True
+except ImportError:
+    has_c_implementation = False
 
-    module = pickle
-    error = KeyError
 
-    def dumps(self, arg, proto=None):
-        return pickle.dumps(arg, proto)
+class PickleTests(AbstractPickleModuleTests):
+    pass
 
-    def loads(self, buf):
-        return pickle.loads(buf)
 
-class PicklerTests(AbstractPickleTests):
+class PyPicklerTests(AbstractPickleTests):
 
-    error = KeyError
+    pickler = pickle._Pickler
+    unpickler = pickle._Unpickler
 
     def dumps(self, arg, proto=None):
         f = io.BytesIO()
-        p = pickle.Pickler(f, proto)
+        p = self.pickler(f, proto)
         p.dump(arg)
         f.seek(0)
         return bytes(f.read())
 
     def loads(self, buf):
         f = io.BytesIO(buf)
-        u = pickle.Unpickler(f)
+        u = self.unpickler(f)
         return u.load()
 
-class PersPicklerTests(AbstractPersistentPicklerTests):
+
+class PyPersPicklerTests(AbstractPersistentPicklerTests):
+
+    pickler = pickle._Pickler
+    unpickler = pickle._Unpickler
 
     def dumps(self, arg, proto=None):
-        class PersPickler(pickle.Pickler):
+        class PersPickler(self.pickler):
             def persistent_id(subself, obj):
                 return self.persistent_id(obj)
         f = io.BytesIO()
@@ -47,19 +52,29 @@
         return f.read()
 
     def loads(self, buf):
-        class PersUnpickler(pickle.Unpickler):
+        class PersUnpickler(self.unpickler):
             def persistent_load(subself, obj):
                 return self.persistent_load(obj)
         f = io.BytesIO(buf)
         u = PersUnpickler(f)
         return u.load()
 
+
+if has_c_implementation:
+    class CPicklerTests(PyPicklerTests):
+        pickler = _pickle.Pickler
+        unpickler = _pickle.Unpickler
+
+    class CPersPicklerTests(PyPersPicklerTests):
+        pickler = _pickle.Pickler
+        unpickler = _pickle.Unpickler
+
+
 def test_main():
-    support.run_unittest(
-        PickleTests,
-        PicklerTests,
-        PersPicklerTests
-    )
+    tests = [PickleTests, PyPicklerTests, PyPersPicklerTests]
+    if has_c_implementation:
+        tests.extend([CPicklerTests, CPersPicklerTests])
+    support.run_unittest(*tests)
     support.run_doctest(pickle)
 
 if __name__ == "__main__":

Modified: python/branches/py3k/Lib/test/test_pickletools.py
==============================================================================
--- python/branches/py3k/Lib/test/test_pickletools.py	(original)
+++ python/branches/py3k/Lib/test/test_pickletools.py	Thu Jun 12 20:26:05 2008
@@ -12,8 +12,6 @@
     def loads(self, buf):
         return pickle.loads(buf)
 
-    module = pickle
-    error = KeyError
 
 def test_main():
     support.run_unittest(OptimizedPickleTests)

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Thu Jun 12 20:26:05 2008
@@ -84,6 +84,10 @@
 
 - Added C optimized implementation of io.StringIO.
 
+- The ``pickle`` module is now automatically use an optimized C
+  implementation of Pickler and Unpickler when available. The
+  ``cPickle`` module is no longer needed.
+
 - Removed the ``htmllib`` and ``sgmllib`` modules.
 
 - The deprecated ``SmartCookie`` and ``SimpleCookie`` classes have

Copied: python/branches/py3k/Modules/_pickle.c (from r64162, /python/branches/py3k/Modules/_pickle.c)
==============================================================================
--- /python/branches/py3k/Modules/_pickle.c	(original)
+++ python/branches/py3k/Modules/_pickle.c	Thu Jun 12 20:26:05 2008
@@ -2694,24 +2694,24 @@
  * of x-platform bugs.
  */
 static long
-calc_binint(char *s, int size)
+calc_binint(char *bytes, int size)
 {
-    unsigned char c;
-    int i;
-    long x = 0L;
+    unsigned char *s = (unsigned char *)bytes;
+    int i = size;
+    long x = 0;
 
     for (i = 0; i < size; i++) {
-        c = (unsigned char)s[i];
-        x |= (long)c << (i * 8);
+        x |= (long)s[i] << (i * 8);
     }
-#if SIZEOF_LONG > 4
+
     /* Unlike BININT1 and BININT2, BININT (more accurately BININT4)
      * is signed, so on a box with longs bigger than 4 bytes we need
      * to extend a BININT's sign bit to the full width.
      */
-    if (x == 4 && x & (1L << 31))
-        x |= (~0L) << 32;
-#endif
+    if (SIZEOF_LONG > 4 && size == 4) {
+        x |= -(x & (1L << 31));
+    }
+
     return x;
 }
 

Modified: python/branches/py3k/setup.py
==============================================================================
--- python/branches/py3k/setup.py	(original)
+++ python/branches/py3k/setup.py	Thu Jun 12 20:26:05 2008
@@ -422,6 +422,9 @@
         exts.append( Extension("_functools", ["_functoolsmodule.c"]) )
         # Memory-based IO accelerator modules
         exts.append( Extension("_bytesio", ["_bytesio.c"]) )
+        exts.append( Extension("_stringio", ["_stringio.c"]) )
+        # C-optimized pickle replacement
+        exts.append( Extension("_pickle", ["_pickle.c"]) )
         # atexit
         exts.append( Extension("atexit", ["atexitmodule.c"]) )
         # _json speedups

From python-3000-checkins at python.org  Thu Jun 12 20:35:39 2008
From: python-3000-checkins at python.org (alexandre.vassalotti)
Date: Thu, 12 Jun 2008 20:35:39 +0200 (CEST)
Subject: [Python-3000-checkins] r64184 - in python/branches/py3k/PC:
	VC6/pythoncore.dsp VS7.1/pythoncore.vcproj
	VS8.0/pythoncore.vcproj config.c
Message-ID: <20080612183539.EA33C1E400C@bag.python.org>

Author: alexandre.vassalotti
Date: Thu Jun 12 20:35:39 2008
New Revision: 64184

Log:
Removed _stringio from Windows build.

For some yet unknown reason, MSVC's linker fails to resolve
_stringio's module initializer (PyInit__stringio). This probably means
the module is not build correctly. Therefore, I am removing temporary
Windows support until I find how to add new modules properly for MSVC.



Modified:
   python/branches/py3k/PC/VC6/pythoncore.dsp
   python/branches/py3k/PC/VS7.1/pythoncore.vcproj
   python/branches/py3k/PC/VS8.0/pythoncore.vcproj
   python/branches/py3k/PC/config.c

Modified: python/branches/py3k/PC/VC6/pythoncore.dsp
==============================================================================
--- python/branches/py3k/PC/VC6/pythoncore.dsp	(original)
+++ python/branches/py3k/PC/VC6/pythoncore.dsp	Thu Jun 12 20:35:39 2008
@@ -141,10 +141,6 @@
 # End Source File
 # Begin Source File
 
-SOURCE=..\..\Modules\_stringio.c
-# End Source File
-# Begin Source File
-
 SOURCE=..\..\Modules\_functoolsmodule.c
 # End Source File
 # Begin Source File

Modified: python/branches/py3k/PC/VS7.1/pythoncore.vcproj
==============================================================================
--- python/branches/py3k/PC/VS7.1/pythoncore.vcproj	(original)
+++ python/branches/py3k/PC/VS7.1/pythoncore.vcproj	Thu Jun 12 20:35:39 2008
@@ -374,9 +374,6 @@
 			RelativePath="..\..\Modules\_bytesio.c">
 		</File>
 		<File
-			RelativePath="..\..\Modules\_stringio.c">
-		</File>
-		<File
 			RelativePath="..\..\Modules\_functoolsmodule.c">
 		</File>
 		<File

Modified: python/branches/py3k/PC/VS8.0/pythoncore.vcproj
==============================================================================
--- python/branches/py3k/PC/VS8.0/pythoncore.vcproj	(original)
+++ python/branches/py3k/PC/VS8.0/pythoncore.vcproj	Thu Jun 12 20:35:39 2008
@@ -991,10 +991,6 @@
 				>
 			</File>
 			<File
-				RelativePath="..\..\Modules\_stringio.c"
-				>
-			</File>
-			<File
 				RelativePath="..\..\Modules\_functoolsmodule.c"
 				>
 			</File>

Modified: python/branches/py3k/PC/config.c
==============================================================================
--- python/branches/py3k/PC/config.c	(original)
+++ python/branches/py3k/PC/config.c	Thu Jun 12 20:35:39 2008
@@ -60,8 +60,6 @@
 extern PyObject* PyInit__ast(void);
 extern PyObject* PyInit__fileio(void);
 extern PyObject* PyInit__bytesio(void);
-extern PyObject* PyInit__stringio(void);
-extern PyObject* PyInit__pickle(void);
 extern PyObject* PyInit_atexit(void);
 extern PyObject* _PyWarnings_Init(void);
 

From python-3000-checkins at python.org  Thu Jun 12 20:52:32 2008
From: python-3000-checkins at python.org (georg.brandl)
Date: Thu, 12 Jun 2008 20:52:32 +0200 (CEST)
Subject: [Python-3000-checkins] r64190 - in python/branches/py3k:
	Doc/library/email.rst Doc/library/http.client.rst
	Doc/library/http.cookiejar.rst Doc/library/http.server.rst
	Doc/library/rfc822.rst Doc/library/urllib.rst Lib/pydoc.py
	Lib/test/test___all__.py
Message-ID: <20080612185232.341EE1E4007@bag.python.org>

Author: georg.brandl
Date: Thu Jun 12 20:52:31 2008
New Revision: 64190

Log:
Remove last traces of mimetools.


Modified:
   python/branches/py3k/Doc/library/email.rst
   python/branches/py3k/Doc/library/http.client.rst
   python/branches/py3k/Doc/library/http.cookiejar.rst
   python/branches/py3k/Doc/library/http.server.rst
   python/branches/py3k/Doc/library/rfc822.rst
   python/branches/py3k/Doc/library/urllib.rst
   python/branches/py3k/Lib/pydoc.py
   python/branches/py3k/Lib/test/test___all__.py

Modified: python/branches/py3k/Doc/library/email.rst
==============================================================================
--- python/branches/py3k/Doc/library/email.rst	(original)
+++ python/branches/py3k/Doc/library/email.rst	Thu Jun 12 20:52:31 2008
@@ -10,15 +10,12 @@
 
 
 The :mod:`email` package is a library for managing email messages, including
-MIME and other :rfc:`2822`\ -based message documents.  It subsumes most of the
-functionality in several older standard modules such as :mod:`rfc822`,
-:mod:`mimetools`, :mod:`multifile`, and other non-standard packages such as
-:mod:`mimecntl`.  It is specifically *not* designed to do any sending of email
-messages to SMTP (:rfc:`2821`), NNTP, or other servers; those are functions of
-modules such as :mod:`smtplib` and :mod:`nntplib`. The :mod:`email` package
-attempts to be as RFC-compliant as possible, supporting in addition to
-:rfc:`2822`, such MIME-related RFCs as :rfc:`2045`, :rfc:`2046`, :rfc:`2047`,
-and :rfc:`2231`.
+MIME and other :rfc:`2822`\ -based message documents.  It is specifically *not*
+designed to do any sending of email messages to SMTP (:rfc:`2821`), NNTP, or
+other servers; those are functions of modules such as :mod:`smtplib` and
+:mod:`nntplib`. The :mod:`email` package attempts to be as RFC-compliant as
+possible, supporting in addition to :rfc:`2822`, such MIME-related RFCs as
+:rfc:`2045`, :rfc:`2046`, :rfc:`2047`, and :rfc:`2231`.
 
 The primary distinguishing feature of the :mod:`email` package is that it splits
 the parsing and generating of email messages from the internal *object model*

Modified: python/branches/py3k/Doc/library/http.client.rst
==============================================================================
--- python/branches/py3k/Doc/library/http.client.rst	(original)
+++ python/branches/py3k/Doc/library/http.client.rst	Thu Jun 12 20:52:31 2008
@@ -445,7 +445,7 @@
 
 .. attribute:: HTTPResponse.msg
 
-   A :class:`mimetools.Message` instance containing the response headers.
+   An :class:`email.message.Message` instance containing the response headers.
 
 
 .. attribute:: HTTPResponse.version

Modified: python/branches/py3k/Doc/library/http.cookiejar.rst
==============================================================================
--- python/branches/py3k/Doc/library/http.cookiejar.rst	(original)
+++ python/branches/py3k/Doc/library/http.cookiejar.rst	Thu Jun 12 20:52:31 2008
@@ -165,10 +165,9 @@
    :mailheader:`Set-Cookie2` headers in the *response* argument, and store cookies
    as appropriate (subject to the :meth:`CookiePolicy.set_ok` method's approval).
 
-   The *response* object (usually the result of a call to :meth:`urllib2.urlopen`,
-   or similar) should support an :meth:`info` method, which returns an object with
-   a :meth:`getallmatchingheaders` method (usually a :class:`mimetools.Message`
-   instance).
+   The *response* object (usually the result of a call to
+   :meth:`urllib2.urlopen`, or similar) should support an :meth:`info` method,
+   which returns a :class:`email.message.Message` instance.
 
    The *request* object (usually a :class:`urllib2.Request` instance) must support
    the methods :meth:`get_full_url`, :meth:`get_host`, :meth:`unverifiable`, and

Modified: python/branches/py3k/Doc/library/http.server.rst
==============================================================================
--- python/branches/py3k/Doc/library/http.server.rst	(original)
+++ python/branches/py3k/Doc/library/http.server.rst	Thu Jun 12 20:52:31 2008
@@ -124,11 +124,9 @@
 
    .. attribute:: MessageClass
 
-      .. index:: single: Message (in module mimetools)
-
-      Specifies a :class:`rfc822.Message`\ -like class to parse HTTP headers.
-      Typically, this is not overridden, and it defaults to
-      :class:`mimetools.Message`.
+      Specifies an :class:`email.message.Message`\ -like class to parse HTTP
+      headers.  Typically, this is not overridden, and it defaults to
+      :class:`http.client.HTTPMessage`.
 
    .. attribute:: responses
 

Modified: python/branches/py3k/Doc/library/rfc822.rst
==============================================================================
--- python/branches/py3k/Doc/library/rfc822.rst	(original)
+++ python/branches/py3k/Doc/library/rfc822.rst	Thu Jun 12 20:52:31 2008
@@ -132,9 +132,6 @@
    Module :mod:`mailbox`
       Classes to read various mailbox formats produced  by end-user mail programs.
 
-   Module :mod:`mimetools`
-      Subclass of :class:`rfc822.Message` that handles MIME encoded messages.
-
 
 .. _message-objects:
 

Modified: python/branches/py3k/Doc/library/urllib.rst
==============================================================================
--- python/branches/py3k/Doc/library/urllib.rst	(original)
+++ python/branches/py3k/Doc/library/urllib.rst	Thu Jun 12 20:52:31 2008
@@ -39,19 +39,17 @@
    however, so it can't be used at those few places where a true built-in file
    object is required.)
 
-   .. index:: module: mimetools
-
    The :meth:`info` method returns an instance of the class
-   :class:`mimetools.Message` containing meta-information associated with the
-   URL.  When the method is HTTP, these headers are those returned by the server
-   at the head of the retrieved HTML page (including Content-Length and
+   :class:`email.message.Message` containing meta-information associated with
+   the URL.  When the method is HTTP, these headers are those returned by the
+   server at the head of the retrieved HTML page (including Content-Length and
    Content-Type).  When the method is FTP, a Content-Length header will be
    present if (as is now usual) the server passed back a file length in response
    to the FTP retrieval request. A Content-Type header will be present if the
    MIME type can be guessed.  When the method is local-file, returned headers
    will include a Date representing the file's last-modified time, a
    Content-Length giving file size, and a Content-Type containing a guess at the
-   file's type. See also the description of the :mod:`mimetools` module.
+   file's type.
 
    The :meth:`geturl` method returns the real URL of the page.  In some cases, the
    HTTP server redirects a client to another URL.  The :func:`urlopen` function
@@ -288,7 +286,7 @@
 
        Retrieves the contents of *url* and places it in *filename*.  The return value
        is a tuple consisting of a local filename and either a
-       :class:`mimetools.Message` object containing the response headers (for remote
+       :class:`email.message.Message` object containing the response headers (for remote
        URLs) or ``None`` (for local URLs).  The caller must then open and read the
        contents of *filename*.  If *filename* is not given and the URL refers to a
        local file, the input filename is returned.  If the URL is non-local and

Modified: python/branches/py3k/Lib/pydoc.py
==============================================================================
--- python/branches/py3k/Lib/pydoc.py	(original)
+++ python/branches/py3k/Lib/pydoc.py	Thu Jun 12 20:52:31 2008
@@ -1903,17 +1903,7 @@
 # --------------------------------------------------- web browser interface
 
 def serve(port, callback=None, completer=None):
-    import http.server, mimetools, select
-
-    # Patch up mimetools.Message so it doesn't break if rfc822 is reloaded.
-    class Message(mimetools.Message):
-        def __init__(self, fp, seekable=1):
-            Message = self.__class__
-            Message.__bases__[0].__bases__[0].__init__(self, fp, seekable)
-            self.encodingheader = self.get('content-transfer-encoding')
-            self.typeheader = self.get('content-type')
-            self.parsetype()
-            self.parseplist()
+    import http.server, email.message, select
 
     class DocHandler(http.server.BaseHTTPRequestHandler):
         def send_document(self, title, contents):
@@ -1981,7 +1971,7 @@
 
     DocServer.base = http.server.HTTPServer
     DocServer.handler = DocHandler
-    DocHandler.MessageClass = Message
+    DocHandler.MessageClass = email.message.Message
     try:
         try:
             DocServer(port, callback).serve_until_quit()

Modified: python/branches/py3k/Lib/test/test___all__.py
==============================================================================
--- python/branches/py3k/Lib/test/test___all__.py	(original)
+++ python/branches/py3k/Lib/test/test___all__.py	Thu Jun 12 20:52:31 2008
@@ -85,7 +85,6 @@
         self.check_all("mailbox")
         self.check_all("mailcap")
         self.check_all("mhlib")
-        self.check_all("mimetools")
         self.check_all("mimetypes")
         self.check_all("multifile")
         self.check_all("netrc")
@@ -111,7 +110,6 @@
         self.check_all("random")
         self.check_all("re")
         self.check_all("reprlib")
-        self.check_all("rfc822")
         self.check_all("rlcompleter")
         self.check_all("robotparser")
         self.check_all("sched")

From python-3000-checkins at python.org  Fri Jun 13 00:15:51 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Fri, 13 Jun 2008 00:15:51 +0200 (CEST)
Subject: [Python-3000-checkins] r64203 - in python/branches/py3k:
	Doc/library/netdata.rst Doc/library/rfc822.rst Lib/rfc822.py
	Lib/test/test_pyclbr.py Lib/test/test_rfc822.py
	Lib/test/test_urllib2.py Misc/NEWS
Message-ID: <20080612221551.644271E4002@bag.python.org>

Author: benjamin.peterson
Date: Fri Jun 13 00:15:50 2008
New Revision: 64203

Log:
remove the rfc822 module

Removed:
   python/branches/py3k/Doc/library/rfc822.rst
   python/branches/py3k/Lib/rfc822.py
   python/branches/py3k/Lib/test/test_rfc822.py
Modified:
   python/branches/py3k/Doc/library/netdata.rst
   python/branches/py3k/Lib/test/test_pyclbr.py
   python/branches/py3k/Lib/test/test_urllib2.py
   python/branches/py3k/Misc/NEWS

Modified: python/branches/py3k/Doc/library/netdata.rst
==============================================================================
--- python/branches/py3k/Doc/library/netdata.rst	(original)
+++ python/branches/py3k/Doc/library/netdata.rst	Fri Jun 13 00:15:50 2008
@@ -16,7 +16,6 @@
    mailcap.rst
    mailbox.rst
    mimetypes.rst
-   rfc822.rst
    base64.rst
    binhex.rst
    binascii.rst

Deleted: python/branches/py3k/Doc/library/rfc822.rst
==============================================================================
--- python/branches/py3k/Doc/library/rfc822.rst	Fri Jun 13 00:15:50 2008
+++ (empty file)
@@ -1,351 +0,0 @@
-
-:mod:`rfc822` --- Parse RFC 2822 mail headers
-=============================================
-
-.. module:: rfc822
-   :synopsis: Parse 2822 style mail messages.
-   :deprecated:
-
-
-.. deprecated:: 2.3
-   The :mod:`email` package should be used in preference to the :mod:`rfc822`
-   module.  This module is present only to maintain backward compatibility.
-
-This module defines a class, :class:`Message`, which represents an "email
-message" as defined by the Internet standard :rfc:`2822`. [#]_  Such messages
-consist of a collection of message headers, and a message body.  This module
-also defines a helper class :class:`AddressList` for parsing :rfc:`2822`
-addresses.  Please refer to the RFC for information on the specific syntax of
-:rfc:`2822` messages.
-
-.. index:: module: mailbox
-
-The :mod:`mailbox` module provides classes  to read mailboxes produced by
-various end-user mail programs.
-
-
-.. class:: Message(file[, seekable])
-
-   A :class:`Message` instance is instantiated with an input object as parameter.
-   Message relies only on the input object having a :meth:`readline` method; in
-   particular, ordinary file objects qualify.  Instantiation reads headers from the
-   input object up to a delimiter line (normally a blank line) and stores them in
-   the instance.  The message body, following the headers, is not consumed.
-
-   This class can work with any input object that supports a :meth:`readline`
-   method.  If the input object has seek and tell capability, the
-   :meth:`rewindbody` method will work; also, illegal lines will be pushed back
-   onto the input stream.  If the input object lacks seek but has an :meth:`unread`
-   method that can push back a line of input, :class:`Message` will use that to
-   push back illegal lines.  Thus this class can be used to parse messages coming
-   from a buffered stream.
-
-   The optional *seekable* argument is provided as a workaround for certain stdio
-   libraries in which :cfunc:`tell` discards buffered data before discovering that
-   the :cfunc:`lseek` system call doesn't work.  For maximum portability, you
-   should set the seekable argument to zero to prevent that initial :meth:`tell`
-   when passing in an unseekable object such as a file object created from a socket
-   object.
-
-   Input lines as read from the file may either be terminated by CR-LF or by a
-   single linefeed; a terminating CR-LF is replaced by a single linefeed before the
-   line is stored.
-
-   All header matching is done independent of upper or lower case; e.g.
-   ``m['From']``, ``m['from']`` and ``m['FROM']`` all yield the same result.
-
-
-.. class:: AddressList(field)
-
-   You may instantiate the :class:`AddressList` helper class using a single string
-   parameter, a comma-separated list of :rfc:`2822` addresses to be parsed.  (The
-   parameter ``None`` yields an empty list.)
-
-
-.. function:: quote(str)
-
-   Return a new string with backslashes in *str* replaced by two backslashes and
-   double quotes replaced by backslash-double quote.
-
-
-.. function:: unquote(str)
-
-   Return a new string which is an *unquoted* version of *str*. If *str* ends and
-   begins with double quotes, they are stripped off.  Likewise if *str* ends and
-   begins with angle brackets, they are stripped off.
-
-
-.. function:: parseaddr(address)
-
-   Parse *address*, which should be the value of some address-containing field such
-   as :mailheader:`To` or :mailheader:`Cc`, into its constituent "realname" and
-   "email address" parts. Returns a tuple of that information, unless the parse
-   fails, in which case a 2-tuple ``(None, None)`` is returned.
-
-
-.. function:: dump_address_pair(pair)
-
-   The inverse of :meth:`parseaddr`, this takes a 2-tuple of the form ``(realname,
-   email_address)`` and returns the string value suitable for a :mailheader:`To` or
-   :mailheader:`Cc` header.  If the first element of *pair* is false, then the
-   second element is returned unmodified.
-
-
-.. function:: parsedate(date)
-
-   Attempts to parse a date according to the rules in :rfc:`2822`. however, some
-   mailers don't follow that format as specified, so :func:`parsedate` tries to
-   guess correctly in such cases.  *date* is a string containing an :rfc:`2822`
-   date, such as  ``'Mon, 20 Nov 1995 19:12:08 -0500'``.  If it succeeds in parsing
-   the date, :func:`parsedate` returns a 9-tuple that can be passed directly to
-   :func:`time.mktime`; otherwise ``None`` will be returned.  Note that indexes 6,
-   7, and 8 of the result tuple are not usable.
-
-
-.. function:: parsedate_tz(date)
-
-   Performs the same function as :func:`parsedate`, but returns either ``None`` or
-   a 10-tuple; the first 9 elements make up a tuple that can be passed directly to
-   :func:`time.mktime`, and the tenth is the offset of the date's timezone from UTC
-   (which is the official term for Greenwich Mean Time).  (Note that the sign of
-   the timezone offset is the opposite of the sign of the ``time.timezone``
-   variable for the same timezone; the latter variable follows the POSIX standard
-   while this module follows :rfc:`2822`.)  If the input string has no timezone,
-   the last element of the tuple returned is ``None``.  Note that indexes 6, 7, and
-   8 of the result tuple are not usable.
-
-
-.. function:: mktime_tz(tuple)
-
-   Turn a 10-tuple as returned by :func:`parsedate_tz` into a UTC timestamp.  If
-   the timezone item in the tuple is ``None``, assume local time.  Minor
-   deficiency: this first interprets the first 8 elements as a local time and then
-   compensates for the timezone difference; this may yield a slight error around
-   daylight savings time switch dates.  Not enough to worry about for common use.
-
-
-.. seealso::
-
-   Module :mod:`email`
-      Comprehensive email handling package; supersedes the :mod:`rfc822` module.
-
-   Module :mod:`mailbox`
-      Classes to read various mailbox formats produced  by end-user mail programs.
-
-
-.. _message-objects:
-
-Message Objects
----------------
-
-A :class:`Message` instance has the following methods:
-
-
-.. method:: Message.rewindbody()
-
-   Seek to the start of the message body.  This only works if the file object is
-   seekable.
-
-
-.. method:: Message.isheader(line)
-
-   Returns a line's canonicalized fieldname (the dictionary key that will be used
-   to index it) if the line is a legal :rfc:`2822` header; otherwise returns
-   ``None`` (implying that parsing should stop here and the line be pushed back on
-   the input stream).  It is sometimes useful to override this method in a
-   subclass.
-
-
-.. method:: Message.islast(line)
-
-   Return true if the given line is a delimiter on which Message should stop.  The
-   delimiter line is consumed, and the file object's read location positioned
-   immediately after it.  By default this method just checks that the line is
-   blank, but you can override it in a subclass.
-
-
-.. method:: Message.iscomment(line)
-
-   Return ``True`` if the given line should be ignored entirely, just skipped. By
-   default this is a stub that always returns ``False``, but you can override it in
-   a subclass.
-
-
-.. method:: Message.getallmatchingheaders(name)
-
-   Return a list of lines consisting of all headers matching *name*, if any.  Each
-   physical line, whether it is a continuation line or not, is a separate list
-   item.  Return the empty list if no header matches *name*.
-
-
-.. method:: Message.getfirstmatchingheader(name)
-
-   Return a list of lines comprising the first header matching *name*, and its
-   continuation line(s), if any.  Return ``None`` if there is no header matching
-   *name*.
-
-
-.. method:: Message.getrawheader(name)
-
-   Return a single string consisting of the text after the colon in the first
-   header matching *name*.  This includes leading whitespace, the trailing
-   linefeed, and internal linefeeds and whitespace if there any continuation
-   line(s) were present.  Return ``None`` if there is no header matching *name*.
-
-
-.. method:: Message.getheader(name[, default])
-
-   Return a single string consisting of the last header matching *name*,
-   but strip leading and trailing whitespace.
-   Internal whitespace is not stripped.  The optional *default* argument can be
-   used to specify a different default to be returned when there is no header
-   matching *name*; it defaults to ``None``.
-   This is the preferred way to get parsed headers.
-
-
-.. method:: Message.get(name[, default])
-
-   An alias for :meth:`getheader`, to make the interface more compatible  with
-   regular dictionaries.
-
-
-.. method:: Message.getaddr(name)
-
-   Return a pair ``(full name, email address)`` parsed from the string returned by
-   ``getheader(name)``.  If no header matching *name* exists, return ``(None,
-   None)``; otherwise both the full name and the address are (possibly empty)
-   strings.
-
-   Example: If *m*'s first :mailheader:`From` header contains the string
-   ``'jack at cwi.nl (Jack Jansen)'``, then ``m.getaddr('From')`` will yield the pair
-   ``('Jack Jansen', 'jack at cwi.nl')``. If the header contained ``'Jack Jansen
-   <jack at cwi.nl>'`` instead, it would yield the exact same result.
-
-
-.. method:: Message.getaddrlist(name)
-
-   This is similar to ``getaddr(list)``, but parses a header containing a list of
-   email addresses (e.g. a :mailheader:`To` header) and returns a list of ``(full
-   name, email address)`` pairs (even if there was only one address in the header).
-   If there is no header matching *name*, return an empty list.
-
-   If multiple headers exist that match the named header (e.g. if there are several
-   :mailheader:`Cc` headers), all are parsed for addresses. Any continuation lines
-   the named headers contain are also parsed.
-
-
-.. method:: Message.getdate(name)
-
-   Retrieve a header using :meth:`getheader` and parse it into a 9-tuple compatible
-   with :func:`time.mktime`; note that fields 6, 7, and 8  are not usable.  If
-   there is no header matching *name*, or it is unparsable, return ``None``.
-
-   Date parsing appears to be a black art, and not all mailers adhere to the
-   standard.  While it has been tested and found correct on a large collection of
-   email from many sources, it is still possible that this function may
-   occasionally yield an incorrect result.
-
-
-.. method:: Message.getdate_tz(name)
-
-   Retrieve a header using :meth:`getheader` and parse it into a 10-tuple; the
-   first 9 elements will make a tuple compatible with :func:`time.mktime`, and the
-   10th is a number giving the offset of the date's timezone from UTC.  Note that
-   fields 6, 7, and 8  are not usable.  Similarly to :meth:`getdate`, if there is
-   no header matching *name*, or it is unparsable, return ``None``.
-
-:class:`Message` instances also support a limited mapping interface. In
-particular: ``m[name]`` is like ``m.getheader(name)`` but raises :exc:`KeyError`
-if there is no matching header; and ``len(m)``, ``m.get(name[, default])``,
-``m.__contains__(name)``, ``m.keys()``, ``m.values()`` ``m.items()``, and
-``m.setdefault(name[, default])`` act as expected, with the one difference
-that :meth:`setdefault` uses an empty string as the default value.
-:class:`Message` instances also support the mapping writable interface ``m[name]
-= value`` and ``del m[name]``.  :class:`Message` objects do not support the
-:meth:`clear`, :meth:`copy`, :meth:`popitem`, or :meth:`update` methods of the
-mapping interface.  (Support for :meth:`get` and :meth:`setdefault` was only
-added in Python 2.2.)
-
-Finally, :class:`Message` instances have some public instance variables:
-
-
-.. attribute:: Message.headers
-
-   A list containing the entire set of header lines, in the order in which they
-   were read (except that setitem calls may disturb this order). Each line contains
-   a trailing newline.  The blank line terminating the headers is not contained in
-   the list.
-
-
-.. attribute:: Message.fp
-
-   The file or file-like object passed at instantiation time.  This can be used to
-   read the message content.
-
-
-.. attribute:: Message.unixfrom
-
-   The Unix ``From`` line, if the message had one, or an empty string.  This is
-   needed to regenerate the message in some contexts, such as an ``mbox``\ -style
-   mailbox file.
-
-
-.. _addresslist-objects:
-
-AddressList Objects
--------------------
-
-An :class:`AddressList` instance has the following methods:
-
-
-.. method:: AddressList.__len__()
-
-   Return the number of addresses in the address list.
-
-
-.. method:: AddressList.__str__()
-
-   Return a canonicalized string representation of the address list. Addresses are
-   rendered in "name" <host at domain> form, comma-separated.
-
-
-.. method:: AddressList.__add__(alist)
-
-   Return a new :class:`AddressList` instance that contains all addresses in both
-   :class:`AddressList` operands, with duplicates removed (set union).
-
-
-.. method:: AddressList.__iadd__(alist)
-
-   In-place version of :meth:`__add__`; turns this :class:`AddressList` instance
-   into the union of itself and the right-hand instance, *alist*.
-
-
-.. method:: AddressList.__sub__(alist)
-
-   Return a new :class:`AddressList` instance that contains every address in the
-   left-hand :class:`AddressList` operand that is not present in the right-hand
-   address operand (set difference).
-
-
-.. method:: AddressList.__isub__(alist)
-
-   In-place version of :meth:`__sub__`, removing addresses in this list which are
-   also in *alist*.
-
-Finally, :class:`AddressList` instances have one public instance variable:
-
-
-.. attribute:: AddressList.addresslist
-
-   A list of tuple string pairs, one per address.  In each member, the first is the
-   canonicalized name part, the second is the actual route-address (``'@'``\
-   -separated username-host.domain pair).
-
-.. rubric:: Footnotes
-
-.. [#] This module originally conformed to :rfc:`822`, hence the name.  Since then,
-   :rfc:`2822` has been released as an update to :rfc:`822`.  This module should be
-   considered :rfc:`2822`\ -conformant, especially in cases where the syntax or
-   semantics have changed since :rfc:`822`.
-

Deleted: python/branches/py3k/Lib/rfc822.py
==============================================================================
--- python/branches/py3k/Lib/rfc822.py	Fri Jun 13 00:15:50 2008
+++ (empty file)
@@ -1,1003 +0,0 @@
-"""RFC 2822 message manipulation.
-
-Note: This is only a very rough sketch of a full RFC-822 parser; in particular
-the tokenizing of addresses does not adhere to all the quoting rules.
-
-Note: RFC 2822 is a long awaited update to RFC 822.  This module should
-conform to RFC 2822, and is thus mis-named (it's not worth renaming it).  Some
-effort at RFC 2822 updates have been made, but a thorough audit has not been
-performed.  Consider any RFC 2822 non-conformance to be a bug.
-
-    RFC 2822: http://www.faqs.org/rfcs/rfc2822.html
-    RFC 822 : http://www.faqs.org/rfcs/rfc822.html (obsolete)
-
-Directions for use:
-
-To create a Message object: first open a file, e.g.:
-
-  fp = open(file, 'r')
-
-You can use any other legal way of getting an open file object, e.g. use
-sys.stdin or call os.popen().  Then pass the open file object to the Message()
-constructor:
-
-  m = Message(fp)
-
-This class can work with any input object that supports a readline method.  If
-the input object has seek and tell capability, the rewindbody method will
-work; also illegal lines will be pushed back onto the input stream.  If the
-input object lacks seek but has an `unread' method that can push back a line
-of input, Message will use that to push back illegal lines.  Thus this class
-can be used to parse messages coming from a buffered stream.
-
-The optional `seekable' argument is provided as a workaround for certain stdio
-libraries in which tell() discards buffered data before discovering that the
-lseek() system call doesn't work.  For maximum portability, you should set the
-seekable argument to zero to prevent that initial \code{tell} when passing in
-an unseekable object such as a a file object created from a socket object.  If
-it is 1 on entry -- which it is by default -- the tell() method of the open
-file object is called once; if this raises an exception, seekable is reset to
-0.  For other nonzero values of seekable, this test is not made.
-
-To get the text of a particular header there are several methods:
-
-  str = m.getheader(name)
-  str = m.getrawheader(name)
-
-where name is the name of the header, e.g. 'Subject'.  The difference is that
-getheader() strips the leading and trailing whitespace, while getrawheader()
-doesn't.  Both functions retain embedded whitespace (including newlines)
-exactly as they are specified in the header, and leave the case of the text
-unchanged.
-
-For addresses and address lists there are functions
-
-  realname, mailaddress = m.getaddr(name)
-  list = m.getaddrlist(name)
-
-where the latter returns a list of (realname, mailaddr) tuples.
-
-There is also a method
-
-  time = m.getdate(name)
-
-which parses a Date-like field and returns a time-compatible tuple,
-i.e. a tuple such as returned by time.localtime() or accepted by
-time.mktime().
-
-See the class definition for lower level access methods.
-
-There are also some utility functions here.
-"""
-# Cleanup and extensions by Eric S. Raymond <esr at thyrsus.com>
-
-import time
-
-__all__ = ["Message","AddressList","parsedate","parsedate_tz","mktime_tz"]
-
-_blanklines = ('\r\n', '\n')            # Optimization for islast()
-
-
-class Message:
-    """Represents a single RFC 2822-compliant message."""
-
-    def __init__(self, fp, seekable = 1):
-        """Initialize the class instance and read the headers."""
-        if seekable == 1:
-            # Exercise tell() to make sure it works
-            # (and then assume seek() works, too)
-            try:
-                fp.tell()
-            except (AttributeError, IOError):
-                seekable = 0
-        self.fp = fp
-        self.seekable = seekable
-        self.startofheaders = None
-        self.startofbody = None
-        #
-        if self.seekable:
-            try:
-                self.startofheaders = self.fp.tell()
-            except IOError:
-                self.seekable = 0
-        #
-        self.readheaders()
-        #
-        if self.seekable:
-            try:
-                self.startofbody = self.fp.tell()
-            except IOError:
-                self.seekable = 0
-
-    def rewindbody(self):
-        """Rewind the file to the start of the body (if seekable)."""
-        if not self.seekable:
-            raise IOError("unseekable file")
-        self.fp.seek(self.startofbody)
-
-    def readheaders(self):
-        """Read header lines.
-
-        Read header lines up to the entirely blank line that terminates them.
-        The (normally blank) line that ends the headers is skipped, but not
-        included in the returned list.  If a non-header line ends the headers,
-        (which is an error), an attempt is made to backspace over it; it is
-        never included in the returned list.
-
-        The variable self.status is set to the empty string if all went well,
-        otherwise it is an error message.  The variable self.headers is a
-        completely uninterpreted list of lines contained in the header (so
-        printing them will reproduce the header exactly as it appears in the
-        file).
-        """
-        self.dict = {}
-        self.unixfrom = ''
-        self.headers = lst = []
-        self.status = ''
-        headerseen = ""
-        firstline = 1
-        startofline = unread = tell = None
-        if hasattr(self.fp, 'unread'):
-            unread = self.fp.unread
-        elif self.seekable:
-            tell = self.fp.tell
-        while 1:
-            if tell:
-                try:
-                    startofline = tell()
-                except IOError:
-                    startofline = tell = None
-                    self.seekable = 0
-            line = self.fp.readline()
-            if not line:
-                self.status = 'EOF in headers'
-                break
-            # Skip unix From name time lines
-            if firstline and line.startswith('From '):
-                self.unixfrom = self.unixfrom + line
-                continue
-            firstline = 0
-            if headerseen and line[0] in ' \t':
-                # It's a continuation line.
-                lst.append(line)
-                x = (self.dict[headerseen] + "\n " + line.strip())
-                self.dict[headerseen] = x.strip()
-                continue
-            elif self.iscomment(line):
-                # It's a comment.  Ignore it.
-                continue
-            elif self.islast(line):
-                # Note! No pushback here!  The delimiter line gets eaten.
-                break
-            headerseen = self.isheader(line)
-            if headerseen:
-                # It's a legal header line, save it.
-                lst.append(line)
-                self.dict[headerseen] = line[len(headerseen)+1:].strip()
-                continue
-            else:
-                # It's not a header line; throw it back and stop here.
-                if not self.dict:
-                    self.status = 'No headers'
-                else:
-                    self.status = 'Non-header line where header expected'
-                # Try to undo the read.
-                if unread:
-                    unread(line)
-                elif tell:
-                    self.fp.seek(startofline)
-                else:
-                    self.status = self.status + '; bad seek'
-                break
-
-    def isheader(self, line):
-        """Determine whether a given line is a legal header.
-
-        This method should return the header name, suitably canonicalized.
-        You may override this method in order to use Message parsing on tagged
-        data in RFC 2822-like formats with special header formats.
-        """
-        i = line.find(':')
-        if i > 0:
-            return line[:i].lower()
-        return None
-
-    def islast(self, line):
-        """Determine whether a line is a legal end of RFC 2822 headers.
-
-        You may override this method if your application wants to bend the
-        rules, e.g. to strip trailing whitespace, or to recognize MH template
-        separators ('--------').  For convenience (e.g. for code reading from
-        sockets) a line consisting of \r\n also matches.
-        """
-        return line in _blanklines
-
-    def iscomment(self, line):
-        """Determine whether a line should be skipped entirely.
-
-        You may override this method in order to use Message parsing on tagged
-        data in RFC 2822-like formats that support embedded comments or
-        free-text data.
-        """
-        return False
-
-    def getallmatchingheaders(self, name):
-        """Find all header lines matching a given header name.
-
-        Look through the list of headers and find all lines matching a given
-        header name (and their continuation lines).  A list of the lines is
-        returned, without interpretation.  If the header does not occur, an
-        empty list is returned.  If the header occurs multiple times, all
-        occurrences are returned.  Case is not important in the header name.
-        """
-        name = name.lower() + ':'
-        n = len(name)
-        lst = []
-        hit = 0
-        for line in self.headers:
-            if line[:n].lower() == name:
-                hit = 1
-            elif not line[:1].isspace():
-                hit = 0
-            if hit:
-                lst.append(line)
-        return lst
-
-    def getfirstmatchingheader(self, name):
-        """Get the first header line matching name.
-
-        This is similar to getallmatchingheaders, but it returns only the
-        first matching header (and its continuation lines).
-        """
-        name = name.lower() + ':'
-        n = len(name)
-        lst = []
-        hit = 0
-        for line in self.headers:
-            if hit:
-                if not line[:1].isspace():
-                    break
-            elif line[:n].lower() == name:
-                hit = 1
-            if hit:
-                lst.append(line)
-        return lst
-
-    def getrawheader(self, name):
-        """A higher-level interface to getfirstmatchingheader().
-
-        Return a string containing the literal text of the header but with the
-        keyword stripped.  All leading, trailing and embedded whitespace is
-        kept in the string, however.  Return None if the header does not
-        occur.
-        """
-
-        lst = self.getfirstmatchingheader(name)
-        if not lst:
-            return None
-        lst[0] = lst[0][len(name) + 1:]
-        return ''.join(lst)
-
-    def getheader(self, name, default=None):
-        """Get the header value for a name.
-
-        This is the normal interface: it returns a stripped version of the
-        header value for a given header name, or None if it doesn't exist.
-        This uses the dictionary version which finds the *last* such header.
-        """
-        return self.dict.get(name.lower(), default)
-    get = getheader
-
-    def getheaders(self, name):
-        """Get all values for a header.
-
-        This returns a list of values for headers given more than once; each
-        value in the result list is stripped in the same way as the result of
-        getheader().  If the header is not given, return an empty list.
-        """
-        result = []
-        current = ''
-        have_header = 0
-        for s in self.getallmatchingheaders(name):
-            if s[0].isspace():
-                if current:
-                    current = "%s\n %s" % (current, s.strip())
-                else:
-                    current = s.strip()
-            else:
-                if have_header:
-                    result.append(current)
-                current = s[s.find(":") + 1:].strip()
-                have_header = 1
-        if have_header:
-            result.append(current)
-        return result
-
-    def getaddr(self, name):
-        """Get a single address from a header, as a tuple.
-
-        An example return value:
-        ('Guido van Rossum', 'guido at cwi.nl')
-        """
-        # New, by Ben Escoto
-        alist = self.getaddrlist(name)
-        if alist:
-            return alist[0]
-        else:
-            return (None, None)
-
-    def getaddrlist(self, name):
-        """Get a list of addresses from a header.
-
-        Retrieves a list of addresses from a header, where each address is a
-        tuple as returned by getaddr().  Scans all named headers, so it works
-        properly with multiple To: or Cc: headers for example.
-        """
-        raw = []
-        for h in self.getallmatchingheaders(name):
-            if h[0] in ' \t':
-                raw.append(h)
-            else:
-                if raw:
-                    raw.append(', ')
-                i = h.find(':')
-                if i > 0:
-                    addr = h[i+1:]
-                raw.append(addr)
-        alladdrs = ''.join(raw)
-        a = AddressList(alladdrs)
-        return a.addresslist
-
-    def getdate(self, name):
-        """Retrieve a date field from a header.
-
-        Retrieves a date field from the named header, returning a tuple
-        compatible with time.mktime().
-        """
-        try:
-            data = self[name]
-        except KeyError:
-            return None
-        return parsedate(data)
-
-    def getdate_tz(self, name):
-        """Retrieve a date field from a header as a 10-tuple.
-
-        The first 9 elements make up a tuple compatible with time.mktime(),
-        and the 10th is the offset of the poster's time zone from GMT/UTC.
-        """
-        try:
-            data = self[name]
-        except KeyError:
-            return None
-        return parsedate_tz(data)
-
-
-    # Access as a dictionary (only finds *last* header of each type):
-
-    def __len__(self):
-        """Get the number of headers in a message."""
-        return len(self.dict)
-
-    def __getitem__(self, name):
-        """Get a specific header, as from a dictionary."""
-        return self.dict[name.lower()]
-
-    def __setitem__(self, name, value):
-        """Set the value of a header.
-
-        Note: This is not a perfect inversion of __getitem__, because any
-        changed headers get stuck at the end of the raw-headers list rather
-        than where the altered header was.
-        """
-        del self[name] # Won't fail if it doesn't exist
-        self.dict[name.lower()] = value
-        text = name + ": " + value
-        for line in text.split("\n"):
-            self.headers.append(line + "\n")
-
-    def __delitem__(self, name):
-        """Delete all occurrences of a specific header, if it is present."""
-        name = name.lower()
-        if not name in self.dict:
-            return
-        del self.dict[name]
-        name = name + ':'
-        n = len(name)
-        lst = []
-        hit = 0
-        for i in range(len(self.headers)):
-            line = self.headers[i]
-            if line[:n].lower() == name:
-                hit = 1
-            elif not line[:1].isspace():
-                hit = 0
-            if hit:
-                lst.append(i)
-        for i in reversed(lst):
-            del self.headers[i]
-
-    def setdefault(self, name, default=""):
-        lowername = name.lower()
-        if lowername in self.dict:
-            return self.dict[lowername]
-        else:
-            text = name + ": " + default
-            for line in text.split("\n"):
-                self.headers.append(line + "\n")
-            self.dict[lowername] = default
-            return default
-
-    def __contains__(self, name):
-        """Determine whether a message contains the named header."""
-        return name.lower() in self.dict
-
-    def __iter__(self):
-        return iter(self.dict)
-
-    def keys(self):
-        """Get all of a message's header field names."""
-        return list(self.dict.keys())
-
-    def values(self):
-        """Get all of a message's header field values."""
-        return list(self.dict.values())
-
-    def items(self):
-        """Get all of a message's headers.
-
-        Returns a list of name, value tuples.
-        """
-        return list(self.dict.items())
-
-    def __str__(self):
-        return ''.join(self.headers)
-
-
-# Utility functions
-# -----------------
-
-# XXX Should fix unquote() and quote() to be really conformant.
-# XXX The inverses of the parse functions may also be useful.
-
-
-def unquote(s):
-    """Remove quotes from a string."""
-    if len(s) > 1:
-        if s.startswith('"') and s.endswith('"'):
-            return s[1:-1].replace('\\\\', '\\').replace('\\"', '"')
-        if s.startswith('<') and s.endswith('>'):
-            return s[1:-1]
-    return s
-
-
-def quote(s):
-    """Add quotes around a string."""
-    return s.replace('\\', '\\\\').replace('"', '\\"')
-
-
-def parseaddr(address):
-    """Parse an address into a (realname, mailaddr) tuple."""
-    a = AddressList(address)
-    lst = a.addresslist
-    if not lst:
-        return (None, None)
-    return lst[0]
-
-
-class AddrlistClass:
-    """Address parser class by Ben Escoto.
-
-    To understand what this class does, it helps to have a copy of
-    RFC 2822 in front of you.
-
-    http://www.faqs.org/rfcs/rfc2822.html
-
-    Note: this class interface is deprecated and may be removed in the future.
-    Use rfc822.AddressList instead.
-    """
-
-    def __init__(self, field):
-        """Initialize a new instance.
-
-        `field' is an unparsed address header field, containing one or more
-        addresses.
-        """
-        self.specials = '()<>@,:;.\"[]'
-        self.pos = 0
-        self.LWS = ' \t'
-        self.CR = '\r\n'
-        self.atomends = self.specials + self.LWS + self.CR
-        # Note that RFC 2822 now specifies `.' as obs-phrase, meaning that it
-        # is obsolete syntax.  RFC 2822 requires that we recognize obsolete
-        # syntax, so allow dots in phrases.
-        self.phraseends = self.atomends.replace('.', '')
-        self.field = field
-        self.commentlist = []
-
-    def gotonext(self):
-        """Parse up to the start of the next address."""
-        while self.pos < len(self.field):
-            if self.field[self.pos] in self.LWS + '\n\r':
-                self.pos = self.pos + 1
-            elif self.field[self.pos] == '(':
-                self.commentlist.append(self.getcomment())
-            else: break
-
-    def getaddrlist(self):
-        """Parse all addresses.
-
-        Returns a list containing all of the addresses.
-        """
-        result = []
-        ad = self.getaddress()
-        while ad:
-            result += ad
-            ad = self.getaddress()
-        return result
-
-    def getaddress(self):
-        """Parse the next address."""
-        self.commentlist = []
-        self.gotonext()
-
-        oldpos = self.pos
-        oldcl = self.commentlist
-        plist = self.getphraselist()
-
-        self.gotonext()
-        returnlist = []
-
-        if self.pos >= len(self.field):
-            # Bad email address technically, no domain.
-            if plist:
-                returnlist = [(' '.join(self.commentlist), plist[0])]
-
-        elif self.field[self.pos] in '.@':
-            # email address is just an addrspec
-            # this isn't very efficient since we start over
-            self.pos = oldpos
-            self.commentlist = oldcl
-            addrspec = self.getaddrspec()
-            returnlist = [(' '.join(self.commentlist), addrspec)]
-
-        elif self.field[self.pos] == ':':
-            # address is a group
-            returnlist = []
-
-            fieldlen = len(self.field)
-            self.pos += 1
-            while self.pos < len(self.field):
-                self.gotonext()
-                if self.pos < fieldlen and self.field[self.pos] == ';':
-                    self.pos += 1
-                    break
-                returnlist = returnlist + self.getaddress()
-
-        elif self.field[self.pos] == '<':
-            # Address is a phrase then a route addr
-            routeaddr = self.getrouteaddr()
-
-            if self.commentlist:
-                returnlist = [(' '.join(plist) + ' (' + \
-                         ' '.join(self.commentlist) + ')', routeaddr)]
-            else: returnlist = [(' '.join(plist), routeaddr)]
-
-        else:
-            if plist:
-                returnlist = [(' '.join(self.commentlist), plist[0])]
-            elif self.field[self.pos] in self.specials:
-                self.pos += 1
-
-        self.gotonext()
-        if self.pos < len(self.field) and self.field[self.pos] == ',':
-            self.pos += 1
-        return returnlist
-
-    def getrouteaddr(self):
-        """Parse a route address (Return-path value).
-
-        This method just skips all the route stuff and returns the addrspec.
-        """
-        if self.field[self.pos] != '<':
-            return
-
-        expectroute = 0
-        self.pos += 1
-        self.gotonext()
-        adlist = ""
-        while self.pos < len(self.field):
-            if expectroute:
-                self.getdomain()
-                expectroute = 0
-            elif self.field[self.pos] == '>':
-                self.pos += 1
-                break
-            elif self.field[self.pos] == '@':
-                self.pos += 1
-                expectroute = 1
-            elif self.field[self.pos] == ':':
-                self.pos += 1
-            else:
-                adlist = self.getaddrspec()
-                self.pos += 1
-                break
-            self.gotonext()
-
-        return adlist
-
-    def getaddrspec(self):
-        """Parse an RFC 2822 addr-spec."""
-        aslist = []
-
-        self.gotonext()
-        while self.pos < len(self.field):
-            if self.field[self.pos] == '.':
-                aslist.append('.')
-                self.pos += 1
-            elif self.field[self.pos] == '"':
-                aslist.append('"%s"' % self.getquote())
-            elif self.field[self.pos] in self.atomends:
-                break
-            else: aslist.append(self.getatom())
-            self.gotonext()
-
-        if self.pos >= len(self.field) or self.field[self.pos] != '@':
-            return ''.join(aslist)
-
-        aslist.append('@')
-        self.pos += 1
-        self.gotonext()
-        return ''.join(aslist) + self.getdomain()
-
-    def getdomain(self):
-        """Get the complete domain name from an address."""
-        sdlist = []
-        while self.pos < len(self.field):
-            if self.field[self.pos] in self.LWS:
-                self.pos += 1
-            elif self.field[self.pos] == '(':
-                self.commentlist.append(self.getcomment())
-            elif self.field[self.pos] == '[':
-                sdlist.append(self.getdomainliteral())
-            elif self.field[self.pos] == '.':
-                self.pos += 1
-                sdlist.append('.')
-            elif self.field[self.pos] in self.atomends:
-                break
-            else: sdlist.append(self.getatom())
-        return ''.join(sdlist)
-
-    def getdelimited(self, beginchar, endchars, allowcomments = 1):
-        """Parse a header fragment delimited by special characters.
-
-        `beginchar' is the start character for the fragment.  If self is not
-        looking at an instance of `beginchar' then getdelimited returns the
-        empty string.
-
-        `endchars' is a sequence of allowable end-delimiting characters.
-        Parsing stops when one of these is encountered.
-
-        If `allowcomments' is non-zero, embedded RFC 2822 comments are allowed
-        within the parsed fragment.
-        """
-        if self.field[self.pos] != beginchar:
-            return ''
-
-        slist = ['']
-        quote = 0
-        self.pos += 1
-        while self.pos < len(self.field):
-            if quote == 1:
-                slist.append(self.field[self.pos])
-                quote = 0
-            elif self.field[self.pos] in endchars:
-                self.pos += 1
-                break
-            elif allowcomments and self.field[self.pos] == '(':
-                slist.append(self.getcomment())
-                continue        # have already advanced pos from getcomment
-            elif self.field[self.pos] == '\\':
-                quote = 1
-            else:
-                slist.append(self.field[self.pos])
-            self.pos += 1
-
-        return ''.join(slist)
-
-    def getquote(self):
-        """Get a quote-delimited fragment from self's field."""
-        return self.getdelimited('"', '"\r', 0)
-
-    def getcomment(self):
-        """Get a parenthesis-delimited fragment from self's field."""
-        return self.getdelimited('(', ')\r', 1)
-
-    def getdomainliteral(self):
-        """Parse an RFC 2822 domain-literal."""
-        return '[%s]' % self.getdelimited('[', ']\r', 0)
-
-    def getatom(self, atomends=None):
-        """Parse an RFC 2822 atom.
-
-        Optional atomends specifies a different set of end token delimiters
-        (the default is to use self.atomends).  This is used e.g. in
-        getphraselist() since phrase endings must not include the `.' (which
-        is legal in phrases)."""
-        atomlist = ['']
-        if atomends is None:
-            atomends = self.atomends
-
-        while self.pos < len(self.field):
-            if self.field[self.pos] in atomends:
-                break
-            else: atomlist.append(self.field[self.pos])
-            self.pos += 1
-
-        return ''.join(atomlist)
-
-    def getphraselist(self):
-        """Parse a sequence of RFC 2822 phrases.
-
-        A phrase is a sequence of words, which are in turn either RFC 2822
-        atoms or quoted-strings.  Phrases are canonicalized by squeezing all
-        runs of continuous whitespace into one space.
-        """
-        plist = []
-
-        while self.pos < len(self.field):
-            if self.field[self.pos] in self.LWS:
-                self.pos += 1
-            elif self.field[self.pos] == '"':
-                plist.append(self.getquote())
-            elif self.field[self.pos] == '(':
-                self.commentlist.append(self.getcomment())
-            elif self.field[self.pos] in self.phraseends:
-                break
-            else:
-                plist.append(self.getatom(self.phraseends))
-
-        return plist
-
-class AddressList(AddrlistClass):
-    """An AddressList encapsulates a list of parsed RFC 2822 addresses."""
-    def __init__(self, field):
-        AddrlistClass.__init__(self, field)
-        if field:
-            self.addresslist = self.getaddrlist()
-        else:
-            self.addresslist = []
-
-    def __len__(self):
-        return len(self.addresslist)
-
-    def __str__(self):
-        return ", ".join(map(dump_address_pair, self.addresslist))
-
-    def __add__(self, other):
-        # Set union
-        newaddr = AddressList(None)
-        newaddr.addresslist = self.addresslist[:]
-        for x in other.addresslist:
-            if not x in self.addresslist:
-                newaddr.addresslist.append(x)
-        return newaddr
-
-    def __iadd__(self, other):
-        # Set union, in-place
-        for x in other.addresslist:
-            if not x in self.addresslist:
-                self.addresslist.append(x)
-        return self
-
-    def __sub__(self, other):
-        # Set difference
-        newaddr = AddressList(None)
-        for x in self.addresslist:
-            if not x in other.addresslist:
-                newaddr.addresslist.append(x)
-        return newaddr
-
-    def __isub__(self, other):
-        # Set difference, in-place
-        for x in other.addresslist:
-            if x in self.addresslist:
-                self.addresslist.remove(x)
-        return self
-
-    def __getitem__(self, index):
-        # Make indexing, slices, and 'in' work
-        return self.addresslist[index]
-
-def dump_address_pair(pair):
-    """Dump a (name, address) pair in a canonicalized form."""
-    if pair[0]:
-        return '"' + pair[0] + '" <' + pair[1] + '>'
-    else:
-        return pair[1]
-
-# Parse a date field
-
-_monthnames = ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul',
-               'aug', 'sep', 'oct', 'nov', 'dec',
-               'january', 'february', 'march', 'april', 'may', 'june', 'july',
-               'august', 'september', 'october', 'november', 'december']
-_daynames = ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun']
-
-# The timezone table does not include the military time zones defined
-# in RFC822, other than Z.  According to RFC1123, the description in
-# RFC822 gets the signs wrong, so we can't rely on any such time
-# zones.  RFC1123 recommends that numeric timezone indicators be used
-# instead of timezone names.
-
-_timezones = {'UT':0, 'UTC':0, 'GMT':0, 'Z':0,
-              'AST': -400, 'ADT': -300,  # Atlantic (used in Canada)
-              'EST': -500, 'EDT': -400,  # Eastern
-              'CST': -600, 'CDT': -500,  # Central
-              'MST': -700, 'MDT': -600,  # Mountain
-              'PST': -800, 'PDT': -700   # Pacific
-              }
-
-
-def parsedate_tz(data):
-    """Convert a date string to a time tuple.
-
-    Accounts for military timezones.
-    """
-    if not data:
-        return None
-    data = data.split()
-    if data[0][-1] in (',', '.') or data[0].lower() in _daynames:
-        # There's a dayname here. Skip it
-        del data[0]
-    else:
-        # no space after the "weekday,"?
-        i = data[0].rfind(',')
-        if i >= 0:
-            data[0] = data[0][i+1:]
-    if len(data) == 3: # RFC 850 date, deprecated
-        stuff = data[0].split('-')
-        if len(stuff) == 3:
-            data = stuff + data[1:]
-    if len(data) == 4:
-        s = data[3]
-        i = s.find('+')
-        if i > 0:
-            data[3:] = [s[:i], s[i+1:]]
-        else:
-            data.append('') # Dummy tz
-    if len(data) < 5:
-        return None
-    data = data[:5]
-    [dd, mm, yy, tm, tz] = data
-    mm = mm.lower()
-    if not mm in _monthnames:
-        dd, mm = mm, dd.lower()
-        if not mm in _monthnames:
-            return None
-    mm = _monthnames.index(mm)+1
-    if mm > 12: mm = mm - 12
-    if dd[-1] == ',':
-        dd = dd[:-1]
-    i = yy.find(':')
-    if i > 0:
-        yy, tm = tm, yy
-    if yy[-1] == ',':
-        yy = yy[:-1]
-    if not yy[0].isdigit():
-        yy, tz = tz, yy
-    if tm[-1] == ',':
-        tm = tm[:-1]
-    tm = tm.split(':')
-    if len(tm) == 2:
-        [thh, tmm] = tm
-        tss = '0'
-    elif len(tm) == 3:
-        [thh, tmm, tss] = tm
-    else:
-        return None
-    try:
-        yy = int(yy)
-        dd = int(dd)
-        thh = int(thh)
-        tmm = int(tmm)
-        tss = int(tss)
-    except ValueError:
-        return None
-    tzoffset = None
-    tz = tz.upper()
-    if tz in _timezones:
-        tzoffset = _timezones[tz]
-    else:
-        try:
-            tzoffset = int(tz)
-        except ValueError:
-            pass
-    # Convert a timezone offset into seconds ; -0500 -> -18000
-    if tzoffset:
-        if tzoffset < 0:
-            tzsign = -1
-            tzoffset = -tzoffset
-        else:
-            tzsign = 1
-        tzoffset = tzsign * ( (tzoffset//100)*3600 + (tzoffset % 100)*60)
-    return (yy, mm, dd, thh, tmm, tss, 0, 1, 0, tzoffset)
-
-
-def parsedate(data):
-    """Convert a time string to a time tuple."""
-    t = parsedate_tz(data)
-    if t is None:
-        return t
-    return t[:9]
-
-
-def mktime_tz(data):
-    """Turn a 10-tuple as returned by parsedate_tz() into a UTC timestamp."""
-    if data[9] is None:
-        # No zone info, so localtime is better assumption than GMT
-        return time.mktime(data[:8] + (-1,))
-    else:
-        t = time.mktime(data[:8] + (0,))
-        return t - data[9] - time.timezone
-
-def formatdate(timeval=None):
-    """Returns time format preferred for Internet standards.
-
-    Sun, 06 Nov 1994 08:49:37 GMT  ; RFC 822, updated by RFC 1123
-
-    According to RFC 1123, day and month names must always be in
-    English.  If not for that, this code could use strftime().  It
-    can't because strftime() honors the locale and could generated
-    non-English names.
-    """
-    if timeval is None:
-        timeval = time.time()
-    timeval = time.gmtime(timeval)
-    return "%s, %02d %s %04d %02d:%02d:%02d GMT" % (
-            ("Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun")[timeval[6]],
-            timeval[2],
-            ("Jan", "Feb", "Mar", "Apr", "May", "Jun",
-             "Jul", "Aug", "Sep", "Oct", "Nov", "Dec")[timeval[1]-1],
-                                timeval[0], timeval[3], timeval[4], timeval[5])
-
-
-# When used as script, run a small test program.
-# The first command line argument must be a filename containing one
-# message in RFC-822 format.
-
-if __name__ == '__main__':
-    import sys, os
-    file = os.path.join(os.environ['HOME'], 'Mail/inbox/1')
-    if sys.argv[1:]: file = sys.argv[1]
-    f = open(file, 'r')
-    m = Message(f)
-    print('From:', m.getaddr('from'))
-    print('To:', m.getaddrlist('to'))
-    print('Subject:', m.getheader('subject'))
-    print('Date:', m.getheader('date'))
-    date = m.getdate_tz('date')
-    tz = date[-1]
-    date = time.localtime(mktime_tz(date))
-    if date:
-        print('ParsedDate:', time.asctime(date), end=' ')
-        hhmmss = tz
-        hhmm, ss = divmod(hhmmss, 60)
-        hh, mm = divmod(hhmm, 60)
-        print("%+03d%02d" % (hh, mm), end=' ')
-        if ss: print(".%02d" % ss, end=' ')
-        print()
-    else:
-        print('ParsedDate:', None)
-    m.rewindbody()
-    n = 0
-    while f.readline():
-        n += 1
-    print('Lines:', n)
-    print('-'*70)
-    print('len =', len(m))
-    if 'Date' in m: print('Date =', m['Date'])
-    if 'X-Nonsense' in m: pass
-    print('keys =', m.keys())
-    print('values =', m.values())
-    print('items =', m.items())

Modified: python/branches/py3k/Lib/test/test_pyclbr.py
==============================================================================
--- python/branches/py3k/Lib/test/test_pyclbr.py	(original)
+++ python/branches/py3k/Lib/test/test_pyclbr.py	Fri Jun 13 00:15:50 2008
@@ -141,7 +141,6 @@
     def test_easy(self):
         self.checkModule('pyclbr')
         self.checkModule('doctest', ignore=("TestResults", "_SpoofOut"))
-        self.checkModule('rfc822')
         self.checkModule('difflib', ignore=("Match",))
 
     def test_decorators(self):

Deleted: python/branches/py3k/Lib/test/test_rfc822.py
==============================================================================
--- python/branches/py3k/Lib/test/test_rfc822.py	Fri Jun 13 00:15:50 2008
+++ (empty file)
@@ -1,256 +0,0 @@
-import rfc822
-import unittest
-from test import support
-
-try:
-    from io import StringIO
-except ImportError:
-    from io import StringIO
-
-
-class MessageTestCase(unittest.TestCase):
-    def create_message(self, msg):
-        return rfc822.Message(StringIO(msg))
-
-    def test_get(self):
-        msg = self.create_message(
-            'To: "last, first" <userid at foo.net>\n\ntest\n')
-        self.assert_(msg.get("to") == '"last, first" <userid at foo.net>')
-        self.assert_(msg.get("TO") == '"last, first" <userid at foo.net>')
-        self.assert_(msg.get("No-Such-Header") is None)
-        self.assert_(msg.get("No-Such-Header", "No-Such-Value")
-                     == "No-Such-Value")
-
-    def test_setdefault(self):
-        msg = self.create_message(
-            'To: "last, first" <userid at foo.net>\n\ntest\n')
-        self.assert_("New-Header" not in msg)
-        self.assert_(msg.setdefault("New-Header", "New-Value") == "New-Value")
-        self.assert_(msg.setdefault("New-Header", "Different-Value")
-                     == "New-Value")
-        self.assertEqual(msg["new-header"], "New-Value")
-
-        self.assertEqual(msg.setdefault("Another-Header"), "")
-        self.assertEqual(msg["another-header"], "")
-
-    def check(self, msg, results):
-        """Check addresses and the date."""
-        m = self.create_message(msg)
-        i = 0
-        for n, a in m.getaddrlist('to') + m.getaddrlist('cc'):
-            try:
-                mn, ma = results[i][0], results[i][1]
-            except IndexError:
-                print('extra parsed address:', repr(n), repr(a))
-                continue
-            i = i + 1
-            self.assertEqual(mn, n,
-                             "Un-expected name: %r != %r" % (mn, n))
-            self.assertEqual(ma, a,
-                             "Un-expected address: %r != %r" % (ma, a))
-            if mn == n and ma == a:
-                pass
-            else:
-                print('not found:', repr(n), repr(a))
-
-        out = m.getdate('date')
-        if out:
-            self.assertEqual(out,
-                             (1999, 1, 13, 23, 57, 35, 0, 1, 0),
-                             "date conversion failed")
-
-
-    # Note: all test cases must have the same date (in various formats),
-    # or no date!
-
-    def test_basic(self):
-        self.check(
-            'Date:    Wed, 13 Jan 1999 23:57:35 -0500\n'
-            'From:    Guido van Rossum <guido at CNRI.Reston.VA.US>\n'
-            'To:      "Guido van\n'
-            '\t : Rossum" <guido at python.org>\n'
-            'Subject: test2\n'
-            '\n'
-            'test2\n',
-            [('Guido van\n\t : Rossum', 'guido at python.org')])
-
-        self.check(
-            'From: Barry <bwarsaw at python.org\n'
-            'To: guido at python.org (Guido: the Barbarian)\n'
-            'Subject: nonsense\n'
-            'Date: Wednesday, January 13 1999 23:57:35 -0500\n'
-            '\n'
-            'test',
-            [('Guido: the Barbarian', 'guido at python.org')])
-
-        self.check(
-            'From: Barry <bwarsaw at python.org\n'
-            'To: guido at python.org (Guido: the Barbarian)\n'
-            'Cc: "Guido: the Madman" <guido at python.org>\n'
-            'Date:  13-Jan-1999 23:57:35 EST\n'
-            '\n'
-            'test',
-            [('Guido: the Barbarian', 'guido at python.org'),
-             ('Guido: the Madman', 'guido at python.org')
-             ])
-
-        self.check(
-            'To: "The monster with\n'
-            '     the very long name: Guido" <guido at python.org>\n'
-            'Date:    Wed, 13 Jan 1999 23:57:35 -0500\n'
-            '\n'
-            'test',
-            [('The monster with\n     the very long name: Guido',
-              'guido at python.org')])
-
-        self.check(
-            'To: "Amit J. Patel" <amitp at Theory.Stanford.EDU>\n'
-            'CC: Mike Fletcher <mfletch at vrtelecom.com>,\n'
-            '        "\'string-sig at python.org\'" <string-sig at python.org>\n'
-            'Cc: fooz at bat.com, bart at toof.com\n'
-            'Cc: goit at lip.com\n'
-            'Date:    Wed, 13 Jan 1999 23:57:35 -0500\n'
-            '\n'
-            'test',
-            [('Amit J. Patel', 'amitp at Theory.Stanford.EDU'),
-             ('Mike Fletcher', 'mfletch at vrtelecom.com'),
-             ("'string-sig at python.org'", 'string-sig at python.org'),
-             ('', 'fooz at bat.com'),
-             ('', 'bart at toof.com'),
-             ('', 'goit at lip.com'),
-             ])
-
-        self.check(
-            'To: Some One <someone at dom.ain>\n'
-            'From: Anudder Persin <subuddy.else at dom.ain>\n'
-            'Date:\n'
-            '\n'
-            'test',
-            [('Some One', 'someone at dom.ain')])
-
-        self.check(
-            'To: person at dom.ain (User J. Person)\n\n',
-            [('User J. Person', 'person at dom.ain')])
-
-    def test_doublecomment(self):
-        # The RFC allows comments within comments in an email addr
-        self.check(
-            'To: person at dom.ain ((User J. Person)), John Doe <foo at bar.com>\n\n',
-            [('User J. Person', 'person at dom.ain'), ('John Doe', 'foo at bar.com')])
-
-    def test_twisted(self):
-        # This one is just twisted.  I don't know what the proper
-        # result should be, but it shouldn't be to infloop, which is
-        # what used to happen!
-        self.check(
-            'To: <[smtp:dd47 at mail.xxx.edu]_at_hmhq at hdq-mdm1-imgout.companay.com>\n'
-            'Date:    Wed, 13 Jan 1999 23:57:35 -0500\n'
-            '\n'
-            'test',
-            [('', ''),
-             ('', 'dd47 at mail.xxx.edu'),
-             ('', '_at_hmhq at hdq-mdm1-imgout.companay.com'),
-             ])
-
-    def test_commas_in_full_name(self):
-        # This exercises the old commas-in-a-full-name bug, which
-        # should be doing the right thing in recent versions of the
-        # module.
-        self.check(
-            'To: "last, first" <userid at foo.net>\n'
-            '\n'
-            'test',
-            [('last, first', 'userid at foo.net')])
-
-    def test_quoted_name(self):
-        self.check(
-            'To: (Comment stuff) "Quoted name"@somewhere.com\n'
-            '\n'
-            'test',
-            [('Comment stuff', '"Quoted name"@somewhere.com')])
-
-    def test_bogus_to_header(self):
-        self.check(
-            'To: :\n'
-            'Cc: goit at lip.com\n'
-            'Date:    Wed, 13 Jan 1999 23:57:35 -0500\n'
-            '\n'
-            'test',
-            [('', 'goit at lip.com')])
-
-    def test_addr_ipquad(self):
-        self.check(
-            'To: guido@[132.151.1.21]\n'
-            '\n'
-            'foo',
-            [('', 'guido@[132.151.1.21]')])
-
-    def test_iter(self):
-        m = rfc822.Message(StringIO(
-            'Date:    Wed, 13 Jan 1999 23:57:35 -0500\n'
-            'From:    Guido van Rossum <guido at CNRI.Reston.VA.US>\n'
-            'To:      "Guido van\n'
-            '\t : Rossum" <guido at python.org>\n'
-            'Subject: test2\n'
-            '\n'
-            'test2\n' ))
-        self.assertEqual(sorted(m), ['date', 'from', 'subject', 'to'])
-
-    def test_rfc2822_phrases(self):
-        # RFC 2822 (the update to RFC 822) specifies that dots in phrases are
-        # obsolete syntax, which conforming programs MUST recognize but NEVER
-        # generate (see $4.1 Miscellaneous obsolete tokens).  This is a
-        # departure from RFC 822 which did not allow dots in non-quoted
-        # phrases.
-        self.check('To: User J. Person <person at dom.ain>\n\n',
-                   [('User J. Person', 'person at dom.ain')])
-
-    # This takes too long to add to the test suite
-##    def test_an_excrutiatingly_long_address_field(self):
-##        OBSCENELY_LONG_HEADER_MULTIPLIER = 10000
-##        oneaddr = ('Person' * 10) + '@' + ('.'.join(['dom']*10)) + '.com'
-##        addr = ', '.join([oneaddr] * OBSCENELY_LONG_HEADER_MULTIPLIER)
-##        lst = rfc822.AddrlistClass(addr).getaddrlist()
-##        self.assertEqual(len(lst), OBSCENELY_LONG_HEADER_MULTIPLIER)
-
-    def test_2getaddrlist(self):
-        eq = self.assertEqual
-        msg = self.create_message("""\
-To: aperson at dom.ain
-Cc: bperson at dom.ain
-Cc: cperson at dom.ain
-Cc: dperson at dom.ain
-
-A test message.
-""")
-        ccs = [('', a) for a in
-               ['bperson at dom.ain', 'cperson at dom.ain', 'dperson at dom.ain']]
-        addrs = msg.getaddrlist('cc')
-        addrs.sort()
-        eq(addrs, ccs)
-        # Try again, this one used to fail
-        addrs = msg.getaddrlist('cc')
-        addrs.sort()
-        eq(addrs, ccs)
-
-    def test_parseaddr(self):
-        eq = self.assertEqual
-        eq(rfc822.parseaddr('<>'), ('', ''))
-        eq(rfc822.parseaddr('aperson at dom.ain'), ('', 'aperson at dom.ain'))
-        eq(rfc822.parseaddr('bperson at dom.ain (Bea A. Person)'),
-           ('Bea A. Person', 'bperson at dom.ain'))
-        eq(rfc822.parseaddr('Cynthia Person <cperson at dom.ain>'),
-           ('Cynthia Person', 'cperson at dom.ain'))
-
-    def test_quote_unquote(self):
-        eq = self.assertEqual
-        eq(rfc822.quote('foo\\wacky"name'), 'foo\\\\wacky\\"name')
-        eq(rfc822.unquote('"foo\\\\wacky\\"name"'), 'foo\\wacky"name')
-
-
-def test_main():
-    support.run_unittest(MessageTestCase)
-
-
-if __name__ == "__main__":
-    test_main()

Modified: python/branches/py3k/Lib/test/test_urllib2.py
==============================================================================
--- python/branches/py3k/Lib/test/test_urllib2.py	(original)
+++ python/branches/py3k/Lib/test/test_urllib2.py	Fri Jun 13 00:15:50 2008
@@ -586,7 +586,7 @@
             self.assertEqual(int(headers["Content-length"]), len(data))
 
     def test_file(self):
-        import rfc822, socket
+        import email.utils, socket
         h = urllib2.FileHandler()
         o = h.parent = MockOpener()
 
@@ -621,7 +621,7 @@
                 finally:
                     r.close()
                 stats = os.stat(TESTFN)
-                modified = rfc822.formatdate(stats.st_mtime)
+                modified = email.utils.formatdate(stats.st_mtime, usegmt=True)
             finally:
                 os.remove(TESTFN)
             self.assertEqual(data, towrite)

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Fri Jun 13 00:15:50 2008
@@ -78,6 +78,8 @@
 Library
 -------
 
+- rfc822 has been removed in favor of the email package.
+
 - mimetools has been removed in favor of the email package.
 
 - Patch #2849: Remove use of rfc822 module from standard library.

From python-3000-checkins at python.org  Fri Jun 13 00:23:59 2008
From: python-3000-checkins at python.org (georg.brandl)
Date: Fri, 13 Jun 2008 00:23:59 +0200 (CEST)
Subject: [Python-3000-checkins] r64204 - in python/branches/py3k:
	Lib/http/server.py Lib/smtplib.py Lib/test/test_pyclbr.py
	Tools/faqwiz/faqwiz.py Tools/scripts/mailerdaemon.py
	Tools/versioncheck/pyversioncheck.py
Message-ID: <20080612222359.D4C9E1E4010@bag.python.org>

Author: georg.brandl
Date: Fri Jun 13 00:23:59 2008
New Revision: 64204

Log:
Remove traces of rfc822.


Modified:
   python/branches/py3k/Lib/http/server.py
   python/branches/py3k/Lib/smtplib.py
   python/branches/py3k/Lib/test/test_pyclbr.py
   python/branches/py3k/Tools/faqwiz/faqwiz.py
   python/branches/py3k/Tools/scripts/mailerdaemon.py
   python/branches/py3k/Tools/versioncheck/pyversioncheck.py

Modified: python/branches/py3k/Lib/http/server.py
==============================================================================
--- python/branches/py3k/Lib/http/server.py	(original)
+++ python/branches/py3k/Lib/http/server.py	Fri Jun 13 00:23:59 2008
@@ -315,7 +315,7 @@
 
         # Examine the headers and look for a Connection directive.
 
-        # MessageClass (rfc822) wants to see strings rather than bytes.
+        # MessageClass wants to see strings rather than bytes.
         # But a TextIOWrapper around self.rfile would buffer too many bytes
         # from the stream, bytes which we later need to read as bytes.
         # So we read the correct bytes here, as bytes, then use StringIO

Modified: python/branches/py3k/Lib/smtplib.py
==============================================================================
--- python/branches/py3k/Lib/smtplib.py	(original)
+++ python/branches/py3k/Lib/smtplib.py	Fri Jun 13 00:23:59 2008
@@ -131,7 +131,7 @@
 def quoteaddr(addr):
     """Quote a subset of the email addresses defined by RFC 821.
 
-    Should be able to handle anything rfc822.parseaddr can handle.
+    Should be able to handle anything email.utils.parseaddr can handle.
     """
     m = (None, None)
     try:

Modified: python/branches/py3k/Lib/test/test_pyclbr.py
==============================================================================
--- python/branches/py3k/Lib/test/test_pyclbr.py	(original)
+++ python/branches/py3k/Lib/test/test_pyclbr.py	Fri Jun 13 00:23:59 2008
@@ -140,6 +140,7 @@
 
     def test_easy(self):
         self.checkModule('pyclbr')
+        self.checkModule('ast')
         self.checkModule('doctest', ignore=("TestResults", "_SpoofOut"))
         self.checkModule('difflib', ignore=("Match",))
 

Modified: python/branches/py3k/Tools/faqwiz/faqwiz.py
==============================================================================
--- python/branches/py3k/Tools/faqwiz/faqwiz.py	(original)
+++ python/branches/py3k/Tools/faqwiz/faqwiz.py	Fri Jun 13 00:23:59 2008
@@ -207,8 +207,8 @@
         self.file = file
         self.sec, self.num = sec_num
         if fp:
-            import rfc822
-            self.__headers = rfc822.Message(fp)
+            import email
+            self.__headers = email.message_from_file(fp)
             self.body = fp.read().strip()
         else:
             self.__headers = {'title': "%d.%d. " % sec_num}

Modified: python/branches/py3k/Tools/scripts/mailerdaemon.py
==============================================================================
--- python/branches/py3k/Tools/scripts/mailerdaemon.py	(original)
+++ python/branches/py3k/Tools/scripts/mailerdaemon.py	Fri Jun 13 00:23:59 2008
@@ -1,16 +1,16 @@
 """mailerdaemon - classes to parse mailer-daemon messages"""
 
-import rfc822
 import calendar
+import email.message
 import re
 import os
 import sys
 
 Unparseable = 'mailerdaemon.Unparseable'
 
-class ErrorMessage(rfc822.Message):
-    def __init__(self, fp):
-        rfc822.Message.__init__(self, fp)
+class ErrorMessage(email.message.Message):
+    def __init__(self):
+        email.message.Message.__init__(self)
         self.sub = ''
 
     def is_warning(self):
@@ -169,7 +169,7 @@
     for fn in files:
         # Lets try to parse the file.
         fp = open(fn)
-        m = ErrorMessage(fp)
+        m = email.message_from_file(fp, _class=ErrorMessage)
         sender = m.getaddr('From')
         print('%s\t%-40s\t'%(fn, sender[1]), end=' ')
 

Modified: python/branches/py3k/Tools/versioncheck/pyversioncheck.py
==============================================================================
--- python/branches/py3k/Tools/versioncheck/pyversioncheck.py	(original)
+++ python/branches/py3k/Tools/versioncheck/pyversioncheck.py	Fri Jun 13 00:23:59 2008
@@ -1,6 +1,6 @@
 """pyversioncheck - Module to help with checking versions"""
-import rfc822
 import urllib
+import email
 import sys
 
 # Verbose options
@@ -52,7 +52,7 @@
         if verbose >= VERBOSE_EACHFILE:
             print('    Cannot open:', arg)
         return -1, None, None
-    msg = rfc822.Message(fp, seekable=0)
+    msg = email.message_from_file(fp)
     newversion = msg.get('current-version')
     if not newversion:
         if verbose >= VERBOSE_EACHFILE:

From python-3000-checkins at python.org  Fri Jun 13 00:27:28 2008
From: python-3000-checkins at python.org (amaury.forgeotdarc)
Date: Fri, 13 Jun 2008 00:27:28 +0200 (CEST)
Subject: [Python-3000-checkins] r64205 - in python/branches/py3k:
	PC/VC6/pythoncore.dsp PC/VS7.1/pythoncore.vcproj
	PC/VS8.0/pythoncore.vcproj PC/config.c PCbuild/pythoncore.vcproj
Message-ID: <20080612222728.2992E1E4002@bag.python.org>

Author: amaury.forgeotdarc
Date: Fri Jun 13 00:27:27 2008
New Revision: 64205

Log:
On Windows, repair compilation of builtin modules _stringio and _pickle.

(Alexandre, the MSVC build files are in PCBuild.
the PC/Vxxx directories try to support older compilers)


Modified:
   python/branches/py3k/PC/VC6/pythoncore.dsp
   python/branches/py3k/PC/VS7.1/pythoncore.vcproj
   python/branches/py3k/PC/VS8.0/pythoncore.vcproj
   python/branches/py3k/PC/config.c
   python/branches/py3k/PCbuild/pythoncore.vcproj

Modified: python/branches/py3k/PC/VC6/pythoncore.dsp
==============================================================================
--- python/branches/py3k/PC/VC6/pythoncore.dsp	(original)
+++ python/branches/py3k/PC/VC6/pythoncore.dsp	Fri Jun 13 00:27:27 2008
@@ -161,6 +161,10 @@
 # End Source File
 # Begin Source File
 
+SOURCE=..\..\Modules\_pickle.c
+# End Source File
+# Begin Source File
+
 SOURCE=..\..\Modules\_randommodule.c
 # End Source File
 # Begin Source File
@@ -169,6 +173,10 @@
 # End Source File
 # Begin Source File
 
+SOURCE=..\..\Modules\_stringio.c
+# End Source File
+# Begin Source File
+
 SOURCE=..\..\Modules\_struct.c
 # End Source File
 # Begin Source File

Modified: python/branches/py3k/PC/VS7.1/pythoncore.vcproj
==============================================================================
--- python/branches/py3k/PC/VS7.1/pythoncore.vcproj	(original)
+++ python/branches/py3k/PC/VS7.1/pythoncore.vcproj	Fri Jun 13 00:27:27 2008
@@ -389,12 +389,18 @@
 			RelativePath="..\..\Modules\_lsprof.c">
 		</File>
 		<File
+			RelativePath="..\..\Modules\_pickle.c">
+		</File>
+		<File
 			RelativePath="..\..\Modules\_randommodule.c">
 		</File>
 		<File
 			RelativePath="..\..\Modules\_sre.c">
 		</File>
 		<File
+			RelativePath="..\..\Modules\_stringio.c">
+		</File>
+		<File
 			RelativePath="..\..\Modules\_struct.c">
 		</File>
 		<File

Modified: python/branches/py3k/PC/VS8.0/pythoncore.vcproj
==============================================================================
--- python/branches/py3k/PC/VS8.0/pythoncore.vcproj	(original)
+++ python/branches/py3k/PC/VS8.0/pythoncore.vcproj	Fri Jun 13 00:27:27 2008
@@ -1011,6 +1011,10 @@
 				>
 			</File>
 			<File
+				RelativePath="..\..\Modules\_pickle.c"
+				>
+			</File>
+			<File
 				RelativePath="..\..\Modules\_randommodule.c"
 				>
 			</File>
@@ -1019,6 +1023,10 @@
 				>
 			</File>
 			<File
+				RelativePath="..\..\Modules\_stringio.c"
+				>
+			</File>
+			<File
 				RelativePath="..\..\Modules\_struct.c"
 				>
 			</File>

Modified: python/branches/py3k/PC/config.c
==============================================================================
--- python/branches/py3k/PC/config.c	(original)
+++ python/branches/py3k/PC/config.c	Fri Jun 13 00:27:27 2008
@@ -60,6 +60,8 @@
 extern PyObject* PyInit__ast(void);
 extern PyObject* PyInit__fileio(void);
 extern PyObject* PyInit__bytesio(void);
+extern PyObject* PyInit__stringio(void);
+extern PyObject* PyInit__pickle(void);
 extern PyObject* PyInit_atexit(void);
 extern PyObject* _PyWarnings_Init(void);
 
@@ -151,6 +153,7 @@
         {"_fileio", PyInit__fileio},
         {"_bytesio", PyInit__bytesio},
         {"_stringio", PyInit__stringio},
+        {"_pickle", PyInit__pickle},
         {"atexit", PyInit_atexit},
 
         /* Sentinel */

Modified: python/branches/py3k/PCbuild/pythoncore.vcproj
==============================================================================
--- python/branches/py3k/PCbuild/pythoncore.vcproj	(original)
+++ python/branches/py3k/PCbuild/pythoncore.vcproj	Fri Jun 13 00:27:27 2008
@@ -1015,6 +1015,10 @@
 				>
 			</File>
 			<File
+				RelativePath="..\Modules\_pickle.c"
+				>
+			</File>
+			<File
 				RelativePath="..\Modules\_randommodule.c"
 				>
 			</File>
@@ -1023,6 +1027,10 @@
 				>
 			</File>
 			<File
+				RelativePath="..\Modules\_stringio.c"
+				>
+			</File>
+			<File
 				RelativePath="..\Modules\_struct.c"
 				>
 			</File>

From python-3000-checkins at python.org  Fri Jun 13 00:34:20 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Fri, 13 Jun 2008 00:34:20 +0200 (CEST)
Subject: [Python-3000-checkins] r64207 - python/branches/py3k
Message-ID: <20080612223420.912CD1E4002@bag.python.org>

Author: benjamin.peterson
Date: Fri Jun 13 00:34:18 2008
New Revision: 64207

Log:
Blocked revisions 64206 via svnmerge

........
  r64206 | benjamin.peterson | 2008-06-12 17:33:06 -0500 (Thu, 12 Jun 2008) | 2 lines
  
  add py3k warnings to  rfc822
........


Modified:
   python/branches/py3k/   (props changed)

From python-3000-checkins at python.org  Fri Jun 13 00:38:07 2008
From: python-3000-checkins at python.org (amaury.forgeotdarc)
Date: Fri, 13 Jun 2008 00:38:07 +0200 (CEST)
Subject: [Python-3000-checkins] r64208 - in python/branches/py3k:
	PCbuild/pcbuild.sln
Message-ID: <20080612223807.B0FF71E4002@bag.python.org>

Author: amaury.forgeotdarc
Date: Fri Jun 13 00:38:07 2008
New Revision: 64208

Log:
Merged revisions 64197 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/trunk

........
  r64197 | amaury.forgeotdarc | 2008-06-12 22:27:42 +0200 (jeu., 12 juin 2008) | 3 lines
  
  It seems that my VS2008 Express does not include a project in the build configuration,
  if its UUID has lowercase letters.
........


Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/PCbuild/pcbuild.sln

Modified: python/branches/py3k/PCbuild/pcbuild.sln
==============================================================================
--- python/branches/py3k/PCbuild/pcbuild.sln	(original)
+++ python/branches/py3k/PCbuild/pcbuild.sln	Fri Jun 13 00:38:07 2008
@@ -131,7 +131,7 @@
 		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31} = {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}
 	EndProjectSection
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_multiprocessing", "_multiprocessing.vcproj", "{9e48b300-37d1-11dd-8c41-005056c00008}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_multiprocessing", "_multiprocessing.vcproj", "{9E48B300-37D1-11DD-8C41-005056C00008}"
 	ProjectSection(ProjectDependencies) = postProject
 		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
 	EndProjectSection
@@ -542,6 +542,22 @@
 		{A1A295E5-463C-437F-81CA-1F32367685DA}.Release|Win32.Build.0 = Release|Win32
 		{A1A295E5-463C-437F-81CA-1F32367685DA}.Release|x64.ActiveCfg = Release|x64
 		{A1A295E5-463C-437F-81CA-1F32367685DA}.Release|x64.Build.0 = Release|x64
+		{9E48B300-37D1-11DD-8C41-005056C00008}.Debug|Win32.ActiveCfg = Debug|Win32
+		{9E48B300-37D1-11DD-8C41-005056C00008}.Debug|Win32.Build.0 = Debug|Win32
+		{9E48B300-37D1-11DD-8C41-005056C00008}.Debug|x64.ActiveCfg = Debug|x64
+		{9E48B300-37D1-11DD-8C41-005056C00008}.Debug|x64.Build.0 = Debug|x64
+		{9E48B300-37D1-11DD-8C41-005056C00008}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
+		{9E48B300-37D1-11DD-8C41-005056C00008}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
+		{9E48B300-37D1-11DD-8C41-005056C00008}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
+		{9E48B300-37D1-11DD-8C41-005056C00008}.PGInstrument|x64.Build.0 = PGInstrument|x64
+		{9E48B300-37D1-11DD-8C41-005056C00008}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
+		{9E48B300-37D1-11DD-8C41-005056C00008}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
+		{9E48B300-37D1-11DD-8C41-005056C00008}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
+		{9E48B300-37D1-11DD-8C41-005056C00008}.PGUpdate|x64.Build.0 = PGUpdate|x64
+		{9E48B300-37D1-11DD-8C41-005056C00008}.Release|Win32.ActiveCfg = Release|Win32
+		{9E48B300-37D1-11DD-8C41-005056C00008}.Release|Win32.Build.0 = Release|Win32
+		{9E48B300-37D1-11DD-8C41-005056C00008}.Release|x64.ActiveCfg = Release|x64
+		{9E48B300-37D1-11DD-8C41-005056C00008}.Release|x64.Build.0 = Release|x64
 		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Debug|Win32.ActiveCfg = Debug|Win32
 		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Debug|Win32.Build.0 = Debug|Win32
 		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Debug|x64.ActiveCfg = Debug|x64
@@ -558,22 +574,6 @@
 		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Release|Win32.Build.0 = Release|Win32
 		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Release|x64.ActiveCfg = Release|x64
 		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Release|x64.Build.0 = Release|x64
-		{9e48b300-37d1-11dd-8c41-005056c00008}.Debug|Win32.ActiveCfg = Debug|Win32
-		{9e48b300-37d1-11dd-8c41-005056c00008}.Debug|Win32.Build.0 = Debug|Win32
-		{9e48b300-37d1-11dd-8c41-005056c00008}.Debug|x64.ActiveCfg = Debug|x64
-		{9e48b300-37d1-11dd-8c41-005056c00008}.Debug|x64.Build.0 = Debug|x64
-		{9e48b300-37d1-11dd-8c41-005056c00008}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
-		{9e48b300-37d1-11dd-8c41-005056c00008}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
-		{9e48b300-37d1-11dd-8c41-005056c00008}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
-		{9e48b300-37d1-11dd-8c41-005056c00008}.PGInstrument|x64.Build.0 = PGInstrument|x64
-		{9e48b300-37d1-11dd-8c41-005056c00008}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
-		{9e48b300-37d1-11dd-8c41-005056c00008}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
-		{9e48b300-37d1-11dd-8c41-005056c00008}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
-		{9e48b300-37d1-11dd-8c41-005056c00008}.PGUpdate|x64.Build.0 = PGUpdate|x64
-		{9e48b300-37d1-11dd-8c41-005056c00008}.Release|Win32.ActiveCfg = Release|Win32
-		{9e48b300-37d1-11dd-8c41-005056c00008}.Release|Win32.Build.0 = Release|Win32
-		{9e48b300-37d1-11dd-8c41-005056c00008}.Release|x64.ActiveCfg = Release|x64
-		{9e48b300-37d1-11dd-8c41-005056c00008}.Release|x64.Build.0 = Release|x64
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE

From python-3000-checkins at python.org  Fri Jun 13 00:53:42 2008
From: python-3000-checkins at python.org (amaury.forgeotdarc)
Date: Fri, 13 Jun 2008 00:53:42 +0200 (CEST)
Subject: [Python-3000-checkins] r64209 - in python/branches/py3k:
	PC/VS8.0/_bsddb.vcproj PC/VS8.0/_elementtree.vcproj
	PC/VS8.0/_sqlite3.vcproj PC/VS8.0/_ssl.vcproj
	PC/VS8.0/_tkinter.vcproj PC/VS8.0/bdist_wininst.vcproj
	PC/VS8.0/debug.vsprops PC/VS8.0/kill_python.c
	PC/VS8.0/make_versioninfo.vcproj PC/VS8.0/pcbuild.sln
	PC/VS8.0/pyd.vsprops PC/VS8.0/pyd_d.vsprops
	PC/VS8.0/pyproject.vsprops PC/VS8.0/python.vcproj
	PC/VS8.0/pythoncore.vcproj PC/VS8.0/release.vsprops
	PC/VS8.0/x64.vsprops PCbuild/_elementtree.vcproj
	PCbuild/make_versioninfo.vcproj PCbuild/pcbuild.sln
	PCbuild/python.vcproj PCbuild/vs9to8.py
Message-ID: <20080612225342.7F6551E4002@bag.python.org>

Author: amaury.forgeotdarc
Date: Fri Jun 13 00:53:41 2008
New Revision: 64209

Log:
Merged revisions 64202 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/trunk

........
  r64202 | amaury.forgeotdarc | 2008-06-12 23:58:20 +0200 (jeu., 12 juin 2008) | 5 lines
  
  Update VS8.0 build files, using the script vs9to8.py.
  
  Also remove references to odbc libraries, which are not shipped with vs2003 express.
  (and certainly not useful)
........


Added:
   python/branches/py3k/PC/VS8.0/kill_python.c
      - copied unchanged from r64202, /python/trunk/PC/VS8.0/kill_python.c
Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/PC/VS8.0/_bsddb.vcproj
   python/branches/py3k/PC/VS8.0/_elementtree.vcproj
   python/branches/py3k/PC/VS8.0/_sqlite3.vcproj
   python/branches/py3k/PC/VS8.0/_ssl.vcproj
   python/branches/py3k/PC/VS8.0/_tkinter.vcproj
   python/branches/py3k/PC/VS8.0/bdist_wininst.vcproj
   python/branches/py3k/PC/VS8.0/debug.vsprops
   python/branches/py3k/PC/VS8.0/make_versioninfo.vcproj
   python/branches/py3k/PC/VS8.0/pcbuild.sln
   python/branches/py3k/PC/VS8.0/pyd.vsprops
   python/branches/py3k/PC/VS8.0/pyd_d.vsprops
   python/branches/py3k/PC/VS8.0/pyproject.vsprops
   python/branches/py3k/PC/VS8.0/python.vcproj
   python/branches/py3k/PC/VS8.0/pythoncore.vcproj
   python/branches/py3k/PC/VS8.0/release.vsprops
   python/branches/py3k/PC/VS8.0/x64.vsprops
   python/branches/py3k/PCbuild/_elementtree.vcproj
   python/branches/py3k/PCbuild/make_versioninfo.vcproj
   python/branches/py3k/PCbuild/pcbuild.sln
   python/branches/py3k/PCbuild/python.vcproj
   python/branches/py3k/PCbuild/vs9to8.py

Modified: python/branches/py3k/PC/VS8.0/_bsddb.vcproj
==============================================================================
--- python/branches/py3k/PC/VS8.0/_bsddb.vcproj	(original)
+++ python/branches/py3k/PC/VS8.0/_bsddb.vcproj	Fri Jun 13 00:53:41 2008
@@ -42,7 +42,7 @@
 			/>
 			<Tool
 				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(bsddbDir)"
+				AdditionalIncludeDirectories="..\..\..\db-4.4.20\build_win32,..\..\..\db-4.4.20\build_win32\.."
 			/>
 			<Tool
 				Name="VCManagedResourceCompilerTool"
@@ -52,11 +52,9 @@
 			/>
 			<Tool
 				Name="VCPreLinkEventTool"
-				CommandLine="cd $(bsddbDir)&#x0D;&#x0A;if exist Debug\libdb44sd.lib exit 0&#x0D;&#x0A;devenv Berkeley_DB.sln /build Debug /project db_static&#x0D;&#x0A;"
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="$(bsddbDir)\Debug\libdb44sd.lib"
 				BaseAddress="0x1e180000"
 			/>
 			<Tool
@@ -105,7 +103,7 @@
 			/>
 			<Tool
 				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(bsddbDir)"
+				AdditionalIncludeDirectories="..\..\..\db-4.4.20\build_win32,..\..\..\db-4.4.20\build_win32\.."
 			/>
 			<Tool
 				Name="VCManagedResourceCompilerTool"
@@ -115,11 +113,11 @@
 			/>
 			<Tool
 				Name="VCPreLinkEventTool"
-				CommandLine="cd $(bsddbDir)&#x0D;&#x0A;if exist Debug_AMD64\libdb44sd.lib exit 0&#x0D;&#x0A;devenv Berkeley_DB.sln /build &quot;Debug AMD64&quot; /project db_static /useenv&#x0D;&#x0A;"
+				CommandLine=""
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="$(bsddbDir)\Debug_AMD64\libdb44sd.lib"
+				AdditionalDependencies="$(bsddbDepLibs)"
 				BaseAddress="0x1e180000"
 			/>
 			<Tool
@@ -168,7 +166,7 @@
 			/>
 			<Tool
 				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(bsddbDir)"
+				AdditionalIncludeDirectories="..\..\..\db-4.4.20\build_win32,..\..\..\db-4.4.20\build_win32\.."
 			/>
 			<Tool
 				Name="VCManagedResourceCompilerTool"
@@ -178,11 +176,10 @@
 			/>
 			<Tool
 				Name="VCPreLinkEventTool"
-				CommandLine="cd $(bsddbDir)&#x0D;&#x0A;if exist Release\libdb44s.lib exit 0&#x0D;&#x0A;devenv Berkeley_DB.sln /build Release /project db_static&#x0D;&#x0A;"
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="$(bsddbDir)\Release\libdb44s.lib"
+				AdditionalDependencies="$(bsddbDepLibs)"
 				BaseAddress="0x1e180000"
 			/>
 			<Tool
@@ -232,7 +229,7 @@
 			/>
 			<Tool
 				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(bsddbDir)"
+				AdditionalIncludeDirectories="..\..\..\db-4.4.20\build_win32,..\..\..\db-4.4.20\build_win32\.."
 			/>
 			<Tool
 				Name="VCManagedResourceCompilerTool"
@@ -242,11 +239,11 @@
 			/>
 			<Tool
 				Name="VCPreLinkEventTool"
-				CommandLine="cd $(bsddbDir)&#x0D;&#x0A;if exist Release_AMD64\libdb44s.lib exit 0&#x0D;&#x0A;devenv Berkeley_DB.sln /build &quot;Release AMD64&quot; /project db_static /useenv&#x0D;&#x0A;"
+				CommandLine=""
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="$(bsddbDir)\Release_AMD64\libdb44s.lib"
+				AdditionalDependencies="$(bsddbDepLibs)"
 				BaseAddress="0x1e180000"
 			/>
 			<Tool
@@ -295,7 +292,7 @@
 			/>
 			<Tool
 				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(bsddbDir)"
+				AdditionalIncludeDirectories="..\..\..\db-4.4.20\build_win32,..\..\..\db-4.4.20\build_win32\.."
 			/>
 			<Tool
 				Name="VCManagedResourceCompilerTool"
@@ -305,11 +302,10 @@
 			/>
 			<Tool
 				Name="VCPreLinkEventTool"
-				CommandLine="cd $(bsddbDir)&#x0D;&#x0A;if exist Release\libdb44s.lib exit 0&#x0D;&#x0A;devenv Berkeley_DB.sln /build Release /project db_static&#x0D;&#x0A;"
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="$(bsddbDir)\Release\libdb44s.lib"
+				AdditionalDependencies="$(bsddbDepLibs)"
 				BaseAddress="0x1e180000"
 			/>
 			<Tool
@@ -359,7 +355,7 @@
 			/>
 			<Tool
 				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(bsddbDir)"
+				AdditionalIncludeDirectories="..\..\..\db-4.4.20\build_win32,..\..\..\db-4.4.20\build_win32\.."
 			/>
 			<Tool
 				Name="VCManagedResourceCompilerTool"
@@ -369,11 +365,10 @@
 			/>
 			<Tool
 				Name="VCPreLinkEventTool"
-				CommandLine="cd $(bsddbDir)&#x0D;&#x0A;if exist Release_AMD64\libdb44s.lib exit 0&#x0D;&#x0A;devenv Berkeley_DB.sln /build &quot;Release AMD64&quot; /project db_static /useenv&#x0D;&#x0A;"
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="$(bsddbDir)\Release_AMD64\libdb44s.lib"
+				AdditionalDependencies="$(bsddbDepLibs)"
 				BaseAddress="0x1e180000"
 				TargetMachine="17"
 			/>
@@ -423,7 +418,7 @@
 			/>
 			<Tool
 				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(bsddbDir)"
+				AdditionalIncludeDirectories="..\..\..\db-4.4.20\build_win32,..\..\..\db-4.4.20\build_win32\.."
 			/>
 			<Tool
 				Name="VCManagedResourceCompilerTool"
@@ -433,11 +428,10 @@
 			/>
 			<Tool
 				Name="VCPreLinkEventTool"
-				CommandLine="cd $(bsddbDir)&#x0D;&#x0A;if exist Release\libdb44s.lib exit 0&#x0D;&#x0A;devenv Berkeley_DB.sln /build Release /project db_static&#x0D;&#x0A;"
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="$(bsddbDir)\Release\libdb44s.lib"
+				AdditionalDependencies="$(bsddbDepLibs)"
 				BaseAddress="0x1e180000"
 			/>
 			<Tool
@@ -487,7 +481,7 @@
 			/>
 			<Tool
 				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(bsddbDir)"
+				AdditionalIncludeDirectories="..\..\..\db-4.4.20\build_win32,..\..\..\db-4.4.20\build_win32\.."
 			/>
 			<Tool
 				Name="VCManagedResourceCompilerTool"
@@ -497,11 +491,10 @@
 			/>
 			<Tool
 				Name="VCPreLinkEventTool"
-				CommandLine="cd $(bsddbDir)&#x0D;&#x0A;if exist Release_AMD64\libdb44s.lib exit 0&#x0D;&#x0A;devenv Berkeley_DB.sln /build &quot;Release AMD64&quot; /project db_static /useenv&#x0D;&#x0A;"
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="$(bsddbDir)\Release_AMD64\libdb44s.lib"
+				AdditionalDependencies="$(bsddbDepLibs)"
 				BaseAddress="0x1e180000"
 				TargetMachine="17"
 			/>

Modified: python/branches/py3k/PC/VS8.0/_elementtree.vcproj
==============================================================================
--- python/branches/py3k/PC/VS8.0/_elementtree.vcproj	(original)
+++ python/branches/py3k/PC/VS8.0/_elementtree.vcproj	Fri Jun 13 00:53:41 2008
@@ -56,7 +56,6 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="odbccp32.lib"
 				BaseAddress="0x1D100000"
 			/>
 			<Tool
@@ -119,7 +118,6 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="odbccp32.lib"
 				BaseAddress="0x1D100000"
 			/>
 			<Tool
@@ -182,7 +180,6 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="odbccp32.lib"
 				BaseAddress="0x1D100000"
 			/>
 			<Tool
@@ -246,7 +243,6 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="odbccp32.lib"
 				BaseAddress="0x1D100000"
 			/>
 			<Tool
@@ -309,7 +305,6 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="odbccp32.lib"
 				BaseAddress="0x1D100000"
 			/>
 			<Tool
@@ -373,7 +368,6 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="odbccp32.lib"
 				BaseAddress="0x1D100000"
 				TargetMachine="17"
 			/>
@@ -437,7 +431,6 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="odbccp32.lib"
 				BaseAddress="0x1D100000"
 			/>
 			<Tool
@@ -501,7 +494,6 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="odbccp32.lib"
 				BaseAddress="0x1D100000"
 				TargetMachine="17"
 			/>

Modified: python/branches/py3k/PC/VS8.0/_sqlite3.vcproj
==============================================================================
--- python/branches/py3k/PC/VS8.0/_sqlite3.vcproj	(original)
+++ python/branches/py3k/PC/VS8.0/_sqlite3.vcproj	Fri Jun 13 00:53:41 2008
@@ -42,7 +42,7 @@
 			/>
 			<Tool
 				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(sqlite3Dir)"
+				AdditionalIncludeDirectories="..\..\..\sqlite-source-3.3.4"
 				PreprocessorDefinitions="MODULE_NAME=\&quot;sqlite3\&quot;"
 			/>
 			<Tool
@@ -53,12 +53,9 @@
 			/>
 			<Tool
 				Name="VCPreLinkEventTool"
-				Description="Build sqlite3 libs and dll"
-				CommandLine="cd &quot;$(sqlite3Dir)&quot;&#x0D;&#x0A;if not exist &quot;$(OutDir)\sqlite3.dll&quot; if exist $(PlatformName)\sqlite3.dll copy $(PlatformName)\sqlite3.dll &quot;$(OutDir)&quot;&#x0D;&#x0A;if exist $(PlatformName)\sqlite3.lib exit 0&#x0D;&#x0A;if not exist $(PlatformName) mkdir $(PlatformName)&#x0D;&#x0A;cd $(PlatformName)&#x0D;&#x0A;cl /DNO_TCL /Ox /Ob1 /Oi /GL /GF /FD /MD /Gy ..\..\*.c&#x0D;&#x0A;link /INCREMENTAL:NO /NOLOGO /DLL /OPT:REF /OPT:ICF /def:..\..\sqlite3.def  /dll /out:sqlite3.dll *.obj&#x0D;&#x0A;if not exist &quot;$(OutDir)\sqlite3.dll&quot; copy sqlite3.dll &quot;$(OutDir)&quot;&#x0D;&#x0A;"
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="$(sqlite3Dir)\$(PlatformName)\sqlite3.lib"
 				BaseAddress="0x1e180000"
 			/>
 			<Tool
@@ -107,7 +104,7 @@
 			/>
 			<Tool
 				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(sqlite3Dir)"
+				AdditionalIncludeDirectories="..\..\..\sqlite-source-3.3.4"
 				PreprocessorDefinitions="MODULE_NAME=\&quot;sqlite3\&quot;"
 			/>
 			<Tool
@@ -118,12 +115,9 @@
 			/>
 			<Tool
 				Name="VCPreLinkEventTool"
-				Description="Build sqlite3 libs and dll"
-				CommandLine="cd &quot;$(sqlite3Dir)&quot;&#x0D;&#x0A;if not exist &quot;$(OutDir)\sqlite3.dll&quot; if exist $(PlatformName)\sqlite3.dll copy $(PlatformName)\sqlite3.dll &quot;$(OutDir)&quot;&#x0D;&#x0A;if exist $(PlatformName)\sqlite3.lib exit 0&#x0D;&#x0A;if not exist $(PlatformName) mkdir $(PlatformName)&#x0D;&#x0A;cd $(PlatformName)&#x0D;&#x0A;cl /DNO_TCL /Ox /Ob1 /Oi /GL /GF /FD /MD /Gy ..\..\*.c&#x0D;&#x0A;link /INCREMENTAL:NO /NOLOGO /DLL /OPT:REF /OPT:ICF /def:..\..\sqlite3.def  /dll /out:sqlite3.dll *.obj&#x0D;&#x0A;if not exist &quot;$(OutDir)\sqlite3.dll&quot; copy sqlite3.dll &quot;$(OutDir)&quot;&#x0D;&#x0A;"
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="$(sqlite3Dir)\$(PlatformName)\sqlite3.lib"
 				BaseAddress="0x1e180000"
 			/>
 			<Tool
@@ -172,7 +166,7 @@
 			/>
 			<Tool
 				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(sqlite3Dir)"
+				AdditionalIncludeDirectories="..\..\..\sqlite-source-3.3.4"
 				PreprocessorDefinitions="MODULE_NAME=\&quot;sqlite3\&quot;"
 			/>
 			<Tool
@@ -183,12 +177,9 @@
 			/>
 			<Tool
 				Name="VCPreLinkEventTool"
-				Description="Build sqlite3 libs and dll"
-				CommandLine="cd &quot;$(sqlite3Dir)&quot;&#x0D;&#x0A;if not exist &quot;$(OutDir)\sqlite3.dll&quot; if exist $(PlatformName)\sqlite3.dll copy $(PlatformName)\sqlite3.dll &quot;$(OutDir)&quot;&#x0D;&#x0A;if exist $(PlatformName)\sqlite3.lib exit 0&#x0D;&#x0A;if not exist $(PlatformName) mkdir $(PlatformName)&#x0D;&#x0A;cd $(PlatformName)&#x0D;&#x0A;cl /DNO_TCL /Ox /Ob1 /Oi /GL /GF /FD /MD /Gy ..\..\*.c&#x0D;&#x0A;link /INCREMENTAL:NO /NOLOGO /DLL /OPT:REF /OPT:ICF /def:..\..\sqlite3.def  /dll /out:sqlite3.dll *.obj&#x0D;&#x0A;if not exist &quot;$(OutDir)\sqlite3.dll&quot; copy sqlite3.dll &quot;$(OutDir)&quot;&#x0D;&#x0A;"
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="$(sqlite3Dir)\$(PlatformName)\sqlite3.lib"
 				BaseAddress="0x1e180000"
 			/>
 			<Tool
@@ -238,7 +229,7 @@
 			/>
 			<Tool
 				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(sqlite3Dir)"
+				AdditionalIncludeDirectories="..\..\..\sqlite-source-3.3.4"
 				PreprocessorDefinitions="MODULE_NAME=\&quot;sqlite3\&quot;"
 			/>
 			<Tool
@@ -249,12 +240,9 @@
 			/>
 			<Tool
 				Name="VCPreLinkEventTool"
-				Description="Build sqlite3 libs and dll"
-				CommandLine="cd &quot;$(sqlite3Dir)&quot;&#x0D;&#x0A;if not exist &quot;$(OutDir)\sqlite3.dll&quot; if exist $(PlatformName)\sqlite3.dll copy $(PlatformName)\sqlite3.dll &quot;$(OutDir)&quot;&#x0D;&#x0A;if exist $(PlatformName)\sqlite3.lib exit 0&#x0D;&#x0A;if not exist $(PlatformName) mkdir $(PlatformName)&#x0D;&#x0A;cd $(PlatformName)&#x0D;&#x0A;cl /DNO_TCL /Ox /Ob1 /Oi /GL /GF /FD /MD /Gy ..\..\*.c&#x0D;&#x0A;link /INCREMENTAL:NO /NOLOGO /DLL /OPT:REF /OPT:ICF /def:..\..\sqlite3.def  /dll /out:sqlite3.dll *.obj&#x0D;&#x0A;if not exist &quot;$(OutDir)\sqlite3.dll&quot; copy sqlite3.dll &quot;$(OutDir)&quot;&#x0D;&#x0A;"
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="$(sqlite3Dir)\$(PlatformName)\sqlite3.lib"
 				BaseAddress="0x1e180000"
 			/>
 			<Tool
@@ -303,7 +291,7 @@
 			/>
 			<Tool
 				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(sqlite3Dir)"
+				AdditionalIncludeDirectories="..\..\..\sqlite-source-3.3.4"
 				PreprocessorDefinitions="MODULE_NAME=\&quot;sqlite3\&quot;"
 			/>
 			<Tool
@@ -314,12 +302,9 @@
 			/>
 			<Tool
 				Name="VCPreLinkEventTool"
-				Description="Build sqlite3 libs and dll"
-				CommandLine="cd &quot;$(sqlite3Dir)&quot;&#x0D;&#x0A;if not exist &quot;$(OutDir)\sqlite3.dll&quot; if exist $(PlatformName)\sqlite3.dll copy $(PlatformName)\sqlite3.dll &quot;$(OutDir)&quot;&#x0D;&#x0A;if exist $(PlatformName)\sqlite3.lib exit 0&#x0D;&#x0A;if not exist $(PlatformName) mkdir $(PlatformName)&#x0D;&#x0A;cd $(PlatformName)&#x0D;&#x0A;cl /DNO_TCL /Ox /Ob1 /Oi /GL /GF /FD /MD /Gy ..\..\*.c&#x0D;&#x0A;link /INCREMENTAL:NO /NOLOGO /DLL /OPT:REF /OPT:ICF /def:..\..\sqlite3.def  /dll /out:sqlite3.dll *.obj&#x0D;&#x0A;if not exist &quot;$(OutDir)\sqlite3.dll&quot; copy sqlite3.dll &quot;$(OutDir)&quot;&#x0D;&#x0A;"
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="$(sqlite3Dir)\$(PlatformName)\sqlite3.lib"
 				BaseAddress="0x1e180000"
 			/>
 			<Tool
@@ -369,7 +354,7 @@
 			/>
 			<Tool
 				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(sqlite3Dir)"
+				AdditionalIncludeDirectories="..\..\..\sqlite-source-3.3.4"
 				PreprocessorDefinitions="MODULE_NAME=\&quot;sqlite3\&quot;"
 			/>
 			<Tool
@@ -380,12 +365,9 @@
 			/>
 			<Tool
 				Name="VCPreLinkEventTool"
-				Description="Build sqlite3 libs and dll"
-				CommandLine="cd &quot;$(sqlite3Dir)&quot;&#x0D;&#x0A;if not exist &quot;$(OutDir)\sqlite3.dll&quot; if exist $(PlatformName)\sqlite3.dll copy $(PlatformName)\sqlite3.dll &quot;$(OutDir)&quot;&#x0D;&#x0A;if exist $(PlatformName)\sqlite3.lib exit 0&#x0D;&#x0A;if not exist $(PlatformName) mkdir $(PlatformName)&#x0D;&#x0A;cd $(PlatformName)&#x0D;&#x0A;cl /DNO_TCL /Ox /Ob1 /Oi /GL /GF /FD /MD /Gy ..\..\*.c&#x0D;&#x0A;link /INCREMENTAL:NO /NOLOGO /DLL /OPT:REF /OPT:ICF /def:..\..\sqlite3.def  /dll /out:sqlite3.dll *.obj&#x0D;&#x0A;if not exist &quot;$(OutDir)\sqlite3.dll&quot; copy sqlite3.dll &quot;$(OutDir)&quot;&#x0D;&#x0A;"
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="$(sqlite3Dir)\$(PlatformName)\sqlite3.lib"
 				BaseAddress="0x1e180000"
 				TargetMachine="17"
 			/>
@@ -435,7 +417,7 @@
 			/>
 			<Tool
 				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(sqlite3Dir)"
+				AdditionalIncludeDirectories="..\..\..\sqlite-source-3.3.4"
 				PreprocessorDefinitions="MODULE_NAME=\&quot;sqlite3\&quot;"
 			/>
 			<Tool
@@ -446,12 +428,9 @@
 			/>
 			<Tool
 				Name="VCPreLinkEventTool"
-				Description="Build sqlite3 libs and dll"
-				CommandLine="cd &quot;$(sqlite3Dir)&quot;&#x0D;&#x0A;if not exist &quot;$(OutDir)\sqlite3.dll&quot; if exist $(PlatformName)\sqlite3.dll copy $(PlatformName)\sqlite3.dll &quot;$(OutDir)&quot;&#x0D;&#x0A;if exist $(PlatformName)\sqlite3.lib exit 0&#x0D;&#x0A;if not exist $(PlatformName) mkdir $(PlatformName)&#x0D;&#x0A;cd $(PlatformName)&#x0D;&#x0A;cl /DNO_TCL /Ox /Ob1 /Oi /GL /GF /FD /MD /Gy ..\..\*.c&#x0D;&#x0A;link /INCREMENTAL:NO /NOLOGO /DLL /OPT:REF /OPT:ICF /def:..\..\sqlite3.def  /dll /out:sqlite3.dll *.obj&#x0D;&#x0A;if not exist &quot;$(OutDir)\sqlite3.dll&quot; copy sqlite3.dll &quot;$(OutDir)&quot;&#x0D;&#x0A;"
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="$(sqlite3Dir)\$(PlatformName)\sqlite3.lib"
 				BaseAddress="0x1e180000"
 			/>
 			<Tool
@@ -501,7 +480,7 @@
 			/>
 			<Tool
 				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(sqlite3Dir)"
+				AdditionalIncludeDirectories="..\..\..\sqlite-source-3.3.4"
 				PreprocessorDefinitions="MODULE_NAME=\&quot;sqlite3\&quot;"
 			/>
 			<Tool
@@ -512,12 +491,9 @@
 			/>
 			<Tool
 				Name="VCPreLinkEventTool"
-				Description="Build sqlite3 libs and dll"
-				CommandLine="cd &quot;$(sqlite3Dir)&quot;&#x0D;&#x0A;if not exist &quot;$(OutDir)\sqlite3.dll&quot; if exist $(PlatformName)\sqlite3.dll copy $(PlatformName)\sqlite3.dll &quot;$(OutDir)&quot;&#x0D;&#x0A;if exist $(PlatformName)\sqlite3.lib exit 0&#x0D;&#x0A;if not exist $(PlatformName) mkdir $(PlatformName)&#x0D;&#x0A;cd $(PlatformName)&#x0D;&#x0A;cl /DNO_TCL /Ox /Ob1 /Oi /GL /GF /FD /MD /Gy ..\..\*.c&#x0D;&#x0A;link /INCREMENTAL:NO /NOLOGO /DLL /OPT:REF /OPT:ICF /def:..\..\sqlite3.def  /dll /out:sqlite3.dll *.obj&#x0D;&#x0A;if not exist &quot;$(OutDir)\sqlite3.dll&quot; copy sqlite3.dll &quot;$(OutDir)&quot;&#x0D;&#x0A;"
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="$(sqlite3Dir)\$(PlatformName)\sqlite3.lib"
 				BaseAddress="0x1e180000"
 				TargetMachine="17"
 			/>

Modified: python/branches/py3k/PC/VS8.0/_ssl.vcproj
==============================================================================
--- python/branches/py3k/PC/VS8.0/_ssl.vcproj	(original)
+++ python/branches/py3k/PC/VS8.0/_ssl.vcproj	Fri Jun 13 00:53:41 2008
@@ -27,7 +27,7 @@
 			>
 			<Tool
 				Name="VCPreBuildEventTool"
-				CommandLine="cd &quot;$(SolutionDir)&quot;&#x0D;&#x0A;&quot;$(PythonExe)&quot; build_ssl.py Release $(PlatformName) -a"
+				CommandLine="cd &quot;$(SolutionDir)&quot;&#x0D;&#x0A;&quot;$(PythonExe)&quot; build_ssl.py Release $(PlatformName) -a&#x0D;&#x0A;"
 			/>
 			<Tool
 				Name="VCCustomBuildTool"
@@ -89,7 +89,7 @@
 			>
 			<Tool
 				Name="VCPreBuildEventTool"
-				CommandLine="cd &quot;$(SolutionDir)&quot;&#x0D;&#x0A;&quot;$(PythonExe)&quot; build_ssl.py Release $(PlatformName) -a"
+				CommandLine="cd &quot;$(SolutionDir)&quot;&#x0D;&#x0A;&quot;$(PythonExe)&quot; build_ssl.py Release $(PlatformName) -a&#x0D;&#x0A;"
 			/>
 			<Tool
 				Name="VCCustomBuildTool"
@@ -153,7 +153,7 @@
 			>
 			<Tool
 				Name="VCPreBuildEventTool"
-				CommandLine="cd &quot;$(SolutionDir)&quot;&#x0D;&#x0A;&quot;$(PythonExe)&quot; build_ssl.py Release $(PlatformName) -a"
+				CommandLine="cd &quot;$(SolutionDir)&quot;&#x0D;&#x0A;&quot;$(PythonExe)&quot; build_ssl.py Release $(PlatformName) -a&#x0D;&#x0A;"
 			/>
 			<Tool
 				Name="VCCustomBuildTool"
@@ -216,7 +216,7 @@
 			>
 			<Tool
 				Name="VCPreBuildEventTool"
-				CommandLine="cd &quot;$(SolutionDir)&quot;&#x0D;&#x0A;&quot;$(PythonExe)&quot; build_ssl.py Release $(PlatformName) -a"
+				CommandLine="cd &quot;$(SolutionDir)&quot;&#x0D;&#x0A;&quot;$(PythonExe)&quot; build_ssl.py Release $(PlatformName) -a&#x0D;&#x0A;"
 			/>
 			<Tool
 				Name="VCCustomBuildTool"
@@ -280,7 +280,7 @@
 			>
 			<Tool
 				Name="VCPreBuildEventTool"
-				CommandLine="cd &quot;$(SolutionDir)&quot;&#x0D;&#x0A;&quot;$(PythonExe)&quot; build_ssl.py Release $(PlatformName) -a"
+				CommandLine="cd &quot;$(SolutionDir)&quot;&#x0D;&#x0A;&quot;$(PythonExe)&quot; build_ssl.py Release $(PlatformName) -a&#x0D;&#x0A;"
 			/>
 			<Tool
 				Name="VCCustomBuildTool"
@@ -343,7 +343,7 @@
 			>
 			<Tool
 				Name="VCPreBuildEventTool"
-				CommandLine="cd &quot;$(SolutionDir)&quot;&#x0D;&#x0A;&quot;$(PythonExe)&quot; build_ssl.py Release $(PlatformName) -a"
+				CommandLine="cd &quot;$(SolutionDir)&quot;&#x0D;&#x0A;&quot;$(PythonExe)&quot; build_ssl.py Release $(PlatformName) -a&#x0D;&#x0A;"
 			/>
 			<Tool
 				Name="VCCustomBuildTool"
@@ -408,7 +408,7 @@
 			>
 			<Tool
 				Name="VCPreBuildEventTool"
-				CommandLine="cd &quot;$(SolutionDir)&quot;&#x0D;&#x0A;&quot;$(PythonExe)&quot; build_ssl.py Release $(PlatformName) -a"
+				CommandLine="cd &quot;$(SolutionDir)&quot;&#x0D;&#x0A;&quot;$(PythonExe)&quot; build_ssl.py Release $(PlatformName) -a&#x0D;&#x0A;"
 			/>
 			<Tool
 				Name="VCCustomBuildTool"
@@ -471,7 +471,7 @@
 			>
 			<Tool
 				Name="VCPreBuildEventTool"
-				CommandLine="cd &quot;$(SolutionDir)&quot;&#x0D;&#x0A;&quot;$(PythonExe)&quot; build_ssl.py Release $(PlatformName) -a"
+				CommandLine="cd &quot;$(SolutionDir)&quot;&#x0D;&#x0A;&quot;$(PythonExe)&quot; build_ssl.py Release $(PlatformName) -a&#x0D;&#x0A;"
 			/>
 			<Tool
 				Name="VCCustomBuildTool"
@@ -535,10 +535,6 @@
 			Name="Source Files"
 			>
 			<File
-				RelativePath="..\..\Modules\_hashopenssl.c"
-				>
-			</File>
-			<File
 				RelativePath="..\..\Modules\_ssl.c"
 				>
 			</File>

Modified: python/branches/py3k/PC/VS8.0/_tkinter.vcproj
==============================================================================
--- python/branches/py3k/PC/VS8.0/_tkinter.vcproj	(original)
+++ python/branches/py3k/PC/VS8.0/_tkinter.vcproj	Fri Jun 13 00:53:41 2008
@@ -56,7 +56,7 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="$(tcltkLib)"
+				AdditionalDependencies="$(tcltkLibDebug)"
 			/>
 			<Tool
 				Name="VCALinkTool"
@@ -104,7 +104,7 @@
 			/>
 			<Tool
 				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="&quot;$(tcltk64Dir)\include&quot;"
+				AdditionalIncludeDirectories="$(tcltk64Dir)\include"
 				PreprocessorDefinitions="WITH_APPINIT"
 			/>
 			<Tool
@@ -118,7 +118,7 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="$(tcltk64Lib)"
+				AdditionalDependencies="$(tcltk64LibDebug)"
 			/>
 			<Tool
 				Name="VCALinkTool"
@@ -229,7 +229,7 @@
 			/>
 			<Tool
 				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="&quot;$(tcltk64Dir)\include&quot;"
+				AdditionalIncludeDirectories="$(tcltk64Dir)\include"
 				PreprocessorDefinitions="WITH_APPINIT"
 			/>
 			<Tool
@@ -354,7 +354,7 @@
 			/>
 			<Tool
 				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="&quot;$(tcltk64Dir)\include&quot;"
+				AdditionalIncludeDirectories="$(tcltk64Dir)\include"
 				PreprocessorDefinitions="WITH_APPINIT"
 			/>
 			<Tool
@@ -480,7 +480,7 @@
 			/>
 			<Tool
 				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="&quot;$(tcltk64Dir)\include&quot;"
+				AdditionalIncludeDirectories="$(tcltk64Dir)\include"
 				PreprocessorDefinitions="WITH_APPINIT"
 			/>
 			<Tool

Modified: python/branches/py3k/PC/VS8.0/bdist_wininst.vcproj
==============================================================================
--- python/branches/py3k/PC/VS8.0/bdist_wininst.vcproj	(original)
+++ python/branches/py3k/PC/VS8.0/bdist_wininst.vcproj	Fri Jun 13 00:53:41 2008
@@ -11,6 +11,9 @@
 		<Platform
 			Name="Win32"
 		/>
+		<Platform
+			Name="x64"
+		/>
 	</Platforms>
 	<ToolFiles>
 	</ToolFiles>
@@ -104,6 +107,96 @@
 				Name="VCPostBuildEventTool"
 			/>
 		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			OutputDirectory="$(PlatformName)\$(ConfigurationName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\pyproject.vsprops;.\release.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				PreprocessorDefinitions="NDEBUG"
+				MkTypLibCompatible="true"
+				SuppressStartupBanner="true"
+				TargetEnvironment="3"
+				TypeLibraryName=".\..\..\lib\distutils\command\wininst.tlb"
+				HeaderFileName=""
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="1"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\..\PC\bdist_wininst;..\..\Include;..\..\Modules\zlib"
+				PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="0"
+				AdditionalIncludeDirectories="..\..\PC;..\..\PC\bdist_wininst;..\..\Include"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="comctl32.lib imagehlp.lib"
+				OutputFile="..\..\lib\distutils\command\wininst-8.0-amd64.exe"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				IgnoreDefaultLibraryNames="LIBC"
+				ProgramDatabaseFile="..\..\lib\distutils\command\wininst-8.0-amd64.pdb"
+				SubSystem="2"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
 	</Configurations>
 	<References>
 	</References>

Modified: python/branches/py3k/PC/VS8.0/debug.vsprops
==============================================================================
--- python/branches/py3k/PC/VS8.0/debug.vsprops	(original)
+++ python/branches/py3k/PC/VS8.0/debug.vsprops	Fri Jun 13 00:53:41 2008
@@ -8,4 +8,8 @@
 		Name="VCCLCompilerTool"
 		PreprocessorDefinitions="_DEBUG"
 	/>
-</VisualStudioPropertySheet>
\ No newline at end of file
+	<UserMacro
+		Name="KillPythonExe"
+		Value="$(OutDir)\kill_python_d.exe"
+	/>
+</VisualStudioPropertySheet>

Modified: python/branches/py3k/PC/VS8.0/make_versioninfo.vcproj
==============================================================================
--- python/branches/py3k/PC/VS8.0/make_versioninfo.vcproj	(original)
+++ python/branches/py3k/PC/VS8.0/make_versioninfo.vcproj	Fri Jun 13 00:53:41 2008
@@ -67,7 +67,6 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="odbccp32.lib"
 				OutputFile="$(SolutionDir)make_versioninfo.exe"
 				ProgramDatabaseFile="$(TargetDir)$(TargetName).pdb"
 				SubSystem="1"
@@ -211,7 +210,6 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="odbccp32.lib"
 				OutputFile="$(SolutionDir)make_versioninfo_d.exe"
 				ProgramDatabaseFile="$(TargetDir)$(TargetName).pdb"
 				SubSystem="1"

Modified: python/branches/py3k/PC/VS8.0/pcbuild.sln
==============================================================================
--- python/branches/py3k/PC/VS8.0/pcbuild.sln	(original)
+++ python/branches/py3k/PC/VS8.0/pcbuild.sln	Fri Jun 13 00:53:41 2008
@@ -11,6 +11,7 @@
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pythoncore", "pythoncore.vcproj", "{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}"
 	ProjectSection(ProjectDependencies) = postProject
 		{F0E0541E-F17D-430B-97C4-93ADF0DD284E} = {F0E0541E-F17D-430B-97C4-93ADF0DD284E}
+		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31} = {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}
 		{C73F0EC1-358B-4177-940F-0846AC8B04CD} = {C73F0EC1-358B-4177-940F-0846AC8B04CD}
 	EndProjectSection
 EndProject
@@ -20,6 +21,9 @@
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "w9xpopen", "w9xpopen.vcproj", "{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}"
+	ProjectSection(ProjectDependencies) = postProject
+		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31} = {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}
+	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "make_buildinfo", "make_buildinfo.vcproj", "{C73F0EC1-358B-4177-940F-0846AC8B04CD}"
 EndProject
@@ -36,6 +40,8 @@
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_bsddb", "_bsddb.vcproj", "{B4D38F3F-68FB-42EC-A45D-E00657BB3627}"
 	ProjectSection(ProjectDependencies) = postProject
+		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31} = {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}
+		{62172C7D-B39E-409A-B352-370FF5098C19} = {62172C7D-B39E-409A-B352-370FF5098C19}
 		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
 	EndProjectSection
 EndProject
@@ -67,6 +73,7 @@
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_sqlite3", "_sqlite3.vcproj", "{13CECB97-4119-4316-9D42-8534019A5A44}"
 	ProjectSection(ProjectDependencies) = postProject
 		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
+		{A1A295E5-463C-437F-81CA-1F32367685DA} = {A1A295E5-463C-437F-81CA-1F32367685DA}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_ssl", "_ssl.vcproj", "{C6E20F84-3247-4AD6-B051-B073268F73BA}"
@@ -108,6 +115,29 @@
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bdist_wininst", "bdist_wininst.vcproj", "{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}"
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_hashlib", "_hashlib.vcproj", "{447F05A8-F581-4CAC-A466-5AC7936E207E}"
+	ProjectSection(ProjectDependencies) = postProject
+		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9} = {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_bsddb44", "_bsddb44.vcproj", "{62172C7D-B39E-409A-B352-370FF5098C19}"
+	ProjectSection(ProjectDependencies) = postProject
+		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31} = {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sqlite3", "sqlite3.vcproj", "{A1A295E5-463C-437F-81CA-1F32367685DA}"
+	ProjectSection(ProjectDependencies) = postProject
+		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31} = {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_multiprocessing", "_multiprocessing.vcproj", "{9E48B300-37D1-11DD-8C41-005056C00008}"
+	ProjectSection(ProjectDependencies) = postProject
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "kill_python", "kill_python.vcproj", "{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Win32 = Debug|Win32
@@ -457,13 +487,93 @@
 		{D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|x64.ActiveCfg = Release|x64
 		{D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|x64.Build.0 = Release|x64
 		{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Debug|Win32.ActiveCfg = Release|Win32
-		{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Debug|x64.ActiveCfg = Release|Win32
+		{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Debug|x64.ActiveCfg = Release|x64
 		{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGInstrument|Win32.ActiveCfg = Release|Win32
-		{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGInstrument|x64.ActiveCfg = Release|Win32
+		{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGInstrument|x64.ActiveCfg = Release|x64
 		{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGUpdate|Win32.ActiveCfg = Release|Win32
-		{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGUpdate|x64.ActiveCfg = Release|Win32
+		{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGUpdate|x64.ActiveCfg = Release|x64
 		{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Release|Win32.ActiveCfg = Release|Win32
-		{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Release|x64.ActiveCfg = Release|Win32
+		{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Release|x64.ActiveCfg = Release|x64
+		{447F05A8-F581-4CAC-A466-5AC7936E207E}.Debug|Win32.ActiveCfg = Debug|Win32
+		{447F05A8-F581-4CAC-A466-5AC7936E207E}.Debug|Win32.Build.0 = Debug|Win32
+		{447F05A8-F581-4CAC-A466-5AC7936E207E}.Debug|x64.ActiveCfg = Debug|x64
+		{447F05A8-F581-4CAC-A466-5AC7936E207E}.Debug|x64.Build.0 = Debug|x64
+		{447F05A8-F581-4CAC-A466-5AC7936E207E}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
+		{447F05A8-F581-4CAC-A466-5AC7936E207E}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
+		{447F05A8-F581-4CAC-A466-5AC7936E207E}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
+		{447F05A8-F581-4CAC-A466-5AC7936E207E}.PGInstrument|x64.Build.0 = PGInstrument|x64
+		{447F05A8-F581-4CAC-A466-5AC7936E207E}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
+		{447F05A8-F581-4CAC-A466-5AC7936E207E}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
+		{447F05A8-F581-4CAC-A466-5AC7936E207E}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
+		{447F05A8-F581-4CAC-A466-5AC7936E207E}.PGUpdate|x64.Build.0 = PGUpdate|x64
+		{447F05A8-F581-4CAC-A466-5AC7936E207E}.Release|Win32.ActiveCfg = Release|Win32
+		{447F05A8-F581-4CAC-A466-5AC7936E207E}.Release|Win32.Build.0 = Release|Win32
+		{447F05A8-F581-4CAC-A466-5AC7936E207E}.Release|x64.ActiveCfg = Release|x64
+		{447F05A8-F581-4CAC-A466-5AC7936E207E}.Release|x64.Build.0 = Release|x64
+		{62172C7D-B39E-409A-B352-370FF5098C19}.Debug|Win32.ActiveCfg = Debug|Win32
+		{62172C7D-B39E-409A-B352-370FF5098C19}.Debug|Win32.Build.0 = Debug|Win32
+		{62172C7D-B39E-409A-B352-370FF5098C19}.Debug|x64.ActiveCfg = Debug|x64
+		{62172C7D-B39E-409A-B352-370FF5098C19}.Debug|x64.Build.0 = Debug|x64
+		{62172C7D-B39E-409A-B352-370FF5098C19}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
+		{62172C7D-B39E-409A-B352-370FF5098C19}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
+		{62172C7D-B39E-409A-B352-370FF5098C19}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
+		{62172C7D-B39E-409A-B352-370FF5098C19}.PGInstrument|x64.Build.0 = PGInstrument|x64
+		{62172C7D-B39E-409A-B352-370FF5098C19}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
+		{62172C7D-B39E-409A-B352-370FF5098C19}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
+		{62172C7D-B39E-409A-B352-370FF5098C19}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
+		{62172C7D-B39E-409A-B352-370FF5098C19}.PGUpdate|x64.Build.0 = PGUpdate|x64
+		{62172C7D-B39E-409A-B352-370FF5098C19}.Release|Win32.ActiveCfg = Release|Win32
+		{62172C7D-B39E-409A-B352-370FF5098C19}.Release|Win32.Build.0 = Release|Win32
+		{62172C7D-B39E-409A-B352-370FF5098C19}.Release|x64.ActiveCfg = Release|x64
+		{62172C7D-B39E-409A-B352-370FF5098C19}.Release|x64.Build.0 = Release|x64
+		{A1A295E5-463C-437F-81CA-1F32367685DA}.Debug|Win32.ActiveCfg = Debug|Win32
+		{A1A295E5-463C-437F-81CA-1F32367685DA}.Debug|Win32.Build.0 = Debug|Win32
+		{A1A295E5-463C-437F-81CA-1F32367685DA}.Debug|x64.ActiveCfg = Debug|x64
+		{A1A295E5-463C-437F-81CA-1F32367685DA}.Debug|x64.Build.0 = Debug|x64
+		{A1A295E5-463C-437F-81CA-1F32367685DA}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
+		{A1A295E5-463C-437F-81CA-1F32367685DA}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
+		{A1A295E5-463C-437F-81CA-1F32367685DA}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
+		{A1A295E5-463C-437F-81CA-1F32367685DA}.PGInstrument|x64.Build.0 = PGInstrument|x64
+		{A1A295E5-463C-437F-81CA-1F32367685DA}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
+		{A1A295E5-463C-437F-81CA-1F32367685DA}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
+		{A1A295E5-463C-437F-81CA-1F32367685DA}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
+		{A1A295E5-463C-437F-81CA-1F32367685DA}.PGUpdate|x64.Build.0 = PGUpdate|x64
+		{A1A295E5-463C-437F-81CA-1F32367685DA}.Release|Win32.ActiveCfg = Release|Win32
+		{A1A295E5-463C-437F-81CA-1F32367685DA}.Release|Win32.Build.0 = Release|Win32
+		{A1A295E5-463C-437F-81CA-1F32367685DA}.Release|x64.ActiveCfg = Release|x64
+		{A1A295E5-463C-437F-81CA-1F32367685DA}.Release|x64.Build.0 = Release|x64
+		{9E48B300-37D1-11DD-8C41-005056C00008}.Debug|Win32.ActiveCfg = Debug|Win32
+		{9E48B300-37D1-11DD-8C41-005056C00008}.Debug|Win32.Build.0 = Debug|Win32
+		{9E48B300-37D1-11DD-8C41-005056C00008}.Debug|x64.ActiveCfg = Debug|x64
+		{9E48B300-37D1-11DD-8C41-005056C00008}.Debug|x64.Build.0 = Debug|x64
+		{9E48B300-37D1-11DD-8C41-005056C00008}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
+		{9E48B300-37D1-11DD-8C41-005056C00008}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
+		{9E48B300-37D1-11DD-8C41-005056C00008}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
+		{9E48B300-37D1-11DD-8C41-005056C00008}.PGInstrument|x64.Build.0 = PGInstrument|x64
+		{9E48B300-37D1-11DD-8C41-005056C00008}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
+		{9E48B300-37D1-11DD-8C41-005056C00008}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
+		{9E48B300-37D1-11DD-8C41-005056C00008}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
+		{9E48B300-37D1-11DD-8C41-005056C00008}.PGUpdate|x64.Build.0 = PGUpdate|x64
+		{9E48B300-37D1-11DD-8C41-005056C00008}.Release|Win32.ActiveCfg = Release|Win32
+		{9E48B300-37D1-11DD-8C41-005056C00008}.Release|Win32.Build.0 = Release|Win32
+		{9E48B300-37D1-11DD-8C41-005056C00008}.Release|x64.ActiveCfg = Release|x64
+		{9E48B300-37D1-11DD-8C41-005056C00008}.Release|x64.Build.0 = Release|x64
+		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Debug|Win32.ActiveCfg = Debug|Win32
+		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Debug|Win32.Build.0 = Debug|Win32
+		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Debug|x64.ActiveCfg = Debug|x64
+		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Debug|x64.Build.0 = Debug|x64
+		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.PGInstrument|Win32.ActiveCfg = Release|Win32
+		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.PGInstrument|Win32.Build.0 = Release|Win32
+		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.PGInstrument|x64.ActiveCfg = Release|x64
+		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.PGInstrument|x64.Build.0 = Release|x64
+		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.PGUpdate|Win32.ActiveCfg = Release|Win32
+		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.PGUpdate|Win32.Build.0 = Release|Win32
+		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.PGUpdate|x64.ActiveCfg = Release|x64
+		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.PGUpdate|x64.Build.0 = Release|x64
+		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Release|Win32.ActiveCfg = Release|Win32
+		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Release|Win32.Build.0 = Release|Win32
+		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Release|x64.ActiveCfg = Release|x64
+		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Release|x64.Build.0 = Release|x64
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE

Modified: python/branches/py3k/PC/VS8.0/pyd.vsprops
==============================================================================
--- python/branches/py3k/PC/VS8.0/pyd.vsprops	(original)
+++ python/branches/py3k/PC/VS8.0/pyd.vsprops	Fri Jun 13 00:53:41 2008
@@ -7,6 +7,7 @@
 	>
 	<Tool
 		Name="VCCLCompilerTool"
+		PreprocessorDefinitions="Py_BUILD_CORE_MODULE"
 		RuntimeLibrary="2"
 	/>
 	<Tool

Modified: python/branches/py3k/PC/VS8.0/pyd_d.vsprops
==============================================================================
--- python/branches/py3k/PC/VS8.0/pyd_d.vsprops	(original)
+++ python/branches/py3k/PC/VS8.0/pyd_d.vsprops	Fri Jun 13 00:53:41 2008
@@ -10,6 +10,7 @@
 		Optimization="0"
 		InlineFunctionExpansion="0"
 		EnableIntrinsicFunctions="false"
+		PreprocessorDefinitions="Py_BUILD_CORE_MODULE"
 		RuntimeLibrary="3"
 	/>
 	<Tool

Modified: python/branches/py3k/PC/VS8.0/pyproject.vsprops
==============================================================================
--- python/branches/py3k/PC/VS8.0/pyproject.vsprops	(original)
+++ python/branches/py3k/PC/VS8.0/pyproject.vsprops	Fri Jun 13 00:53:41 2008
@@ -45,35 +45,67 @@
 		Value="$(SolutionDir)\python.exe"
 	/>
 	<UserMacro
+		Name="externalsDir"
+		Value="..\..\.."
+	/>
+	<UserMacro
 		Name="bsddbDir"
-		Value="..\..\..\db-4.4.20\build_win32\"
+		Value="$(bsddb44Dir)"
+	/>
+	<UserMacro
+		Name="bsddbDepLibs"
+		Value="$(bsddb44DepLibs)"
+	/>
+	<UserMacro
+		Name="bsddb44Dir"
+		Value="$(externalsDir)\db-4.4.20\build_win32"
+	/>
+	<UserMacro
+		Name="bsddb44DepLibs"
+		Value=""
+	/>
+	<UserMacro
+		Name="bsddb45Dir"
+		Value="$(externalsDir)\db-4.5.20.x\build_windows"
+	/>
+	<UserMacro
+		Name="bsddb45DepLibs"
+		Value="ws2_32.lib"
 	/>
 	<UserMacro
 		Name="sqlite3Dir"
-		Value="..\..\..\sqlite-source-3.3.4\"
+		Value="$(externalsDir)\sqlite-source-3.3.4"
 	/>
 	<UserMacro
 		Name="bz2Dir"
-		Value="..\..\..\bzip2-1.0.3\"
+		Value="$(externalsDir)\bzip2-1.0.3"
 	/>
 	<UserMacro
 		Name="opensslDir"
-		Value="..\..\..\openssl-0.9.8g\"
+		Value="$(externalsDir)\openssl-0.9.8g"
 	/>
 	<UserMacro
 		Name="tcltkDir"
-		Value="..\..\..\tcltk\"
+		Value="$(externalsDir)\tcltk"
 	/>
 	<UserMacro
 		Name="tcltk64Dir"
-		Value="..\..\..\tcltk64"
+		Value="$(externalsDir)\tcltk64"
 	/>
 	<UserMacro
 		Name="tcltkLib"
 		Value="$(tcltkDir)\lib\tcl84.lib $(tcltkDir)\lib\tk84.lib"
 	/>
 	<UserMacro
+		Name="tcltkLibDebug"
+		Value="$(tcltkDir)\lib\tcl84g.lib $(tcltkDir)\lib\tk84g.lib"
+	/>
+	<UserMacro
 		Name="tcltk64Lib"
 		Value="$(tcltk64Dir)\lib\tcl84.lib $(tcltk64Dir)\lib\tk84.lib"
 	/>
+	<UserMacro
+		Name="tcltk64LibDebug"
+		Value="$(tcltk64Dir)\lib\tcl84g.lib $(tcltk64Dir)\lib\tk84g.lib"
+	/>
 </VisualStudioPropertySheet>

Modified: python/branches/py3k/PC/VS8.0/python.vcproj
==============================================================================
--- python/branches/py3k/PC/VS8.0/python.vcproj	(original)
+++ python/branches/py3k/PC/VS8.0/python.vcproj	Fri Jun 13 00:53:41 2008
@@ -62,7 +62,6 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="odbccp32.lib"
 				OutputFile="$(OutDir)\python.exe"
 				SubSystem="1"
 				StackReserveSize="2000000"
@@ -136,7 +135,6 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="odbccp32.lib"
 				OutputFile="$(OutDir)\python.exe"
 				SubSystem="1"
 				StackReserveSize="2000000"
@@ -211,7 +209,6 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="odbccp32.lib"
 				OutputFile="$(OutDir)\python_d.exe"
 				SubSystem="1"
 				StackReserveSize="2000000"
@@ -287,10 +284,9 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="odbccp32.lib"
 				OutputFile="$(OutDir)\python_d.exe"
 				SubSystem="1"
-				StackReserveSize="2000000"
+				StackReserveSize="2100000"
 				BaseAddress="0x1d000000"
 			/>
 			<Tool
@@ -360,7 +356,6 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="odbccp32.lib"
 				OutputFile="$(OutDir)\python.exe"
 				SubSystem="1"
 				StackReserveSize="2000000"
@@ -435,7 +430,6 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="odbccp32.lib"
 				OutputFile="$(OutDir)\python.exe"
 				SubSystem="1"
 				StackReserveSize="2000000"
@@ -510,7 +504,6 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="odbccp32.lib"
 				OutputFile="$(OutDir)\python.exe"
 				SubSystem="1"
 				StackReserveSize="2000000"
@@ -585,7 +578,6 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="odbccp32.lib"
 				OutputFile="$(OutDir)\python.exe"
 				SubSystem="1"
 				StackReserveSize="2000000"

Modified: python/branches/py3k/PC/VS8.0/pythoncore.vcproj
==============================================================================
--- python/branches/py3k/PC/VS8.0/pythoncore.vcproj	(original)
+++ python/branches/py3k/PC/VS8.0/pythoncore.vcproj	Fri Jun 13 00:53:41 2008
@@ -58,8 +58,8 @@
 			/>
 			<Tool
 				Name="VCPreLinkEventTool"
-				Description="generate buildinfo"
-				CommandLine="&quot;$(SolutionDir)make_buildinfo.exe&quot; $(ConfigurationName)"
+				Description="Generate build information..."
+				CommandLine="&quot;$(SolutionDir)make_buildinfo.exe&quot; Release"
 			/>
 			<Tool
 				Name="VCLinkerTool"
@@ -133,8 +133,8 @@
 			/>
 			<Tool
 				Name="VCPreLinkEventTool"
-				Description="generate buildinfo"
-				CommandLine="$(SolutionDir)make_buildinfo.exe $(ConfigurationName)"
+				Description="Generate build information..."
+				CommandLine="&quot;$(SolutionDir)make_buildinfo.exe&quot; Release"
 			/>
 			<Tool
 				Name="VCLinkerTool"
@@ -211,8 +211,8 @@
 			/>
 			<Tool
 				Name="VCPreLinkEventTool"
-				Description="generate buildinfo"
-				CommandLine="&quot;$(SolutionDir)make_buildinfo.exe&quot; $(ConfigurationName)"
+				Description="Generate build information..."
+				CommandLine="&quot;$(SolutionDir)make_buildinfo.exe&quot; Debug"
 			/>
 			<Tool
 				Name="VCLinkerTool"
@@ -289,8 +289,8 @@
 			/>
 			<Tool
 				Name="VCPreLinkEventTool"
-				Description="generate buildinfo"
-				CommandLine="$(SolutionDir)make_buildinfo.exe $(ConfigurationName)"
+				Description="Generate build information..."
+				CommandLine="&quot;$(SolutionDir)make_buildinfo.exe&quot; Debug"
 			/>
 			<Tool
 				Name="VCLinkerTool"
@@ -363,8 +363,8 @@
 			/>
 			<Tool
 				Name="VCPreLinkEventTool"
-				Description="generate buildinfo"
-				CommandLine="$(SolutionDir)make_buildinfo.exe Release"
+				Description="Generate build information..."
+				CommandLine="&quot;$(SolutionDir)make_buildinfo.exe&quot; Release"
 			/>
 			<Tool
 				Name="VCLinkerTool"
@@ -438,8 +438,8 @@
 			/>
 			<Tool
 				Name="VCPreLinkEventTool"
-				Description="generate buildinfo"
-				CommandLine="$(SolutionDir)make_buildinfo.exe $(ConfigurationName)"
+				Description="Generate build information..."
+				CommandLine="&quot;$(SolutionDir)make_buildinfo.exe&quot; Release"
 			/>
 			<Tool
 				Name="VCLinkerTool"
@@ -513,8 +513,8 @@
 			/>
 			<Tool
 				Name="VCPreLinkEventTool"
-				Description="generate buildinfo"
-				CommandLine="$(SolutionDir)make_buildinfo.exe Release"
+				Description="Generate build information..."
+				CommandLine="&quot;$(SolutionDir)make_buildinfo.exe&quot; Release"
 			/>
 			<Tool
 				Name="VCLinkerTool"
@@ -588,8 +588,8 @@
 			/>
 			<Tool
 				Name="VCPreLinkEventTool"
-				Description="generate buildinfo"
-				CommandLine="$(SolutionDir)make_buildinfo.exe $(ConfigurationName)"
+				Description="Generate build information..."
+				CommandLine="&quot;$(SolutionDir)make_buildinfo.exe&quot; Release"
 			/>
 			<Tool
 				Name="VCLinkerTool"
@@ -655,6 +655,10 @@
 				>
 			</File>
 			<File
+				RelativePath="..\..\Include\bytearrayobject.h"
+				>
+			</File>
+			<File
 				RelativePath="..\..\Include\bytesobject.h"
 				>
 			</File>
@@ -867,6 +871,10 @@
 				>
 			</File>
 			<File
+				RelativePath="..\..\Include\pymath.h"
+				>
+			</File>
+			<File
 				RelativePath="..\..\Include\pymem.h"
 				>
 			</File>
@@ -915,10 +923,6 @@
 				>
 			</File>
 			<File
-				RelativePath="..\..\Include\stringobject.h"
-				>
-			</File>
-			<File
 				RelativePath="..\..\Include\structmember.h"
 				>
 			</File>
@@ -986,10 +990,10 @@
 				RelativePath="..\..\Modules\_fileio.c"
 				>
 			</File>
-			<File
-				RelativePath="..\..\Modules\_bytesio.c"
-				>
-			</File>
+                        <File
+                                RelativePath="..\..\Modules\_bytesio.c"
+                                >
+                        </File>
 			<File
 				RelativePath="..\..\Modules\_functoolsmodule.c"
 				>
@@ -1339,6 +1343,10 @@
 				>
 			</File>
 			<File
+				RelativePath="..\..\Objects\bytearrayobject.c"
+				>
+			</File>
+			<File
 				RelativePath="..\..\Objects\bytesobject.c"
 				>
 			</File>
@@ -1459,10 +1467,6 @@
 				>
 			</File>
 			<File
-				RelativePath="..\..\Objects\stringobject.c"
-				>
-			</File>
-			<File
 				RelativePath="..\..\Objects\structseq.c"
 				>
 			</File>

Modified: python/branches/py3k/PC/VS8.0/release.vsprops
==============================================================================
--- python/branches/py3k/PC/VS8.0/release.vsprops	(original)
+++ python/branches/py3k/PC/VS8.0/release.vsprops	Fri Jun 13 00:53:41 2008
@@ -8,4 +8,8 @@
 		Name="VCCLCompilerTool"
 		PreprocessorDefinitions="NDEBUG"
 	/>
+	<UserMacro
+		Name="KillPythonExe"
+		Value="$(OutDir)\kill_python.exe"
+	/>	
 </VisualStudioPropertySheet>

Modified: python/branches/py3k/PC/VS8.0/x64.vsprops
==============================================================================
--- python/branches/py3k/PC/VS8.0/x64.vsprops	(original)
+++ python/branches/py3k/PC/VS8.0/x64.vsprops	Fri Jun 13 00:53:41 2008
@@ -15,4 +15,8 @@
 		Name="VCLinkerTool"
 		TargetMachine="17"
 	/>
+	<UserMacro
+		Name="PythonExe"
+		Value="$(HOST_PYTHON)"
+	/>
 </VisualStudioPropertySheet>

Modified: python/branches/py3k/PCbuild/_elementtree.vcproj
==============================================================================
--- python/branches/py3k/PCbuild/_elementtree.vcproj	(original)
+++ python/branches/py3k/PCbuild/_elementtree.vcproj	Fri Jun 13 00:53:41 2008
@@ -56,7 +56,6 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="odbccp32.lib"
 				BaseAddress="0x1D100000"
 			/>
 			<Tool
@@ -119,7 +118,6 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="odbccp32.lib"
 				BaseAddress="0x1D100000"
 			/>
 			<Tool
@@ -182,7 +180,6 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="odbccp32.lib"
 				BaseAddress="0x1D100000"
 			/>
 			<Tool
@@ -246,7 +243,6 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="odbccp32.lib"
 				BaseAddress="0x1D100000"
 			/>
 			<Tool
@@ -309,7 +305,6 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="odbccp32.lib"
 				BaseAddress="0x1D100000"
 			/>
 			<Tool
@@ -373,7 +368,6 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="odbccp32.lib"
 				BaseAddress="0x1D100000"
 				TargetMachine="17"
 			/>
@@ -437,7 +431,6 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="odbccp32.lib"
 				BaseAddress="0x1D100000"
 			/>
 			<Tool
@@ -501,7 +494,6 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="odbccp32.lib"
 				BaseAddress="0x1D100000"
 				TargetMachine="17"
 			/>

Modified: python/branches/py3k/PCbuild/make_versioninfo.vcproj
==============================================================================
--- python/branches/py3k/PCbuild/make_versioninfo.vcproj	(original)
+++ python/branches/py3k/PCbuild/make_versioninfo.vcproj	Fri Jun 13 00:53:41 2008
@@ -67,7 +67,6 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="odbccp32.lib"
 				OutputFile="$(SolutionDir)make_versioninfo.exe"
 				ProgramDatabaseFile="$(TargetDir)$(TargetName).pdb"
 				SubSystem="1"
@@ -211,7 +210,6 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="odbccp32.lib"
 				OutputFile="$(SolutionDir)make_versioninfo_d.exe"
 				ProgramDatabaseFile="$(TargetDir)$(TargetName).pdb"
 				SubSystem="1"

Modified: python/branches/py3k/PCbuild/pcbuild.sln
==============================================================================
--- python/branches/py3k/PCbuild/pcbuild.sln	(original)
+++ python/branches/py3k/PCbuild/pcbuild.sln	Fri Jun 13 00:53:41 2008
@@ -1,5 +1,5 @@
 Microsoft Visual Studio Solution File, Format Version 10.00
-# Visual Studio 2008
+# Visual C++ Express 2008
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "python", "python.vcproj", "{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}"
 	ProjectSection(ProjectDependencies) = postProject
 		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
@@ -152,20 +152,16 @@
 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
 		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Debug|Win32.ActiveCfg = Debug|Win32
 		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Debug|Win32.Build.0 = Debug|Win32
-		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Debug|x64.ActiveCfg = Debug|x64
-		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Debug|x64.Build.0 = Debug|x64
+		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Debug|x64.ActiveCfg = Debug|Win32
 		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
 		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
-		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
-		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGInstrument|x64.Build.0 = PGInstrument|x64
+		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGInstrument|x64.ActiveCfg = PGInstrument|Win32
 		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
 		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
-		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
-		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGUpdate|x64.Build.0 = PGUpdate|x64
+		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGUpdate|x64.ActiveCfg = PGUpdate|Win32
 		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release|Win32.ActiveCfg = Release|Win32
 		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release|Win32.Build.0 = Release|Win32
-		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release|x64.ActiveCfg = Release|x64
-		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release|x64.Build.0 = Release|x64
+		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release|x64.ActiveCfg = Release|Win32
 		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Debug|Win32.ActiveCfg = Debug|Win32
 		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Debug|Win32.Build.0 = Debug|Win32
 		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Debug|x64.ActiveCfg = Debug|Win32
@@ -312,20 +308,16 @@
 		{9EC7190A-249F-4180-A900-548FDCF3055F}.Release|x64.Build.0 = Release|x64
 		{17E1E049-C309-4D79-843F-AE483C264AEA}.Debug|Win32.ActiveCfg = Debug|Win32
 		{17E1E049-C309-4D79-843F-AE483C264AEA}.Debug|Win32.Build.0 = Debug|Win32
-		{17E1E049-C309-4D79-843F-AE483C264AEA}.Debug|x64.ActiveCfg = Debug|x64
-		{17E1E049-C309-4D79-843F-AE483C264AEA}.Debug|x64.Build.0 = Debug|x64
+		{17E1E049-C309-4D79-843F-AE483C264AEA}.Debug|x64.ActiveCfg = Debug|Win32
 		{17E1E049-C309-4D79-843F-AE483C264AEA}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
 		{17E1E049-C309-4D79-843F-AE483C264AEA}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
-		{17E1E049-C309-4D79-843F-AE483C264AEA}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
-		{17E1E049-C309-4D79-843F-AE483C264AEA}.PGInstrument|x64.Build.0 = PGInstrument|x64
+		{17E1E049-C309-4D79-843F-AE483C264AEA}.PGInstrument|x64.ActiveCfg = PGInstrument|Win32
 		{17E1E049-C309-4D79-843F-AE483C264AEA}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
 		{17E1E049-C309-4D79-843F-AE483C264AEA}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
-		{17E1E049-C309-4D79-843F-AE483C264AEA}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
-		{17E1E049-C309-4D79-843F-AE483C264AEA}.PGUpdate|x64.Build.0 = PGUpdate|x64
+		{17E1E049-C309-4D79-843F-AE483C264AEA}.PGUpdate|x64.ActiveCfg = PGUpdate|Win32
 		{17E1E049-C309-4D79-843F-AE483C264AEA}.Release|Win32.ActiveCfg = Release|Win32
 		{17E1E049-C309-4D79-843F-AE483C264AEA}.Release|Win32.Build.0 = Release|Win32
-		{17E1E049-C309-4D79-843F-AE483C264AEA}.Release|x64.ActiveCfg = Release|x64
-		{17E1E049-C309-4D79-843F-AE483C264AEA}.Release|x64.Build.0 = Release|x64
+		{17E1E049-C309-4D79-843F-AE483C264AEA}.Release|x64.ActiveCfg = Release|Win32
 		{31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Debug|Win32.ActiveCfg = Debug|Win32
 		{31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Debug|Win32.Build.0 = Debug|Win32
 		{31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Debug|x64.ActiveCfg = Debug|x64

Modified: python/branches/py3k/PCbuild/python.vcproj
==============================================================================
--- python/branches/py3k/PCbuild/python.vcproj	(original)
+++ python/branches/py3k/PCbuild/python.vcproj	Fri Jun 13 00:53:41 2008
@@ -62,7 +62,6 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="odbccp32.lib"
 				OutputFile="$(OutDir)\python.exe"
 				SubSystem="1"
 				StackReserveSize="2000000"
@@ -136,7 +135,6 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="odbccp32.lib"
 				OutputFile="$(OutDir)\python.exe"
 				SubSystem="1"
 				StackReserveSize="2000000"
@@ -211,7 +209,6 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="odbccp32.lib"
 				OutputFile="$(OutDir)\python_d.exe"
 				SubSystem="1"
 				StackReserveSize="2000000"
@@ -287,7 +284,6 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="odbccp32.lib"
 				OutputFile="$(OutDir)\python_d.exe"
 				SubSystem="1"
 				StackReserveSize="2100000"
@@ -360,7 +356,6 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="odbccp32.lib"
 				OutputFile="$(OutDir)\python.exe"
 				SubSystem="1"
 				StackReserveSize="2000000"
@@ -435,7 +430,6 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="odbccp32.lib"
 				OutputFile="$(OutDir)\python.exe"
 				SubSystem="1"
 				StackReserveSize="2000000"
@@ -510,7 +504,6 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="odbccp32.lib"
 				OutputFile="$(OutDir)\python.exe"
 				SubSystem="1"
 				StackReserveSize="2000000"
@@ -585,7 +578,6 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="odbccp32.lib"
 				OutputFile="$(OutDir)\python.exe"
 				SubSystem="1"
 				StackReserveSize="2000000"

Modified: python/branches/py3k/PCbuild/vs9to8.py
==============================================================================
--- python/branches/py3k/PCbuild/vs9to8.py	(original)
+++ python/branches/py3k/PCbuild/vs9to8.py	Fri Jun 13 00:53:41 2008
@@ -22,6 +22,12 @@
             lines = lines.replace('..\\', '..\\..\\')
             lines = lines.replace('..\\..\\..\\..\\', '..\\..\\..\\')
 
+            # Bah. VS8.0 does not expand macros in file names.
+            # Replace them here.
+            lines = lines.replace('$(sqlite3Dir)', '..\\..\\..\\sqlite-source-3.3.4')
+            lines = lines.replace('$(bsddbDir)\\..\\..', '..\\..\\..\\db-4.4.20\\build_win32\\..')
+            lines = lines.replace('$(bsddbDir)', '..\\..\\..\\db-4.4.20\\build_win32')
+
         with open(destname, 'wb') as fout:
             lines = lines.replace("\n", "\r\n").encode()
             fout.write(lines)

From python-3000-checkins at python.org  Fri Jun 13 01:03:42 2008
From: python-3000-checkins at python.org (amaury.forgeotdarc)
Date: Fri, 13 Jun 2008 01:03:42 +0200 (CEST)
Subject: [Python-3000-checkins] r64210 - in python/branches/py3k:
	Modules/socketmodule.c PC/pyconfig.h
Message-ID: <20080612230342.2F1EE1E4002@bag.python.org>

Author: amaury.forgeotdarc
Date: Fri Jun 13 01:03:41 2008
New Revision: 64210

Log:
Slowly apply part of #2065: py3k can be compiled with VS8.0


Modified:
   python/branches/py3k/Modules/socketmodule.c
   python/branches/py3k/PC/pyconfig.h

Modified: python/branches/py3k/Modules/socketmodule.c
==============================================================================
--- python/branches/py3k/Modules/socketmodule.c	(original)
+++ python/branches/py3k/Modules/socketmodule.c	Fri Jun 13 01:03:41 2008
@@ -5001,8 +5001,12 @@
 	PyModule_AddIntConstant(m, "RCVALL_OFF", RCVALL_OFF);
 	PyModule_AddIntConstant(m, "RCVALL_ON", RCVALL_ON);
 	PyModule_AddIntConstant(m, "RCVALL_SOCKETLEVELONLY", RCVALL_SOCKETLEVELONLY);
+#ifdef RCVALL_IPLEVEL
 	PyModule_AddIntConstant(m, "RCVALL_IPLEVEL", RCVALL_IPLEVEL);
+#endif
+#ifdef RCVALL_MAX
 	PyModule_AddIntConstant(m, "RCVALL_MAX", RCVALL_MAX);
+#endif
 #endif /* _MSTCPIP_ */
 
 	/* Initialize gethostbyname lock */

Modified: python/branches/py3k/PC/pyconfig.h
==============================================================================
--- python/branches/py3k/PC/pyconfig.h	(original)
+++ python/branches/py3k/PC/pyconfig.h	Fri Jun 13 01:03:41 2008
@@ -158,11 +158,11 @@
 /* set the version macros for the windows headers */
 #ifdef MS_WINX64
 /* 64 bit only runs on XP or greater */
-#define Py_WINVER _WIN32_WINNT_WINXP
+#define Py_WINVER 0x0501 /* _WIN32_WINNT_WINXP */
 #define Py_NTDDI NTDDI_WINXP
 #else
 /* Python 2.6+ requires Windows 2000 or greater */
-#define Py_WINVER _WIN32_WINNT_WIN2K
+#define Py_WINVER 0x0500 /* _WIN32_WINNT_WIN2K */
 #define Py_NTDDI NTDDI_WIN2KSP4
 #endif
 

From alexandre at peadrop.com  Fri Jun 13 01:52:26 2008
From: alexandre at peadrop.com (Alexandre Vassalotti)
Date: Thu, 12 Jun 2008 19:52:26 -0400
Subject: [Python-3000-checkins] r64205 - in python/branches/py3k:
	PC/VC6/pythoncore.dsp PC/VS7.1/pythoncore.vcproj
	PC/VS8.0/pythoncore.vcproj PC/config.c PCbuild/pythoncore.vcproj
In-Reply-To: <20080612222728.2992E1E4002@bag.python.org>
References: <20080612222728.2992E1E4002@bag.python.org>
Message-ID: <acd65fa20806121652h5a8748e3g3eeab2401825b203@mail.gmail.com>

On Thu, Jun 12, 2008 at 6:27 PM, amaury.forgeotdarc
<python-3000-checkins at python.org> wrote:
> Author: amaury.forgeotdarc
> Date: Fri Jun 13 00:27:27 2008
> New Revision: 64205
>
> Log:
> On Windows, repair compilation of builtin modules _stringio and _pickle.
>
> (Alexandre, the MSVC build files are in PCBuild.
> the PC/Vxxx directories try to support older compilers)
>
>

Oh thank you!

-- Alexandre

From python-3000-checkins at python.org  Fri Jun 13 02:26:50 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Fri, 13 Jun 2008 02:26:50 +0200 (CEST)
Subject: [Python-3000-checkins] r64213 - in python/branches/py3k:
	Include/pythread.h Modules/signalmodule.c Parser/intrcheck.c
	Python/thread.c
Message-ID: <20080613002650.B6CC01E4002@bag.python.org>

Author: benjamin.peterson
Date: Fri Jun 13 02:26:50 2008
New Revision: 64213

Log:
Merged revisions 64212 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/trunk

........
  r64212 | benjamin.peterson | 2008-06-12 19:09:47 -0500 (Thu, 12 Jun 2008) | 3 lines
  
  #1683 prevent forking from interfering in threading storage
  This should prevent some test_multiprocessing failures
........


Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Include/pythread.h
   python/branches/py3k/Modules/signalmodule.c
   python/branches/py3k/Parser/intrcheck.c
   python/branches/py3k/Python/thread.c

Modified: python/branches/py3k/Include/pythread.h
==============================================================================
--- python/branches/py3k/Include/pythread.h	(original)
+++ python/branches/py3k/Include/pythread.h	Fri Jun 13 02:26:50 2008
@@ -40,6 +40,9 @@
 PyAPI_FUNC(void *) PyThread_get_key_value(int);
 PyAPI_FUNC(void) PyThread_delete_key_value(int key);
 
+/* Cleanup after a fork */
+PyAPI_FUNC(void) PyThread_ReInitTLS(void);
+
 #ifdef __cplusplus
 }
 #endif

Modified: python/branches/py3k/Modules/signalmodule.c
==============================================================================
--- python/branches/py3k/Modules/signalmodule.c	(original)
+++ python/branches/py3k/Modules/signalmodule.c	Fri Jun 13 02:26:50 2008
@@ -941,5 +941,6 @@
 	main_thread = PyThread_get_thread_ident();
 	main_pid = getpid();
 	_PyImport_ReInitLock();
+	PyThread_ReInitTLS();
 #endif
 }

Modified: python/branches/py3k/Parser/intrcheck.c
==============================================================================
--- python/branches/py3k/Parser/intrcheck.c	(original)
+++ python/branches/py3k/Parser/intrcheck.c	Fri Jun 13 02:26:50 2008
@@ -2,6 +2,7 @@
 /* Check for interrupts */
 
 #include "Python.h"
+#include "pythread.h"
 
 #ifdef QUICKWIN
 
@@ -168,5 +169,6 @@
 {
 #ifdef WITH_THREAD
 	PyEval_ReInitThreads();
+	PyThread_ReInitTLS();
 #endif
 }

Modified: python/branches/py3k/Python/thread.c
==============================================================================
--- python/branches/py3k/Python/thread.c	(original)
+++ python/branches/py3k/Python/thread.c	Fri Jun 13 02:26:50 2008
@@ -377,4 +377,35 @@
 	PyThread_release_lock(keymutex);
 }
 
+/* Forget everything not associated with the current thread id.
+ * This function is called from PyOS_AfterFork().  It is necessary
+ * because other thread ids which were in use at the time of the fork
+ * may be reused for new threads created in the forked process.
+ */
+void
+PyThread_ReInitTLS(void)
+{
+	long id = PyThread_get_thread_ident();
+	struct key *p, **q;
+
+	if (!keymutex)
+		return;
+	
+	/* As with interpreter_lock in PyEval_ReInitThreads()
+	   we just create a new lock without freeing the old one */
+	keymutex = PyThread_allocate_lock();
+
+	/* Delete all keys which do not match the current thread id */
+	q = &keyhead;
+	while ((p = *q) != NULL) {
+		if (p->id != id) {
+			*q = p->next;
+			free((void *)p);
+			/* NB This does *not* free p->value! */
+		}
+		else
+			q = &p->next;
+	}
+}
+
 #endif /* Py_HAVE_NATIVE_TLS */

From python-3000-checkins at python.org  Fri Jun 13 03:09:35 2008
From: python-3000-checkins at python.org (amaury.forgeotdarc)
Date: Fri, 13 Jun 2008 03:09:35 +0200 (CEST)
Subject: [Python-3000-checkins] r64215 - in python/branches/py3k:
	Include/pythonrun.h Modules/errnomodule.c
	Modules/socketmodule.c Modules/socketmodule.h
	PC/VC6/_socket.dsp PC/VC6/pythoncore.dsp PC/getpathp.c
	PC/msvcrtmodule.c PC/pyconfig.h
Message-ID: <20080613010935.2DAB91E4002@bag.python.org>

Author: amaury.forgeotdarc
Date: Fri Jun 13 03:09:34 2008
New Revision: 64215

Log:
Merged revisions 64214 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/trunk

........
  r64214 | amaury.forgeotdarc | 2008-06-13 02:42:22 +0200 (ven., 13 juin 2008) | 6 lines
  
  Restore support for Microsoft VC6 compiler.
  Some functions in the msvcrt module are skipped,
  and socket.ioctl is enabled only when using a more recent Platform SDK.
  
  (and yes, there are still companies that use a 10-years old compiler)
........


Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Include/pythonrun.h
   python/branches/py3k/Modules/errnomodule.c
   python/branches/py3k/Modules/socketmodule.c
   python/branches/py3k/Modules/socketmodule.h
   python/branches/py3k/PC/VC6/_socket.dsp
   python/branches/py3k/PC/VC6/pythoncore.dsp
   python/branches/py3k/PC/getpathp.c
   python/branches/py3k/PC/msvcrtmodule.c
   python/branches/py3k/PC/pyconfig.h

Modified: python/branches/py3k/Include/pythonrun.h
==============================================================================
--- python/branches/py3k/Include/pythonrun.h	(original)
+++ python/branches/py3k/Include/pythonrun.h	Fri Jun 13 03:09:34 2008
@@ -154,7 +154,7 @@
    to a 8k margin. */
 #define PYOS_STACK_MARGIN 2048
 
-#if defined(WIN32) && !defined(MS_WIN64) && defined(_MSC_VER)
+#if defined(WIN32) && !defined(MS_WIN64) && defined(_MSC_VER) && _MSC_VER >= 1300
 /* Enable stack checking under Microsoft C */
 #define USE_STACKCHECK
 #endif

Modified: python/branches/py3k/Modules/errnomodule.c
==============================================================================
--- python/branches/py3k/Modules/errnomodule.c	(original)
+++ python/branches/py3k/Modules/errnomodule.c	Fri Jun 13 03:09:34 2008
@@ -6,7 +6,7 @@
 /* Windows socket errors (WSA*)  */
 #ifdef MS_WINDOWS
 #define WIN32_LEAN_AND_MEAN
-#include <winsock.h>
+#include <windows.h>
 #endif
 
 /*

Modified: python/branches/py3k/Modules/socketmodule.c
==============================================================================
--- python/branches/py3k/Modules/socketmodule.c	(original)
+++ python/branches/py3k/Modules/socketmodule.c	Fri Jun 13 03:09:34 2008
@@ -2628,7 +2628,7 @@
 Shut down the reading side of the socket (flag == SHUT_RD), the writing side\n\
 of the socket (flag == SHUT_WR), or both ends (flag == SHUT_RDWR).");
 
-#ifdef MS_WINDOWS
+#if defined(MS_WINDOWS) && defined(SIO_RCVALL)
 static PyObject*
 sock_ioctl(PySocketSockObject *s, PyObject *arg)
 {
@@ -2677,7 +2677,7 @@
 			  METH_NOARGS, getsockname_doc},
 	{"getsockopt",	  (PyCFunction)sock_getsockopt, METH_VARARGS,
 			  getsockopt_doc},
-#ifdef MS_WINDOWS
+#if defined(MS_WINDOWS) && defined(SIO_RCVALL)
 	{"ioctl",	  (PyCFunction)sock_ioctl, METH_VARARGS,
 			  sock_ioctl_doc},
 #endif

Modified: python/branches/py3k/Modules/socketmodule.h
==============================================================================
--- python/branches/py3k/Modules/socketmodule.h	(original)
+++ python/branches/py3k/Modules/socketmodule.h	Fri Jun 13 03:09:34 2008
@@ -13,20 +13,23 @@
 # endif
 
 #else /* MS_WINDOWS */
-#if _MSC_VER >= 1300
 # include <winsock2.h>
 # include <ws2tcpip.h>
-# include <MSTcpIP.h> /* for SIO_RCVALL */
-# define HAVE_ADDRINFO
-# define HAVE_SOCKADDR_STORAGE
-# define HAVE_GETADDRINFO
-# define HAVE_GETNAMEINFO
-# define ENABLE_IPV6
-#else
-# define WIN32_LEAN_AND_MEAN
-# include <winsock.h>
-#endif
-#endif
+/* VC6 is shipped with old platform headers, and does not have MSTcpIP.h
+ * Separate SDKs have all the functions we want, but older ones don't have
+ * any version information. I use IPPROTO_IPV6 to detect a decent SDK.
+ */
+# ifdef IPPROTO_IPV6
+#  include <MSTcpIP.h> /* for SIO_RCVALL */
+#  define HAVE_ADDRINFO
+#  define HAVE_SOCKADDR_STORAGE
+#  define HAVE_GETADDRINFO
+#  define HAVE_GETNAMEINFO
+#  define ENABLE_IPV6
+# else
+typedef int socklen_t;
+# endif /* IPPROTO_IPV6 */
+#endif /* MS_WINDOWS */
 
 #ifdef HAVE_SYS_UN_H
 # include <sys/un.h>

Modified: python/branches/py3k/PC/VC6/_socket.dsp
==============================================================================
--- python/branches/py3k/PC/VC6/_socket.dsp	(original)
+++ python/branches/py3k/PC/VC6/_socket.dsp	Fri Jun 13 03:09:34 2008
@@ -54,7 +54,7 @@
 # ADD BSC32 /nologo
 LINK32=link.exe
 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
-# ADD LINK32 user32.lib kernel32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /base:"0x1e1D0000" /subsystem:windows /dll /debug /machine:I386 /out:"./_socket.pyd"
+# ADD LINK32 user32.lib kernel32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ws2_32.lib /nologo /base:"0x1e1D0000" /subsystem:windows /dll /debug /machine:I386 /out:"./_socket.pyd"
 # SUBTRACT LINK32 /pdb:none
 
 !ELSEIF  "$(CFG)" == "_socket - Win32 Debug"
@@ -82,7 +82,7 @@
 # ADD BSC32 /nologo
 LINK32=link.exe
 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 user32.lib kernel32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /base:"0x1e1D0000" /subsystem:windows /dll /debug /machine:I386 /out:"./_socket_d.pyd" /pdbtype:sept
+# ADD LINK32 user32.lib kernel32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ws2_32.lib /nologo /base:"0x1e1D0000" /subsystem:windows /dll /debug /machine:I386 /out:"./_socket_d.pyd" /pdbtype:sept
 # SUBTRACT LINK32 /pdb:none
 
 !ENDIF 

Modified: python/branches/py3k/PC/VC6/pythoncore.dsp
==============================================================================
--- python/branches/py3k/PC/VC6/pythoncore.dsp	(original)
+++ python/branches/py3k/PC/VC6/pythoncore.dsp	Fri Jun 13 03:09:34 2008
@@ -97,6 +97,10 @@
 # End Source File
 # Begin Source File
 
+SOURCE=..\..\Modules\_bytesio.c
+# End Source File
+# Begin Source File
+
 SOURCE=..\..\Modules\cjkcodecs\_codecs_cn.c
 # End Source File
 # Begin Source File
@@ -137,10 +141,6 @@
 # End Source File
 # Begin Source File
 
-SOURCE=..\..\Modules\_bytesio.c
-# End Source File
-# Begin Source File
-
 SOURCE=..\..\Modules\_functoolsmodule.c
 # End Source File
 # Begin Source File
@@ -245,6 +245,10 @@
 # End Source File
 # Begin Source File
 
+SOURCE=..\..\Objects\bytearrayobject.c
+# End Source File
+# Begin Source File
+
 SOURCE=..\..\Objects\bytes_methods.c
 # End Source File
 # Begin Source File
@@ -281,10 +285,6 @@
 # End Source File
 # Begin Source File
 
-SOURCE=..\..\Modules\_collectionsmodule.c
-# End Source File
-# Begin Source File
-
 SOURCE=..\..\Python\compile.c
 # End Source File
 # Begin Source File
@@ -365,10 +365,6 @@
 # End Source File
 # Begin Source File
 
-SOURCE=..\..\Python\formatter_string.c
-# End Source File
-# Begin Source File
-
 SOURCE=..\..\Python\formatter_unicode.c
 # End Source File
 # Begin Source File
@@ -377,10 +373,6 @@
 # End Source File
 # Begin Source File
 
-SOURCE=..\..\Python\formatter_unicode.c
-# End Source File
-# Begin Source File
-
 SOURCE=..\..\Python\frozen.c
 # End Source File
 # Begin Source File
@@ -659,10 +651,6 @@
 # End Source File
 # Begin Source File
 
-SOURCE=..\..\Objects\stringobject.c
-# End Source File
-# Begin Source File
-
 SOURCE=..\..\Python\structmember.c
 # End Source File
 # Begin Source File

Modified: python/branches/py3k/PC/getpathp.c
==============================================================================
--- python/branches/py3k/PC/getpathp.c	(original)
+++ python/branches/py3k/PC/getpathp.c	Fri Jun 13 03:09:34 2008
@@ -117,8 +117,7 @@
 static int
 exists(wchar_t *filename)
 {
-	struct _stat64 buf;
-	return _wstat64(filename, &buf) == 0;
+	return GetFileAttributesW(filename) != 0xFFFFFFFF;
 }
 
 /* Assumes 'filename' MAXPATHLEN+1 bytes long - 

Modified: python/branches/py3k/PC/msvcrtmodule.c
==============================================================================
--- python/branches/py3k/PC/msvcrtmodule.c	(original)
+++ python/branches/py3k/PC/msvcrtmodule.c	Fri Jun 13 03:09:34 2008
@@ -145,7 +145,7 @@
 	return PyBytes_FromStringAndSize(s, 1);
 }
 
-#if _MSC_VER >= 1300
+#ifdef _WCONIO_DEFINED
 static PyObject *
 msvcrt_getwch(PyObject *self, PyObject *args)
 {
@@ -179,7 +179,7 @@
 	return PyBytes_FromStringAndSize(s, 1);
 }
 
-#if _MSC_VER >= 1300
+#ifdef _WCONIO_DEFINED
 static PyObject *
 msvcrt_getwche(PyObject *self, PyObject *args)
 {
@@ -210,8 +210,7 @@
 	return Py_None;
 }
 
-
-#if _MSC_VER >= 1300
+#ifdef _WCONIO_DEFINED
 static PyObject *
 msvcrt_putwch(PyObject *self, PyObject *args)
 {
@@ -246,7 +245,7 @@
 	return Py_None;
 }
 
-#if _MSC_VER >= 1300
+#ifdef _WCONIO_DEFINED
 static PyObject *
 msvcrt_ungetwch(PyObject *self, PyObject *args)
 {
@@ -349,7 +348,7 @@
 	{"CrtSetReportMode",	msvcrt_setreportmode, METH_VARARGS},
 	{"set_error_mode",	msvcrt_seterrormode, METH_VARARGS},
 #endif
-#if _MSC_VER >= 1300
+#ifdef _WCONIO_DEFINED
 	{"getwch",		msvcrt_getwch, METH_VARARGS},
 	{"getwche",		msvcrt_getwche, METH_VARARGS},
 	{"putwch",		msvcrt_putwch, METH_VARARGS},

Modified: python/branches/py3k/PC/pyconfig.h
==============================================================================
--- python/branches/py3k/PC/pyconfig.h	(original)
+++ python/branches/py3k/PC/pyconfig.h	Fri Jun 13 03:09:34 2008
@@ -463,13 +463,6 @@
 /* Define to `unsigned' if <sys/types.h> doesn't define.  */
 /* #undef size_t */
 
-/* Define to `int' if <sys/types.h> doesn't define.  */
-#if _MSC_VER + 0 >= 1300
-/* VC.NET typedefs socklen_t in ws2tcpip.h. */
-#else
-#define socklen_t int
-#endif
-
 /* Define if you have the ANSI C header files.  */
 #define STDC_HEADERS 1
 

From python-3000-checkins at python.org  Fri Jun 13 03:31:43 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Fri, 13 Jun 2008 03:31:43 +0200 (CEST)
Subject: [Python-3000-checkins] r64216 -
	python/branches/py3k/Lib/subprocess.py
Message-ID: <20080613013143.769111E4002@bag.python.org>

Author: benjamin.peterson
Date: Fri Jun 13 03:31:43 2008
New Revision: 64216

Log:
fix more threading API usage

Modified:
   python/branches/py3k/Lib/subprocess.py

Modified: python/branches/py3k/Lib/subprocess.py
==============================================================================
--- python/branches/py3k/Lib/subprocess.py	(original)
+++ python/branches/py3k/Lib/subprocess.py	Fri Jun 13 03:31:43 2008
@@ -872,13 +872,13 @@
                 stdout = []
                 stdout_thread = threading.Thread(target=self._readerthread,
                                                  args=(self.stdout, stdout))
-                stdout_thread.setDaemon(True)
+                stdout_thread.set_daemon(True)
                 stdout_thread.start()
             if self.stderr:
                 stderr = []
                 stderr_thread = threading.Thread(target=self._readerthread,
                                                  args=(self.stderr, stderr))
-                stderr_thread.setDaemon(True)
+                stderr_thread.set_daemon(True)
                 stderr_thread.start()
 
             if self.stdin:

From python-3000-checkins at python.org  Fri Jun 13 04:00:48 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Fri, 13 Jun 2008 04:00:48 +0200 (CEST)
Subject: [Python-3000-checkins] r64217 - in python/branches/py3k/Lib:
	bsddb/test/test_associate.py bsddb/test/test_join.py
	bsddb/test/test_lock.py bsddb/test/test_thread.py
	idlelib/rpc.py idlelib/run.py socketserver.py
	test/test_threadedtempfile.py threading.py
Message-ID: <20080613020048.264021E4002@bag.python.org>

Author: benjamin.peterson
Date: Fri Jun 13 04:00:47 2008
New Revision: 64217

Log:
fix more threading API related bugs

Modified:
   python/branches/py3k/Lib/bsddb/test/test_associate.py
   python/branches/py3k/Lib/bsddb/test/test_join.py
   python/branches/py3k/Lib/bsddb/test/test_lock.py
   python/branches/py3k/Lib/bsddb/test/test_thread.py
   python/branches/py3k/Lib/idlelib/rpc.py
   python/branches/py3k/Lib/idlelib/run.py
   python/branches/py3k/Lib/socketserver.py
   python/branches/py3k/Lib/test/test_threadedtempfile.py
   python/branches/py3k/Lib/threading.py

Modified: python/branches/py3k/Lib/bsddb/test/test_associate.py
==============================================================================
--- python/branches/py3k/Lib/bsddb/test/test_associate.py	(original)
+++ python/branches/py3k/Lib/bsddb/test/test_associate.py	Fri Jun 13 04:00:47 2008
@@ -9,7 +9,7 @@
 from pprint import pprint
 
 try:
-    from threading import Thread, currentThread
+    from threading import Thread, current_thread
     have_threads = 1
 except ImportError:
     have_threads = 0

Modified: python/branches/py3k/Lib/bsddb/test/test_join.py
==============================================================================
--- python/branches/py3k/Lib/bsddb/test/test_join.py	(original)
+++ python/branches/py3k/Lib/bsddb/test/test_join.py	Fri Jun 13 04:00:47 2008
@@ -8,7 +8,7 @@
 from pprint import pprint
 
 try:
-    from threading import Thread, currentThread
+    from threading import Thread, current_thread
     have_threads = 1
 except ImportError:
     have_threads = 0

Modified: python/branches/py3k/Lib/bsddb/test/test_lock.py
==============================================================================
--- python/branches/py3k/Lib/bsddb/test/test_lock.py	(original)
+++ python/branches/py3k/Lib/bsddb/test/test_lock.py	Fri Jun 13 04:00:47 2008
@@ -7,7 +7,7 @@
 import time
 
 try:
-    from threading import Thread, currentThread
+    from threading import Thread, current_thread
     have_threads = 1
 except ImportError:
     have_threads = 0
@@ -117,7 +117,7 @@
         deadlock_detection.end=False
         deadlock_detection.count=0
         t=Thread(target=deadlock_detection)
-        t.setDaemon(True)
+        t.set_daemon(True)
         t.start()
         self.env.set_timeout(100000, db.DB_SET_LOCK_TIMEOUT)
         anID = self.env.lock_id()
@@ -143,7 +143,7 @@
             self.assertTrue(deadlock_detection.count>0)
 
     def theThread(self, sleepTime, lockType):
-        name = currentThread().getName()
+        name = current_thread().get_name()
         if lockType ==  db.DB_LOCK_WRITE:
             lt = "write"
         else:

Modified: python/branches/py3k/Lib/bsddb/test/test_thread.py
==============================================================================
--- python/branches/py3k/Lib/bsddb/test/test_thread.py	(original)
+++ python/branches/py3k/Lib/bsddb/test/test_thread.py	Fri Jun 13 04:00:47 2008
@@ -12,7 +12,7 @@
 DASH = b'-'
 
 try:
-    from threading import Thread, currentThread
+    from threading import Thread, current_thread
     have_threads = True
 except ImportError:
     have_threads = False
@@ -89,20 +89,20 @@
             self._writerThread(*args, **kwargs)
         except db.DBLockDeadlockError:
             if verbose:
-                print(currentThread().getName(), 'died from', e)
+                print(current_thread().get_name(), 'died from', e)
         else:
             if verbose:
-                print(currentThread().getName(), "finished.")
+                print(current_thread().get_name(), "finished.")
 
     def readerThread(self, *args, **kwargs):
         try:
             self._readerThread(*args, **kwargs)
         except db.DBLockDeadlockError as e:
             if verbose:
-                print(currentThread().getName(), 'died from', e)
+                print(current_thread().get_name(), 'died from', e)
         else:
             if verbose:
-                print(currentThread().getName(), "finished.")
+                print(current_thread().get_name(), "finished.")
 
 
 
@@ -143,7 +143,7 @@
             t.join()
 
     def _writerThread(self, d, howMany):
-        name = currentThread().getName()
+        name = current_thread().get_name()
         start = 0
         stop = howMany
         if verbose:
@@ -172,7 +172,7 @@
 
     def _readerThread(self, d, readerNum):
         time.sleep(0.01 * readerNum)
-        name = currentThread().getName()
+        name = current_thread().get_name()
 
         for loop in range(5):
             c = d.cursor()
@@ -240,7 +240,7 @@
             t.join()
 
     def _writerThread(self, d, howMany, writerNum):
-        name = currentThread().getName()
+        name = current_thread().get_name()
         start = howMany * writerNum
         stop = howMany * (writerNum + 1) - 1
         if verbose:
@@ -286,7 +286,7 @@
 
     def _readerThread(self, d, readerNum):
         time.sleep(0.01 * readerNum)
-        name = currentThread().getName()
+        name = current_thread().get_name()
 
         for loop in range(5):
             c = d.cursor()
@@ -385,7 +385,7 @@
                 time.sleep(0.05)
 
     def _writerThread(self, d, howMany, writerNum):
-        name = currentThread().getName()
+        name = current_thread().get_name()
         start = howMany * writerNum
         stop = howMany * (writerNum + 1) - 1
         if verbose:
@@ -427,7 +427,7 @@
 
     def _readerThread(self, d, readerNum):
         time.sleep(0.01 * readerNum + 0.05)
-        name = currentThread().getName()
+        name = current_thread().get_name()
 
         for loop in range(5):
             finished = False

Modified: python/branches/py3k/Lib/idlelib/rpc.py
==============================================================================
--- python/branches/py3k/Lib/idlelib/rpc.py	(original)
+++ python/branches/py3k/Lib/idlelib/rpc.py	Fri Jun 13 04:00:47 2008
@@ -106,7 +106,7 @@
             erf = sys.__stderr__
             print('\n' + '-'*40, file=erf)
             print('Unhandled server exception!', file=erf)
-            print('Thread: %s' % threading.currentThread().getName(), file=erf)
+            print('Thread: %s' % threading.current_thread().get_name(), file=erf)
             print('Client Address: ', client_address, file=erf)
             print('Request: ', repr(request), file=erf)
             traceback.print_exc(file=erf)
@@ -126,7 +126,7 @@
     nextseq = 0
 
     def __init__(self, sock, objtable=None, debugging=None):
-        self.sockthread = threading.currentThread()
+        self.sockthread = threading.current_thread()
         if debugging is not None:
             self.debugging = debugging
         self.sock = sock
@@ -149,7 +149,7 @@
     def debug(self, *args):
         if not self.debugging:
             return
-        s = self.location + " " + str(threading.currentThread().getName())
+        s = self.location + " " + str(threading.current_thread().getName())
         for a in args:
             s = s + " " + str(a)
         print(s, file=sys.__stderr__)
@@ -218,7 +218,7 @@
     def asynccall(self, oid, methodname, args, kwargs):
         request = ("CALL", (oid, methodname, args, kwargs))
         seq = self.newseq()
-        if threading.currentThread() != self.sockthread:
+        if threading.current_thread() != self.sockthread:
             cvar = threading.Condition()
             self.cvars[seq] = cvar
         self.debug(("asynccall:%d:" % seq), oid, methodname, args, kwargs)
@@ -228,7 +228,7 @@
     def asyncqueue(self, oid, methodname, args, kwargs):
         request = ("QUEUE", (oid, methodname, args, kwargs))
         seq = self.newseq()
-        if threading.currentThread() != self.sockthread:
+        if threading.current_thread() != self.sockthread:
             cvar = threading.Condition()
             self.cvars[seq] = cvar
         self.debug(("asyncqueue:%d:" % seq), oid, methodname, args, kwargs)
@@ -294,7 +294,7 @@
 
     def _getresponse(self, myseq, wait):
         self.debug("_getresponse:myseq:", myseq)
-        if threading.currentThread() is self.sockthread:
+        if threading.current_thread() is self.sockthread:
             # this thread does all reading of requests or responses
             while 1:
                 response = self.pollresponse(myseq, wait)

Modified: python/branches/py3k/Lib/idlelib/run.py
==============================================================================
--- python/branches/py3k/Lib/idlelib/run.py	(original)
+++ python/branches/py3k/Lib/idlelib/run.py	Fri Jun 13 04:00:47 2008
@@ -73,7 +73,7 @@
     sockthread = threading.Thread(target=manage_socket,
                                   name='SockThread',
                                   args=((LOCALHOST, port),))
-    sockthread.setDaemon(True)
+    sockthread.set_daemon(True)
     sockthread.start()
     while 1:
         try:
@@ -227,7 +227,7 @@
             erf = sys.__stderr__
             print('\n' + '-'*40, file=erf)
             print('Unhandled server exception!', file=erf)
-            print('Thread: %s' % threading.currentThread().getName(), file=erf)
+            print('Thread: %s' % threading.current_thread().get_name(), file=erf)
             print('Client Address: ', client_address, file=erf)
             print('Request: ', repr(request), file=erf)
             traceback.print_exc(file=erf)

Modified: python/branches/py3k/Lib/socketserver.py
==============================================================================
--- python/branches/py3k/Lib/socketserver.py	(original)
+++ python/branches/py3k/Lib/socketserver.py	Fri Jun 13 04:00:47 2008
@@ -566,7 +566,7 @@
         t = threading.Thread(target = self.process_request_thread,
                              args = (request, client_address))
         if self.daemon_threads:
-            t.setDaemon (1)
+            t.set_daemon(True)
         t.start()
 
 

Modified: python/branches/py3k/Lib/test/test_threadedtempfile.py
==============================================================================
--- python/branches/py3k/Lib/test/test_threadedtempfile.py	(original)
+++ python/branches/py3k/Lib/test/test_threadedtempfile.py	Fri Jun 13 04:00:47 2008
@@ -63,7 +63,7 @@
             t.join()
             ok += t.ok_count
             if t.error_count:
-                errors.append(str(t.getName()) + str(t.errors.getvalue()))
+                errors.append(str(t.get_name()) + str(t.errors.getvalue()))
 
         threading_cleanup(*thread_info)
 

Modified: python/branches/py3k/Lib/threading.py
==============================================================================
--- python/branches/py3k/Lib/threading.py	(original)
+++ python/branches/py3k/Lib/threading.py	Fri Jun 13 04:00:47 2008
@@ -856,7 +856,7 @@
     P = []
     for i in range(NP):
         t = ProducerThread(Q, NI)
-        t.setName("Producer-%d" % (i+1))
+        t.set_name("Producer-%d" % (i+1))
         P.append(t)
     C = ConsumerThread(Q, NI*NP)
     for t in P:

From python-3000-checkins at python.org  Fri Jun 13 04:16:06 2008
From: python-3000-checkins at python.org (alexandre.vassalotti)
Date: Fri, 13 Jun 2008 04:16:06 +0200 (CEST)
Subject: [Python-3000-checkins] r64218 -
	python/branches/py3k/Modules/_pickle.c
Message-ID: <20080613021606.82D2B1E4002@bag.python.org>

Author: alexandre.vassalotti
Date: Fri Jun 13 04:16:06 2008
New Revision: 64218

Log:
Fixed compiler warnings on MSVC9.0


Modified:
   python/branches/py3k/Modules/_pickle.c

Modified: python/branches/py3k/Modules/_pickle.c
==============================================================================
--- python/branches/py3k/Modules/_pickle.c	(original)
+++ python/branches/py3k/Modules/_pickle.c	Fri Jun 13 04:16:06 2008
@@ -627,7 +627,7 @@
     else {
         if (x < 256) {
             pdata[0] = BINPUT;
-            pdata[1] = x;
+            pdata[1] = (unsigned char)x;
             len = 2;
         }
         else if (x <= 0xffffffffL) {
@@ -3930,7 +3930,8 @@
 
         /* Use the size_t type to check for overflow. */
         alloc = ((size_t)self->num_marks << 1) + 20;
-        if (alloc > PY_SSIZE_T_MAX || alloc <= (self->num_marks + 1)) {
+        if (alloc > PY_SSIZE_T_MAX || 
+            alloc <= ((size_t)self->num_marks + 1)) {
             PyErr_NoMemory();
             return -1;
         }

From guido at python.org  Fri Jun 13 05:51:38 2008
From: guido at python.org (Guido van Rossum)
Date: Thu, 12 Jun 2008 20:51:38 -0700
Subject: [Python-3000-checkins] r64217 - in python/branches/py3k/Lib:
	bsddb/test/test_associate.py bsddb/test/test_join.py
	bsddb/test/test_lock.py bsddb/test/test_thread.py
	idlelib/rpc.py idlelib/run.py socketserver.py
	test/test_threadedtempfile.py thread
Message-ID: <ca471dc20806122051r6f7b0087lb0f0d6606793430c@mail.gmail.com>

It's water under the bridge now, but IMO it was too rash to *remove*
the old threading API from Py3k, and doubly rash to do so one day
before the beta release. Running up to a release (whether alpha, beta
or final) we should practice extra restraint, not rush to get things
in right before the deadline. Let's all be more careful the rest of
this release cycle! (I think it wasn't just Benjamin who raced to get
things in...)

--Guido

On Thu, Jun 12, 2008 at 7:00 PM, benjamin.peterson
<python-3000-checkins at python.org> wrote:
> Author: benjamin.peterson
> Date: Fri Jun 13 04:00:47 2008
> New Revision: 64217
>
> Log:
> fix more threading API related bugs
>
> Modified:
>   python/branches/py3k/Lib/bsddb/test/test_associate.py
>   python/branches/py3k/Lib/bsddb/test/test_join.py
>   python/branches/py3k/Lib/bsddb/test/test_lock.py
>   python/branches/py3k/Lib/bsddb/test/test_thread.py
>   python/branches/py3k/Lib/idlelib/rpc.py
>   python/branches/py3k/Lib/idlelib/run.py
>   python/branches/py3k/Lib/socketserver.py
>   python/branches/py3k/Lib/test/test_threadedtempfile.py
>   python/branches/py3k/Lib/threading.py
>
> Modified: python/branches/py3k/Lib/bsddb/test/test_associate.py
> ==============================================================================
> --- python/branches/py3k/Lib/bsddb/test/test_associate.py       (original)
> +++ python/branches/py3k/Lib/bsddb/test/test_associate.py       Fri Jun 13 04:00:47 2008
> @@ -9,7 +9,7 @@
>  from pprint import pprint
>
>  try:
> -    from threading import Thread, currentThread
> +    from threading import Thread, current_thread
>     have_threads = 1
>  except ImportError:
>     have_threads = 0
>
[etc.]

-- 
--Guido van Rossum (home page: http://www.python.org/~guido/)

From nnorwitz at gmail.com  Fri Jun 13 08:25:34 2008
From: nnorwitz at gmail.com (Neal Norwitz)
Date: Thu, 12 Jun 2008 23:25:34 -0700
Subject: [Python-3000-checkins] r64033 -
	python/branches/py3k/Lib/calendar.py
In-Reply-To: <20080608084006.14F371E4004@bag.python.org>
References: <20080608084006.14F371E4004@bag.python.org>
Message-ID: <ee2a432c0806122325g69a13eb4iee630d020ea73196@mail.gmail.com>

On Sun, Jun 8, 2008 at 1:40 AM, georg.brandl
<python-3000-checkins at python.org> wrote:
> Author: georg.brandl
> Date: Sun Jun  8 10:40:05 2008
> New Revision: 64033
>
> Log:
> #3059: Stop decoding Unicode in calendar module.
> The strftime routines must know how to decode
> localized month/day names themselves.
>
>
> Modified:
>   python/branches/py3k/Lib/calendar.py
>
> Modified: python/branches/py3k/Lib/calendar.py
> ==============================================================================
> --- python/branches/py3k/Lib/calendar.py        (original)
> +++ python/branches/py3k/Lib/calendar.py        Sun Jun  8 10:40:05 2008
> @@ -481,13 +481,13 @@
>         return ''.join(v).encode(encoding, "xmlcharrefreplace")
>
>
> -class TimeEncoding:
> +class different_locale:
>     def __init__(self, locale):
>         self.locale = locale
>
>     def __enter__(self):
>         self.oldlocale = _locale.setlocale(_locale.LC_TIME, self.locale)
> -        return _locale.getlocale(_locale.LC_TIME)[1]
> +        #return _locale.getlocale(_locale.LC_TIME)[1]

This doesn't seem right, ie returning None from an __enter__ method.

n

From python-3000-checkins at python.org  Fri Jun 13 08:32:25 2008
From: python-3000-checkins at python.org (georg.brandl)
Date: Fri, 13 Jun 2008 08:32:25 +0200 (CEST)
Subject: [Python-3000-checkins] r64222 - in python/branches/py3k:
	Doc/includes/mp_distributing.py Doc/library/queue.rst
	Doc/library/socketserver.rst Doc/library/threading.rst
	Lib/decimal.py Lib/idlelib/rpc.py Misc/NEWS
Message-ID: <20080613063225.D87AA1E4006@bag.python.org>

Author: georg.brandl
Date: Fri Jun 13 08:32:25 2008
New Revision: 64222

Log:
Fix last traces of old threading API.


Modified:
   python/branches/py3k/Doc/includes/mp_distributing.py
   python/branches/py3k/Doc/library/queue.rst
   python/branches/py3k/Doc/library/socketserver.rst
   python/branches/py3k/Doc/library/threading.rst
   python/branches/py3k/Lib/decimal.py
   python/branches/py3k/Lib/idlelib/rpc.py
   python/branches/py3k/Misc/NEWS

Modified: python/branches/py3k/Doc/includes/mp_distributing.py
==============================================================================
--- python/branches/py3k/Doc/includes/mp_distributing.py	(original)
+++ python/branches/py3k/Doc/includes/mp_distributing.py	Fri Jun 13 08:32:25 2008
@@ -243,7 +243,7 @@
         try:
             self.queue.clear()
             self.queue.extend(contents)
-            self.not_empty.notifyAll()
+            self.not_empty.notify_all()
         finally:
             self.not_empty.release()
 

Modified: python/branches/py3k/Doc/library/queue.rst
==============================================================================
--- python/branches/py3k/Doc/library/queue.rst	(original)
+++ python/branches/py3k/Doc/library/queue.rst	Fri Jun 13 08:32:25 2008
@@ -147,7 +147,7 @@
    q = Queue() 
    for i in range(num_worker_threads): 
         t = Thread(target=worker)
-        t.setDaemon(True)
+        t.set_daemon(True)
         t.start() 
 
    for item in source():

Modified: python/branches/py3k/Doc/library/socketserver.rst
==============================================================================
--- python/branches/py3k/Doc/library/socketserver.rst	(original)
+++ python/branches/py3k/Doc/library/socketserver.rst	Fri Jun 13 08:32:25 2008
@@ -480,8 +480,8 @@
 
        def handle(self):
            data = self.request.recv(1024)
-           cur_thread = threading.currentThread()
-           response = "%s: %s" % (cur_thread.getName(), data)
+           cur_thread = threading.current_thread()
+           response = "%s: %s" % (cur_thread.get_name(), data)
            self.request.send(response)
 
    class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
@@ -506,9 +506,9 @@
        # more thread for each request
        server_thread = threading.Thread(target=server.serve_forever)
        # Exit the server thread when the main thread terminates
-       server_thread.setDaemon(True)
+       server_thread.set_daemon(True)
        server_thread.start()
-       print "Server loop running in thread:", t.getName()
+       print "Server loop running in thread:", t.get_name()
 
        client(ip, port, "Hello World 1")
        client(ip, port, "Hello World 2")

Modified: python/branches/py3k/Doc/library/threading.rst
==============================================================================
--- python/branches/py3k/Doc/library/threading.rst	(original)
+++ python/branches/py3k/Doc/library/threading.rst	Fri Jun 13 08:32:25 2008
@@ -283,29 +283,29 @@
 
 A condition variable has :meth:`acquire` and :meth:`release` methods that call
 the corresponding methods of the associated lock. It also has a :meth:`wait`
-method, and :meth:`notify` and :meth:`notifyAll` methods.  These three must only
+method, and :meth:`notify` and :meth:`notify_all` methods.  These three must only
 be called when the calling thread has acquired the lock, otherwise a
 :exc:`RuntimeError` is raised.
 
 The :meth:`wait` method releases the lock, and then blocks until it is awakened
-by a :meth:`notify` or :meth:`notifyAll` call for the same condition variable in
+by a :meth:`notify` or :meth:`notify_all` call for the same condition variable in
 another thread.  Once awakened, it re-acquires the lock and returns.  It is also
 possible to specify a timeout.
 
 The :meth:`notify` method wakes up one of the threads waiting for the condition
-variable, if any are waiting.  The :meth:`notifyAll` method wakes up all threads
+variable, if any are waiting.  The :meth:`notify_all` method wakes up all threads
 waiting for the condition variable.
 
-Note: the :meth:`notify` and :meth:`notifyAll` methods don't release the lock;
+Note: the :meth:`notify` and :meth:`notify_all` methods don't release the lock;
 this means that the thread or threads awakened will not return from their
 :meth:`wait` call immediately, but only when the thread that called
-:meth:`notify` or :meth:`notifyAll` finally relinquishes ownership of the lock.
+:meth:`notify` or :meth:`notify_all` finally relinquishes ownership of the lock.
 
 Tip: the typical programming style using condition variables uses the lock to
 synchronize access to some shared state; threads that are interested in a
 particular change of state call :meth:`wait` repeatedly until they see the
 desired state, while threads that modify the state call :meth:`notify` or
-:meth:`notifyAll` when they change the state in such a way that it could
+:meth:`notify_all` when they change the state in such a way that it could
 possibly be a desired state for one of the waiters.  For example, the following
 code is a generic producer-consumer situation with unlimited buffer capacity::
 
@@ -322,7 +322,7 @@
    cv.notify()
    cv.release()
 
-To choose between :meth:`notify` and :meth:`notifyAll`, consider whether one
+To choose between :meth:`notify` and :meth:`notify_all`, consider whether one
 state change can be interesting for only one or several waiting threads.  E.g.
 in a typical producer-consumer situation, adding one item to the buffer only
 needs to wake up one consumer thread.
@@ -353,7 +353,7 @@
    acquired the lock when this method is called, a :exc:`RuntimeError` is raised.
 
    This method releases the underlying lock, and then blocks until it is awakened
-   by a :meth:`notify` or :meth:`notifyAll` call for the same condition variable in
+   by a :meth:`notify` or :meth:`notify_all` call for the same condition variable in
    another thread, or until the optional timeout occurs.  Once awakened or timed
    out, it re-acquires the lock and returns.
 
@@ -490,7 +490,7 @@
    The internal flag is initially false.
 
 
-.. method:: Event.isSet()
+.. method:: Event.is_set()
 
    Return true if and only if the internal flag is true.
 
@@ -537,7 +537,7 @@
 
 Once the thread's activity is started, the thread is considered 'alive'. It
 stops being alive when its :meth:`run` method terminates -- either normally, or
-by raising an unhandled exception.  The :meth:`isAlive` method tests whether the
+by raising an unhandled exception.  The :meth:`is_alive` method tests whether the
 thread is alive.
 
 Other threads can call a thread's :meth:`join` method.  This blocks the calling
@@ -614,7 +614,7 @@
 
    When the *timeout* argument is present and not ``None``, it should be a floating
    point number specifying a timeout for the operation in seconds (or fractions
-   thereof). As :meth:`join` always returns ``None``, you must call :meth:`isAlive`
+   thereof). As :meth:`join` always returns ``None``, you must call :meth:`is_alive`
    after :meth:`join` to decide whether a timeout happened -- if the thread is
    still alive, the :meth:`join` call timed out.
 

Modified: python/branches/py3k/Lib/decimal.py
==============================================================================
--- python/branches/py3k/Lib/decimal.py	(original)
+++ python/branches/py3k/Lib/decimal.py	Fri Jun 13 08:32:25 2008
@@ -383,7 +383,7 @@
 
 # The getcontext() and setcontext() function manage access to a thread-local
 # current context.  Py2.4 offers direct support for thread locals.  If that
-# is not available, use threading.currentThread() which is slower but will
+# is not available, use threading.current_thread() which is slower but will
 # work for older Pythons.  If threads are not part of the build, create a
 # mock threading object with threading.local() returning the module namespace.
 
@@ -405,15 +405,15 @@
 
     # To fix reloading, force it to create a new context
     # Old contexts have different exceptions in their dicts, making problems.
-    if hasattr(threading.currentThread(), '__decimal_context__'):
-        del threading.currentThread().__decimal_context__
+    if hasattr(threading.current_thread(), '__decimal_context__'):
+        del threading.current_thread().__decimal_context__
 
     def setcontext(context):
         """Set this thread's context to context."""
         if context in (DefaultContext, BasicContext, ExtendedContext):
             context = context.copy()
             context.clear_flags()
-        threading.currentThread().__decimal_context__ = context
+        threading.current_thread().__decimal_context__ = context
 
     def getcontext():
         """Returns this thread's context.
@@ -423,10 +423,10 @@
         New contexts are copies of DefaultContext.
         """
         try:
-            return threading.currentThread().__decimal_context__
+            return threading.current_thread().__decimal_context__
         except AttributeError:
             context = Context()
-            threading.currentThread().__decimal_context__ = context
+            threading.current_thread().__decimal_context__ = context
             return context
 
 else:

Modified: python/branches/py3k/Lib/idlelib/rpc.py
==============================================================================
--- python/branches/py3k/Lib/idlelib/rpc.py	(original)
+++ python/branches/py3k/Lib/idlelib/rpc.py	Fri Jun 13 08:32:25 2008
@@ -149,7 +149,7 @@
     def debug(self, *args):
         if not self.debugging:
             return
-        s = self.location + " " + str(threading.current_thread().getName())
+        s = self.location + " " + str(threading.current_thread().get_name())
         for a in args:
             s = s + " " + str(a)
         print(s, file=sys.__stderr__)

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Fri Jun 13 08:32:25 2008
@@ -175,7 +175,7 @@
 
 - The test.test_support module has been renamed to test.support.
 
-- The threading module API's were renamed to by PEP 8 complaint.
+- The threading module API was renamed to be PEP 8 complaint.
 
 Tools/Demos
 -----------

From g.brandl at gmx.net  Fri Jun 13 08:33:23 2008
From: g.brandl at gmx.net (Georg Brandl)
Date: Fri, 13 Jun 2008 08:33:23 +0200
Subject: [Python-3000-checkins] r64033 -
	python/branches/py3k/Lib/calendar.py
In-Reply-To: <ee2a432c0806122325g69a13eb4iee630d020ea73196@mail.gmail.com>
References: <20080608084006.14F371E4004@bag.python.org>
	<ee2a432c0806122325g69a13eb4iee630d020ea73196@mail.gmail.com>
Message-ID: <g2t4bo$3p7$2@ger.gmane.org>

Neal Norwitz schrieb:
> On Sun, Jun 8, 2008 at 1:40 AM, georg.brandl
> <python-3000-checkins at python.org> wrote:
>> Author: georg.brandl
>> Date: Sun Jun  8 10:40:05 2008
>> New Revision: 64033
>>
>> Log:
>> #3059: Stop decoding Unicode in calendar module.
>> The strftime routines must know how to decode
>> localized month/day names themselves.
>>
>>
>> Modified:
>>   python/branches/py3k/Lib/calendar.py
>>
>> Modified: python/branches/py3k/Lib/calendar.py
>> ==============================================================================
>> --- python/branches/py3k/Lib/calendar.py        (original)
>> +++ python/branches/py3k/Lib/calendar.py        Sun Jun  8 10:40:05 2008
>> @@ -481,13 +481,13 @@
>>         return ''.join(v).encode(encoding, "xmlcharrefreplace")
>>
>>
>> -class TimeEncoding:
>> +class different_locale:
>>     def __init__(self, locale):
>>         self.locale = locale
>>
>>     def __enter__(self):
>>         self.oldlocale = _locale.setlocale(_locale.LC_TIME, self.locale)
>> -        return _locale.getlocale(_locale.LC_TIME)[1]
>> +        #return _locale.getlocale(_locale.LC_TIME)[1]
> 
> This doesn't seem right, ie returning None from an __enter__ method.

The code that uses it does

with different_locale(self.locale):
     ...

so returning something isn't necessary.

Georg


From nnorwitz at gmail.com  Fri Jun 13 08:55:21 2008
From: nnorwitz at gmail.com (Neal Norwitz)
Date: Thu, 12 Jun 2008 23:55:21 -0700
Subject: [Python-3000-checkins] r64033 -
	python/branches/py3k/Lib/calendar.py
In-Reply-To: <g2t4bo$3p7$2@ger.gmane.org>
References: <20080608084006.14F371E4004@bag.python.org>
	<ee2a432c0806122325g69a13eb4iee630d020ea73196@mail.gmail.com>
	<g2t4bo$3p7$2@ger.gmane.org>
Message-ID: <ee2a432c0806122355m6b9a18fdq78bac1ca50a8734e@mail.gmail.com>

On Thu, Jun 12, 2008 at 11:33 PM, Georg Brandl <g.brandl at gmx.net> wrote:
> Neal Norwitz schrieb:
>>
>> On Sun, Jun 8, 2008 at 1:40 AM, georg.brandl
>> <python-3000-checkins at python.org> wrote:
>>>
>>> Author: georg.brandl
>>> Date: Sun Jun  8 10:40:05 2008
>>> New Revision: 64033
>>>
>>> Log:
>>> #3059: Stop decoding Unicode in calendar module.
>>> The strftime routines must know how to decode
>>> localized month/day names themselves.
>>>
>>>
>>> Modified:
>>>  python/branches/py3k/Lib/calendar.py
>>>
>>> Modified: python/branches/py3k/Lib/calendar.py
>>>
>>> ==============================================================================
>>> --- python/branches/py3k/Lib/calendar.py        (original)
>>> +++ python/branches/py3k/Lib/calendar.py        Sun Jun  8 10:40:05 2008
>>> @@ -481,13 +481,13 @@
>>>        return ''.join(v).encode(encoding, "xmlcharrefreplace")
>>>
>>>
>>> -class TimeEncoding:
>>> +class different_locale:
>>>    def __init__(self, locale):
>>>        self.locale = locale
>>>
>>>    def __enter__(self):
>>>        self.oldlocale = _locale.setlocale(_locale.LC_TIME, self.locale)
>>> -        return _locale.getlocale(_locale.LC_TIME)[1]
>>> +        #return _locale.getlocale(_locale.LC_TIME)[1]
>>
>> This doesn't seem right, ie returning None from an __enter__ method.
>
> The code that uses it does
>
> with different_locale(self.locale):
>    ...
>
> so returning something isn't necessary.

Do you want to leave the old code in and commented out?

Do you want to prevent code like:

  with different_locale(self.locale) as old_locale:
    ...

(I see different_locale isn't exported in __all__ and probably not
considered public.)

n

From python-3000-checkins at python.org  Fri Jun 13 09:24:48 2008
From: python-3000-checkins at python.org (martin.v.loewis)
Date: Fri, 13 Jun 2008 09:24:48 +0200 (CEST)
Subject: [Python-3000-checkins] r64225 -
	python/branches/py3k/Objects/fileobject.c
Message-ID: <20080613072448.779F01E401E@bag.python.org>

Author: martin.v.loewis
Date: Fri Jun 13 09:24:48 2008
New Revision: 64225

Log:
Make stdprinter_write static.


Modified:
   python/branches/py3k/Objects/fileobject.c

Modified: python/branches/py3k/Objects/fileobject.c
==============================================================================
--- python/branches/py3k/Objects/fileobject.c	(original)
+++ python/branches/py3k/Objects/fileobject.c	Fri Jun 13 09:24:48 2008
@@ -377,7 +377,7 @@
 	return (PyObject*)self;
 }
 
-PyObject *
+static PyObject *
 stdprinter_write(PyStdPrinter_Object *self, PyObject *args)
 {
 	char *c;

From python-3000-checkins at python.org  Fri Jun 13 09:48:20 2008
From: python-3000-checkins at python.org (martin.v.loewis)
Date: Fri, 13 Jun 2008 09:48:20 +0200 (CEST)
Subject: [Python-3000-checkins] r64227 -
	python/branches/py3k/Modules/_testcapimodule.c
Message-ID: <20080613074820.29AD51E4020@bag.python.org>

Author: martin.v.loewis
Date: Fri Jun 13 09:48:19 2008
New Revision: 64227

Log:
Make print_delta static.


Modified:
   python/branches/py3k/Modules/_testcapimodule.c

Modified: python/branches/py3k/Modules/_testcapimodule.c
==============================================================================
--- python/branches/py3k/Modules/_testcapimodule.c	(original)
+++ python/branches/py3k/Modules/_testcapimodule.c	Fri Jun 13 09:48:19 2008
@@ -822,7 +822,7 @@
 
 #ifdef HAVE_GETTIMEOFDAY
 /* Profiling of integer performance */
-void print_delta(int test, struct timeval *s, struct timeval *e)
+static void print_delta(int test, struct timeval *s, struct timeval *e)
 {
 	e->tv_sec -= s->tv_sec;
 	e->tv_usec -= s->tv_usec;

From python-3000-checkins at python.org  Fri Jun 13 09:50:46 2008
From: python-3000-checkins at python.org (martin.v.loewis)
Date: Fri, 13 Jun 2008 09:50:46 +0200 (CEST)
Subject: [Python-3000-checkins] r64228 - in python/branches/py3k:
	Modules/_collectionsmodule.c Modules/_localemodule.c
	Modules/_tkinter.c Modules/arraymodule.c
	Modules/unicodedata_db.h Tools/unicode/makeunicodedata.py
Message-ID: <20080613075046.43BEC1E4006@bag.python.org>

Author: martin.v.loewis
Date: Fri Jun 13 09:50:45 2008
New Revision: 64228

Log:
Merged revisions 64226 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/trunk

........
  r64226 | martin.v.loewis | 2008-06-13 09:47:47 +0200 (Fr, 13 Jun 2008) | 2 lines
  
  Make more symbols static.
........


Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Modules/_collectionsmodule.c
   python/branches/py3k/Modules/_localemodule.c
   python/branches/py3k/Modules/_tkinter.c
   python/branches/py3k/Modules/arraymodule.c
   python/branches/py3k/Modules/unicodedata_db.h
   python/branches/py3k/Tools/unicode/makeunicodedata.py

Modified: python/branches/py3k/Modules/_collectionsmodule.c
==============================================================================
--- python/branches/py3k/Modules/_collectionsmodule.c	(original)
+++ python/branches/py3k/Modules/_collectionsmodule.c	Fri Jun 13 09:50:45 2008
@@ -85,7 +85,7 @@
 	return b;
 }
 
-void
+static void
 freeblock(block *b)
 {
 	if (numfreeblocks < MAXFREEBLOCKS) {
@@ -898,7 +898,7 @@
 	int counter;    /* number of items remaining for iteration */
 } dequeiterobject;
 
-PyTypeObject dequeiter_type;
+static PyTypeObject dequeiter_type;
 
 static PyObject *
 deque_iter(dequeobject *deque)
@@ -965,7 +965,7 @@
  	{NULL,		NULL}		/* sentinel */
 };
 
-PyTypeObject dequeiter_type = {
+static PyTypeObject dequeiter_type = {
 	PyVarObject_HEAD_INIT(NULL, 0)
 	"deque_iterator",			/* tp_name */
 	sizeof(dequeiterobject),		/* tp_basicsize */
@@ -1000,7 +1000,7 @@
 
 /*********************** Deque Reverse Iterator **************************/
 
-PyTypeObject dequereviter_type;
+static PyTypeObject dequereviter_type;
 
 static PyObject *
 deque_reviter(dequeobject *deque)
@@ -1047,7 +1047,7 @@
 	return item;
 }
 
-PyTypeObject dequereviter_type = {
+static PyTypeObject dequereviter_type = {
 	PyVarObject_HEAD_INIT(NULL, 0)
 	"deque_reverse_iterator",		/* tp_name */
 	sizeof(dequeiterobject),		/* tp_basicsize */

Modified: python/branches/py3k/Modules/_localemodule.c
==============================================================================
--- python/branches/py3k/Modules/_localemodule.c	(original)
+++ python/branches/py3k/Modules/_localemodule.c	Fri Jun 13 09:50:45 2008
@@ -387,7 +387,7 @@
 
 #ifdef HAVE_LANGINFO_H
 #define LANGINFO(X) {#X, X}
-struct langinfo_constant{
+static struct langinfo_constant{
 	char* name;
 	int value;
 } langinfo_constants[] = 

Modified: python/branches/py3k/Modules/_tkinter.c
==============================================================================
--- python/branches/py3k/Modules/_tkinter.c	(original)
+++ python/branches/py3k/Modules/_tkinter.c	Fri Jun 13 09:50:45 2008
@@ -488,7 +488,7 @@
    lists. SplitObj walks through a nested tuple, finding string objects that
    need to be split. */
 
-PyObject *
+static PyObject *
 SplitObj(PyObject *arg)
 {
 	if (PyTuple_Check(arg)) {
@@ -1435,7 +1435,7 @@
 	return 0;
 }
 
-void
+static void
 var_perform(VarEvent *ev)
 {
 	*(ev->res) = ev->func(ev->self, ev->args, ev->flags);

Modified: python/branches/py3k/Modules/arraymodule.c
==============================================================================
--- python/branches/py3k/Modules/arraymodule.c	(original)
+++ python/branches/py3k/Modules/arraymodule.c	Fri Jun 13 09:50:45 2008
@@ -1493,7 +1493,7 @@
 	{NULL}
 };
 
-PyMethodDef array_methods[] = {
+static PyMethodDef array_methods[] = {
 	{"append",	(PyCFunction)array_append,	METH_O,
 	 append_doc},
 	{"buffer_info", (PyCFunction)array_buffer_info, METH_NOARGS,

Modified: python/branches/py3k/Modules/unicodedata_db.h
==============================================================================
--- python/branches/py3k/Modules/unicodedata_db.h	(original)
+++ python/branches/py3k/Modules/unicodedata_db.h	Fri Jun 13 09:50:45 2008
@@ -228,7 +228,7 @@
 #define TOTAL_FIRST 356
 #define TOTAL_LAST 53
 struct reindex{int start;short count,index;};
-struct reindex nfc_first[] = {
+static struct reindex nfc_first[] = {
   { 60, 2, 0},
   { 65, 15, 3},
   { 82, 8, 19},
@@ -425,7 +425,7 @@
   {0,0,0}
 };
 
-struct reindex nfc_last[] = {
+static struct reindex nfc_last[] = {
   { 768, 4, 0},
   { 774, 6, 5},
   { 783, 0, 12},

Modified: python/branches/py3k/Tools/unicode/makeunicodedata.py
==============================================================================
--- python/branches/py3k/Tools/unicode/makeunicodedata.py	(original)
+++ python/branches/py3k/Tools/unicode/makeunicodedata.py	Fri Jun 13 09:50:45 2008
@@ -234,12 +234,12 @@
     print("#define TOTAL_FIRST",total_first, file=fp)
     print("#define TOTAL_LAST",total_last, file=fp)
     print("struct reindex{int start;short count,index;};", file=fp)
-    print("struct reindex nfc_first[] = {", file=fp)
+    print("static struct reindex nfc_first[] = {", file=fp)
     for start,end in comp_first_ranges:
         print("  { %d, %d, %d}," % (start,end-start,comp_first[start]), file=fp)
     print("  {0,0,0}", file=fp)
     print("};\n", file=fp)
-    print("struct reindex nfc_last[] = {", file=fp)
+    print("static struct reindex nfc_last[] = {", file=fp)
     for start,end in comp_last_ranges:
         print("  { %d, %d, %d}," % (start,end-start,comp_last[start]), file=fp)
     print("  {0,0,0}", file=fp)

From steve at holdenweb.com  Fri Jun 13 12:53:14 2008
From: steve at holdenweb.com (Steve Holden)
Date: Fri, 13 Jun 2008 06:53:14 -0400
Subject: [Python-3000-checkins] r64217 - in python/branches/py3k/Lib:
 bsddb/test/test_associate.py bsddb/test/test_join.py
 bsddb/test/test_lock.py bsddb/test/test_thread.py idlelib/rpc.py
 idlelib/run.py socketserver.py test/test_threadedtempfile.py thread
In-Reply-To: <ca471dc20806122051r6f7b0087lb0f0d6606793430c@mail.gmail.com>
References: <ca471dc20806122051r6f7b0087lb0f0d6606793430c@mail.gmail.com>
Message-ID: <4852519A.6070506@holdenweb.com>

Guido van Rossum wrote:
> It's water under the bridge now, but IMO it was too rash to *remove*
> the old threading API from Py3k, and doubly rash to do so one day
> before the beta release. Running up to a release (whether alpha, beta
> or final) we should practice extra restraint, not rush to get things
> in right before the deadline. Let's all be more careful the rest of
> this release cycle! (I think it wasn't just Benjamin who raced to get
> things in...)

Well, it wouldn't be "adding a new feature" to reinstate the old API for 
beta two, would it, as long as we retain the new one too? It does seem 
that change was a little precipitate.

regards
  Steve
-- 
Steve Holden        +1 571 484 6266   +1 800 494 3119
Holden Web LLC              http://www.holdenweb.com/


From ncoghlan at gmail.com  Fri Jun 13 15:07:47 2008
From: ncoghlan at gmail.com (Nick Coghlan)
Date: Fri, 13 Jun 2008 23:07:47 +1000
Subject: [Python-3000-checkins] [Python-3000] r64217 - in
 python/branches/py3k/Lib: bsddb/test/test_associate.py
 bsddb/test/test_join.py bsddb/test/test_lock.py bsddb/test/test_thread.py
 idlelib/rpc.py idlelib/run.py socketserver.py test/test_threadedtempfile.py
 thread
In-Reply-To: <4852519A.6070506@holdenweb.com>
References: <ca471dc20806122051r6f7b0087lb0f0d6606793430c@mail.gmail.com>
	<4852519A.6070506@holdenweb.com>
Message-ID: <48527123.9010802@gmail.com>

Steve Holden wrote:
> Guido van Rossum wrote:
>> It's water under the bridge now, but IMO it was too rash to *remove*
>> the old threading API from Py3k, and doubly rash to do so one day
>> before the beta release. Running up to a release (whether alpha, beta
>> or final) we should practice extra restraint, not rush to get things
>> in right before the deadline. Let's all be more careful the rest of
>> this release cycle! (I think it wasn't just Benjamin who raced to get
>> things in...)
> 
> Well, it wouldn't be "adding a new feature" to reinstate the old API for 
> beta two, would it, as long as we retain the new one too? It does seem 
> that change was a little precipitate.

Although if we weren't actually planning on removing the old API in 3.0, 
I'm a little confused as to why we were adding Py3k warnings to it in 2.6...

Cheers,
Nick.

-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia
---------------------------------------------------------------
             http://www.boredomandlaziness.org

From python-3000-checkins at python.org  Fri Jun 13 16:12:00 2008
From: python-3000-checkins at python.org (martin.v.loewis)
Date: Fri, 13 Jun 2008 16:12:00 +0200 (CEST)
Subject: [Python-3000-checkins] r64231 - in python/branches/py3k:
	PCbuild/build_tkinter.py PCbuild/pyproject.vsprops
	Tools/buildbot/external-amd64.bat Tools/buildbot/external-common.bat
	Tools/buildbot/external.bat Tools/msi/msi.py Tools/msi/msilib.py
Message-ID: <20080613141200.7871C1E4006@bag.python.org>

Author: martin.v.loewis
Date: Fri Jun 13 16:11:59 2008
New Revision: 64231

Log:
Merged revisions 64185-64196 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/trunk

........
  r64185 | martin.v.loewis | 2008-06-12 20:38:47 +0200 (Do, 12 Jun 2008) | 1 line
  
  Switch to Tcl/Tk 8.5.2.
........
  r64189 | martin.v.loewis | 2008-06-12 20:52:00 +0200 (Do, 12 Jun 2008) | 1 line
  
  Switch to Tcl/Tk 8.5.
........
  r64191 | martin.v.loewis | 2008-06-12 21:00:14 +0200 (Do, 12 Jun 2008) | 1 line
  
  Revert bogus disabling of Tcl and Tk.
........
  r64194 | martin.v.loewis | 2008-06-12 21:51:59 +0200 (Do, 12 Jun 2008) | 1 line
  
  Split Tcl make targets into separate ones.
........
  r64195 | martin.v.loewis | 2008-06-12 22:06:18 +0200 (Do, 12 Jun 2008) | 1 line
  
  Support file names which include '+' (for Tk 8.5).
........
  r64196 | martin.v.loewis | 2008-06-12 22:07:53 +0200 (Do, 12 Jun 2008) | 1 line
  
  Fix Tcl/Tk license file in tcl8*/tk8*, include Tix license.
........


Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/PCbuild/build_tkinter.py
   python/branches/py3k/PCbuild/pyproject.vsprops
   python/branches/py3k/Tools/buildbot/external-amd64.bat
   python/branches/py3k/Tools/buildbot/external-common.bat
   python/branches/py3k/Tools/buildbot/external.bat
   python/branches/py3k/Tools/msi/msi.py
   python/branches/py3k/Tools/msi/msilib.py

Modified: python/branches/py3k/PCbuild/build_tkinter.py
==============================================================================
--- python/branches/py3k/PCbuild/build_tkinter.py	(original)
+++ python/branches/py3k/PCbuild/build_tkinter.py	Fri Jun 13 16:11:59 2008
@@ -11,14 +11,9 @@
 here = os.path.abspath(os.path.dirname(__file__))
 par = os.path.pardir
 
-if 1:
-    TCL = "tcl8.4.16"
-    TK = "tk8.4.16"
-    TIX = "tix-8.4.0"
-else:
-    TCL = "tcl8.5b3"
-    TK = "tcl8.5b3"
-    TIX = "Tix8.4.2"
+TCL = "tcl8.5.2"
+TK = "tk8.5.2"
+TIX = "tix-8.4.0.x"
 
 ROOT = os.path.abspath(os.path.join(here, par, par))
 # Windows 2000 compatibility: WINVER 0x0500
@@ -38,9 +33,9 @@
     if platform == "Win32":
         dest = os.path.join(ROOT, "tcltk")
         machine = "X86"
-    elif platform == "x64":
+    elif platform == "AMD64":
         dest = os.path.join(ROOT, "tcltk64")
-        machine = "X64"
+        machine = "AMD64"
     else:
         raise ValueError(platform)
 
@@ -50,16 +45,16 @@
         os.chdir(os.path.join(tcldir, "win"))
         if clean:
             nmake("makefile.vc", "clean")
-        nmake("makefile.vc")
-        nmake("makefile.vc", "install", INSTALLDIR=dest)
+        nmake("makefile.vc", MACHINE=machine)
+        nmake("makefile.vc", "install", INSTALLDIR=dest, MACHINE=machine)
 
     # TK
     if 1:
         os.chdir(os.path.join(ROOT, TK, "win"))
         if clean:
             nmake("makefile.vc", "clean", TCLDIR=tcldir)
-        nmake("makefile.vc", TCLDIR=tcldir)
-        nmake("makefile.vc", "install", TCLDIR=tcldir, INSTALLDIR=dest)
+        nmake("makefile.vc", TCLDIR=tcldir, MACHINE=machine)
+        nmake("makefile.vc", "install", TCLDIR=tcldir, INSTALLDIR=dest, MACHINE=machine)
 
     # TIX
     if 1:
@@ -67,12 +62,12 @@
         os.chdir(os.path.join(ROOT, TIX, "win"))
         if clean:
             nmake("python9.mak", "clean")
-        nmake("python9.mak", MACHINE=machine)
-        nmake("python9.mak", "install")
+        nmake("python9.mak", MACHINE=machine, INSTALL_DIR=dest)
+        nmake("python9.mak", "install", INSTALL_DIR=dest)
 
 def main():
-    if len(sys.argv) < 2 or sys.argv[1] not in ("Win32", "x64"):
-        print("%s Win32|x64" % sys.argv[0])
+    if len(sys.argv) < 2 or sys.argv[1] not in ("Win32", "AMD64"):
+        print("%s Win32|AMD64" % sys.argv[0])
         sys.exit(1)
 
     if "-c" in sys.argv:

Modified: python/branches/py3k/PCbuild/pyproject.vsprops
==============================================================================
--- python/branches/py3k/PCbuild/pyproject.vsprops	(original)
+++ python/branches/py3k/PCbuild/pyproject.vsprops	Fri Jun 13 16:11:59 2008
@@ -94,18 +94,18 @@
 	/>
 	<UserMacro
 		Name="tcltkLib"
-		Value="$(tcltkDir)\lib\tcl84.lib $(tcltkDir)\lib\tk84.lib"
+		Value="$(tcltkDir)\lib\tcl85.lib $(tcltkDir)\lib\tk85.lib"
 	/>
 	<UserMacro
 		Name="tcltkLibDebug"
-		Value="$(tcltkDir)\lib\tcl84g.lib $(tcltkDir)\lib\tk84g.lib"
+		Value="$(tcltkDir)\lib\tcl85g.lib $(tcltkDir)\lib\tk85g.lib"
 	/>
 	<UserMacro
 		Name="tcltk64Lib"
-		Value="$(tcltk64Dir)\lib\tcl84.lib $(tcltk64Dir)\lib\tk84.lib"
+		Value="$(tcltk64Dir)\lib\tcl85.lib $(tcltk64Dir)\lib\tk85.lib"
 	/>
 	<UserMacro
 		Name="tcltk64LibDebug"
-		Value="$(tcltk64Dir)\lib\tcl84g.lib $(tcltk64Dir)\lib\tk84g.lib"
+		Value="$(tcltk64Dir)\lib\tcl85g.lib $(tcltk64Dir)\lib\tk85g.lib"
 	/>
 </VisualStudioPropertySheet>

Modified: python/branches/py3k/Tools/buildbot/external-amd64.bat
==============================================================================
--- python/branches/py3k/Tools/buildbot/external-amd64.bat	(original)
+++ python/branches/py3k/Tools/buildbot/external-amd64.bat	Fri Jun 13 16:11:59 2008
@@ -4,14 +4,14 @@
 call "Tools\buildbot\external-common.bat"
 call "%VS90COMNTOOLS%\..\..\VC\vcvarsall.bat" x86_amd64
 
-if not exist tcltk64\bin\tcl84g.dll (
-    cd tcl-8.4.18.2\win
+if not exist tcltk64\bin\tcl85g.dll (
+    cd tcl-8.5.2.1\win
     nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 DEBUG=1 MACHINE=AMD64 INSTALLDIR=..\..\tcltk64 clean all install
     cd ..\..
 )
 
-if not exist tcltk64\bin\tk84g.dll (
-    cd tk-8.4.18.1\win    
-    nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 DEBUG=1 MACHINE=AMD64 INSTALLDIR=..\..\tcltk64 TCLDIR=..\..\tcl-8.4.18.2 clean all install
+if not exist tcltk64\bin\tk85g.dll (
+    cd tk-8.5.2.1\win    
+    nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 DEBUG=1 MACHINE=AMD64 INSTALLDIR=..\..\tcltk64 TCLDIR=..\..\tcl-8.5.2.1 clean all install
     cd ..\..
 )

Modified: python/branches/py3k/Tools/buildbot/external-common.bat
==============================================================================
--- python/branches/py3k/Tools/buildbot/external-common.bat	(original)
+++ python/branches/py3k/Tools/buildbot/external-common.bat	Fri Jun 13 16:11:59 2008
@@ -27,8 +27,11 @@
 if not exist openssl-0.9.8g svn export http://svn.python.org/projects/external/openssl-0.9.8g
 
 @rem tcl/tk
-if not exist tcl-8.4.18.2 svn export http://svn.python.org/projects/external/tcl-8.4.18.2
-if not exist tk-8.4.18.1 svn export http://svn.python.org/projects/external/tk-8.4.18.1
+if not exist tcl-8.5.2.1 (
+   rd /s/q tcltk tcltk64
+   svn export http://svn.python.org/projects/external/tcl-8.5.2.1
+)
+if not exist tk-8.5.2.0 svn export http://svn.python.org/projects/external/tk-8.5.2.0
 
 @rem sqlite3
 if not exist sqlite-source-3.3.4 svn export http://svn.python.org/projects/external/sqlite-source-3.3.4

Modified: python/branches/py3k/Tools/buildbot/external.bat
==============================================================================
--- python/branches/py3k/Tools/buildbot/external.bat	(original)
+++ python/branches/py3k/Tools/buildbot/external.bat	Fri Jun 13 16:11:59 2008
@@ -4,14 +4,18 @@
 call "Tools\buildbot\external-common.bat"
 call "%VS90COMNTOOLS%\vsvars32.bat"
 
-if not exist tcltk\bin\tcl84g.dll (
-    cd tcl-8.4.18.2\win
-    nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 DEBUG=1 INSTALLDIR=..\..\tcltk clean all install
+if not exist tcltk\bin\tcl85.dll (
+    @rem all and install need to be separate invocations, otherwise nmakehlp is not found on install
+    cd tcl-8.5.2.1\win
+    nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 DEBUG=1 INSTALLDIR=..\..\tcltk clean all 
+    nmake -f makefile.vc DEBUG=1 INSTALLDIR=..\..\tcltk install
     cd ..\..
 )
 
-if not exist tcltk\bin\tk84g.dll (
-    cd tk-8.4.18.1\win    
-    nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 DEBUG=1 INSTALLDIR=..\..\tcltk TCLDIR=..\..\tcl-8.4.18.2 clean all install
+if not exist tcltk\bin\tk85.dll (
+    cd tk-8.5.2.0\win    
+    nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 DEBUG=1 INSTALLDIR=..\..\tcltk TCLDIR=..\..\tcl-8.5.2.1 clean
+    nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 DEBUG=1 INSTALLDIR=..\..\tcltk TCLDIR=..\..\tcl-8.5.2.1 all
+    nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 DEBUG=1 INSTALLDIR=..\..\tcltk TCLDIR=..\..\tcl-8.5.2.1 install
     cd ..\..
 )

Modified: python/branches/py3k/Tools/msi/msi.py
==============================================================================
--- python/branches/py3k/Tools/msi/msi.py	(original)
+++ python/branches/py3k/Tools/msi/msi.py	Fri Jun 13 16:11:59 2008
@@ -849,17 +849,18 @@
     import shutil, glob
     out = open("LICENSE.txt", "w")
     shutil.copyfileobj(open(os.path.join(srcdir, "LICENSE")), out)
-    for dir, file in (("bzip2","LICENSE"),
-                      ("db", "LICENSE"),
-                      ("openssl", "LICENSE"),
-                      ("tcl", "license.terms"),
-                      ("tk", "license.terms")):
-        out.write("\nThis copy of Python includes a copy of %s, which is licensed under the following terms:\n\n" % dir)
-        dirs = glob.glob(srcdir+"/../"+dir+"-*")
+    for name, pat, file in (("bzip2","bzip2-*", "LICENSE"),
+                      ("Berkeley DB", "db-*", "LICENSE"),
+                      ("openssl", "openssl-*", "LICENSE"),
+                      ("Tcl", "tcl8*", "license.terms"),
+                      ("Tk", "tk8*", "license.terms"),
+                      ("Tix", "tix-*", "license.terms")):
+        out.write("\nThis copy of Python includes a copy of %s, which is licensed under the following terms:\n\n" % name)
+        dirs = glob.glob(srcdir+"/../"+pat)
         if not dirs:
-            raise ValueError, "Could not find "+srcdir+"/../"+dir+"-*"
+            raise ValueError, "Could not find "+srcdir+"/../"+pat
         if len(dirs) > 2:
-            raise ValueError, "Multiple copies of "+dir
+            raise ValueError, "Multiple copies of "+pat
         dir = dirs[0]
         shutil.copyfileobj(open(os.path.join(dir, file)), out)
     out.close()

Modified: python/branches/py3k/Tools/msi/msilib.py
==============================================================================
--- python/branches/py3k/Tools/msi/msilib.py	(original)
+++ python/branches/py3k/Tools/msi/msilib.py	Fri Jun 13 16:11:59 2008
@@ -328,6 +328,7 @@
     #str = str.replace(".", "_") # colons are allowed
     str = str.replace(" ", "_")
     str = str.replace("-", "_")
+    str = str.replace("+", "_")
     if str[0] in string.digits:
         str = "_"+str
     assert re.match("^[A-Za-z_][A-Za-z0-9_.]*$", str), "FILE"+str
@@ -472,6 +473,7 @@
                         [(feature.id, component)])
 
     def make_short(self, file):
+        file = re.sub(r'[\?|><:/*"+,;=\[\]]', '_', file) # restrictions on short names
         parts = file.split(".")
         if len(parts)>1:
             suffix = parts[-1].upper()
@@ -500,7 +502,6 @@
                 if pos in (10, 100, 1000):
                     prefix = prefix[:-1]
         self.short_names.add(file)
-        assert not re.search(r'[\?|><:/*"+,;=\[\]]', file) # restrictions on short names
         return file
 
     def add_file(self, file, src=None, version=None, language=None):

From steve at holdenweb.com  Fri Jun 13 12:53:14 2008
From: steve at holdenweb.com (Steve Holden)
Date: Fri, 13 Jun 2008 06:53:14 -0400
Subject: [Python-3000-checkins] r64217 - in python/branches/py3k/Lib:
 bsddb/test/test_associate.py bsddb/test/test_join.py
 bsddb/test/test_lock.py bsddb/test/test_thread.py idlelib/rpc.py
 idlelib/run.py socketserver.py test/test_threadedtempfile.py thread
In-Reply-To: <ca471dc20806122051r6f7b0087lb0f0d6606793430c@mail.gmail.com>
References: <ca471dc20806122051r6f7b0087lb0f0d6606793430c@mail.gmail.com>
Message-ID: <4852519A.6070506@holdenweb.com>

Guido van Rossum wrote:
> It's water under the bridge now, but IMO it was too rash to *remove*
> the old threading API from Py3k, and doubly rash to do so one day
> before the beta release. Running up to a release (whether alpha, beta
> or final) we should practice extra restraint, not rush to get things
> in right before the deadline. Let's all be more careful the rest of
> this release cycle! (I think it wasn't just Benjamin who raced to get
> things in...)

Well, it wouldn't be "adding a new feature" to reinstate the old API for 
beta two, would it, as long as we retain the new one too? It does seem 
that change was a little precipitate.

regards
  Steve
-- 
Steve Holden        +1 571 484 6266   +1 800 494 3119
Holden Web LLC              http://www.holdenweb.com/



From python-3000-checkins at python.org  Fri Jun 13 17:36:43 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Fri, 13 Jun 2008 17:36:43 +0200 (CEST)
Subject: [Python-3000-checkins] r64234 - in python/branches/py3k:
	Modules/_multiprocessing/multiprocessing.c
Message-ID: <20080613153643.7F8021E4006@bag.python.org>

Author: benjamin.peterson
Date: Fri Jun 13 17:36:43 2008
New Revision: 64234

Log:
Merged revisions 64223-64224 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/trunk

........
  r64223 | georg.brandl | 2008-06-13 01:56:50 -0500 (Fri, 13 Jun 2008) | 2 lines
  
  #3095: don't leak values from Py_BuildValue.
........
  r64224 | georg.brandl | 2008-06-13 02:08:48 -0500 (Fri, 13 Jun 2008) | 2 lines
  
  Typo.
........


Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Modules/_multiprocessing/multiprocessing.c

Modified: python/branches/py3k/Modules/_multiprocessing/multiprocessing.c
==============================================================================
--- python/branches/py3k/Modules/_multiprocessing/multiprocessing.c	(original)
+++ python/branches/py3k/Modules/_multiprocessing/multiprocessing.c	Fri Jun 13 17:36:43 2008
@@ -1,5 +1,5 @@
 /*
- * Extension module used by mutliprocessing package
+ * Extension module used by multiprocessing package
  *
  * multiprocessing.c
  *
@@ -228,7 +228,7 @@
 PyMODINIT_FUNC 
 PyInit__multiprocessing(void)
 {
-	PyObject *module, *temp;
+	PyObject *module, *temp, *value;
 
 	/* Initialize module */
 	module = PyModule_Create(&multiprocessing_module);
@@ -297,11 +297,13 @@
 	temp = PyDict_New();
 	if (!temp)
 		return NULL;
-	if (PyModule_AddObject(module, "flags", temp) < 0)
-		return NULL;
 
-#define ADD_FLAG(name) \
-       if (PyDict_SetItemString(temp, #name, Py_BuildValue("i", name)) < 0) return NULL
+#define ADD_FLAG(name)						  \
+	value = Py_BuildValue("i", name);			  \
+	if (value == NULL) { Py_DECREF(temp); return NULL; }	  \
+	if (PyDict_SetItemString(temp, #name, value) < 0) {	  \
+		Py_DECREF(temp); Py_DECREF(value); return NULL; }	  \
+	Py_DECREF(value)
 	
 #ifdef HAVE_SEM_OPEN
 	ADD_FLAG(HAVE_SEM_OPEN);
@@ -318,5 +320,9 @@
 #ifdef HAVE_BROKEN_SEM_UNLINK
 	ADD_FLAG(HAVE_BROKEN_SEM_UNLINK);
 #endif
+
+	if (PyModule_AddObject(module, "flags", temp) < 0)
+		return NULL;
+
         return module;
 }

From guido at python.org  Fri Jun 13 19:25:41 2008
From: guido at python.org (Guido van Rossum)
Date: Fri, 13 Jun 2008 10:25:41 -0700
Subject: [Python-3000-checkins] [Python-3000] r64217 - in
	python/branches/py3k/Lib: bsddb/test/test_associate.py
	bsddb/test/test_join.py bsddb/test/test_lock.py
	bsddb/test/test_thread.py idlelib/rpc.py idlelib/run.py
	socketserver.py test/test_threadedtemp
Message-ID: <ca471dc20806131025p53b39256ob3e181283f65bea3@mail.gmail.com>

On Fri, Jun 13, 2008 at 6:07 AM, Nick Coghlan <ncoghlan at gmail.com> wrote:
> Steve Holden wrote:
>>
>> Guido van Rossum wrote:
>>>
>>> It's water under the bridge now, but IMO it was too rash to *remove*
>>> the old threading API from Py3k, and doubly rash to do so one day
>>> before the beta release. Running up to a release (whether alpha, beta
>>> or final) we should practice extra restraint, not rush to get things
>>> in right before the deadline. Let's all be more careful the rest of
>>> this release cycle! (I think it wasn't just Benjamin who raced to get
>>> things in...)
>>
>> Well, it wouldn't be "adding a new feature" to reinstate the old API for
>> beta two, would it, as long as we retain the new one too? It does seem that
>> change was a little precipitate.
>
> Although if we weren't actually planning on removing the old API in 3.0, I'm
> a little confused as to why we were adding Py3k warnings to it in 2.6...

It all went way too fast for anyone to think about the decision, so I
suspect these two issues are directly related.

-- 
--Guido van Rossum (home page: http://www.python.org/~guido/)

From python-3000-checkins at python.org  Fri Jun 13 19:28:35 2008
From: python-3000-checkins at python.org (martin.v.loewis)
Date: Fri, 13 Jun 2008 19:28:35 +0200 (CEST)
Subject: [Python-3000-checkins] r64240 - in python/branches/py3k:
	PCbuild/pyproject.vsprops PCbuild/readme.txt
	Tools/buildbot/external-common.bat
Message-ID: <20080613172835.8DAAE1E4006@bag.python.org>

Author: martin.v.loewis
Date: Fri Jun 13 19:28:35 2008
New Revision: 64240

Log:
Merged revisions 64239 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/trunk

........
  r64239 | martin.v.loewis | 2008-06-13 19:22:39 +0200 (Fr, 13 Jun 2008) | 1 line
  
  Switch to bzip2 1.0.5.
........


Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/PCbuild/pyproject.vsprops
   python/branches/py3k/PCbuild/readme.txt
   python/branches/py3k/Tools/buildbot/external-common.bat

Modified: python/branches/py3k/PCbuild/pyproject.vsprops
==============================================================================
--- python/branches/py3k/PCbuild/pyproject.vsprops	(original)
+++ python/branches/py3k/PCbuild/pyproject.vsprops	Fri Jun 13 19:28:35 2008
@@ -78,7 +78,7 @@
 	/>
 	<UserMacro
 		Name="bz2Dir"
-		Value="$(externalsDir)\bzip2-1.0.3"
+		Value="$(externalsDir)\bzip2-1.0.5"
 	/>
 	<UserMacro
 		Name="opensslDir"

Modified: python/branches/py3k/PCbuild/readme.txt
==============================================================================
--- python/branches/py3k/PCbuild/readme.txt	(original)
+++ python/branches/py3k/PCbuild/readme.txt	Fri Jun 13 19:28:35 2008
@@ -121,21 +121,21 @@
     Download the source from the python.org copy into the dist
     directory:
 
-    svn export http://svn.python.org/projects/external/bzip2-1.0.3
+    svn export http://svn.python.org/projects/external/bzip2-1.0.5
 
     ** NOTE: if you use the Tools\buildbot\external(-amd64).bat approach for
     obtaining external sources then you don't need to manually get the source
     above via subversion. **
 
     A custom pre-link step in the bz2 project settings should manage to
-    build bzip2-1.0.3\libbz2.lib by magic before bz2.pyd (or bz2_d.pyd) is
+    build bzip2-1.0.5\libbz2.lib by magic before bz2.pyd (or bz2_d.pyd) is
     linked in PCbuild\.
     However, the bz2 project is not smart enough to remove anything under
-    bzip2-1.0.3\ when you do a clean, so if you want to rebuild bzip2.lib
-    you need to clean up bzip2-1.0.3\ by hand.
+    bzip2-1.0.5\ when you do a clean, so if you want to rebuild bzip2.lib
+    you need to clean up bzip2-1.0.5\ by hand.
 
     All of this managed to build libbz2.lib in 
-    bzip2-1.0.3\$platform-$configuration\, which the Python project links in.
+    bzip2-1.0.5\$platform-$configuration\, which the Python project links in.
 
 _ssl
     Python wrapper for the secure sockets library.

Modified: python/branches/py3k/Tools/buildbot/external-common.bat
==============================================================================
--- python/branches/py3k/Tools/buildbot/external-common.bat	(original)
+++ python/branches/py3k/Tools/buildbot/external-common.bat	Fri Jun 13 19:28:35 2008
@@ -4,7 +4,7 @@
 cd ..
 @rem XXX: If you need to force the buildbots to start from a fresh environment, uncomment
 @rem the following, check it in, then check it out, comment it out, then check it back in.
- at rem if exist bzip2-1.0.3 rd /s/q bzip2-1.0.3
+ at rem if exist bzip2-1.0.5 rd /s/q bzip2-1.0.5
 @rem if exist tcltk rd /s/q tcltk
 @rem if exist tcltk64 rd /s/q tcltk64
 @rem if exist tcl8.4.12 rd /s/q tcl8.4.12
@@ -18,7 +18,10 @@
 @rem if exist sqlite-source-3.3.4 rd /s/q sqlite-source-3.3.4    
 
 @rem bzip
-if not exist bzip2-1.0.3 svn export http://svn.python.org/projects/external/bzip2-1.0.3
+if not exist bzip2-1.0.5 (
+   rd /s/q bzip2-1.0.3
+  svn export http://svn.python.org/projects/external/bzip2-1.0.5
+)
 
 @rem Sleepycat db
 if not exist db-4.4.20 svn export http://svn.python.org/projects/external/db-4.4.20-vs9 db-4.4.20

From guido at python.org  Fri Jun 13 19:30:59 2008
From: guido at python.org (Guido van Rossum)
Date: Fri, 13 Jun 2008 10:30:59 -0700
Subject: [Python-3000-checkins] [Python-3000] r64217 - in
	python/branches/py3k/Lib: bsddb/test/test_associate.py
	bsddb/test/test_join.py bsddb/test/test_lock.py
	bsddb/test/test_thread.py idlelib/rpc.py idlelib/run.py
	socketserver.py test/test_threadedtemp
Message-ID: <ca471dc20806131030w104111cbmd3c148f0ca73dcd0@mail.gmail.com>

On Thu, Jun 12, 2008 at 11:32 PM, Georg Brandl <g.brandl at gmx.net> wrote:
> Guido van Rossum schrieb:
>>
>> It's water under the bridge now, but IMO it was too rash to *remove*
>> the old threading API from Py3k, and doubly rash to do so one day
>> before the beta release. Running up to a release (whether alpha, beta
>> or final) we should practice extra restraint, not rush to get things
>> in right before the deadline. Let's all be more careful the rest of
>> this release cycle! (I think it wasn't just Benjamin who raced to get
>> things in...)
>
> Also, for any method or module renaming, there is no way around a full
> grep through the code base to really catch all uses of the old API.

Eh? Even a full grep won't reveal 3rd party uses of the old API. While
3.x is intentionally breaking some things, this is not (and was never
meant to be) as a blanket approval to break any API we feel like
breaking. Each specific breakage must have a good motivation, e.g. the
old API is confusing, or inefficient, or disallows certain uses --
non-PEP-8-conformance alone is not enough! In addition, each specific
breakage must be weighed against the cost of updating 3rd party code,
and whether a good (or at least fair) automatic conversion can be
added to 2to3.

> It may be tedious, especially with common names, but such bugs really
> must be avoided as they can easily be -- I still could find uses of
> old-style threading names, even in the stdlib. (Fixed in r64222.)

All the more reason not to rush into API renamings without due process
and lots of discussion. Let's err on the side of the status quo --
otherwise we'll never be ready for beta.

-- 
--Guido van Rossum (home page: http://www.python.org/~guido/)

From python-3000-checkins at python.org  Fri Jun 13 20:21:45 2008
From: python-3000-checkins at python.org (martin.v.loewis)
Date: Fri, 13 Jun 2008 20:21:45 +0200 (CEST)
Subject: [Python-3000-checkins] r64245 - in python/branches/py3k:
	PCbuild/pyproject.vsprops PCbuild/readme.txt
	PCbuild/sqlite3.vcproj Tools/buildbot/external-common.bat
Message-ID: <20080613182145.F136C1E4006@bag.python.org>

Author: martin.v.loewis
Date: Fri Jun 13 20:21:45 2008
New Revision: 64245

Log:
Merged revisions 64243-64244 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/trunk

........
  r64243 | martin.v.loewis | 2008-06-13 20:12:51 +0200 (Fr, 13 Jun 2008) | 1 line
  
  Switch to SQLite 3.5.9.
........
  r64244 | martin.v.loewis | 2008-06-13 20:19:49 +0200 (Fr, 13 Jun 2008) | 1 line
  
  Update AMD64 build for amalgamated sqlite.
........


Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/PCbuild/pyproject.vsprops
   python/branches/py3k/PCbuild/readme.txt
   python/branches/py3k/PCbuild/sqlite3.vcproj
   python/branches/py3k/Tools/buildbot/external-common.bat

Modified: python/branches/py3k/PCbuild/pyproject.vsprops
==============================================================================
--- python/branches/py3k/PCbuild/pyproject.vsprops	(original)
+++ python/branches/py3k/PCbuild/pyproject.vsprops	Fri Jun 13 20:21:45 2008
@@ -74,7 +74,7 @@
 	/>
 	<UserMacro
 		Name="sqlite3Dir"
-		Value="$(externalsDir)\sqlite-source-3.3.4"
+		Value="$(externalsDir)\sqlite-3.5.9"
 	/>
 	<UserMacro
 		Name="bz2Dir"

Modified: python/branches/py3k/PCbuild/readme.txt
==============================================================================
--- python/branches/py3k/PCbuild/readme.txt	(original)
+++ python/branches/py3k/PCbuild/readme.txt	Fri Jun 13 20:21:45 2008
@@ -107,7 +107,7 @@
     Wraps Berkeley DB 4.4.20, which is currently built by _bsddb44.vcproj.
     project (see below).
 _sqlite3
-    Wraps SQLite 3.3.4, which is currently built by sqlite3.vcproj (see below).
+    Wraps SQLite 3.5.9, which is currently built by sqlite3.vcproj (see below).
 _tkinter
     Wraps the Tk windowing system.  Unlike _bsddb and _sqlite3, there's no
     corresponding tcltk.vcproj-type project that builds Tcl/Tk from vcproj's

Modified: python/branches/py3k/PCbuild/sqlite3.vcproj
==============================================================================
--- python/branches/py3k/PCbuild/sqlite3.vcproj	(original)
+++ python/branches/py3k/PCbuild/sqlite3.vcproj	Fri Jun 13 20:21:45 2008
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="Windows-1252"?>
 <VisualStudioProject
 	ProjectType="Visual C++"
-	Version="9.00"
+	Version="9,00"
 	Name="sqlite3"
 	ProjectGUID="{A1A295E5-463C-437F-81CA-1F32367685DA}"
 	RootNamespace="sqlite3"
@@ -43,6 +43,7 @@
 			<Tool
 				Name="VCCLCompilerTool"
 				AdditionalIncludeDirectories="$(sqlite3Dir)"
+				PreprocessorDefinitions="SQLITE_API=__declspec(dllexport)"
 			/>
 			<Tool
 				Name="VCManagedResourceCompilerTool"
@@ -56,7 +57,6 @@
 			<Tool
 				Name="VCLinkerTool"
 				OutputFile="$(OutDir)\$(ProjectName)_d.dll"
-				ModuleDefinitionFile="$(sqlite3Dir)\sqlite3.def"
 			/>
 			<Tool
 				Name="VCALinkTool"
@@ -105,6 +105,7 @@
 			<Tool
 				Name="VCCLCompilerTool"
 				AdditionalIncludeDirectories="$(sqlite3Dir)"
+				PreprocessorDefinitions="SQLITE_API=__declspec(dllexport)"
 			/>
 			<Tool
 				Name="VCManagedResourceCompilerTool"
@@ -118,7 +119,6 @@
 			<Tool
 				Name="VCLinkerTool"
 				OutputFile="$(OutDir)\$(ProjectName)_d.dll"
-				ModuleDefinitionFile="$(sqlite3Dir)\sqlite3.def"
 			/>
 			<Tool
 				Name="VCALinkTool"
@@ -167,6 +167,7 @@
 			<Tool
 				Name="VCCLCompilerTool"
 				AdditionalIncludeDirectories="$(sqlite3Dir)"
+				PreprocessorDefinitions="SQLITE_API=__declspec(dllexport)"
 			/>
 			<Tool
 				Name="VCManagedResourceCompilerTool"
@@ -180,7 +181,6 @@
 			<Tool
 				Name="VCLinkerTool"
 				OutputFile="$(OutDir)\$(ProjectName).dll"
-				ModuleDefinitionFile="$(sqlite3Dir)\sqlite3.def"
 			/>
 			<Tool
 				Name="VCALinkTool"
@@ -230,6 +230,7 @@
 			<Tool
 				Name="VCCLCompilerTool"
 				AdditionalIncludeDirectories="$(sqlite3Dir)"
+				PreprocessorDefinitions="SQLITE_API=__declspec(dllexport)"
 			/>
 			<Tool
 				Name="VCManagedResourceCompilerTool"
@@ -243,7 +244,6 @@
 			<Tool
 				Name="VCLinkerTool"
 				OutputFile="$(OutDir)\$(ProjectName).dll"
-				ModuleDefinitionFile="$(sqlite3Dir)\sqlite3.def"
 			/>
 			<Tool
 				Name="VCALinkTool"
@@ -292,6 +292,7 @@
 			<Tool
 				Name="VCCLCompilerTool"
 				AdditionalIncludeDirectories="$(sqlite3Dir)"
+				PreprocessorDefinitions="SQLITE_API=__declspec(dllexport)"
 			/>
 			<Tool
 				Name="VCManagedResourceCompilerTool"
@@ -304,7 +305,6 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				ModuleDefinitionFile="$(sqlite3Dir)\sqlite3.def"
 			/>
 			<Tool
 				Name="VCALinkTool"
@@ -354,6 +354,7 @@
 			<Tool
 				Name="VCCLCompilerTool"
 				AdditionalIncludeDirectories="$(sqlite3Dir)"
+				PreprocessorDefinitions="SQLITE_API=__declspec(dllexport)"
 			/>
 			<Tool
 				Name="VCManagedResourceCompilerTool"
@@ -366,7 +367,6 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				ModuleDefinitionFile="$(sqlite3Dir)\sqlite3.def"
 			/>
 			<Tool
 				Name="VCALinkTool"
@@ -415,6 +415,7 @@
 			<Tool
 				Name="VCCLCompilerTool"
 				AdditionalIncludeDirectories="$(sqlite3Dir)"
+				PreprocessorDefinitions="SQLITE_API=__declspec(dllexport)"
 			/>
 			<Tool
 				Name="VCManagedResourceCompilerTool"
@@ -427,7 +428,6 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				ModuleDefinitionFile="$(sqlite3Dir)\sqlite3.def"
 			/>
 			<Tool
 				Name="VCALinkTool"
@@ -477,6 +477,7 @@
 			<Tool
 				Name="VCCLCompilerTool"
 				AdditionalIncludeDirectories="$(sqlite3Dir)"
+				PreprocessorDefinitions="SQLITE_API=__declspec(dllexport)"
 			/>
 			<Tool
 				Name="VCManagedResourceCompilerTool"
@@ -489,7 +490,6 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				ModuleDefinitionFile="$(sqlite3Dir)\sqlite3.def"
 			/>
 			<Tool
 				Name="VCALinkTool"
@@ -521,51 +521,11 @@
 			Name="Header Files"
 			>
 			<File
-				RelativePath="$(sqlite3Dir)\btree.h"
-				>
-			</File>
-			<File
-				RelativePath="$(sqlite3Dir)\hash.h"
-				>
-			</File>
-			<File
-				RelativePath="$(sqlite3Dir)\keywordhash.h"
-				>
-			</File>
-			<File
-				RelativePath="$(sqlite3Dir)\opcodes.h"
-				>
-			</File>
-			<File
-				RelativePath="$(sqlite3Dir)\os.h"
-				>
-			</File>
-			<File
-				RelativePath="$(sqlite3Dir)\os_common.h"
-				>
-			</File>
-			<File
-				RelativePath="$(sqlite3Dir)\pager.h"
-				>
-			</File>
-			<File
-				RelativePath="$(sqlite3Dir)\parse.h"
-				>
-			</File>
-			<File
 				RelativePath="$(sqlite3Dir)\sqlite3.h"
 				>
 			</File>
 			<File
-				RelativePath="$(sqlite3Dir)\sqliteInt.h"
-				>
-			</File>
-			<File
-				RelativePath="$(sqlite3Dir)\vdbe.h"
-				>
-			</File>
-			<File
-				RelativePath="$(sqlite3Dir)\vdbeInt.h"
+				RelativePath="$(sqlite3Dir)\sqlite3ext.h"
 				>
 			</File>
 		</Filter>
@@ -573,167 +533,7 @@
 			Name="Source Files"
 			>
 			<File
-				RelativePath="$(sqlite3Dir)\alter.c"
-				>
-			</File>
-			<File
-				RelativePath="$(sqlite3Dir)\analyze.c"
-				>
-			</File>
-			<File
-				RelativePath="$(sqlite3Dir)\attach.c"
-				>
-			</File>
-			<File
-				RelativePath="$(sqlite3Dir)\auth.c"
-				>
-			</File>
-			<File
-				RelativePath="$(sqlite3Dir)\btree.c"
-				>
-			</File>
-			<File
-				RelativePath="$(sqlite3Dir)\build.c"
-				>
-			</File>
-			<File
-				RelativePath="$(sqlite3Dir)\callback.c"
-				>
-			</File>
-			<File
-				RelativePath="$(sqlite3Dir)\complete.c"
-				>
-			</File>
-			<File
-				RelativePath="$(sqlite3Dir)\date.c"
-				>
-			</File>
-			<File
-				RelativePath="$(sqlite3Dir)\delete.c"
-				>
-			</File>
-			<File
-				RelativePath="$(sqlite3Dir)\expr.c"
-				>
-			</File>
-			<File
-				RelativePath="$(sqlite3Dir)\func.c"
-				>
-			</File>
-			<File
-				RelativePath="$(sqlite3Dir)\hash.c"
-				>
-			</File>
-			<File
-				RelativePath="$(sqlite3Dir)\insert.c"
-				>
-			</File>
-			<File
-				RelativePath="$(sqlite3Dir)\legacy.c"
-				>
-			</File>
-			<File
-				RelativePath="$(sqlite3Dir)\main.c"
-				>
-			</File>
-			<File
-				RelativePath="$(sqlite3Dir)\opcodes.c"
-				>
-			</File>
-			<File
-				RelativePath="$(sqlite3Dir)\os.c"
-				>
-			</File>
-			<File
-				RelativePath="$(sqlite3Dir)\os_unix.c"
-				>
-			</File>
-			<File
-				RelativePath="$(sqlite3Dir)\os_win.c"
-				>
-			</File>
-			<File
-				RelativePath="$(sqlite3Dir)\pager.c"
-				>
-			</File>
-			<File
-				RelativePath="$(sqlite3Dir)\parse.c"
-				>
-			</File>
-			<File
-				RelativePath="$(sqlite3Dir)\pragma.c"
-				>
-			</File>
-			<File
-				RelativePath="$(sqlite3Dir)\prepare.c"
-				>
-			</File>
-			<File
-				RelativePath="$(sqlite3Dir)\printf.c"
-				>
-			</File>
-			<File
-				RelativePath="$(sqlite3Dir)\random.c"
-				>
-			</File>
-			<File
-				RelativePath="$(sqlite3Dir)\select.c"
-				>
-			</File>
-			<File
-				RelativePath="$(sqlite3Dir)\shell.c"
-				>
-			</File>
-			<File
-				RelativePath="$(sqlite3Dir)\table.c"
-				>
-			</File>
-			<File
-				RelativePath="$(sqlite3Dir)\tokenize.c"
-				>
-			</File>
-			<File
-				RelativePath="$(sqlite3Dir)\trigger.c"
-				>
-			</File>
-			<File
-				RelativePath="$(sqlite3Dir)\update.c"
-				>
-			</File>
-			<File
-				RelativePath="$(sqlite3Dir)\utf.c"
-				>
-			</File>
-			<File
-				RelativePath="$(sqlite3Dir)\util.c"
-				>
-			</File>
-			<File
-				RelativePath="$(sqlite3Dir)\vacuum.c"
-				>
-			</File>
-			<File
-				RelativePath="$(sqlite3Dir)\vdbe.c"
-				>
-			</File>
-			<File
-				RelativePath="$(sqlite3Dir)\vdbeapi.c"
-				>
-			</File>
-			<File
-				RelativePath="$(sqlite3Dir)\vdbeaux.c"
-				>
-			</File>
-			<File
-				RelativePath="$(sqlite3Dir)\vdbefifo.c"
-				>
-			</File>
-			<File
-				RelativePath="$(sqlite3Dir)\vdbemem.c"
-				>
-			</File>
-			<File
-				RelativePath="$(sqlite3Dir)\where.c"
+				RelativePath="$(sqlite3Dir)\sqlite3.c"
 				>
 			</File>
 		</Filter>

Modified: python/branches/py3k/Tools/buildbot/external-common.bat
==============================================================================
--- python/branches/py3k/Tools/buildbot/external-common.bat	(original)
+++ python/branches/py3k/Tools/buildbot/external-common.bat	Fri Jun 13 20:21:45 2008
@@ -15,7 +15,7 @@
 @rem if exist tk-8.4.18.1 rd /s/q tk-8.4.18.1
 @rem if exist db-4.4.20 rd /s/q db-4.4.20
 @rem if exist openssl-0.9.8g rd /s/q openssl-0.9.8g
- at rem if exist sqlite-source-3.3.4 rd /s/q sqlite-source-3.3.4    
+ at rem if exist sqlite-source-3.5.9 rd /s/q sqlite-source-3.5.9    
 
 @rem bzip
 if not exist bzip2-1.0.5 (
@@ -37,4 +37,7 @@
 if not exist tk-8.5.2.0 svn export http://svn.python.org/projects/external/tk-8.5.2.0
 
 @rem sqlite3
-if not exist sqlite-source-3.3.4 svn export http://svn.python.org/projects/external/sqlite-source-3.3.4
+if not exist sqlite-source-3.5.9 (
+  rd /s/q sqlite-source-3.3.4
+  svn export http://svn.python.org/projects/external/sqlite-source-3.5.9
+)

From python-3000-checkins at python.org  Fri Jun 13 21:00:35 2008
From: python-3000-checkins at python.org (martin.v.loewis)
Date: Fri, 13 Jun 2008 21:00:35 +0200 (CEST)
Subject: [Python-3000-checkins] r64247 - in python/branches/py3k:
	Tools/msi/msi.py
Message-ID: <20080613190035.61BA61E4006@bag.python.org>

Author: martin.v.loewis
Date: Fri Jun 13 21:00:35 2008
New Revision: 64247

Log:
Merged revisions 64246 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/trunk

........
  r64246 | martin.v.loewis | 2008-06-13 20:58:47 +0200 (Fr, 13 Jun 2008) | 2 lines
  
  Pickup sqlite3.dll from binary directory.
  Commit more often.
........


Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Tools/msi/msi.py

Modified: python/branches/py3k/Tools/msi/msi.py
==============================================================================
--- python/branches/py3k/Tools/msi/msi.py	(original)
+++ python/branches/py3k/Tools/msi/msi.py	Fri Jun 13 21:00:35 2008
@@ -24,8 +24,6 @@
 full_current_version = None
 # Is Tcl available at all?
 have_tcl = True
-# Where is sqlite3.dll located, relative to srcdir?
-sqlite_dir = "../sqlite-source-3.3.4"
 # path to PCbuild directory
 PCBUILD="PCbuild"
 # msvcrt version
@@ -940,6 +938,8 @@
     dirs={}
     pydirs = [(root,"Lib")]
     while pydirs:
+        # Commit every now and then, or else installer will complain
+        db.Commit()
         parent, dir = pydirs.pop()
         if dir == ".svn" or dir.startswith("plat-"):
             continue
@@ -1042,7 +1042,7 @@
     else:
         sqlite_arch = ""
         tclsuffix = ""
-    lib.add_file(srcdir+"/"+sqlite_dir+sqlite_arch+"/sqlite3.dll")
+    lib.add_file("sqlite3.dll")
     if have_tcl:
         if not os.path.exists("%s/%s/_tkinter.pyd" % (srcdir, PCBUILD)):
             print("WARNING: Missing _tkinter.pyd")

From python-3000-checkins at python.org  Fri Jun 13 21:16:07 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Fri, 13 Jun 2008 21:16:07 +0200 (CEST)
Subject: [Python-3000-checkins] r64249 - python/branches/py3k
Message-ID: <20080613191607.C165E1E4006@bag.python.org>

Author: benjamin.peterson
Date: Fri Jun 13 21:16:07 2008
New Revision: 64249

Log:
Blocked revisions 64248 via svnmerge

........
  r64248 | benjamin.peterson | 2008-06-13 14:13:39 -0500 (Fri, 13 Jun 2008) | 1 line
  
  convert multiprocessing to unix line endings
........


Modified:
   python/branches/py3k/   (props changed)

From python-3000-checkins at python.org  Fri Jun 13 21:23:31 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Fri, 13 Jun 2008 21:23:31 +0200 (CEST)
Subject: [Python-3000-checkins] r64251 - python/branches/py3k
Message-ID: <20080613192331.964EA1E4006@bag.python.org>

Author: benjamin.peterson
Date: Fri Jun 13 21:23:31 2008
New Revision: 64251

Log:
Blocked revisions 64250 via svnmerge

........
  r64250 | benjamin.peterson | 2008-06-13 14:20:48 -0500 (Fri, 13 Jun 2008) | 1 line
  
  darn! I converted half of the files the wrong way.
........


Modified:
   python/branches/py3k/   (props changed)

From python-3000-checkins at python.org  Fri Jun 13 21:28:21 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Fri, 13 Jun 2008 21:28:21 +0200 (CEST)
Subject: [Python-3000-checkins] r64252 - in
	python/branches/py3k/Modules/_multiprocessing:
	multiprocessing.c multiprocessing.h pipe_connection.c
	win32_functions.c
Message-ID: <20080613192821.E84871E4006@bag.python.org>

Author: benjamin.peterson
Date: Fri Jun 13 21:28:21 2008
New Revision: 64252

Log:
fix multiprocessing line endings in py3k

Modified:
   python/branches/py3k/Modules/_multiprocessing/multiprocessing.c
   python/branches/py3k/Modules/_multiprocessing/multiprocessing.h
   python/branches/py3k/Modules/_multiprocessing/pipe_connection.c
   python/branches/py3k/Modules/_multiprocessing/win32_functions.c

Modified: python/branches/py3k/Modules/_multiprocessing/multiprocessing.c
==============================================================================
--- python/branches/py3k/Modules/_multiprocessing/multiprocessing.c	(original)
+++ python/branches/py3k/Modules/_multiprocessing/multiprocessing.c	Fri Jun 13 21:28:21 2008
@@ -1,328 +1,328 @@
-/*
- * Extension module used by multiprocessing package
- *
- * multiprocessing.c
- *
- * Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
- */
-
-#include "multiprocessing.h"
-
-PyObject *create_win32_namespace(void);
-
-PyObject *pickle_dumps, *pickle_loads, *pickle_protocol;
-PyObject *ProcessError, *BufferTooShort;
-
-/*
- * Function which raises exceptions based on error codes
- */
-
-PyObject *
-mp_SetError(PyObject *Type, int num)
-{
-	switch (num) {
-#ifdef MS_WINDOWS
-	case MP_STANDARD_ERROR: 
-		if (Type == NULL)
-			Type = PyExc_WindowsError;
-		PyErr_SetExcFromWindowsErr(Type, 0);
-		break;
-	case MP_SOCKET_ERROR:
-		if (Type == NULL)
-			Type = PyExc_WindowsError;
-		PyErr_SetExcFromWindowsErr(Type, WSAGetLastError());
-		break;
-#else /* !MS_WINDOWS */
-	case MP_STANDARD_ERROR:
-	case MP_SOCKET_ERROR:
-		if (Type == NULL)
-			Type = PyExc_OSError;
-		PyErr_SetFromErrno(Type);
-		break;
-#endif /* !MS_WINDOWS */
-	case MP_MEMORY_ERROR:
-		PyErr_NoMemory();
-		break;
-	case MP_END_OF_FILE:
-		PyErr_SetNone(PyExc_EOFError);
-		break;
-	case MP_EARLY_END_OF_FILE:
-		PyErr_SetString(PyExc_IOError,
-				"got end of file during message");
-		break;
-	case MP_BAD_MESSAGE_LENGTH:
-		PyErr_SetString(PyExc_IOError, "bad message length");
-		break;
-	case MP_EXCEPTION_HAS_BEEN_SET:
-		break;
-	default:
-		PyErr_Format(PyExc_RuntimeError,
-			     "unkown error number %d", num);
-	}
-	return NULL;
-}
-
-
-/*
- * Windows only
- */
-
-#ifdef MS_WINDOWS
-
-/* On Windows we set an event to signal Ctrl-C; compare with timemodule.c */
-
-HANDLE sigint_event = NULL;
-
-static BOOL WINAPI
-ProcessingCtrlHandler(DWORD dwCtrlType)
-{
-	SetEvent(sigint_event);
-	return FALSE;
-}
-
-/*
- * Unix only
- */
-
-#else /* !MS_WINDOWS */
-
-#if HAVE_FD_TRANSFER
-
-/* Functions for transferring file descriptors between processes.
-   Reimplements some of the functionality of the fdcred
-   module at http://www.mca-ltd.com/resources/fdcred_1.tgz. */
-
-static PyObject *
-multiprocessing_sendfd(PyObject *self, PyObject *args)
-{
-	int conn, fd, res;
-	char dummy_char;
-	char buf[CMSG_SPACE(sizeof(int))];
-	struct msghdr msg = {0};
-	struct iovec dummy_iov;
-	struct cmsghdr *cmsg;
-
-	if (!PyArg_ParseTuple(args, "ii", &conn, &fd))
-		return NULL;
-
-	dummy_iov.iov_base = &dummy_char;
-	dummy_iov.iov_len = 1;
-	msg.msg_control = buf;
-	msg.msg_controllen = sizeof(buf);
-	msg.msg_iov = &dummy_iov;
-	msg.msg_iovlen = 1;
-	cmsg = CMSG_FIRSTHDR(&msg);
-	cmsg->cmsg_level = SOL_SOCKET;
-	cmsg->cmsg_type = SCM_RIGHTS;
-	cmsg->cmsg_len = CMSG_LEN(sizeof(int));
-	msg.msg_controllen = cmsg->cmsg_len;
-	*(int*)CMSG_DATA(cmsg) = fd;
-
-	Py_BEGIN_ALLOW_THREADS
-	res = sendmsg(conn, &msg, 0);
-	Py_END_ALLOW_THREADS
-
-	if (res < 0)
-		return PyErr_SetFromErrno(PyExc_OSError);
-	Py_RETURN_NONE;
-}
-
-static PyObject *
-multiprocessing_recvfd(PyObject *self, PyObject *args)
-{
-	int conn, fd, res;
-	char dummy_char;
-	char buf[CMSG_SPACE(sizeof(int))];
-	struct msghdr msg = {0};
-	struct iovec dummy_iov;
-	struct cmsghdr *cmsg;
-
-	if (!PyArg_ParseTuple(args, "i", &conn))
-		return NULL;
-
-	dummy_iov.iov_base = &dummy_char;
-	dummy_iov.iov_len = 1;
-	msg.msg_control = buf;
-	msg.msg_controllen = sizeof(buf);
-	msg.msg_iov = &dummy_iov;
-	msg.msg_iovlen = 1;
-	cmsg = CMSG_FIRSTHDR(&msg);
-	cmsg->cmsg_level = SOL_SOCKET;
-	cmsg->cmsg_type = SCM_RIGHTS;
-	cmsg->cmsg_len = CMSG_LEN(sizeof(int));
-	msg.msg_controllen = cmsg->cmsg_len;
-
-	Py_BEGIN_ALLOW_THREADS
-	res = recvmsg(conn, &msg, 0);
-	Py_END_ALLOW_THREADS
-
-	if (res < 0)
-		return PyErr_SetFromErrno(PyExc_OSError);
-
-	fd = *(int*)CMSG_DATA(cmsg);
-	return Py_BuildValue("i", fd);
-}
-
-#endif /* HAVE_FD_TRANSFER */
-
-#endif /* !MS_WINDOWS */
-
-
-/*
- * All platforms
- */
-
-static PyObject*
-multiprocessing_address_of_buffer(PyObject *self, PyObject *obj)
-{
-	void *buffer;
-	Py_ssize_t buffer_len;
-
-	if (PyObject_AsWriteBuffer(obj, &buffer, &buffer_len) < 0)
-		return NULL;
-
-	return Py_BuildValue("N" F_PY_SSIZE_T, 
-			     PyLong_FromVoidPtr(buffer), buffer_len);
-}
-
-
-/*
- * Function table
- */
-
-static PyMethodDef module_methods[] = {
-	{"address_of_buffer", multiprocessing_address_of_buffer, METH_O, 
-	 "address_of_buffer(obj) -> int\n" 
-	 "Return address of obj assuming obj supports buffer inteface"},
-#if HAVE_FD_TRANSFER
-	{"sendfd", multiprocessing_sendfd, METH_VARARGS, 
-	 "sendfd(sockfd, fd) -> None\n"
-	 "Send file descriptor given by fd over the unix domain socket\n"
-	 "whose file decriptor is sockfd"},
-	{"recvfd", multiprocessing_recvfd, METH_VARARGS,
-	 "recvfd(sockfd) -> fd\n"
-	 "Receive a file descriptor over a unix domain socket\n"
-	 "whose file decriptor is sockfd"},
-#endif
-	{NULL}
-};
-
-
-/*
- * Initialize
- */
-
-static struct PyModuleDef multiprocessing_module = {
-	PyModuleDef_HEAD_INIT,
-	"_multiprocessing",
-	NULL,
-	-1,
-	module_methods,
-	NULL,
-	NULL,
-	NULL,
-	NULL
-};
-
-
-PyMODINIT_FUNC 
-PyInit__multiprocessing(void)
-{
-	PyObject *module, *temp, *value;
-
-	/* Initialize module */
-	module = PyModule_Create(&multiprocessing_module);
-	if (!module)
-		return NULL;
-
-	/* Get copy of objects from pickle */
-	temp = PyImport_ImportModule(PICKLE_MODULE);
-	if (!temp)
-		return NULL;
-	pickle_dumps = PyObject_GetAttrString(temp, "dumps");
-	pickle_loads = PyObject_GetAttrString(temp, "loads");
-	pickle_protocol = PyObject_GetAttrString(temp, "HIGHEST_PROTOCOL");
-	Py_XDECREF(temp);
-
-	/* Get copy of BufferTooShort */
-	temp = PyImport_ImportModule("multiprocessing");
-	if (!temp)
-		return NULL;
-	BufferTooShort = PyObject_GetAttrString(temp, "BufferTooShort");
-	Py_XDECREF(temp);
-
-	/* Add connection type to module */
-	if (PyType_Ready(&ConnectionType) < 0)
-		return NULL;
-	Py_INCREF(&ConnectionType);	
-	PyModule_AddObject(module, "Connection", (PyObject*)&ConnectionType);
-
-#if defined(MS_WINDOWS) || HAVE_SEM_OPEN
-	/* Add SemLock type to module */
-	if (PyType_Ready(&SemLockType) < 0)
-		return NULL;
-	Py_INCREF(&SemLockType);
-	PyDict_SetItemString(SemLockType.tp_dict, "SEM_VALUE_MAX", 
-			     Py_BuildValue("i", SEM_VALUE_MAX));
-	PyModule_AddObject(module, "SemLock", (PyObject*)&SemLockType);   
-#endif
-
-#ifdef MS_WINDOWS
-	/* Add PipeConnection to module */
-	if (PyType_Ready(&PipeConnectionType) < 0)
-		return NULL;
-	Py_INCREF(&PipeConnectionType);
-	PyModule_AddObject(module, "PipeConnection",
-			   (PyObject*)&PipeConnectionType);
-
-	/* Initialize win32 class and add to multiprocessing */
-	temp = create_win32_namespace();
-	if (!temp)
-		return NULL;
-	PyModule_AddObject(module, "win32", temp);
-
-	/* Initialize the event handle used to signal Ctrl-C */
-	sigint_event = CreateEvent(NULL, TRUE, FALSE, NULL);
-	if (!sigint_event) {
-		PyErr_SetFromWindowsErr(0);
-		return NULL;
-	}
-	if (!SetConsoleCtrlHandler(ProcessingCtrlHandler, TRUE)) {
-		PyErr_SetFromWindowsErr(0);
-		return NULL;
-	}
-#endif
-
-	/* Add configuration macros */
-	temp = PyDict_New();
-	if (!temp)
-		return NULL;
-
-#define ADD_FLAG(name)						  \
-	value = Py_BuildValue("i", name);			  \
-	if (value == NULL) { Py_DECREF(temp); return NULL; }	  \
-	if (PyDict_SetItemString(temp, #name, value) < 0) {	  \
-		Py_DECREF(temp); Py_DECREF(value); return NULL; }	  \
-	Py_DECREF(value)
-	
-#ifdef HAVE_SEM_OPEN
-	ADD_FLAG(HAVE_SEM_OPEN);
-#endif
-#ifdef HAVE_SEM_TIMEDWAIT
-	ADD_FLAG(HAVE_SEM_TIMEDWAIT);
-#endif
-#ifdef HAVE_FD_TRANSFER
-	ADD_FLAG(HAVE_FD_TRANSFER);
-#endif
-#ifdef HAVE_BROKEN_SEM_GETVALUE
-	ADD_FLAG(HAVE_BROKEN_SEM_GETVALUE);
-#endif
-#ifdef HAVE_BROKEN_SEM_UNLINK
-	ADD_FLAG(HAVE_BROKEN_SEM_UNLINK);
-#endif
-
-	if (PyModule_AddObject(module, "flags", temp) < 0)
-		return NULL;
-
-        return module;
-}
+/*
+ * Extension module used by multiprocessing package
+ *
+ * multiprocessing.c
+ *
+ * Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
+ */
+
+#include "multiprocessing.h"
+
+PyObject *create_win32_namespace(void);
+
+PyObject *pickle_dumps, *pickle_loads, *pickle_protocol;
+PyObject *ProcessError, *BufferTooShort;
+
+/*
+ * Function which raises exceptions based on error codes
+ */
+
+PyObject *
+mp_SetError(PyObject *Type, int num)
+{
+	switch (num) {
+#ifdef MS_WINDOWS
+	case MP_STANDARD_ERROR: 
+		if (Type == NULL)
+			Type = PyExc_WindowsError;
+		PyErr_SetExcFromWindowsErr(Type, 0);
+		break;
+	case MP_SOCKET_ERROR:
+		if (Type == NULL)
+			Type = PyExc_WindowsError;
+		PyErr_SetExcFromWindowsErr(Type, WSAGetLastError());
+		break;
+#else /* !MS_WINDOWS */
+	case MP_STANDARD_ERROR:
+	case MP_SOCKET_ERROR:
+		if (Type == NULL)
+			Type = PyExc_OSError;
+		PyErr_SetFromErrno(Type);
+		break;
+#endif /* !MS_WINDOWS */
+	case MP_MEMORY_ERROR:
+		PyErr_NoMemory();
+		break;
+	case MP_END_OF_FILE:
+		PyErr_SetNone(PyExc_EOFError);
+		break;
+	case MP_EARLY_END_OF_FILE:
+		PyErr_SetString(PyExc_IOError,
+				"got end of file during message");
+		break;
+	case MP_BAD_MESSAGE_LENGTH:
+		PyErr_SetString(PyExc_IOError, "bad message length");
+		break;
+	case MP_EXCEPTION_HAS_BEEN_SET:
+		break;
+	default:
+		PyErr_Format(PyExc_RuntimeError,
+			     "unkown error number %d", num);
+	}
+	return NULL;
+}
+
+
+/*
+ * Windows only
+ */
+
+#ifdef MS_WINDOWS
+
+/* On Windows we set an event to signal Ctrl-C; compare with timemodule.c */
+
+HANDLE sigint_event = NULL;
+
+static BOOL WINAPI
+ProcessingCtrlHandler(DWORD dwCtrlType)
+{
+	SetEvent(sigint_event);
+	return FALSE;
+}
+
+/*
+ * Unix only
+ */
+
+#else /* !MS_WINDOWS */
+
+#if HAVE_FD_TRANSFER
+
+/* Functions for transferring file descriptors between processes.
+   Reimplements some of the functionality of the fdcred
+   module at http://www.mca-ltd.com/resources/fdcred_1.tgz. */
+
+static PyObject *
+multiprocessing_sendfd(PyObject *self, PyObject *args)
+{
+	int conn, fd, res;
+	char dummy_char;
+	char buf[CMSG_SPACE(sizeof(int))];
+	struct msghdr msg = {0};
+	struct iovec dummy_iov;
+	struct cmsghdr *cmsg;
+
+	if (!PyArg_ParseTuple(args, "ii", &conn, &fd))
+		return NULL;
+
+	dummy_iov.iov_base = &dummy_char;
+	dummy_iov.iov_len = 1;
+	msg.msg_control = buf;
+	msg.msg_controllen = sizeof(buf);
+	msg.msg_iov = &dummy_iov;
+	msg.msg_iovlen = 1;
+	cmsg = CMSG_FIRSTHDR(&msg);
+	cmsg->cmsg_level = SOL_SOCKET;
+	cmsg->cmsg_type = SCM_RIGHTS;
+	cmsg->cmsg_len = CMSG_LEN(sizeof(int));
+	msg.msg_controllen = cmsg->cmsg_len;
+	*(int*)CMSG_DATA(cmsg) = fd;
+
+	Py_BEGIN_ALLOW_THREADS
+	res = sendmsg(conn, &msg, 0);
+	Py_END_ALLOW_THREADS
+
+	if (res < 0)
+		return PyErr_SetFromErrno(PyExc_OSError);
+	Py_RETURN_NONE;
+}
+
+static PyObject *
+multiprocessing_recvfd(PyObject *self, PyObject *args)
+{
+	int conn, fd, res;
+	char dummy_char;
+	char buf[CMSG_SPACE(sizeof(int))];
+	struct msghdr msg = {0};
+	struct iovec dummy_iov;
+	struct cmsghdr *cmsg;
+
+	if (!PyArg_ParseTuple(args, "i", &conn))
+		return NULL;
+
+	dummy_iov.iov_base = &dummy_char;
+	dummy_iov.iov_len = 1;
+	msg.msg_control = buf;
+	msg.msg_controllen = sizeof(buf);
+	msg.msg_iov = &dummy_iov;
+	msg.msg_iovlen = 1;
+	cmsg = CMSG_FIRSTHDR(&msg);
+	cmsg->cmsg_level = SOL_SOCKET;
+	cmsg->cmsg_type = SCM_RIGHTS;
+	cmsg->cmsg_len = CMSG_LEN(sizeof(int));
+	msg.msg_controllen = cmsg->cmsg_len;
+
+	Py_BEGIN_ALLOW_THREADS
+	res = recvmsg(conn, &msg, 0);
+	Py_END_ALLOW_THREADS
+
+	if (res < 0)
+		return PyErr_SetFromErrno(PyExc_OSError);
+
+	fd = *(int*)CMSG_DATA(cmsg);
+	return Py_BuildValue("i", fd);
+}
+
+#endif /* HAVE_FD_TRANSFER */
+
+#endif /* !MS_WINDOWS */
+
+
+/*
+ * All platforms
+ */
+
+static PyObject*
+multiprocessing_address_of_buffer(PyObject *self, PyObject *obj)
+{
+	void *buffer;
+	Py_ssize_t buffer_len;
+
+	if (PyObject_AsWriteBuffer(obj, &buffer, &buffer_len) < 0)
+		return NULL;
+
+	return Py_BuildValue("N" F_PY_SSIZE_T, 
+			     PyLong_FromVoidPtr(buffer), buffer_len);
+}
+
+
+/*
+ * Function table
+ */
+
+static PyMethodDef module_methods[] = {
+	{"address_of_buffer", multiprocessing_address_of_buffer, METH_O, 
+	 "address_of_buffer(obj) -> int\n" 
+	 "Return address of obj assuming obj supports buffer inteface"},
+#if HAVE_FD_TRANSFER
+	{"sendfd", multiprocessing_sendfd, METH_VARARGS, 
+	 "sendfd(sockfd, fd) -> None\n"
+	 "Send file descriptor given by fd over the unix domain socket\n"
+	 "whose file decriptor is sockfd"},
+	{"recvfd", multiprocessing_recvfd, METH_VARARGS,
+	 "recvfd(sockfd) -> fd\n"
+	 "Receive a file descriptor over a unix domain socket\n"
+	 "whose file decriptor is sockfd"},
+#endif
+	{NULL}
+};
+
+
+/*
+ * Initialize
+ */
+
+static struct PyModuleDef multiprocessing_module = {
+	PyModuleDef_HEAD_INIT,
+	"_multiprocessing",
+	NULL,
+	-1,
+	module_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
+
+PyMODINIT_FUNC 
+PyInit__multiprocessing(void)
+{
+	PyObject *module, *temp, *value;
+
+	/* Initialize module */
+	module = PyModule_Create(&multiprocessing_module);
+	if (!module)
+		return NULL;
+
+	/* Get copy of objects from pickle */
+	temp = PyImport_ImportModule(PICKLE_MODULE);
+	if (!temp)
+		return NULL;
+	pickle_dumps = PyObject_GetAttrString(temp, "dumps");
+	pickle_loads = PyObject_GetAttrString(temp, "loads");
+	pickle_protocol = PyObject_GetAttrString(temp, "HIGHEST_PROTOCOL");
+	Py_XDECREF(temp);
+
+	/* Get copy of BufferTooShort */
+	temp = PyImport_ImportModule("multiprocessing");
+	if (!temp)
+		return NULL;
+	BufferTooShort = PyObject_GetAttrString(temp, "BufferTooShort");
+	Py_XDECREF(temp);
+
+	/* Add connection type to module */
+	if (PyType_Ready(&ConnectionType) < 0)
+		return NULL;
+	Py_INCREF(&ConnectionType);	
+	PyModule_AddObject(module, "Connection", (PyObject*)&ConnectionType);
+
+#if defined(MS_WINDOWS) || HAVE_SEM_OPEN
+	/* Add SemLock type to module */
+	if (PyType_Ready(&SemLockType) < 0)
+		return NULL;
+	Py_INCREF(&SemLockType);
+	PyDict_SetItemString(SemLockType.tp_dict, "SEM_VALUE_MAX", 
+			     Py_BuildValue("i", SEM_VALUE_MAX));
+	PyModule_AddObject(module, "SemLock", (PyObject*)&SemLockType);   
+#endif
+
+#ifdef MS_WINDOWS
+	/* Add PipeConnection to module */
+	if (PyType_Ready(&PipeConnectionType) < 0)
+		return NULL;
+	Py_INCREF(&PipeConnectionType);
+	PyModule_AddObject(module, "PipeConnection",
+			   (PyObject*)&PipeConnectionType);
+
+	/* Initialize win32 class and add to multiprocessing */
+	temp = create_win32_namespace();
+	if (!temp)
+		return NULL;
+	PyModule_AddObject(module, "win32", temp);
+
+	/* Initialize the event handle used to signal Ctrl-C */
+	sigint_event = CreateEvent(NULL, TRUE, FALSE, NULL);
+	if (!sigint_event) {
+		PyErr_SetFromWindowsErr(0);
+		return NULL;
+	}
+	if (!SetConsoleCtrlHandler(ProcessingCtrlHandler, TRUE)) {
+		PyErr_SetFromWindowsErr(0);
+		return NULL;
+	}
+#endif
+
+	/* Add configuration macros */
+	temp = PyDict_New();
+	if (!temp)
+		return NULL;
+
+#define ADD_FLAG(name)						  \
+	value = Py_BuildValue("i", name);			  \
+	if (value == NULL) { Py_DECREF(temp); return NULL; }	  \
+	if (PyDict_SetItemString(temp, #name, value) < 0) {	  \
+		Py_DECREF(temp); Py_DECREF(value); return NULL; }	  \
+	Py_DECREF(value)
+	
+#ifdef HAVE_SEM_OPEN
+	ADD_FLAG(HAVE_SEM_OPEN);
+#endif
+#ifdef HAVE_SEM_TIMEDWAIT
+	ADD_FLAG(HAVE_SEM_TIMEDWAIT);
+#endif
+#ifdef HAVE_FD_TRANSFER
+	ADD_FLAG(HAVE_FD_TRANSFER);
+#endif
+#ifdef HAVE_BROKEN_SEM_GETVALUE
+	ADD_FLAG(HAVE_BROKEN_SEM_GETVALUE);
+#endif
+#ifdef HAVE_BROKEN_SEM_UNLINK
+	ADD_FLAG(HAVE_BROKEN_SEM_UNLINK);
+#endif
+
+	if (PyModule_AddObject(module, "flags", temp) < 0)
+		return NULL;
+
+        return module;
+}

Modified: python/branches/py3k/Modules/_multiprocessing/multiprocessing.h
==============================================================================
--- python/branches/py3k/Modules/_multiprocessing/multiprocessing.h	(original)
+++ python/branches/py3k/Modules/_multiprocessing/multiprocessing.h	Fri Jun 13 21:28:21 2008
@@ -1,163 +1,163 @@
-#ifndef MULTIPROCESSING_H
-#define MULTIPROCESSING_H
-
-#define PY_SSIZE_T_CLEAN
-
-#include "Python.h"
-#include "structmember.h"
-#include "pythread.h"
-
-/*
- * Platform includes and definitions
- */
-
-#ifdef MS_WINDOWS
-#  define WIN32_LEAN_AND_MEAN
-#  include <windows.h>
-#  include <winsock2.h>
-#  include <process.h>		     /* getpid() */
-#  define SEM_HANDLE HANDLE
-#  define SEM_VALUE_MAX LONG_MAX
-#else
-#  include <fcntl.h>                 /* O_CREAT and O_EXCL */
-#  include <sys/socket.h>
-#  include <arpa/inet.h>             /* htonl() and ntohl() */
-#  if HAVE_SEM_OPEN
-#    include <semaphore.h>
-     typedef sem_t *SEM_HANDLE;
-#  endif
-#  define HANDLE int
-#  define SOCKET int
-#  define BOOL int
-#  define UINT32 uint32_t
-#  define INT32 int32_t
-#  define TRUE 1
-#  define FALSE 0
-#  define INVALID_HANDLE_VALUE (-1)
-#endif
-
-/*
- * Make sure Py_ssize_t available
- */
-
-#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN)
-   typedef int Py_ssize_t;
-#  define PY_SSIZE_T_MAX INT_MAX
-#  define PY_SSIZE_T_MIN INT_MIN
-#  define F_PY_SSIZE_T "i"
-#  define PY_FORMAT_SIZE_T ""
-#  define PyInt_FromSsize_t(n) PyInt_FromLong((long)n)
-#else
-#  define F_PY_SSIZE_T "n"
-#endif
-
-/*
- * Format codes
- */
-
-#if SIZEOF_VOID_P == SIZEOF_LONG
-#  define F_POINTER "k"
-#  define T_POINTER T_ULONG
-#elif defined(HAVE_LONG_LONG) && (SIZEOF_VOID_P == SIZEOF_LONG_LONG)
-#  define F_POINTER "K"
-#  define T_POINTER T_ULONGLONG
-#else
-#  error "can't find format code for unsigned integer of same size as void*"
-#endif
-
-#ifdef MS_WINDOWS
-#  define F_HANDLE F_POINTER
-#  define T_HANDLE T_POINTER
-#  define F_SEM_HANDLE F_HANDLE
-#  define T_SEM_HANDLE T_HANDLE
-#  define F_DWORD "k"
-#  define T_DWORD T_ULONG
-#else
-#  define F_HANDLE "i"
-#  define T_HANDLE T_INT
-#  define F_SEM_HANDLE F_POINTER
-#  define T_SEM_HANDLE T_POINTER
-#endif
-
-#if PY_VERSION_HEX >= 0x03000000
-#  define F_RBUFFER "y"
-#else
-#  define F_RBUFFER "s"
-#endif
-
-/*
- * Error codes which can be returned by functions called without GIL
- */
-
-#define MP_SUCCESS (0)
-#define MP_STANDARD_ERROR (-1)
-#define MP_MEMORY_ERROR (-1001)
-#define MP_END_OF_FILE (-1002)
-#define MP_EARLY_END_OF_FILE (-1003)
-#define MP_BAD_MESSAGE_LENGTH (-1004)
-#define MP_SOCKET_ERROR (-1005)
-#define MP_EXCEPTION_HAS_BEEN_SET (-1006)
-
-PyObject *mp_SetError(PyObject *Type, int num);
-
-/*
- * Externs - not all will really exist on all platforms
- */
-
-extern PyObject *pickle_dumps;
-extern PyObject *pickle_loads;
-extern PyObject *pickle_protocol;
-extern PyObject *BufferTooShort;
-extern PyTypeObject SemLockType;
-extern PyTypeObject ConnectionType;
-extern PyTypeObject PipeConnectionType;
-extern HANDLE sigint_event;
-
-/*
- * Py3k compatibility
- */
-
-#if PY_VERSION_HEX >= 0x03000000
-#  define PICKLE_MODULE "pickle"
-#  define FROM_FORMAT PyUnicode_FromFormat
-#  define PyInt_FromLong PyLong_FromLong
-#  define PyInt_FromSsize_t PyLong_FromSsize_t
-#else
-#  define PICKLE_MODULE "cPickle"
-#  define FROM_FORMAT PyString_FromFormat
-#endif
-
-#ifndef PyVarObject_HEAD_INIT
-#  define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size,
-#endif
-
-#ifndef Py_TPFLAGS_HAVE_WEAKREFS
-#  define Py_TPFLAGS_HAVE_WEAKREFS 0
-#endif
-
-/*
- * Connection definition
- */
-
-#define CONNECTION_BUFFER_SIZE 1024
-
-typedef struct {
-	PyObject_HEAD
-	HANDLE handle;
-	int flags;
-	PyObject *weakreflist;
-	char buffer[CONNECTION_BUFFER_SIZE];
-} ConnectionObject;
-
-/*
- * Miscellaneous
- */
-
-#define MAX_MESSAGE_LENGTH 0x7fffffff
-
-#ifndef MIN
-#  define MIN(x, y) ((x) < (y) ? x : y)
-#  define MAX(x, y) ((x) > (y) ? x : y)
-#endif
-
-#endif /* MULTIPROCESSING_H */
+#ifndef MULTIPROCESSING_H
+#define MULTIPROCESSING_H
+
+#define PY_SSIZE_T_CLEAN
+
+#include "Python.h"
+#include "structmember.h"
+#include "pythread.h"
+
+/*
+ * Platform includes and definitions
+ */
+
+#ifdef MS_WINDOWS
+#  define WIN32_LEAN_AND_MEAN
+#  include <windows.h>
+#  include <winsock2.h>
+#  include <process.h>		     /* getpid() */
+#  define SEM_HANDLE HANDLE
+#  define SEM_VALUE_MAX LONG_MAX
+#else
+#  include <fcntl.h>                 /* O_CREAT and O_EXCL */
+#  include <sys/socket.h>
+#  include <arpa/inet.h>             /* htonl() and ntohl() */
+#  if HAVE_SEM_OPEN
+#    include <semaphore.h>
+     typedef sem_t *SEM_HANDLE;
+#  endif
+#  define HANDLE int
+#  define SOCKET int
+#  define BOOL int
+#  define UINT32 uint32_t
+#  define INT32 int32_t
+#  define TRUE 1
+#  define FALSE 0
+#  define INVALID_HANDLE_VALUE (-1)
+#endif
+
+/*
+ * Make sure Py_ssize_t available
+ */
+
+#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN)
+   typedef int Py_ssize_t;
+#  define PY_SSIZE_T_MAX INT_MAX
+#  define PY_SSIZE_T_MIN INT_MIN
+#  define F_PY_SSIZE_T "i"
+#  define PY_FORMAT_SIZE_T ""
+#  define PyInt_FromSsize_t(n) PyInt_FromLong((long)n)
+#else
+#  define F_PY_SSIZE_T "n"
+#endif
+
+/*
+ * Format codes
+ */
+
+#if SIZEOF_VOID_P == SIZEOF_LONG
+#  define F_POINTER "k"
+#  define T_POINTER T_ULONG
+#elif defined(HAVE_LONG_LONG) && (SIZEOF_VOID_P == SIZEOF_LONG_LONG)
+#  define F_POINTER "K"
+#  define T_POINTER T_ULONGLONG
+#else
+#  error "can't find format code for unsigned integer of same size as void*"
+#endif
+
+#ifdef MS_WINDOWS
+#  define F_HANDLE F_POINTER
+#  define T_HANDLE T_POINTER
+#  define F_SEM_HANDLE F_HANDLE
+#  define T_SEM_HANDLE T_HANDLE
+#  define F_DWORD "k"
+#  define T_DWORD T_ULONG
+#else
+#  define F_HANDLE "i"
+#  define T_HANDLE T_INT
+#  define F_SEM_HANDLE F_POINTER
+#  define T_SEM_HANDLE T_POINTER
+#endif
+
+#if PY_VERSION_HEX >= 0x03000000
+#  define F_RBUFFER "y"
+#else
+#  define F_RBUFFER "s"
+#endif
+
+/*
+ * Error codes which can be returned by functions called without GIL
+ */
+
+#define MP_SUCCESS (0)
+#define MP_STANDARD_ERROR (-1)
+#define MP_MEMORY_ERROR (-1001)
+#define MP_END_OF_FILE (-1002)
+#define MP_EARLY_END_OF_FILE (-1003)
+#define MP_BAD_MESSAGE_LENGTH (-1004)
+#define MP_SOCKET_ERROR (-1005)
+#define MP_EXCEPTION_HAS_BEEN_SET (-1006)
+
+PyObject *mp_SetError(PyObject *Type, int num);
+
+/*
+ * Externs - not all will really exist on all platforms
+ */
+
+extern PyObject *pickle_dumps;
+extern PyObject *pickle_loads;
+extern PyObject *pickle_protocol;
+extern PyObject *BufferTooShort;
+extern PyTypeObject SemLockType;
+extern PyTypeObject ConnectionType;
+extern PyTypeObject PipeConnectionType;
+extern HANDLE sigint_event;
+
+/*
+ * Py3k compatibility
+ */
+
+#if PY_VERSION_HEX >= 0x03000000
+#  define PICKLE_MODULE "pickle"
+#  define FROM_FORMAT PyUnicode_FromFormat
+#  define PyInt_FromLong PyLong_FromLong
+#  define PyInt_FromSsize_t PyLong_FromSsize_t
+#else
+#  define PICKLE_MODULE "cPickle"
+#  define FROM_FORMAT PyString_FromFormat
+#endif
+
+#ifndef PyVarObject_HEAD_INIT
+#  define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size,
+#endif
+
+#ifndef Py_TPFLAGS_HAVE_WEAKREFS
+#  define Py_TPFLAGS_HAVE_WEAKREFS 0
+#endif
+
+/*
+ * Connection definition
+ */
+
+#define CONNECTION_BUFFER_SIZE 1024
+
+typedef struct {
+	PyObject_HEAD
+	HANDLE handle;
+	int flags;
+	PyObject *weakreflist;
+	char buffer[CONNECTION_BUFFER_SIZE];
+} ConnectionObject;
+
+/*
+ * Miscellaneous
+ */
+
+#define MAX_MESSAGE_LENGTH 0x7fffffff
+
+#ifndef MIN
+#  define MIN(x, y) ((x) < (y) ? x : y)
+#  define MAX(x, y) ((x) > (y) ? x : y)
+#endif
+
+#endif /* MULTIPROCESSING_H */

Modified: python/branches/py3k/Modules/_multiprocessing/pipe_connection.c
==============================================================================
--- python/branches/py3k/Modules/_multiprocessing/pipe_connection.c	(original)
+++ python/branches/py3k/Modules/_multiprocessing/pipe_connection.c	Fri Jun 13 21:28:21 2008
@@ -1,136 +1,136 @@
-/*
- * A type which wraps a pipe handle in message oriented mode
- *
- * pipe_connection.c
- *
- * Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
- */
-
-#include "multiprocessing.h"
-
-#define CLOSE(h) CloseHandle(h)
-
-/*
- * Send string to the pipe; assumes in message oriented mode
- */
-
-static Py_ssize_t
-conn_send_string(ConnectionObject *conn, char *string, size_t length)
-{
-	DWORD amount_written;
-
-	return WriteFile(conn->handle, string, length, &amount_written, NULL)
-		? MP_SUCCESS : MP_STANDARD_ERROR;
-}
-
-/*
- * Attempts to read into buffer, or if buffer too small into *newbuffer.
- *
- * Returns number of bytes read.  Assumes in message oriented mode.
- */
-
-static Py_ssize_t
-conn_recv_string(ConnectionObject *conn, char *buffer, 
-		 size_t buflength, char **newbuffer, size_t maxlength)
-{
-	DWORD left, length, full_length, err;
-
-	*newbuffer = NULL;
-
-	if (ReadFile(conn->handle, buffer, MIN(buflength, maxlength), 
-		     &length, NULL))
-		return length;
-
-	err = GetLastError();
-	if (err != ERROR_MORE_DATA) {
-		if (err == ERROR_BROKEN_PIPE)
-			return MP_END_OF_FILE;
-		return MP_STANDARD_ERROR;
-	}
-
-	if (!PeekNamedPipe(conn->handle, NULL, 0, NULL, NULL, &left))
-		return MP_STANDARD_ERROR;
-
-	full_length = length + left;
-	if (full_length > maxlength)
-		return MP_BAD_MESSAGE_LENGTH;
-
-	*newbuffer = PyMem_Malloc(full_length);
-	if (*newbuffer == NULL)
-		return MP_MEMORY_ERROR;
-
-	memcpy(*newbuffer, buffer, length);
-
-	if (ReadFile(conn->handle, *newbuffer+length, left, &length, NULL)) {
-		assert(length == left);
-		return full_length;
-	} else {
-		PyMem_Free(*newbuffer);
-		return MP_STANDARD_ERROR;
-	}
-}
-
-/*
- * Check whether any data is available for reading
- */
-
-#define conn_poll(conn, timeout) conn_poll_save(conn, timeout, _save)
-
-static int
-conn_poll_save(ConnectionObject *conn, double timeout, PyThreadState *_save)
-{
-	DWORD bytes, deadline, delay;
-	int difference, res;
-	BOOL block = FALSE;
-
-	if (!PeekNamedPipe(conn->handle, NULL, 0, NULL, &bytes, NULL))
-		return MP_STANDARD_ERROR;
-
-	if (timeout == 0.0)
-		return bytes > 0;
-
-	if (timeout < 0.0)
-		block = TRUE;
-	else
-		/* XXX does not check for overflow */
-		deadline = GetTickCount() + (DWORD)(1000 * timeout + 0.5);
-
-	Sleep(0);
-
-	for (delay = 1 ; ; delay += 1) {
-		if (!PeekNamedPipe(conn->handle, NULL, 0, NULL, &bytes, NULL))
-			return MP_STANDARD_ERROR;
-		else if (bytes > 0)
-			return TRUE;
-
-		if (!block) {
-			difference = deadline - GetTickCount();
-			if (difference < 0)
-				return FALSE;
-			if ((int)delay > difference)
-				delay = difference;
-		}
-
-		if (delay > 20)
-			delay = 20;
-
-		Sleep(delay);
-
-		/* check for signals */
-		Py_BLOCK_THREADS 
-		res = PyErr_CheckSignals();
-		Py_UNBLOCK_THREADS
-
-		if (res)
-			return MP_EXCEPTION_HAS_BEEN_SET;
-	}
-}
-
-/*
- * "connection.h" defines the PipeConnection type using the definitions above
- */
-
-#define CONNECTION_NAME "PipeConnection"
-#define CONNECTION_TYPE PipeConnectionType
-
-#include "connection.h"
+/*
+ * A type which wraps a pipe handle in message oriented mode
+ *
+ * pipe_connection.c
+ *
+ * Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
+ */
+
+#include "multiprocessing.h"
+
+#define CLOSE(h) CloseHandle(h)
+
+/*
+ * Send string to the pipe; assumes in message oriented mode
+ */
+
+static Py_ssize_t
+conn_send_string(ConnectionObject *conn, char *string, size_t length)
+{
+	DWORD amount_written;
+
+	return WriteFile(conn->handle, string, length, &amount_written, NULL)
+		? MP_SUCCESS : MP_STANDARD_ERROR;
+}
+
+/*
+ * Attempts to read into buffer, or if buffer too small into *newbuffer.
+ *
+ * Returns number of bytes read.  Assumes in message oriented mode.
+ */
+
+static Py_ssize_t
+conn_recv_string(ConnectionObject *conn, char *buffer, 
+		 size_t buflength, char **newbuffer, size_t maxlength)
+{
+	DWORD left, length, full_length, err;
+
+	*newbuffer = NULL;
+
+	if (ReadFile(conn->handle, buffer, MIN(buflength, maxlength), 
+		     &length, NULL))
+		return length;
+
+	err = GetLastError();
+	if (err != ERROR_MORE_DATA) {
+		if (err == ERROR_BROKEN_PIPE)
+			return MP_END_OF_FILE;
+		return MP_STANDARD_ERROR;
+	}
+
+	if (!PeekNamedPipe(conn->handle, NULL, 0, NULL, NULL, &left))
+		return MP_STANDARD_ERROR;
+
+	full_length = length + left;
+	if (full_length > maxlength)
+		return MP_BAD_MESSAGE_LENGTH;
+
+	*newbuffer = PyMem_Malloc(full_length);
+	if (*newbuffer == NULL)
+		return MP_MEMORY_ERROR;
+
+	memcpy(*newbuffer, buffer, length);
+
+	if (ReadFile(conn->handle, *newbuffer+length, left, &length, NULL)) {
+		assert(length == left);
+		return full_length;
+	} else {
+		PyMem_Free(*newbuffer);
+		return MP_STANDARD_ERROR;
+	}
+}
+
+/*
+ * Check whether any data is available for reading
+ */
+
+#define conn_poll(conn, timeout) conn_poll_save(conn, timeout, _save)
+
+static int
+conn_poll_save(ConnectionObject *conn, double timeout, PyThreadState *_save)
+{
+	DWORD bytes, deadline, delay;
+	int difference, res;
+	BOOL block = FALSE;
+
+	if (!PeekNamedPipe(conn->handle, NULL, 0, NULL, &bytes, NULL))
+		return MP_STANDARD_ERROR;
+
+	if (timeout == 0.0)
+		return bytes > 0;
+
+	if (timeout < 0.0)
+		block = TRUE;
+	else
+		/* XXX does not check for overflow */
+		deadline = GetTickCount() + (DWORD)(1000 * timeout + 0.5);
+
+	Sleep(0);
+
+	for (delay = 1 ; ; delay += 1) {
+		if (!PeekNamedPipe(conn->handle, NULL, 0, NULL, &bytes, NULL))
+			return MP_STANDARD_ERROR;
+		else if (bytes > 0)
+			return TRUE;
+
+		if (!block) {
+			difference = deadline - GetTickCount();
+			if (difference < 0)
+				return FALSE;
+			if ((int)delay > difference)
+				delay = difference;
+		}
+
+		if (delay > 20)
+			delay = 20;
+
+		Sleep(delay);
+
+		/* check for signals */
+		Py_BLOCK_THREADS 
+		res = PyErr_CheckSignals();
+		Py_UNBLOCK_THREADS
+
+		if (res)
+			return MP_EXCEPTION_HAS_BEEN_SET;
+	}
+}
+
+/*
+ * "connection.h" defines the PipeConnection type using the definitions above
+ */
+
+#define CONNECTION_NAME "PipeConnection"
+#define CONNECTION_TYPE PipeConnectionType
+
+#include "connection.h"

Modified: python/branches/py3k/Modules/_multiprocessing/win32_functions.c
==============================================================================
--- python/branches/py3k/Modules/_multiprocessing/win32_functions.c	(original)
+++ python/branches/py3k/Modules/_multiprocessing/win32_functions.c	Fri Jun 13 21:28:21 2008
@@ -1,260 +1,260 @@
-/*
- * Win32 functions used by multiprocessing package
- *
- * win32_functions.c
- *
- * Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
- */
-
-#include "multiprocessing.h"
-
-
-#define WIN32_FUNCTION(func) \
-    {#func, (PyCFunction)win32_ ## func, METH_VARARGS | METH_STATIC, ""}
-
-#define WIN32_CONSTANT(fmt, con) \
-    PyDict_SetItemString(Win32Type.tp_dict, #con, Py_BuildValue(fmt, con))
-
-
-static PyObject *
-win32_CloseHandle(PyObject *self, PyObject *args)
-{
-	HANDLE hObject;
-	BOOL success;
-
-	if (!PyArg_ParseTuple(args, F_HANDLE, &hObject))
-		return NULL;
-
-	Py_BEGIN_ALLOW_THREADS
-	success = CloseHandle(hObject); 
-	Py_END_ALLOW_THREADS
-
-	if (!success)
-		return PyErr_SetFromWindowsErr(0);
-
-	Py_RETURN_NONE;
-}
-
-static PyObject *
-win32_ConnectNamedPipe(PyObject *self, PyObject *args)
-{
-	HANDLE hNamedPipe;
-	LPOVERLAPPED lpOverlapped;
-	BOOL success;
-
-	if (!PyArg_ParseTuple(args, F_HANDLE F_POINTER, 
-			      &hNamedPipe, &lpOverlapped))
-		return NULL;
-
-	Py_BEGIN_ALLOW_THREADS
-	success = ConnectNamedPipe(hNamedPipe, lpOverlapped);
-	Py_END_ALLOW_THREADS
-
-	if (!success)
-		return PyErr_SetFromWindowsErr(0);
-
-	Py_RETURN_NONE;
-}
-
-static PyObject *
-win32_CreateFile(PyObject *self, PyObject *args)
-{
-	LPCTSTR lpFileName;
-	DWORD dwDesiredAccess;
-	DWORD dwShareMode;
-	LPSECURITY_ATTRIBUTES lpSecurityAttributes;
-	DWORD dwCreationDisposition;
-	DWORD dwFlagsAndAttributes;
-	HANDLE hTemplateFile;
-	HANDLE handle;
-
-	if (!PyArg_ParseTuple(args, "s" F_DWORD F_DWORD F_POINTER 
-			      F_DWORD F_DWORD F_HANDLE,
-			      &lpFileName, &dwDesiredAccess, &dwShareMode, 
-			      &lpSecurityAttributes, &dwCreationDisposition, 
-			      &dwFlagsAndAttributes, &hTemplateFile))
-		return NULL;
-
-	Py_BEGIN_ALLOW_THREADS
-	handle = CreateFile(lpFileName, dwDesiredAccess, 
-			    dwShareMode, lpSecurityAttributes, 
-			    dwCreationDisposition, 
-			    dwFlagsAndAttributes, hTemplateFile);
-	Py_END_ALLOW_THREADS
-
-	if (handle == INVALID_HANDLE_VALUE)
-		return PyErr_SetFromWindowsErr(0);
-
-	return Py_BuildValue(F_HANDLE, handle);
-}
-
-static PyObject *
-win32_CreateNamedPipe(PyObject *self, PyObject *args)
-{
-	LPCTSTR lpName;
-	DWORD dwOpenMode;
-	DWORD dwPipeMode;
-	DWORD nMaxInstances;
-	DWORD nOutBufferSize;
-	DWORD nInBufferSize;
-	DWORD nDefaultTimeOut;
-	LPSECURITY_ATTRIBUTES lpSecurityAttributes;
-	HANDLE handle;
-
-	if (!PyArg_ParseTuple(args, "s" F_DWORD F_DWORD F_DWORD 
-			      F_DWORD F_DWORD F_DWORD F_POINTER,
-			      &lpName, &dwOpenMode, &dwPipeMode, 
-			      &nMaxInstances, &nOutBufferSize, 
-			      &nInBufferSize, &nDefaultTimeOut,
-			      &lpSecurityAttributes))
-		return NULL;
-
-	Py_BEGIN_ALLOW_THREADS
-	handle = CreateNamedPipe(lpName, dwOpenMode, dwPipeMode, 
-				 nMaxInstances, nOutBufferSize, 
-				 nInBufferSize, nDefaultTimeOut,
-				 lpSecurityAttributes);
-	Py_END_ALLOW_THREADS
-
-	if (handle == INVALID_HANDLE_VALUE)
-		return PyErr_SetFromWindowsErr(0);
-
-	return Py_BuildValue(F_HANDLE, handle);
-}
-
-static PyObject *
-win32_ExitProcess(PyObject *self, PyObject *args)
-{
-	UINT uExitCode;
-
-	if (!PyArg_ParseTuple(args, "I", &uExitCode))
-		return NULL;
-
-	ExitProcess(uExitCode);
-
-	return NULL;
-}
-
-static PyObject *
-win32_GetLastError(PyObject *self, PyObject *args)
-{
-	return Py_BuildValue(F_DWORD, GetLastError());
-}
-
-static PyObject *
-win32_OpenProcess(PyObject *self, PyObject *args)
-{
-	DWORD dwDesiredAccess;
-	BOOL bInheritHandle;
-	DWORD dwProcessId;
-	HANDLE handle;
-
-	if (!PyArg_ParseTuple(args, F_DWORD "i" F_DWORD, 
-			      &dwDesiredAccess, &bInheritHandle, &dwProcessId))
-		return NULL;
-
-	handle = OpenProcess(dwDesiredAccess, bInheritHandle, dwProcessId);    
-	if (handle == NULL)
-		return PyErr_SetFromWindowsErr(0);
-
-	return Py_BuildValue(F_HANDLE, handle);
-}
-
-static PyObject *
-win32_SetNamedPipeHandleState(PyObject *self, PyObject *args)
-{
-	HANDLE hNamedPipe;
-	PyObject *oArgs[3];
-	DWORD dwArgs[3], *pArgs[3] = {NULL, NULL, NULL};
-	int i;
-
-	if (!PyArg_ParseTuple(args, F_HANDLE "OOO", 
-			      &hNamedPipe, &oArgs[0], &oArgs[1], &oArgs[2]))
-		return NULL;
-
-	PyErr_Clear();
-
-	for (i = 0 ; i < 3 ; i++) {
-		if (oArgs[i] != Py_None) {
-			dwArgs[i] = PyLong_AsUnsignedLongMask(oArgs[i]);
-			if (PyErr_Occurred())
-				return NULL;
-			pArgs[i] = &dwArgs[i];
-		}
-	}
-
-	if (!SetNamedPipeHandleState(hNamedPipe, pArgs[0], pArgs[1], pArgs[2]))
-		return PyErr_SetFromWindowsErr(0);
-
-	Py_RETURN_NONE;
-}
-
-static PyObject *
-win32_WaitNamedPipe(PyObject *self, PyObject *args)
-{
-	LPCTSTR lpNamedPipeName;
-	DWORD nTimeOut;
-	BOOL success;
-
-	if (!PyArg_ParseTuple(args, "s" F_DWORD, &lpNamedPipeName, &nTimeOut))
-		return NULL;
-
-	Py_BEGIN_ALLOW_THREADS
-	success = WaitNamedPipe(lpNamedPipeName, nTimeOut);
-	Py_END_ALLOW_THREADS
-
-	if (!success)
-		return PyErr_SetFromWindowsErr(0);
-
-	Py_RETURN_NONE;
-}
-
-static PyMethodDef win32_methods[] = {
-	WIN32_FUNCTION(CloseHandle),
-	WIN32_FUNCTION(GetLastError),
-	WIN32_FUNCTION(OpenProcess),
-	WIN32_FUNCTION(ExitProcess),
-	WIN32_FUNCTION(ConnectNamedPipe),
-	WIN32_FUNCTION(CreateFile),
-	WIN32_FUNCTION(CreateNamedPipe),
-	WIN32_FUNCTION(SetNamedPipeHandleState),
-	WIN32_FUNCTION(WaitNamedPipe),
-	{NULL}
-};
-
-
-PyTypeObject Win32Type = {
-	PyVarObject_HEAD_INIT(NULL, 0)
-};
-
-
-PyObject *
-create_win32_namespace(void)
-{
-	Win32Type.tp_name = "_multiprocessing.win32";
-	Win32Type.tp_methods = win32_methods;
-	if (PyType_Ready(&Win32Type) < 0)
-		return NULL;
-	Py_INCREF(&Win32Type);
-
-	WIN32_CONSTANT(F_DWORD, ERROR_ALREADY_EXISTS);
-	WIN32_CONSTANT(F_DWORD, ERROR_PIPE_BUSY);
-	WIN32_CONSTANT(F_DWORD, ERROR_PIPE_CONNECTED);
-	WIN32_CONSTANT(F_DWORD, ERROR_SEM_TIMEOUT);
-	WIN32_CONSTANT(F_DWORD, GENERIC_READ);
-	WIN32_CONSTANT(F_DWORD, GENERIC_WRITE);
-	WIN32_CONSTANT(F_DWORD, INFINITE);
-	WIN32_CONSTANT(F_DWORD, NMPWAIT_WAIT_FOREVER);
-	WIN32_CONSTANT(F_DWORD, OPEN_EXISTING);
-	WIN32_CONSTANT(F_DWORD, PIPE_ACCESS_DUPLEX);
-	WIN32_CONSTANT(F_DWORD, PIPE_ACCESS_INBOUND);
-	WIN32_CONSTANT(F_DWORD, PIPE_READMODE_MESSAGE);
-	WIN32_CONSTANT(F_DWORD, PIPE_TYPE_MESSAGE);
-	WIN32_CONSTANT(F_DWORD, PIPE_UNLIMITED_INSTANCES);
-	WIN32_CONSTANT(F_DWORD, PIPE_WAIT);
-	WIN32_CONSTANT(F_DWORD, PROCESS_ALL_ACCESS);
-
-	WIN32_CONSTANT("i", NULL);
-
-	return (PyObject*)&Win32Type;
-}
+/*
+ * Win32 functions used by multiprocessing package
+ *
+ * win32_functions.c
+ *
+ * Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
+ */
+
+#include "multiprocessing.h"
+
+
+#define WIN32_FUNCTION(func) \
+    {#func, (PyCFunction)win32_ ## func, METH_VARARGS | METH_STATIC, ""}
+
+#define WIN32_CONSTANT(fmt, con) \
+    PyDict_SetItemString(Win32Type.tp_dict, #con, Py_BuildValue(fmt, con))
+
+
+static PyObject *
+win32_CloseHandle(PyObject *self, PyObject *args)
+{
+	HANDLE hObject;
+	BOOL success;
+
+	if (!PyArg_ParseTuple(args, F_HANDLE, &hObject))
+		return NULL;
+
+	Py_BEGIN_ALLOW_THREADS
+	success = CloseHandle(hObject); 
+	Py_END_ALLOW_THREADS
+
+	if (!success)
+		return PyErr_SetFromWindowsErr(0);
+
+	Py_RETURN_NONE;
+}
+
+static PyObject *
+win32_ConnectNamedPipe(PyObject *self, PyObject *args)
+{
+	HANDLE hNamedPipe;
+	LPOVERLAPPED lpOverlapped;
+	BOOL success;
+
+	if (!PyArg_ParseTuple(args, F_HANDLE F_POINTER, 
+			      &hNamedPipe, &lpOverlapped))
+		return NULL;
+
+	Py_BEGIN_ALLOW_THREADS
+	success = ConnectNamedPipe(hNamedPipe, lpOverlapped);
+	Py_END_ALLOW_THREADS
+
+	if (!success)
+		return PyErr_SetFromWindowsErr(0);
+
+	Py_RETURN_NONE;
+}
+
+static PyObject *
+win32_CreateFile(PyObject *self, PyObject *args)
+{
+	LPCTSTR lpFileName;
+	DWORD dwDesiredAccess;
+	DWORD dwShareMode;
+	LPSECURITY_ATTRIBUTES lpSecurityAttributes;
+	DWORD dwCreationDisposition;
+	DWORD dwFlagsAndAttributes;
+	HANDLE hTemplateFile;
+	HANDLE handle;
+
+	if (!PyArg_ParseTuple(args, "s" F_DWORD F_DWORD F_POINTER 
+			      F_DWORD F_DWORD F_HANDLE,
+			      &lpFileName, &dwDesiredAccess, &dwShareMode, 
+			      &lpSecurityAttributes, &dwCreationDisposition, 
+			      &dwFlagsAndAttributes, &hTemplateFile))
+		return NULL;
+
+	Py_BEGIN_ALLOW_THREADS
+	handle = CreateFile(lpFileName, dwDesiredAccess, 
+			    dwShareMode, lpSecurityAttributes, 
+			    dwCreationDisposition, 
+			    dwFlagsAndAttributes, hTemplateFile);
+	Py_END_ALLOW_THREADS
+
+	if (handle == INVALID_HANDLE_VALUE)
+		return PyErr_SetFromWindowsErr(0);
+
+	return Py_BuildValue(F_HANDLE, handle);
+}
+
+static PyObject *
+win32_CreateNamedPipe(PyObject *self, PyObject *args)
+{
+	LPCTSTR lpName;
+	DWORD dwOpenMode;
+	DWORD dwPipeMode;
+	DWORD nMaxInstances;
+	DWORD nOutBufferSize;
+	DWORD nInBufferSize;
+	DWORD nDefaultTimeOut;
+	LPSECURITY_ATTRIBUTES lpSecurityAttributes;
+	HANDLE handle;
+
+	if (!PyArg_ParseTuple(args, "s" F_DWORD F_DWORD F_DWORD 
+			      F_DWORD F_DWORD F_DWORD F_POINTER,
+			      &lpName, &dwOpenMode, &dwPipeMode, 
+			      &nMaxInstances, &nOutBufferSize, 
+			      &nInBufferSize, &nDefaultTimeOut,
+			      &lpSecurityAttributes))
+		return NULL;
+
+	Py_BEGIN_ALLOW_THREADS
+	handle = CreateNamedPipe(lpName, dwOpenMode, dwPipeMode, 
+				 nMaxInstances, nOutBufferSize, 
+				 nInBufferSize, nDefaultTimeOut,
+				 lpSecurityAttributes);
+	Py_END_ALLOW_THREADS
+
+	if (handle == INVALID_HANDLE_VALUE)
+		return PyErr_SetFromWindowsErr(0);
+
+	return Py_BuildValue(F_HANDLE, handle);
+}
+
+static PyObject *
+win32_ExitProcess(PyObject *self, PyObject *args)
+{
+	UINT uExitCode;
+
+	if (!PyArg_ParseTuple(args, "I", &uExitCode))
+		return NULL;
+
+	ExitProcess(uExitCode);
+
+	return NULL;
+}
+
+static PyObject *
+win32_GetLastError(PyObject *self, PyObject *args)
+{
+	return Py_BuildValue(F_DWORD, GetLastError());
+}
+
+static PyObject *
+win32_OpenProcess(PyObject *self, PyObject *args)
+{
+	DWORD dwDesiredAccess;
+	BOOL bInheritHandle;
+	DWORD dwProcessId;
+	HANDLE handle;
+
+	if (!PyArg_ParseTuple(args, F_DWORD "i" F_DWORD, 
+			      &dwDesiredAccess, &bInheritHandle, &dwProcessId))
+		return NULL;
+
+	handle = OpenProcess(dwDesiredAccess, bInheritHandle, dwProcessId);    
+	if (handle == NULL)
+		return PyErr_SetFromWindowsErr(0);
+
+	return Py_BuildValue(F_HANDLE, handle);
+}
+
+static PyObject *
+win32_SetNamedPipeHandleState(PyObject *self, PyObject *args)
+{
+	HANDLE hNamedPipe;
+	PyObject *oArgs[3];
+	DWORD dwArgs[3], *pArgs[3] = {NULL, NULL, NULL};
+	int i;
+
+	if (!PyArg_ParseTuple(args, F_HANDLE "OOO", 
+			      &hNamedPipe, &oArgs[0], &oArgs[1], &oArgs[2]))
+		return NULL;
+
+	PyErr_Clear();
+
+	for (i = 0 ; i < 3 ; i++) {
+		if (oArgs[i] != Py_None) {
+			dwArgs[i] = PyLong_AsUnsignedLongMask(oArgs[i]);
+			if (PyErr_Occurred())
+				return NULL;
+			pArgs[i] = &dwArgs[i];
+		}
+	}
+
+	if (!SetNamedPipeHandleState(hNamedPipe, pArgs[0], pArgs[1], pArgs[2]))
+		return PyErr_SetFromWindowsErr(0);
+
+	Py_RETURN_NONE;
+}
+
+static PyObject *
+win32_WaitNamedPipe(PyObject *self, PyObject *args)
+{
+	LPCTSTR lpNamedPipeName;
+	DWORD nTimeOut;
+	BOOL success;
+
+	if (!PyArg_ParseTuple(args, "s" F_DWORD, &lpNamedPipeName, &nTimeOut))
+		return NULL;
+
+	Py_BEGIN_ALLOW_THREADS
+	success = WaitNamedPipe(lpNamedPipeName, nTimeOut);
+	Py_END_ALLOW_THREADS
+
+	if (!success)
+		return PyErr_SetFromWindowsErr(0);
+
+	Py_RETURN_NONE;
+}
+
+static PyMethodDef win32_methods[] = {
+	WIN32_FUNCTION(CloseHandle),
+	WIN32_FUNCTION(GetLastError),
+	WIN32_FUNCTION(OpenProcess),
+	WIN32_FUNCTION(ExitProcess),
+	WIN32_FUNCTION(ConnectNamedPipe),
+	WIN32_FUNCTION(CreateFile),
+	WIN32_FUNCTION(CreateNamedPipe),
+	WIN32_FUNCTION(SetNamedPipeHandleState),
+	WIN32_FUNCTION(WaitNamedPipe),
+	{NULL}
+};
+
+
+PyTypeObject Win32Type = {
+	PyVarObject_HEAD_INIT(NULL, 0)
+};
+
+
+PyObject *
+create_win32_namespace(void)
+{
+	Win32Type.tp_name = "_multiprocessing.win32";
+	Win32Type.tp_methods = win32_methods;
+	if (PyType_Ready(&Win32Type) < 0)
+		return NULL;
+	Py_INCREF(&Win32Type);
+
+	WIN32_CONSTANT(F_DWORD, ERROR_ALREADY_EXISTS);
+	WIN32_CONSTANT(F_DWORD, ERROR_PIPE_BUSY);
+	WIN32_CONSTANT(F_DWORD, ERROR_PIPE_CONNECTED);
+	WIN32_CONSTANT(F_DWORD, ERROR_SEM_TIMEOUT);
+	WIN32_CONSTANT(F_DWORD, GENERIC_READ);
+	WIN32_CONSTANT(F_DWORD, GENERIC_WRITE);
+	WIN32_CONSTANT(F_DWORD, INFINITE);
+	WIN32_CONSTANT(F_DWORD, NMPWAIT_WAIT_FOREVER);
+	WIN32_CONSTANT(F_DWORD, OPEN_EXISTING);
+	WIN32_CONSTANT(F_DWORD, PIPE_ACCESS_DUPLEX);
+	WIN32_CONSTANT(F_DWORD, PIPE_ACCESS_INBOUND);
+	WIN32_CONSTANT(F_DWORD, PIPE_READMODE_MESSAGE);
+	WIN32_CONSTANT(F_DWORD, PIPE_TYPE_MESSAGE);
+	WIN32_CONSTANT(F_DWORD, PIPE_UNLIMITED_INSTANCES);
+	WIN32_CONSTANT(F_DWORD, PIPE_WAIT);
+	WIN32_CONSTANT(F_DWORD, PROCESS_ALL_ACCESS);
+
+	WIN32_CONSTANT("i", NULL);
+
+	return (PyObject*)&Win32Type;
+}

From python-3000-checkins at python.org  Fri Jun 13 23:56:27 2008
From: python-3000-checkins at python.org (amaury.forgeotdarc)
Date: Fri, 13 Jun 2008 23:56:27 +0200 (CEST)
Subject: [Python-3000-checkins] r64255 - in python/branches/py3k/PC/VS8.0:
	_bsddb44.vcproj _hashlib.vcproj _multiprocessing.vcproj
	kill_python.vcproj sqlite3.vcproj
Message-ID: <20080613215627.C0B581E4013@bag.python.org>

Author: amaury.forgeotdarc
Date: Fri Jun 13 23:56:27 2008
New Revision: 64255

Log:
Add missing files for the windows VS2005 compiler


Added:
   python/branches/py3k/PC/VS8.0/_bsddb44.vcproj
   python/branches/py3k/PC/VS8.0/_hashlib.vcproj
   python/branches/py3k/PC/VS8.0/_multiprocessing.vcproj
   python/branches/py3k/PC/VS8.0/kill_python.vcproj
   python/branches/py3k/PC/VS8.0/sqlite3.vcproj

Added: python/branches/py3k/PC/VS8.0/_bsddb44.vcproj
==============================================================================
--- (empty file)
+++ python/branches/py3k/PC/VS8.0/_bsddb44.vcproj	Fri Jun 13 23:56:27 2008
@@ -0,0 +1,1252 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="_bsddb44"
+	ProjectGUID="{62172C7D-B39E-409A-B352-370FF5098C19}"
+	RootNamespace="_bsddb44"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			ConfigurationType="4"
+			InheritedPropertySheets=".\pyd_d.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\..\db-4.4.20\build_win32;..\..\..\db-4.4.20\build_win32\.."
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			ConfigurationType="4"
+			InheritedPropertySheets=".\pyd_d.vsprops;.\x64.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\..\db-4.4.20\build_win32;..\..\..\db-4.4.20\build_win32\.."
+				PreprocessorDefinitions="DIAGNOSTIC"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			ConfigurationType="4"
+			InheritedPropertySheets=".\pyd.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\..\db-4.4.20\build_win32;..\..\..\db-4.4.20\build_win32\.."
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			ConfigurationType="4"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\..\db-4.4.20\build_win32;..\..\..\db-4.4.20\build_win32\.."
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|Win32"
+			ConfigurationType="4"
+			InheritedPropertySheets=".\pyd.vsprops;.\pginstrument.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\..\db-4.4.20\build_win32;..\..\..\db-4.4.20\build_win32\.."
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|x64"
+			ConfigurationType="4"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pginstrument.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\..\db-4.4.20\build_win32;..\..\..\db-4.4.20\build_win32\.."
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|Win32"
+			ConfigurationType="4"
+			InheritedPropertySheets=".\pyd.vsprops;.\pgupdate.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\..\db-4.4.20\build_win32;..\..\..\db-4.4.20\build_win32\.."
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|x64"
+			ConfigurationType="4"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pgupdate.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\..\db-4.4.20\build_win32;..\..\..\db-4.4.20\build_win32\.."
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\bt_compact.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\bt_compare.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\bt_conv.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\bt_curadj.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\bt_cursor.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\bt_delete.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\bt_method.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\bt_open.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\bt_put.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\bt_rec.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\bt_reclaim.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\bt_recno.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\bt_rsearch.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\bt_search.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\bt_split.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\bt_stat.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\bt_upgrade.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\bt_verify.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\btree_auto.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\crdel_auto.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\crdel_rec.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\common\crypto_stub.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_am.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_auto.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\common\db_byteorder.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_cam.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\common\db_clock.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_conv.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_dispatch.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_dup.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\common\db_err.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\common\db_getlong.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\common\db_idspace.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_iface.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_join.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\common\db_log2.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_meta.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_method.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_open.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_overflow.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_ovfl_vrfy.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_pr.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_rec.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_reclaim.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_remove.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_rename.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_ret.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\env\db_salloc.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_setid.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_setlsn.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\env\db_shash.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_stati.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_truncate.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_upg.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_upg_opd.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_vrfy.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_vrfyutil.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\dbm\dbm.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\dbreg\dbreg.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\dbreg\dbreg_auto.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\dbreg\dbreg_rec.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\dbreg\dbreg_stat.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\dbreg\dbreg_util.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\env\env_failchk.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\env\env_file.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\env\env_method.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\env\env_open.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\env\env_recover.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\env\env_region.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\env\env_register.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\env\env_stat.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\fileops\fileops_auto.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\fileops\fop_basic.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\fileops\fop_rec.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\fileops\fop_util.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\hash\hash.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\hash\hash_auto.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\hash\hash_conv.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\hash\hash_dup.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\hash\hash_func.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\hash\hash_meta.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\hash\hash_method.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\hash\hash_open.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\hash\hash_page.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\hash\hash_rec.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\hash\hash_reclaim.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\hash\hash_stat.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\hash\hash_upgrade.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\hash\hash_verify.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\hmac\hmac.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\hsearch\hsearch.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\lock\lock.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\lock\lock_deadlock.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\lock\lock_failchk.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\lock\lock_id.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\lock\lock_list.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\lock\lock_method.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\lock\lock_region.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\lock\lock_stat.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\lock\lock_timer.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\lock\lock_util.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\log\log.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\log\log_archive.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\log\log_compare.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\log\log_debug.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\log\log_get.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\log\log_method.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\log\log_put.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\log\log_stat.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\mp\mp_alloc.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\mp\mp_bh.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\mp\mp_fget.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\mp\mp_fmethod.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\mp\mp_fopen.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\mp\mp_fput.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\mp\mp_fset.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\mp\mp_method.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\mp\mp_region.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\mp\mp_register.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\mp\mp_stat.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\mp\mp_sync.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\mp\mp_trickle.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\mutex\mut_alloc.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\mutex\mut_method.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\mutex\mut_region.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\mutex\mut_stat.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\mutex\mut_win32.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_abs.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\os\os_alloc.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_clock.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_config.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_dir.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_errno.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_fid.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_flock.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_fsync.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_handle.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\os\os_id.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_map.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\os\os_method.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\os\os_mkdir.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\os\os_oflags.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_open.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\os\os_region.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_rename.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\os\os_root.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\os\os_rpath.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_rw.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_seek.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_sleep.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_spin.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_stat.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\os\os_tmpdir.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_truncate.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_unlink.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\qam\qam.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\qam\qam_auto.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\qam\qam_conv.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\qam\qam_files.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\qam\qam_method.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\qam\qam_open.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\qam\qam_rec.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\qam\qam_stat.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\qam\qam_upgrade.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\qam\qam_verify.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\rep\rep_auto.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\rep\rep_backup.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\rep\rep_elect.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\rep\rep_log.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\rep\rep_method.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\rep\rep_record.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\rep\rep_region.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\rep\rep_stat.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\rep\rep_util.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\rep\rep_verify.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\sequence\seq_stat.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\sequence\sequence.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\hmac\sha1.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\clib\strcasecmp.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\txn\txn.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\txn\txn_auto.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\txn\txn_chkpt.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\txn\txn_failchk.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\txn\txn_method.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\txn\txn_rec.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\txn\txn_recover.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\txn\txn_region.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\txn\txn_stat.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\txn\txn_util.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\common\util_cache.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\common\util_log.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\common\util_sig.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\xa\xa.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\xa\xa_db.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\xa\xa_map.c"
+				>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Added: python/branches/py3k/PC/VS8.0/_hashlib.vcproj
==============================================================================
--- (empty file)
+++ python/branches/py3k/PC/VS8.0/_hashlib.vcproj	Fri Jun 13 23:56:27 2008
@@ -0,0 +1,545 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="_hashlib"
+	ProjectGUID="{447F05A8-F581-4CAC-A466-5AC7936E207E}"
+	RootNamespace="_hashlib"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd_d.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+				CommandLine="cd &quot;$(SolutionDir)&quot;&#x0D;&#x0A;&quot;$(PythonExe)&quot; build_ssl.py Release $(PlatformName) -a&#x0D;&#x0A;"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(opensslDir)\inc32"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				CommandLine=""
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ws2_32.lib $(opensslDir)\out32\libeay32.lib $(opensslDir)\out32\ssleay32.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd_d.vsprops;.\x64.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+				CommandLine="cd &quot;$(SolutionDir)&quot;&#x0D;&#x0A;&quot;$(PythonExe)&quot; build_ssl.py Release $(PlatformName) -a&#x0D;&#x0A;"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(opensslDir)\inc64"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				CommandLine=""
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ws2_32.lib $(opensslDir)\out64\libeay32.lib $(opensslDir)\out64\ssleay32.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+				CommandLine="cd &quot;$(SolutionDir)&quot;&#x0D;&#x0A;&quot;$(PythonExe)&quot; build_ssl.py Release $(PlatformName) -a&#x0D;&#x0A;"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(opensslDir)\inc32"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				CommandLine=""
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ws2_32.lib $(opensslDir)\out32\libeay32.lib $(opensslDir)\out32\ssleay32.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+				CommandLine="cd &quot;$(SolutionDir)&quot;&#x0D;&#x0A;&quot;$(PythonExe)&quot; build_ssl.py Release $(PlatformName) -a&#x0D;&#x0A;"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(opensslDir)\inc64"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				CommandLine=""
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ws2_32.lib $(opensslDir)\out64\libeay32.lib $(opensslDir)\out64\ssleay32.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\pginstrument.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+				CommandLine="cd &quot;$(SolutionDir)&quot;&#x0D;&#x0A;&quot;$(PythonExe)&quot; build_ssl.py Release $(PlatformName) -a&#x0D;&#x0A;"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(opensslDir)\inc32"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				CommandLine=""
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ws2_32.lib $(opensslDir)\out32\libeay32.lib $(opensslDir)\out32\ssleay32.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pginstrument.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+				CommandLine="cd &quot;$(SolutionDir)&quot;&#x0D;&#x0A;&quot;$(PythonExe)&quot; build_ssl.py Release $(PlatformName) -a&#x0D;&#x0A;"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(opensslDir)\inc64"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				CommandLine=""
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ws2_32.lib $(opensslDir)\out64\libeay32.lib $(opensslDir)\out64\ssleay32.lib"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\pgupdate.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+				CommandLine="cd &quot;$(SolutionDir)&quot;&#x0D;&#x0A;&quot;$(PythonExe)&quot; build_ssl.py Release $(PlatformName) -a&#x0D;&#x0A;"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(opensslDir)\inc32"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				CommandLine=""
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ws2_32.lib $(opensslDir)\out32\libeay32.lib $(opensslDir)\out32\ssleay32.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pgupdate.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+				CommandLine="cd &quot;$(SolutionDir)&quot;&#x0D;&#x0A;&quot;$(PythonExe)&quot; build_ssl.py Release $(PlatformName) -a&#x0D;&#x0A;"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(opensslDir)\inc64"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				CommandLine=""
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ws2_32.lib $(opensslDir)\out64\libeay32.lib $(opensslDir)\out64\ssleay32.lib"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			>
+			<File
+				RelativePath="..\..\Modules\_hashopenssl.c"
+				>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Added: python/branches/py3k/PC/VS8.0/_multiprocessing.vcproj
==============================================================================
--- (empty file)
+++ python/branches/py3k/PC/VS8.0/_multiprocessing.vcproj	Fri Jun 13 23:56:27 2008
@@ -0,0 +1,557 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="_multiprocessing"
+	ProjectGUID="{9e48b300-37d1-11dd-8c41-005056c00008}"
+	RootNamespace="_multiprocessing"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd_d.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ws2_32.lib"
+				BaseAddress="0x1e1D0000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd_d.vsprops;.\x64.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ws2_32.lib"
+				BaseAddress="0x1e1D0000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ws2_32.lib"
+				BaseAddress="0x1e1D0000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ws2_32.lib"
+				BaseAddress="0x1e1D0000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\pginstrument.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ws2_32.lib"
+				BaseAddress="0x1e1D0000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pginstrument.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ws2_32.lib"
+				BaseAddress="0x1e1D0000"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\pgupdate.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ws2_32.lib"
+				BaseAddress="0x1e1D0000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pgupdate.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ws2_32.lib"
+				BaseAddress="0x1e1D0000"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Header Files"
+			>
+			<File
+				RelativePath="..\..\Modules\_multiprocessing\multiprocessing.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_multiprocessing\connection.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Source Files"
+			>
+			<File
+				RelativePath="..\..\Modules\_multiprocessing\multiprocessing.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_multiprocessing\pipe_connection.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_multiprocessing\semaphore.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_multiprocessing\socket_connection.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_multiprocessing\win32_functions.c"
+				>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Added: python/branches/py3k/PC/VS8.0/kill_python.vcproj
==============================================================================
--- (empty file)
+++ python/branches/py3k/PC/VS8.0/kill_python.vcproj	Fri Jun 13 23:56:27 2008
@@ -0,0 +1,279 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="kill_python"
+	ProjectGUID="{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}"
+	RootNamespace="kill_python"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\pyproject.vsprops;.\debug.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\$(ProjectName)_d.exe"
+				SubSystem="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\pyproject.vsprops;.\debug.vsprops;.\x64.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\$(ProjectName)_d.exe"
+				SubSystem="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\pyproject.vsprops;.\release.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				SubSystem="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\pyproject.vsprops;.\release.vsprops;.\x64.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				SubSystem="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			>
+			<File
+				RelativePath=".\kill_python.c"
+				>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Added: python/branches/py3k/PC/VS8.0/sqlite3.vcproj
==============================================================================
--- (empty file)
+++ python/branches/py3k/PC/VS8.0/sqlite3.vcproj	Fri Jun 13 23:56:27 2008
@@ -0,0 +1,743 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="sqlite3"
+	ProjectGUID="{A1A295E5-463C-437F-81CA-1F32367685DA}"
+	RootNamespace="sqlite3"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd_d.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\..\sqlite-source-3.3.4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\$(ProjectName)_d.dll"
+				ModuleDefinitionFile="..\..\..\sqlite-source-3.3.4\sqlite3.def"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd_d.vsprops;.\x64.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\..\sqlite-source-3.3.4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\$(ProjectName)_d.dll"
+				ModuleDefinitionFile="..\..\..\sqlite-source-3.3.4\sqlite3.def"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\..\sqlite-source-3.3.4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\$(ProjectName).dll"
+				ModuleDefinitionFile="..\..\..\sqlite-source-3.3.4\sqlite3.def"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\..\sqlite-source-3.3.4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\$(ProjectName).dll"
+				ModuleDefinitionFile="..\..\..\sqlite-source-3.3.4\sqlite3.def"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\pginstrument.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\..\sqlite-source-3.3.4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				ModuleDefinitionFile="..\..\..\sqlite-source-3.3.4\sqlite3.def"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pginstrument.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\..\sqlite-source-3.3.4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				ModuleDefinitionFile="..\..\..\sqlite-source-3.3.4\sqlite3.def"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\pgupdate.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\..\sqlite-source-3.3.4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				ModuleDefinitionFile="..\..\..\sqlite-source-3.3.4\sqlite3.def"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pgupdate.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\..\sqlite-source-3.3.4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				ModuleDefinitionFile="..\..\..\sqlite-source-3.3.4\sqlite3.def"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Header Files"
+			>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\btree.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\hash.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\keywordhash.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\opcodes.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\os.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\os_common.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\pager.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\parse.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\sqlite3.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\sqliteInt.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\vdbe.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\vdbeInt.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Source Files"
+			>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\alter.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\analyze.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\attach.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\auth.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\btree.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\build.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\callback.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\complete.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\date.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\delete.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\expr.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\func.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\hash.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\insert.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\legacy.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\main.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\opcodes.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\os.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\os_unix.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\os_win.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\pager.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\parse.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\pragma.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\prepare.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\printf.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\random.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\select.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\shell.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\table.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\tokenize.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\trigger.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\update.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\utf.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\util.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\vacuum.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\vdbe.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\vdbeapi.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\vdbeaux.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\vdbefifo.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\vdbemem.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\where.c"
+				>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

From python-3000-checkins at python.org  Fri Jun 13 23:58:10 2008
From: python-3000-checkins at python.org (amaury.forgeotdarc)
Date: Fri, 13 Jun 2008 23:58:10 +0200 (CEST)
Subject: [Python-3000-checkins] r64256 - python/branches/py3k
Message-ID: <20080613215810.334C61E4014@bag.python.org>

Author: amaury.forgeotdarc
Date: Fri Jun 13 23:58:09 2008
New Revision: 64256

Log:
Blocked revisions 64254 via svnmerge

........
  r64254 | amaury.forgeotdarc | 2008-06-13 23:54:30 +0200 (ven., 13 juin 2008) | 2 lines
  
  Add a missing file for VS2005
........


Modified:
   python/branches/py3k/   (props changed)

From python-3000-checkins at python.org  Sat Jun 14 00:53:15 2008
From: python-3000-checkins at python.org (martin.v.loewis)
Date: Sat, 14 Jun 2008 00:53:15 +0200 (CEST)
Subject: [Python-3000-checkins] r64258 - in python/branches/py3k:
	Doc/includes/email-alternative.py
	Doc/includes/mp_benchmarks.py Doc/includes/mp_distributing.py
	Doc/includes/mp_newtype.py Doc/includes/mp_pool.py
	Doc/includes/mp_synchronize.py Doc/includes/mp_webserver.py
	Doc/includes/mp_workers.py Doc/includes/noddy.c
	Doc/includes/noddy2.c Doc/includes/noddy3.c
	Doc/includes/noddy4.c Doc/includes/run-func.c
	Doc/includes/shoddy.c Doc/includes/sqlite3/ctx_manager.py
	Doc/includes/typestruct.h Doc/tools/sphinxext/patchlevel.py
	Doc/tools/sphinxext/pyspecific.py Include/bytes_methods.h
	Include/warnings.h Lib/_weakrefset.py Lib/ast.py
	Lib/copyreg.py Lib/dbm/__init__.py Lib/dbm/gnu.py
	Lib/dbm/ndbm.py Lib/distutils/config.py
	Lib/distutils/tests/test_build_ext.py
	Lib/distutils/tests/test_config.py
	Lib/distutils/tests/test_upload.py Lib/encodings/utf_32.py
	Lib/encodings/utf_32_be.py Lib/encodings/utf_32_le.py
	Lib/http/__init__.py Lib/json/__init__.py Lib/json/decoder.py
	Lib/json/encoder.py Lib/json/scanner.py
	Lib/json/tests/__init__.py Lib/json/tests/test_decode.py
	Lib/json/tests/test_default.py Lib/json/tests/test_dump.py
	Lib/json/tests/test_encode_basestring_ascii.py
	Lib/json/tests/test_fail.py Lib/json/tests/test_float.py
	Lib/json/tests/test_indent.py Lib/json/tests/test_pass1.py
	Lib/json/tests/test_pass2.py Lib/json/tests/test_pass3.py
	Lib/json/tests/test_recursion.py Lib/json/tests/test_scanstring.py
	Lib/json/tests/test_separators.py Lib/json/tests/test_speedups.py
	Lib/json/tests/test_unicode.py Lib/json/tool.py
	Lib/lib2to3/__init__.py Lib/lib2to3/fixes/fix_execfile.py
	Lib/lib2to3/fixes/fix_funcattrs.py Lib/lib2to3/fixes/fix_idioms.py
	Lib/lib2to3/fixes/fix_import.py Lib/lib2to3/fixes/fix_imports.py
	Lib/lib2to3/fixes/fix_itertools.py
	Lib/lib2to3/fixes/fix_itertools_imports.py
	Lib/lib2to3/fixes/fix_standarderror.py
	Lib/lib2to3/fixes/fix_types.py Lib/lib2to3/fixes/fix_xreadlines.py
	Lib/lib2to3/fixes/fix_zip.py Lib/lib2to3/tests/test_all_fixers.py
	Lib/lib2to3/tests/test_parser.py Lib/multiprocessing/__init__.py
	Lib/multiprocessing/connection.py
	Lib/multiprocessing/dummy/__init__.py
	Lib/multiprocessing/dummy/connection.py
	Lib/multiprocessing/forking.py Lib/multiprocessing/heap.py
	Lib/multiprocessing/managers.py Lib/multiprocessing/pool.py
	Lib/multiprocessing/process.py Lib/multiprocessing/queues.py
	Lib/multiprocessing/reduction.py Lib/multiprocessing/sharedctypes.py
	Lib/multiprocessing/synchronize.py
	Lib/multiprocessing/util.py Lib/pydoc_topics.py
	Lib/sqlite3/dump.py Lib/sqlite3/test/dump.py
	Lib/test/buffer_tests.py Lib/test/cmath_testcases.txt
	Lib/test/curses_tests.py Lib/test/dis_module.py
	Lib/test/profilee.py Lib/test/pydoc_mod.py
	Lib/test/relimport.py Lib/test/test_SimpleHTTPServer.py
	Lib/test/test_asyncore.py Lib/test/test_cmd.py
	Lib/test/test_copyreg.py Lib/test/test_dictcomps.py
	Lib/test/test_docxmlrpc.py Lib/test/test_email.py
	Lib/test/test_fractions.py Lib/test/test_httpservers.py
	Lib/test/test_int.py Lib/test/test_json.py
	Lib/test/test_memoryio.py Lib/test/test_multiprocessing.py
	Lib/test/test_pipes.py Lib/test/test_print.py
	Lib/test/test_pstats.py Lib/test/test_pydoc.py
	Lib/test/test_raise.py Lib/test/test_unpack_ex.py
	Lib/test/test_urllib2_localnet.py Lib/test/test_weakset.py
	Lib/test/test_xmlrpc_net.py Lib/xmlrpc/__init__.py
	Modules/_ctypes/libffi_osx/ffi.c
	Modules/_ctypes/libffi_osx/include/ffi.h
	Modules/_ctypes/libffi_osx/include/ffi_common.h
	Modules/_ctypes/libffi_osx/include/fficonfig.h
	Modules/_ctypes/libffi_osx/include/ffitarget.h
	Modules/_ctypes/libffi_osx/include/ppc-ffitarget.h
	Modules/_ctypes/libffi_osx/include/x86-ffitarget.h
	Modules/_ctypes/libffi_osx/powerpc/ppc-darwin.h
	Modules/_ctypes/libffi_osx/powerpc/ppc-ffi_darwin.c
	Modules/_ctypes/libffi_osx/types.c
	Modules/_ctypes/libffi_osx/x86/x86-ffi64.c
	Modules/_ctypes/libffi_osx/x86/x86-ffi_darwin.c
	Modules/_gestalt.c Modules/_json.c
	Modules/_multiprocessing/connection.h
	Modules/_multiprocessing/multiprocessing.c
	Modules/_multiprocessing/multiprocessing.h
	Modules/_multiprocessing/pipe_connection.c
	Modules/_multiprocessing/semaphore.c
	Modules/_multiprocessing/socket_connection.c
	Modules/_multiprocessing/win32_functions.c Modules/bsddb.h
	Modules/md5module.c Modules/sha1module.c
	Objects/bytes_methods.c Objects/stringlib/ctype.h
	Objects/stringlib/formatter.h Objects/stringlib/localeutil.h
	Objects/stringlib/string_format.h Objects/stringlib/stringdefs.h
	Objects/stringlib/transmogrify.h Objects/stringlib/unicodedefs.h
	PCbuild/_multiprocessing.vcproj Python/formatter_unicode.c
	Tools/pybench/With.py Tools/scripts/patchcheck.py
Message-ID: <20080613225315.1503C1E4006@bag.python.org>

Author: martin.v.loewis
Date: Sat Jun 14 00:53:14 2008
New Revision: 64258

Log:
Run svneol.py for all files currently using Unix line endings.


Modified:
   python/branches/py3k/Doc/includes/email-alternative.py   (props changed)
   python/branches/py3k/Doc/includes/mp_benchmarks.py   (props changed)
   python/branches/py3k/Doc/includes/mp_distributing.py   (props changed)
   python/branches/py3k/Doc/includes/mp_newtype.py   (props changed)
   python/branches/py3k/Doc/includes/mp_pool.py   (props changed)
   python/branches/py3k/Doc/includes/mp_synchronize.py   (props changed)
   python/branches/py3k/Doc/includes/mp_webserver.py   (props changed)
   python/branches/py3k/Doc/includes/mp_workers.py   (props changed)
   python/branches/py3k/Doc/includes/noddy.c   (props changed)
   python/branches/py3k/Doc/includes/noddy2.c   (props changed)
   python/branches/py3k/Doc/includes/noddy3.c   (props changed)
   python/branches/py3k/Doc/includes/noddy4.c   (props changed)
   python/branches/py3k/Doc/includes/run-func.c   (props changed)
   python/branches/py3k/Doc/includes/shoddy.c   (props changed)
   python/branches/py3k/Doc/includes/sqlite3/ctx_manager.py   (props changed)
   python/branches/py3k/Doc/includes/typestruct.h   (props changed)
   python/branches/py3k/Doc/tools/sphinxext/patchlevel.py   (props changed)
   python/branches/py3k/Doc/tools/sphinxext/pyspecific.py   (props changed)
   python/branches/py3k/Include/bytes_methods.h   (props changed)
   python/branches/py3k/Include/warnings.h   (props changed)
   python/branches/py3k/Lib/_weakrefset.py   (props changed)
   python/branches/py3k/Lib/ast.py   (props changed)
   python/branches/py3k/Lib/copyreg.py   (props changed)
   python/branches/py3k/Lib/dbm/__init__.py   (props changed)
   python/branches/py3k/Lib/dbm/gnu.py   (props changed)
   python/branches/py3k/Lib/dbm/ndbm.py   (props changed)
   python/branches/py3k/Lib/distutils/config.py   (props changed)
   python/branches/py3k/Lib/distutils/tests/test_build_ext.py   (props changed)
   python/branches/py3k/Lib/distutils/tests/test_config.py   (props changed)
   python/branches/py3k/Lib/distutils/tests/test_upload.py   (props changed)
   python/branches/py3k/Lib/encodings/utf_32.py   (props changed)
   python/branches/py3k/Lib/encodings/utf_32_be.py   (props changed)
   python/branches/py3k/Lib/encodings/utf_32_le.py   (props changed)
   python/branches/py3k/Lib/http/__init__.py   (props changed)
   python/branches/py3k/Lib/json/__init__.py   (props changed)
   python/branches/py3k/Lib/json/decoder.py   (props changed)
   python/branches/py3k/Lib/json/encoder.py   (props changed)
   python/branches/py3k/Lib/json/scanner.py   (props changed)
   python/branches/py3k/Lib/json/tests/__init__.py   (props changed)
   python/branches/py3k/Lib/json/tests/test_decode.py   (props changed)
   python/branches/py3k/Lib/json/tests/test_default.py   (props changed)
   python/branches/py3k/Lib/json/tests/test_dump.py   (props changed)
   python/branches/py3k/Lib/json/tests/test_encode_basestring_ascii.py   (props changed)
   python/branches/py3k/Lib/json/tests/test_fail.py   (props changed)
   python/branches/py3k/Lib/json/tests/test_float.py   (props changed)
   python/branches/py3k/Lib/json/tests/test_indent.py   (props changed)
   python/branches/py3k/Lib/json/tests/test_pass1.py   (props changed)
   python/branches/py3k/Lib/json/tests/test_pass2.py   (props changed)
   python/branches/py3k/Lib/json/tests/test_pass3.py   (props changed)
   python/branches/py3k/Lib/json/tests/test_recursion.py   (props changed)
   python/branches/py3k/Lib/json/tests/test_scanstring.py   (props changed)
   python/branches/py3k/Lib/json/tests/test_separators.py   (props changed)
   python/branches/py3k/Lib/json/tests/test_speedups.py   (props changed)
   python/branches/py3k/Lib/json/tests/test_unicode.py   (props changed)
   python/branches/py3k/Lib/json/tool.py   (props changed)
   python/branches/py3k/Lib/lib2to3/__init__.py   (props changed)
   python/branches/py3k/Lib/lib2to3/fixes/fix_execfile.py   (props changed)
   python/branches/py3k/Lib/lib2to3/fixes/fix_funcattrs.py   (props changed)
   python/branches/py3k/Lib/lib2to3/fixes/fix_idioms.py   (props changed)
   python/branches/py3k/Lib/lib2to3/fixes/fix_import.py   (props changed)
   python/branches/py3k/Lib/lib2to3/fixes/fix_imports.py   (props changed)
   python/branches/py3k/Lib/lib2to3/fixes/fix_itertools.py   (props changed)
   python/branches/py3k/Lib/lib2to3/fixes/fix_itertools_imports.py   (props changed)
   python/branches/py3k/Lib/lib2to3/fixes/fix_standarderror.py   (props changed)
   python/branches/py3k/Lib/lib2to3/fixes/fix_types.py   (props changed)
   python/branches/py3k/Lib/lib2to3/fixes/fix_xreadlines.py   (props changed)
   python/branches/py3k/Lib/lib2to3/fixes/fix_zip.py   (props changed)
   python/branches/py3k/Lib/lib2to3/tests/test_all_fixers.py   (props changed)
   python/branches/py3k/Lib/lib2to3/tests/test_parser.py   (props changed)
   python/branches/py3k/Lib/multiprocessing/__init__.py   (props changed)
   python/branches/py3k/Lib/multiprocessing/connection.py   (props changed)
   python/branches/py3k/Lib/multiprocessing/dummy/__init__.py   (props changed)
   python/branches/py3k/Lib/multiprocessing/dummy/connection.py   (props changed)
   python/branches/py3k/Lib/multiprocessing/forking.py   (props changed)
   python/branches/py3k/Lib/multiprocessing/heap.py   (props changed)
   python/branches/py3k/Lib/multiprocessing/managers.py   (props changed)
   python/branches/py3k/Lib/multiprocessing/pool.py   (props changed)
   python/branches/py3k/Lib/multiprocessing/process.py   (props changed)
   python/branches/py3k/Lib/multiprocessing/queues.py   (props changed)
   python/branches/py3k/Lib/multiprocessing/reduction.py   (props changed)
   python/branches/py3k/Lib/multiprocessing/sharedctypes.py   (props changed)
   python/branches/py3k/Lib/multiprocessing/synchronize.py   (props changed)
   python/branches/py3k/Lib/multiprocessing/util.py   (props changed)
   python/branches/py3k/Lib/pydoc_topics.py   (props changed)
   python/branches/py3k/Lib/sqlite3/dump.py   (props changed)
   python/branches/py3k/Lib/sqlite3/test/dump.py   (props changed)
   python/branches/py3k/Lib/test/buffer_tests.py   (props changed)
   python/branches/py3k/Lib/test/cmath_testcases.txt   (props changed)
   python/branches/py3k/Lib/test/curses_tests.py   (props changed)
   python/branches/py3k/Lib/test/dis_module.py   (props changed)
   python/branches/py3k/Lib/test/profilee.py   (props changed)
   python/branches/py3k/Lib/test/pydoc_mod.py   (props changed)
   python/branches/py3k/Lib/test/relimport.py   (props changed)
   python/branches/py3k/Lib/test/test_SimpleHTTPServer.py   (props changed)
   python/branches/py3k/Lib/test/test_asyncore.py   (props changed)
   python/branches/py3k/Lib/test/test_cmd.py   (props changed)
   python/branches/py3k/Lib/test/test_copyreg.py   (props changed)
   python/branches/py3k/Lib/test/test_dictcomps.py   (props changed)
   python/branches/py3k/Lib/test/test_docxmlrpc.py   (props changed)
   python/branches/py3k/Lib/test/test_email.py   (props changed)
   python/branches/py3k/Lib/test/test_fractions.py   (props changed)
   python/branches/py3k/Lib/test/test_httpservers.py   (props changed)
   python/branches/py3k/Lib/test/test_int.py   (props changed)
   python/branches/py3k/Lib/test/test_json.py   (props changed)
   python/branches/py3k/Lib/test/test_memoryio.py   (props changed)
   python/branches/py3k/Lib/test/test_multiprocessing.py   (props changed)
   python/branches/py3k/Lib/test/test_pipes.py   (props changed)
   python/branches/py3k/Lib/test/test_print.py   (props changed)
   python/branches/py3k/Lib/test/test_pstats.py   (props changed)
   python/branches/py3k/Lib/test/test_pydoc.py   (props changed)
   python/branches/py3k/Lib/test/test_raise.py   (props changed)
   python/branches/py3k/Lib/test/test_unpack_ex.py   (props changed)
   python/branches/py3k/Lib/test/test_urllib2_localnet.py   (props changed)
   python/branches/py3k/Lib/test/test_weakset.py   (props changed)
   python/branches/py3k/Lib/test/test_xmlrpc_net.py   (props changed)
   python/branches/py3k/Lib/xmlrpc/__init__.py   (props changed)
   python/branches/py3k/Modules/_ctypes/libffi_osx/ffi.c   (props changed)
   python/branches/py3k/Modules/_ctypes/libffi_osx/include/ffi.h   (props changed)
   python/branches/py3k/Modules/_ctypes/libffi_osx/include/ffi_common.h   (props changed)
   python/branches/py3k/Modules/_ctypes/libffi_osx/include/fficonfig.h   (props changed)
   python/branches/py3k/Modules/_ctypes/libffi_osx/include/ffitarget.h   (props changed)
   python/branches/py3k/Modules/_ctypes/libffi_osx/include/ppc-ffitarget.h   (props changed)
   python/branches/py3k/Modules/_ctypes/libffi_osx/include/x86-ffitarget.h   (props changed)
   python/branches/py3k/Modules/_ctypes/libffi_osx/powerpc/ppc-darwin.h   (props changed)
   python/branches/py3k/Modules/_ctypes/libffi_osx/powerpc/ppc-ffi_darwin.c   (props changed)
   python/branches/py3k/Modules/_ctypes/libffi_osx/types.c   (props changed)
   python/branches/py3k/Modules/_ctypes/libffi_osx/x86/x86-ffi64.c   (props changed)
   python/branches/py3k/Modules/_ctypes/libffi_osx/x86/x86-ffi_darwin.c   (props changed)
   python/branches/py3k/Modules/_gestalt.c   (props changed)
   python/branches/py3k/Modules/_json.c   (props changed)
   python/branches/py3k/Modules/_multiprocessing/connection.h   (props changed)
   python/branches/py3k/Modules/_multiprocessing/multiprocessing.c   (props changed)
   python/branches/py3k/Modules/_multiprocessing/multiprocessing.h   (props changed)
   python/branches/py3k/Modules/_multiprocessing/pipe_connection.c   (props changed)
   python/branches/py3k/Modules/_multiprocessing/semaphore.c   (props changed)
   python/branches/py3k/Modules/_multiprocessing/socket_connection.c   (props changed)
   python/branches/py3k/Modules/_multiprocessing/win32_functions.c   (props changed)
   python/branches/py3k/Modules/bsddb.h   (props changed)
   python/branches/py3k/Modules/md5module.c   (props changed)
   python/branches/py3k/Modules/sha1module.c   (props changed)
   python/branches/py3k/Objects/bytes_methods.c   (props changed)
   python/branches/py3k/Objects/stringlib/ctype.h   (props changed)
   python/branches/py3k/Objects/stringlib/formatter.h   (props changed)
   python/branches/py3k/Objects/stringlib/localeutil.h   (props changed)
   python/branches/py3k/Objects/stringlib/string_format.h   (props changed)
   python/branches/py3k/Objects/stringlib/stringdefs.h   (props changed)
   python/branches/py3k/Objects/stringlib/transmogrify.h   (props changed)
   python/branches/py3k/Objects/stringlib/unicodedefs.h   (props changed)
   python/branches/py3k/PCbuild/_multiprocessing.vcproj   (props changed)
   python/branches/py3k/Python/formatter_unicode.c   (props changed)
   python/branches/py3k/Tools/pybench/With.py   (props changed)
   python/branches/py3k/Tools/scripts/patchcheck.py   (props changed)

From python-3000-checkins at python.org  Sat Jun 14 01:34:39 2008
From: python-3000-checkins at python.org (martin.v.loewis)
Date: Sat, 14 Jun 2008 01:34:39 +0200 (CEST)
Subject: [Python-3000-checkins] r64259 - in python/branches/py3k:
	Lib/ctypes/test/test_errno.py Lib/email/test/data/msg_26.txt
	Lib/test/tokenize_tests-latin1-coding-cookie-and-utf8-bom-sig.txt
	Lib/test/tokenize_tests-no-coding-cookie-and-utf8-bom-sig-only.txt
	Lib/test/tokenize_tests-utf8-coding-cookie-and-no-utf8-bom-sig.txt
	Lib/test/tokenize_tests-utf8-coding-cookie-and-utf8-bom-sig.txt
	PC/VS8.0/_bsddb.vcproj PC/VS8.0/_bsddb44.vcproj
	PC/VS8.0/_ctypes.vcproj PC/VS8.0/_ctypes_test.vcproj
	PC/VS8.0/_elementtree.vcproj PC/VS8.0/_hashlib.vcproj
	PC/VS8.0/_msi.vcproj PC/VS8.0/_multiprocessing.vcproj
	PC/VS8.0/_socket.vcproj PC/VS8.0/_sqlite3.vcproj
	PC/VS8.0/_ssl.vcproj PC/VS8.0/_testcapi.vcproj
	PC/VS8.0/_tkinter.vcproj PC/VS8.0/bdist_wininst.vcproj
	PC/VS8.0/bz2.vcproj PC/VS8.0/kill_python.c
	PC/VS8.0/kill_python.vcproj PC/VS8.0/make_buildinfo.vcproj
	PC/VS8.0/make_versioninfo.vcproj PC/VS8.0/pcbuild.sln
	PC/VS8.0/pyexpat.vcproj PC/VS8.0/python.vcproj
	PC/VS8.0/pythoncore.vcproj PC/VS8.0/pythonw.vcproj
	PC/VS8.0/select.vcproj PC/VS8.0/sqlite3.vcproj
	PC/VS8.0/unicodedata.vcproj PC/VS8.0/w9xpopen.vcproj
	PC/VS8.0/winsound.vcproj PCbuild/_bsddb44.vcproj
	PCbuild/bdist_wininst.vcproj PCbuild/kill_python.c
	PCbuild/kill_python.vcproj PCbuild/sqlite3.vcproj
Message-ID: <20080613233439.18A6D1E4013@bag.python.org>

Author: martin.v.loewis
Date: Sat Jun 14 01:34:35 2008
New Revision: 64259

Log:
Ran svneol.py

Modified:
   python/branches/py3k/Lib/ctypes/test/test_errno.py   (contents, props changed)
   python/branches/py3k/Lib/email/test/data/msg_26.txt   (contents, props changed)
   python/branches/py3k/Lib/test/tokenize_tests-latin1-coding-cookie-and-utf8-bom-sig.txt   (contents, props changed)
   python/branches/py3k/Lib/test/tokenize_tests-no-coding-cookie-and-utf8-bom-sig-only.txt   (contents, props changed)
   python/branches/py3k/Lib/test/tokenize_tests-utf8-coding-cookie-and-no-utf8-bom-sig.txt   (contents, props changed)
   python/branches/py3k/Lib/test/tokenize_tests-utf8-coding-cookie-and-utf8-bom-sig.txt   (contents, props changed)
   python/branches/py3k/PC/VS8.0/_bsddb.vcproj   (contents, props changed)
   python/branches/py3k/PC/VS8.0/_bsddb44.vcproj   (contents, props changed)
   python/branches/py3k/PC/VS8.0/_ctypes.vcproj   (contents, props changed)
   python/branches/py3k/PC/VS8.0/_ctypes_test.vcproj   (contents, props changed)
   python/branches/py3k/PC/VS8.0/_elementtree.vcproj   (contents, props changed)
   python/branches/py3k/PC/VS8.0/_hashlib.vcproj   (contents, props changed)
   python/branches/py3k/PC/VS8.0/_msi.vcproj   (contents, props changed)
   python/branches/py3k/PC/VS8.0/_multiprocessing.vcproj   (contents, props changed)
   python/branches/py3k/PC/VS8.0/_socket.vcproj   (contents, props changed)
   python/branches/py3k/PC/VS8.0/_sqlite3.vcproj   (contents, props changed)
   python/branches/py3k/PC/VS8.0/_ssl.vcproj   (contents, props changed)
   python/branches/py3k/PC/VS8.0/_testcapi.vcproj   (contents, props changed)
   python/branches/py3k/PC/VS8.0/_tkinter.vcproj   (contents, props changed)
   python/branches/py3k/PC/VS8.0/bdist_wininst.vcproj   (contents, props changed)
   python/branches/py3k/PC/VS8.0/bz2.vcproj   (contents, props changed)
   python/branches/py3k/PC/VS8.0/kill_python.c   (contents, props changed)
   python/branches/py3k/PC/VS8.0/kill_python.vcproj   (contents, props changed)
   python/branches/py3k/PC/VS8.0/make_buildinfo.vcproj   (contents, props changed)
   python/branches/py3k/PC/VS8.0/make_versioninfo.vcproj   (contents, props changed)
   python/branches/py3k/PC/VS8.0/pcbuild.sln   (contents, props changed)
   python/branches/py3k/PC/VS8.0/pyexpat.vcproj   (contents, props changed)
   python/branches/py3k/PC/VS8.0/python.vcproj   (contents, props changed)
   python/branches/py3k/PC/VS8.0/pythoncore.vcproj   (contents, props changed)
   python/branches/py3k/PC/VS8.0/pythonw.vcproj   (contents, props changed)
   python/branches/py3k/PC/VS8.0/select.vcproj   (contents, props changed)
   python/branches/py3k/PC/VS8.0/sqlite3.vcproj   (contents, props changed)
   python/branches/py3k/PC/VS8.0/unicodedata.vcproj   (contents, props changed)
   python/branches/py3k/PC/VS8.0/w9xpopen.vcproj   (contents, props changed)
   python/branches/py3k/PC/VS8.0/winsound.vcproj   (contents, props changed)
   python/branches/py3k/PCbuild/_bsddb44.vcproj   (contents, props changed)
   python/branches/py3k/PCbuild/bdist_wininst.vcproj   (contents, props changed)
   python/branches/py3k/PCbuild/kill_python.c   (contents, props changed)
   python/branches/py3k/PCbuild/kill_python.vcproj   (contents, props changed)
   python/branches/py3k/PCbuild/sqlite3.vcproj   (contents, props changed)

Modified: python/branches/py3k/Lib/ctypes/test/test_errno.py
==============================================================================
--- python/branches/py3k/Lib/ctypes/test/test_errno.py	(original)
+++ python/branches/py3k/Lib/ctypes/test/test_errno.py	Sat Jun 14 01:34:35 2008
@@ -1,76 +1,76 @@
-import unittest, os, errno
-from ctypes import *
-from ctypes.util import find_library
-import threading
-
-class Test(unittest.TestCase):
-    def test_open(self):
-        libc_name = find_library("c")
-        if libc_name is not None:
-            libc = CDLL(libc_name, use_errno=True)
-            if os.name == "nt":
-                libc_open = libc._open
-            else:
-                libc_open = libc.open
-
-            libc_open.argtypes = c_char_p, c_int
-
-            self.failUnlessEqual(libc_open("", 0), -1)
-            self.failUnlessEqual(get_errno(), errno.ENOENT)
-
-            self.failUnlessEqual(set_errno(32), errno.ENOENT)
-            self.failUnlessEqual(get_errno(), 32)
-
-
-            def _worker():
-                set_errno(0)
-
-                libc = CDLL(libc_name, use_errno=False)
-                if os.name == "nt":
-                    libc_open = libc._open
-                else:
-                    libc_open = libc.open
-                libc_open.argtypes = c_char_p, c_int
-                self.failUnlessEqual(libc_open("", 0), -1)
-                self.failUnlessEqual(get_errno(), 0)
-
-            t = threading.Thread(target=_worker)
-            t.start()
-            t.join()
-
-            self.failUnlessEqual(get_errno(), 32)
-            set_errno(0)
-
-    if os.name == "nt":
-
-        def test_GetLastError(self):
-            dll = WinDLL("kernel32", use_last_error=True)
-            GetModuleHandle = dll.GetModuleHandleA
-            GetModuleHandle.argtypes = [c_wchar_p]
-
-            self.failUnlessEqual(0, GetModuleHandle("foo"))
-            self.failUnlessEqual(get_last_error(), 126)
-
-            self.failUnlessEqual(set_last_error(32), 126)
-            self.failUnlessEqual(get_last_error(), 32)
-
-            def _worker():
-                set_last_error(0)
-
-                dll = WinDLL("kernel32", use_last_error=False)
-                GetModuleHandle = dll.GetModuleHandleW
-                GetModuleHandle.argtypes = [c_wchar_p]
-                GetModuleHandle("bar")
-
-                self.failUnlessEqual(get_last_error(), 0)
-
-            t = threading.Thread(target=_worker)
-            t.start()
-            t.join()
-
-            self.failUnlessEqual(get_last_error(), 32)
-
-            set_last_error(0)
-
-if __name__ == "__main__":
-    unittest.main()
+import unittest, os, errno
+from ctypes import *
+from ctypes.util import find_library
+import threading
+
+class Test(unittest.TestCase):
+    def test_open(self):
+        libc_name = find_library("c")
+        if libc_name is not None:
+            libc = CDLL(libc_name, use_errno=True)
+            if os.name == "nt":
+                libc_open = libc._open
+            else:
+                libc_open = libc.open
+
+            libc_open.argtypes = c_char_p, c_int
+
+            self.failUnlessEqual(libc_open("", 0), -1)
+            self.failUnlessEqual(get_errno(), errno.ENOENT)
+
+            self.failUnlessEqual(set_errno(32), errno.ENOENT)
+            self.failUnlessEqual(get_errno(), 32)
+
+
+            def _worker():
+                set_errno(0)
+
+                libc = CDLL(libc_name, use_errno=False)
+                if os.name == "nt":
+                    libc_open = libc._open
+                else:
+                    libc_open = libc.open
+                libc_open.argtypes = c_char_p, c_int
+                self.failUnlessEqual(libc_open("", 0), -1)
+                self.failUnlessEqual(get_errno(), 0)
+
+            t = threading.Thread(target=_worker)
+            t.start()
+            t.join()
+
+            self.failUnlessEqual(get_errno(), 32)
+            set_errno(0)
+
+    if os.name == "nt":
+
+        def test_GetLastError(self):
+            dll = WinDLL("kernel32", use_last_error=True)
+            GetModuleHandle = dll.GetModuleHandleA
+            GetModuleHandle.argtypes = [c_wchar_p]
+
+            self.failUnlessEqual(0, GetModuleHandle("foo"))
+            self.failUnlessEqual(get_last_error(), 126)
+
+            self.failUnlessEqual(set_last_error(32), 126)
+            self.failUnlessEqual(get_last_error(), 32)
+
+            def _worker():
+                set_last_error(0)
+
+                dll = WinDLL("kernel32", use_last_error=False)
+                GetModuleHandle = dll.GetModuleHandleW
+                GetModuleHandle.argtypes = [c_wchar_p]
+                GetModuleHandle("bar")
+
+                self.failUnlessEqual(get_last_error(), 0)
+
+            t = threading.Thread(target=_worker)
+            t.start()
+            t.join()
+
+            self.failUnlessEqual(get_last_error(), 32)
+
+            set_last_error(0)
+
+if __name__ == "__main__":
+    unittest.main()

Modified: python/branches/py3k/Lib/email/test/data/msg_26.txt
==============================================================================
--- python/branches/py3k/Lib/email/test/data/msg_26.txt	(original)
+++ python/branches/py3k/Lib/email/test/data/msg_26.txt	Sat Jun 14 01:34:35 2008
@@ -1,45 +1,45 @@
-Received: from xcar [192.168.0.2] by jeeves.wooster.local
-  (SMTPD32-7.07 EVAL) id AFF92F0214; Sun, 12 May 2002 08:55:37 +0100
-Date: Sun, 12 May 2002 08:56:15 +0100
-From: Father Time <father.time at xcar.wooster.local>
-To: timbo at jeeves.wooster.local
-Subject: IMAP file test
-Message-ID: <6df65d354b.father.time at rpc.wooster.local>
-X-Organization: Home
-User-Agent: Messenger-Pro/2.50a (MsgServe/1.50) (RISC-OS/4.02) POPstar/2.03
-MIME-Version: 1.0
-Content-Type: multipart/mixed; boundary="1618492860--2051301190--113853680"
-Status: R
-X-UIDL: 319998302
-
-This message is in MIME format which your mailer apparently does not support.
-You either require a newer version of your software which supports MIME, or
-a separate MIME decoding utility.  Alternatively, ask the sender of this
-message to resend it in a different format.
-
---1618492860--2051301190--113853680
-Content-Type: text/plain; charset=us-ascii
-
-Simple email with attachment.
-
-
---1618492860--2051301190--113853680
-Content-Type: application/riscos; name="clock.bmp,69c"; type=BMP; load=&fff69c4b; exec=&355dd4d1; access=&03
-Content-Disposition: attachment; filename="clock.bmp"
-Content-Transfer-Encoding: base64
-
-Qk12AgAAAAAAAHYAAAAoAAAAIAAAACAAAAABAAQAAAAAAAAAAADXDQAA1w0AAAAAAAAA
-AAAAAAAAAAAAiAAAiAAAAIiIAIgAAACIAIgAiIgAALu7uwCIiIgAERHdACLuIgAz//8A
-zAAAAN0R3QDu7iIA////AAAAAAAAAAAAAAAAAAAAAAAAAAi3AAAAAAAAADeAAAAAAAAA
-C3ADMzMzMANwAAAAAAAAAAAHMAAAAANwAAAAAAAAAACAMAd3zPfwAwgAAAAAAAAIAwd/
-f8x/f3AwgAAAAAAAgDB0x/f3//zPAwgAAAAAAAcHfM9////8z/AwAAAAAAiwd/f3////
-////A4AAAAAAcEx/f///////zAMAAAAAiwfM9////3///8zwOAAAAAcHf3////B/////
-8DAAAAALB/f3///wd3d3//AwAAAABwTPf//wCQAAD/zAMAAAAAsEx/f///B////8wDAA
-AAAHB39////wf/////AwAAAACwf39///8H/////wMAAAAIcHfM9///B////M8DgAAAAA
-sHTH///wf///xAMAAAAACHB3f3//8H////cDgAAAAAALB3zH//D//M9wMAAAAAAAgLB0
-z39///xHAwgAAAAAAAgLB3d3RHd3cDCAAAAAAAAAgLAHd0R3cAMIAAAAAAAAgAgLcAAA
-AAMwgAgAAAAACDAAAAu7t7cwAAgDgAAAAABzcIAAAAAAAAgDMwAAAAAAN7uwgAAAAAgH
-MzMAAAAACH97tzAAAAALu3c3gAAAAAAL+7tzDABAu7f7cAAAAAAACA+3MA7EQAv/sIAA
-AAAAAAAIAAAAAAAAAIAAAAAA
-
---1618492860--2051301190--113853680--
+Received: from xcar [192.168.0.2] by jeeves.wooster.local
+  (SMTPD32-7.07 EVAL) id AFF92F0214; Sun, 12 May 2002 08:55:37 +0100
+Date: Sun, 12 May 2002 08:56:15 +0100
+From: Father Time <father.time at xcar.wooster.local>
+To: timbo at jeeves.wooster.local
+Subject: IMAP file test
+Message-ID: <6df65d354b.father.time at rpc.wooster.local>
+X-Organization: Home
+User-Agent: Messenger-Pro/2.50a (MsgServe/1.50) (RISC-OS/4.02) POPstar/2.03
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary="1618492860--2051301190--113853680"
+Status: R
+X-UIDL: 319998302
+
+This message is in MIME format which your mailer apparently does not support.
+You either require a newer version of your software which supports MIME, or
+a separate MIME decoding utility.  Alternatively, ask the sender of this
+message to resend it in a different format.
+
+--1618492860--2051301190--113853680
+Content-Type: text/plain; charset=us-ascii
+
+Simple email with attachment.
+
+
+--1618492860--2051301190--113853680
+Content-Type: application/riscos; name="clock.bmp,69c"; type=BMP; load=&fff69c4b; exec=&355dd4d1; access=&03
+Content-Disposition: attachment; filename="clock.bmp"
+Content-Transfer-Encoding: base64
+
+Qk12AgAAAAAAAHYAAAAoAAAAIAAAACAAAAABAAQAAAAAAAAAAADXDQAA1w0AAAAAAAAA
+AAAAAAAAAAAAiAAAiAAAAIiIAIgAAACIAIgAiIgAALu7uwCIiIgAERHdACLuIgAz//8A
+zAAAAN0R3QDu7iIA////AAAAAAAAAAAAAAAAAAAAAAAAAAi3AAAAAAAAADeAAAAAAAAA
+C3ADMzMzMANwAAAAAAAAAAAHMAAAAANwAAAAAAAAAACAMAd3zPfwAwgAAAAAAAAIAwd/
+f8x/f3AwgAAAAAAAgDB0x/f3//zPAwgAAAAAAAcHfM9////8z/AwAAAAAAiwd/f3////
+////A4AAAAAAcEx/f///////zAMAAAAAiwfM9////3///8zwOAAAAAcHf3////B/////
+8DAAAAALB/f3///wd3d3//AwAAAABwTPf//wCQAAD/zAMAAAAAsEx/f///B////8wDAA
+AAAHB39////wf/////AwAAAACwf39///8H/////wMAAAAIcHfM9///B////M8DgAAAAA
+sHTH///wf///xAMAAAAACHB3f3//8H////cDgAAAAAALB3zH//D//M9wMAAAAAAAgLB0
+z39///xHAwgAAAAAAAgLB3d3RHd3cDCAAAAAAAAAgLAHd0R3cAMIAAAAAAAAgAgLcAAA
+AAMwgAgAAAAACDAAAAu7t7cwAAgDgAAAAABzcIAAAAAAAAgDMwAAAAAAN7uwgAAAAAgH
+MzMAAAAACH97tzAAAAALu3c3gAAAAAAL+7tzDABAu7f7cAAAAAAACA+3MA7EQAv/sIAA
+AAAAAAAIAAAAAAAAAIAAAAAA
+
+--1618492860--2051301190--113853680--

Modified: python/branches/py3k/Lib/test/tokenize_tests-latin1-coding-cookie-and-utf8-bom-sig.txt
==============================================================================
--- python/branches/py3k/Lib/test/tokenize_tests-latin1-coding-cookie-and-utf8-bom-sig.txt	(original)
+++ python/branches/py3k/Lib/test/tokenize_tests-latin1-coding-cookie-and-utf8-bom-sig.txt	Sat Jun 14 01:34:35 2008
@@ -1,13 +1,13 @@
-?# -*- coding: latin1 -*-
-# IMPORTANT: this file has the utf-8 BOM signature '\xef\xbb\xbf' 
-# at the start of it.  Make sure this is preserved if any changes
-# are made!  Also note that the coding cookie above conflicts with
-# the presense of a utf-8 BOM signature -- this is intended.
-
-# Arbitrary encoded utf-8 text (stolen from test_doctest2.py).
-x = '?????'
-def y():
-    """
-    And again in a comment.  ?????
-    """
-    pass
+?# -*- coding: latin1 -*-
+# IMPORTANT: this file has the utf-8 BOM signature '\xef\xbb\xbf' 
+# at the start of it.  Make sure this is preserved if any changes
+# are made!  Also note that the coding cookie above conflicts with
+# the presense of a utf-8 BOM signature -- this is intended.
+
+# Arbitrary encoded utf-8 text (stolen from test_doctest2.py).
+x = '?????'
+def y():
+    """
+    And again in a comment.  ?????
+    """
+    pass

Modified: python/branches/py3k/Lib/test/tokenize_tests-no-coding-cookie-and-utf8-bom-sig-only.txt
==============================================================================
--- python/branches/py3k/Lib/test/tokenize_tests-no-coding-cookie-and-utf8-bom-sig-only.txt	(original)
+++ python/branches/py3k/Lib/test/tokenize_tests-no-coding-cookie-and-utf8-bom-sig-only.txt	Sat Jun 14 01:34:35 2008
@@ -1,11 +1,11 @@
-?# IMPORTANT: this file has the utf-8 BOM signature '\xef\xbb\xbf' 
-# at the start of it.  Make sure this is preserved if any changes
-# are made!
-
-# Arbitrary encoded utf-8 text (stolen from test_doctest2.py).
-x = '?????'
-def y():
-    """
-    And again in a comment.  ?????
-    """
-    pass
+?# IMPORTANT: this file has the utf-8 BOM signature '\xef\xbb\xbf' 
+# at the start of it.  Make sure this is preserved if any changes
+# are made!
+
+# Arbitrary encoded utf-8 text (stolen from test_doctest2.py).
+x = '?????'
+def y():
+    """
+    And again in a comment.  ?????
+    """
+    pass

Modified: python/branches/py3k/Lib/test/tokenize_tests-utf8-coding-cookie-and-no-utf8-bom-sig.txt
==============================================================================
--- python/branches/py3k/Lib/test/tokenize_tests-utf8-coding-cookie-and-no-utf8-bom-sig.txt	(original)
+++ python/branches/py3k/Lib/test/tokenize_tests-utf8-coding-cookie-and-no-utf8-bom-sig.txt	Sat Jun 14 01:34:35 2008
@@ -1,13 +1,13 @@
-?# -*- coding: utf-8 -*-
-# IMPORTANT: unlike the other test_tokenize-*.txt files, this file
-# does NOT have the utf-8 BOM signature '\xef\xbb\xbf' at the start
-# of it.  Make sure this is not added inadvertently by your editor
-# if any changes are made to this file!
-
-# Arbitrary encoded utf-8 text (stolen from test_doctest2.py).
-x = '?????'
-def y():
-    """
-    And again in a comment.  ?????
-    """
-    pass
+?# -*- coding: utf-8 -*-
+# IMPORTANT: unlike the other test_tokenize-*.txt files, this file
+# does NOT have the utf-8 BOM signature '\xef\xbb\xbf' at the start
+# of it.  Make sure this is not added inadvertently by your editor
+# if any changes are made to this file!
+
+# Arbitrary encoded utf-8 text (stolen from test_doctest2.py).
+x = '?????'
+def y():
+    """
+    And again in a comment.  ?????
+    """
+    pass

Modified: python/branches/py3k/Lib/test/tokenize_tests-utf8-coding-cookie-and-utf8-bom-sig.txt
==============================================================================
--- python/branches/py3k/Lib/test/tokenize_tests-utf8-coding-cookie-and-utf8-bom-sig.txt	(original)
+++ python/branches/py3k/Lib/test/tokenize_tests-utf8-coding-cookie-and-utf8-bom-sig.txt	Sat Jun 14 01:34:35 2008
@@ -1,12 +1,12 @@
-?# -*- coding: utf-8 -*-
-# IMPORTANT: this file has the utf-8 BOM signature '\xef\xbb\xbf' 
-# at the start of it.  Make sure this is preserved if any changes
-# are made!
-
-# Arbitrary encoded utf-8 text (stolen from test_doctest2.py).
-x = '?????'
-def y():
-    """
-    And again in a comment.  ?????
-    """
-    pass
+?# -*- coding: utf-8 -*-
+# IMPORTANT: this file has the utf-8 BOM signature '\xef\xbb\xbf' 
+# at the start of it.  Make sure this is preserved if any changes
+# are made!
+
+# Arbitrary encoded utf-8 text (stolen from test_doctest2.py).
+x = '?????'
+def y():
+    """
+    And again in a comment.  ?????
+    """
+    pass

Modified: python/branches/py3k/PC/VS8.0/_bsddb.vcproj
==============================================================================
--- python/branches/py3k/PC/VS8.0/_bsddb.vcproj	(original)
+++ python/branches/py3k/PC/VS8.0/_bsddb.vcproj	Sat Jun 14 01:34:35 2008
@@ -1,546 +1,546 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="8.00"
-	Name="_bsddb"
-	ProjectGUID="{B4D38F3F-68FB-42EC-A45D-E00657BB3627}"
-	RootNamespace="_bsddb"
-	Keyword="Win32Proj"
-	TargetFrameworkVersion="196613"
-	>
-	<Platforms>
-		<Platform
-			Name="Win32"
-		/>
-		<Platform
-			Name="x64"
-		/>
-	</Platforms>
-	<ToolFiles>
-	</ToolFiles>
-	<Configurations>
-		<Configuration
-			Name="Debug|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd_d.vsprops"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="..\..\..\db-4.4.20\build_win32,..\..\..\db-4.4.20\build_win32\.."
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				BaseAddress="0x1e180000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Debug|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd_d.vsprops;.\x64.vsprops"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="..\..\..\db-4.4.20\build_win32,..\..\..\db-4.4.20\build_win32\.."
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-				CommandLine=""
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="$(bsddbDepLibs)"
-				BaseAddress="0x1e180000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="..\..\..\db-4.4.20\build_win32,..\..\..\db-4.4.20\build_win32\.."
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="$(bsddbDepLibs)"
-				BaseAddress="0x1e180000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="..\..\..\db-4.4.20\build_win32,..\..\..\db-4.4.20\build_win32\.."
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-				CommandLine=""
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="$(bsddbDepLibs)"
-				BaseAddress="0x1e180000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGInstrument|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\pginstrument.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="..\..\..\db-4.4.20\build_win32,..\..\..\db-4.4.20\build_win32\.."
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="$(bsddbDepLibs)"
-				BaseAddress="0x1e180000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGInstrument|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pginstrument.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="..\..\..\db-4.4.20\build_win32,..\..\..\db-4.4.20\build_win32\.."
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="$(bsddbDepLibs)"
-				BaseAddress="0x1e180000"
-				TargetMachine="17"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGUpdate|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\pgupdate.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="..\..\..\db-4.4.20\build_win32,..\..\..\db-4.4.20\build_win32\.."
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="$(bsddbDepLibs)"
-				BaseAddress="0x1e180000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGUpdate|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pgupdate.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="..\..\..\db-4.4.20\build_win32,..\..\..\db-4.4.20\build_win32\.."
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="$(bsddbDepLibs)"
-				BaseAddress="0x1e180000"
-				TargetMachine="17"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<Filter
-			Name="Header Files"
-			>
-			<File
-				RelativePath="..\..\Modules\bsddb.h"
-				>
-			</File>
-		</Filter>
-		<Filter
-			Name="Source Files"
-			>
-			<File
-				RelativePath="..\..\Modules\_bsddb.c"
-				>
-			</File>
-		</Filter>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="_bsddb"
+	ProjectGUID="{B4D38F3F-68FB-42EC-A45D-E00657BB3627}"
+	RootNamespace="_bsddb"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd_d.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\..\db-4.4.20\build_win32,..\..\..\db-4.4.20\build_win32\.."
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				BaseAddress="0x1e180000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd_d.vsprops;.\x64.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\..\db-4.4.20\build_win32,..\..\..\db-4.4.20\build_win32\.."
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				CommandLine=""
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="$(bsddbDepLibs)"
+				BaseAddress="0x1e180000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\..\db-4.4.20\build_win32,..\..\..\db-4.4.20\build_win32\.."
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="$(bsddbDepLibs)"
+				BaseAddress="0x1e180000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\..\db-4.4.20\build_win32,..\..\..\db-4.4.20\build_win32\.."
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				CommandLine=""
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="$(bsddbDepLibs)"
+				BaseAddress="0x1e180000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\pginstrument.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\..\db-4.4.20\build_win32,..\..\..\db-4.4.20\build_win32\.."
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="$(bsddbDepLibs)"
+				BaseAddress="0x1e180000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pginstrument.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\..\db-4.4.20\build_win32,..\..\..\db-4.4.20\build_win32\.."
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="$(bsddbDepLibs)"
+				BaseAddress="0x1e180000"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\pgupdate.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\..\db-4.4.20\build_win32,..\..\..\db-4.4.20\build_win32\.."
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="$(bsddbDepLibs)"
+				BaseAddress="0x1e180000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pgupdate.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\..\db-4.4.20\build_win32,..\..\..\db-4.4.20\build_win32\.."
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="$(bsddbDepLibs)"
+				BaseAddress="0x1e180000"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Header Files"
+			>
+			<File
+				RelativePath="..\..\Modules\bsddb.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Source Files"
+			>
+			<File
+				RelativePath="..\..\Modules\_bsddb.c"
+				>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Modified: python/branches/py3k/PC/VS8.0/_bsddb44.vcproj
==============================================================================
--- python/branches/py3k/PC/VS8.0/_bsddb44.vcproj	(original)
+++ python/branches/py3k/PC/VS8.0/_bsddb44.vcproj	Sat Jun 14 01:34:35 2008
@@ -1,1252 +1,1252 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="8.00"
-	Name="_bsddb44"
-	ProjectGUID="{62172C7D-B39E-409A-B352-370FF5098C19}"
-	RootNamespace="_bsddb44"
-	Keyword="Win32Proj"
-	TargetFrameworkVersion="196613"
-	>
-	<Platforms>
-		<Platform
-			Name="Win32"
-		/>
-		<Platform
-			Name="x64"
-		/>
-	</Platforms>
-	<ToolFiles>
-	</ToolFiles>
-	<Configurations>
-		<Configuration
-			Name="Debug|Win32"
-			ConfigurationType="4"
-			InheritedPropertySheets=".\pyd_d.vsprops"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="..\..\..\db-4.4.20\build_win32;..\..\..\db-4.4.20\build_win32\.."
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Debug|x64"
-			ConfigurationType="4"
-			InheritedPropertySheets=".\pyd_d.vsprops;.\x64.vsprops"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="..\..\..\db-4.4.20\build_win32;..\..\..\db-4.4.20\build_win32\.."
-				PreprocessorDefinitions="DIAGNOSTIC"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|Win32"
-			ConfigurationType="4"
-			InheritedPropertySheets=".\pyd.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="..\..\..\db-4.4.20\build_win32;..\..\..\db-4.4.20\build_win32\.."
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|x64"
-			ConfigurationType="4"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="..\..\..\db-4.4.20\build_win32;..\..\..\db-4.4.20\build_win32\.."
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGInstrument|Win32"
-			ConfigurationType="4"
-			InheritedPropertySheets=".\pyd.vsprops;.\pginstrument.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="..\..\..\db-4.4.20\build_win32;..\..\..\db-4.4.20\build_win32\.."
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGInstrument|x64"
-			ConfigurationType="4"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pginstrument.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="..\..\..\db-4.4.20\build_win32;..\..\..\db-4.4.20\build_win32\.."
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGUpdate|Win32"
-			ConfigurationType="4"
-			InheritedPropertySheets=".\pyd.vsprops;.\pgupdate.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="..\..\..\db-4.4.20\build_win32;..\..\..\db-4.4.20\build_win32\.."
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGUpdate|x64"
-			ConfigurationType="4"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pgupdate.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="..\..\..\db-4.4.20\build_win32;..\..\..\db-4.4.20\build_win32\.."
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<Filter
-			Name="Source Files"
-			>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\bt_compact.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\bt_compare.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\bt_conv.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\bt_curadj.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\bt_cursor.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\bt_delete.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\bt_method.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\bt_open.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\bt_put.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\bt_rec.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\bt_reclaim.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\bt_recno.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\bt_rsearch.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\bt_search.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\bt_split.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\bt_stat.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\bt_upgrade.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\bt_verify.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\btree_auto.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\crdel_auto.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\crdel_rec.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\common\crypto_stub.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_am.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_auto.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\common\db_byteorder.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_cam.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\common\db_clock.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_conv.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_dispatch.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_dup.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\common\db_err.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\common\db_getlong.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\common\db_idspace.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_iface.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_join.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\common\db_log2.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_meta.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_method.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_open.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_overflow.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_ovfl_vrfy.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_pr.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_rec.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_reclaim.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_remove.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_rename.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_ret.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\env\db_salloc.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_setid.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_setlsn.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\env\db_shash.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_stati.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_truncate.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_upg.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_upg_opd.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_vrfy.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_vrfyutil.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\dbm\dbm.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\dbreg\dbreg.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\dbreg\dbreg_auto.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\dbreg\dbreg_rec.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\dbreg\dbreg_stat.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\dbreg\dbreg_util.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\env\env_failchk.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\env\env_file.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\env\env_method.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\env\env_open.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\env\env_recover.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\env\env_region.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\env\env_register.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\env\env_stat.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\fileops\fileops_auto.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\fileops\fop_basic.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\fileops\fop_rec.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\fileops\fop_util.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\hash\hash.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\hash\hash_auto.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\hash\hash_conv.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\hash\hash_dup.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\hash\hash_func.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\hash\hash_meta.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\hash\hash_method.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\hash\hash_open.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\hash\hash_page.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\hash\hash_rec.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\hash\hash_reclaim.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\hash\hash_stat.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\hash\hash_upgrade.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\hash\hash_verify.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\hmac\hmac.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\hsearch\hsearch.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\lock\lock.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\lock\lock_deadlock.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\lock\lock_failchk.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\lock\lock_id.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\lock\lock_list.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\lock\lock_method.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\lock\lock_region.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\lock\lock_stat.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\lock\lock_timer.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\lock\lock_util.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\log\log.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\log\log_archive.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\log\log_compare.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\log\log_debug.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\log\log_get.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\log\log_method.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\log\log_put.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\log\log_stat.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\mp\mp_alloc.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\mp\mp_bh.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\mp\mp_fget.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\mp\mp_fmethod.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\mp\mp_fopen.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\mp\mp_fput.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\mp\mp_fset.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\mp\mp_method.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\mp\mp_region.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\mp\mp_register.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\mp\mp_stat.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\mp\mp_sync.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\mp\mp_trickle.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\mutex\mut_alloc.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\mutex\mut_method.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\mutex\mut_region.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\mutex\mut_stat.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\mutex\mut_win32.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_abs.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\os\os_alloc.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_clock.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_config.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_dir.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_errno.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_fid.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_flock.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_fsync.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_handle.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\os\os_id.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_map.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\os\os_method.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\os\os_mkdir.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\os\os_oflags.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_open.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\os\os_region.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_rename.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\os\os_root.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\os\os_rpath.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_rw.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_seek.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_sleep.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_spin.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_stat.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\os\os_tmpdir.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_truncate.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_unlink.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\qam\qam.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\qam\qam_auto.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\qam\qam_conv.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\qam\qam_files.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\qam\qam_method.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\qam\qam_open.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\qam\qam_rec.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\qam\qam_stat.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\qam\qam_upgrade.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\qam\qam_verify.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\rep\rep_auto.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\rep\rep_backup.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\rep\rep_elect.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\rep\rep_log.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\rep\rep_method.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\rep\rep_record.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\rep\rep_region.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\rep\rep_stat.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\rep\rep_util.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\rep\rep_verify.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\sequence\seq_stat.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\sequence\sequence.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\hmac\sha1.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\clib\strcasecmp.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\txn\txn.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\txn\txn_auto.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\txn\txn_chkpt.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\txn\txn_failchk.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\txn\txn_method.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\txn\txn_rec.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\txn\txn_recover.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\txn\txn_region.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\txn\txn_stat.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\txn\txn_util.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\common\util_cache.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\common\util_log.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\common\util_sig.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\xa\xa.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\xa\xa_db.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\db-4.4.20\build_win32\..\xa\xa_map.c"
-				>
-			</File>
-		</Filter>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="_bsddb44"
+	ProjectGUID="{62172C7D-B39E-409A-B352-370FF5098C19}"
+	RootNamespace="_bsddb44"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			ConfigurationType="4"
+			InheritedPropertySheets=".\pyd_d.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\..\db-4.4.20\build_win32;..\..\..\db-4.4.20\build_win32\.."
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			ConfigurationType="4"
+			InheritedPropertySheets=".\pyd_d.vsprops;.\x64.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\..\db-4.4.20\build_win32;..\..\..\db-4.4.20\build_win32\.."
+				PreprocessorDefinitions="DIAGNOSTIC"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			ConfigurationType="4"
+			InheritedPropertySheets=".\pyd.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\..\db-4.4.20\build_win32;..\..\..\db-4.4.20\build_win32\.."
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			ConfigurationType="4"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\..\db-4.4.20\build_win32;..\..\..\db-4.4.20\build_win32\.."
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|Win32"
+			ConfigurationType="4"
+			InheritedPropertySheets=".\pyd.vsprops;.\pginstrument.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\..\db-4.4.20\build_win32;..\..\..\db-4.4.20\build_win32\.."
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|x64"
+			ConfigurationType="4"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pginstrument.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\..\db-4.4.20\build_win32;..\..\..\db-4.4.20\build_win32\.."
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|Win32"
+			ConfigurationType="4"
+			InheritedPropertySheets=".\pyd.vsprops;.\pgupdate.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\..\db-4.4.20\build_win32;..\..\..\db-4.4.20\build_win32\.."
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|x64"
+			ConfigurationType="4"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pgupdate.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\..\db-4.4.20\build_win32;..\..\..\db-4.4.20\build_win32\.."
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\bt_compact.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\bt_compare.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\bt_conv.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\bt_curadj.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\bt_cursor.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\bt_delete.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\bt_method.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\bt_open.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\bt_put.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\bt_rec.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\bt_reclaim.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\bt_recno.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\bt_rsearch.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\bt_search.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\bt_split.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\bt_stat.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\bt_upgrade.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\bt_verify.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\btree\btree_auto.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\crdel_auto.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\crdel_rec.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\common\crypto_stub.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_am.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_auto.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\common\db_byteorder.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_cam.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\common\db_clock.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_conv.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_dispatch.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_dup.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\common\db_err.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\common\db_getlong.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\common\db_idspace.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_iface.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_join.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\common\db_log2.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_meta.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_method.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_open.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_overflow.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_ovfl_vrfy.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_pr.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_rec.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_reclaim.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_remove.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_rename.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_ret.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\env\db_salloc.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_setid.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_setlsn.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\env\db_shash.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_stati.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_truncate.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_upg.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_upg_opd.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_vrfy.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\db\db_vrfyutil.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\dbm\dbm.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\dbreg\dbreg.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\dbreg\dbreg_auto.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\dbreg\dbreg_rec.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\dbreg\dbreg_stat.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\dbreg\dbreg_util.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\env\env_failchk.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\env\env_file.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\env\env_method.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\env\env_open.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\env\env_recover.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\env\env_region.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\env\env_register.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\env\env_stat.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\fileops\fileops_auto.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\fileops\fop_basic.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\fileops\fop_rec.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\fileops\fop_util.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\hash\hash.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\hash\hash_auto.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\hash\hash_conv.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\hash\hash_dup.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\hash\hash_func.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\hash\hash_meta.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\hash\hash_method.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\hash\hash_open.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\hash\hash_page.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\hash\hash_rec.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\hash\hash_reclaim.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\hash\hash_stat.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\hash\hash_upgrade.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\hash\hash_verify.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\hmac\hmac.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\hsearch\hsearch.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\lock\lock.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\lock\lock_deadlock.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\lock\lock_failchk.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\lock\lock_id.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\lock\lock_list.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\lock\lock_method.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\lock\lock_region.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\lock\lock_stat.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\lock\lock_timer.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\lock\lock_util.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\log\log.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\log\log_archive.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\log\log_compare.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\log\log_debug.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\log\log_get.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\log\log_method.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\log\log_put.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\log\log_stat.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\mp\mp_alloc.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\mp\mp_bh.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\mp\mp_fget.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\mp\mp_fmethod.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\mp\mp_fopen.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\mp\mp_fput.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\mp\mp_fset.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\mp\mp_method.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\mp\mp_region.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\mp\mp_register.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\mp\mp_stat.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\mp\mp_sync.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\mp\mp_trickle.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\mutex\mut_alloc.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\mutex\mut_method.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\mutex\mut_region.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\mutex\mut_stat.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\mutex\mut_win32.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_abs.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\os\os_alloc.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_clock.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_config.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_dir.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_errno.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_fid.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_flock.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_fsync.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_handle.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\os\os_id.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_map.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\os\os_method.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\os\os_mkdir.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\os\os_oflags.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_open.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\os\os_region.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_rename.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\os\os_root.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\os\os_rpath.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_rw.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_seek.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_sleep.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_spin.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_stat.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\os\os_tmpdir.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_truncate.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\os_win32\os_unlink.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\qam\qam.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\qam\qam_auto.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\qam\qam_conv.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\qam\qam_files.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\qam\qam_method.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\qam\qam_open.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\qam\qam_rec.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\qam\qam_stat.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\qam\qam_upgrade.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\qam\qam_verify.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\rep\rep_auto.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\rep\rep_backup.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\rep\rep_elect.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\rep\rep_log.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\rep\rep_method.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\rep\rep_record.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\rep\rep_region.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\rep\rep_stat.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\rep\rep_util.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\rep\rep_verify.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\sequence\seq_stat.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\sequence\sequence.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\hmac\sha1.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\clib\strcasecmp.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\txn\txn.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\txn\txn_auto.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\txn\txn_chkpt.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\txn\txn_failchk.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\txn\txn_method.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\txn\txn_rec.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\txn\txn_recover.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\txn\txn_region.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\txn\txn_stat.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\txn\txn_util.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\common\util_cache.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\common\util_log.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\common\util_sig.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\xa\xa.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\xa\xa_db.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\db-4.4.20\build_win32\..\xa\xa_map.c"
+				>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Modified: python/branches/py3k/PC/VS8.0/_ctypes.vcproj
==============================================================================
--- python/branches/py3k/PC/VS8.0/_ctypes.vcproj	(original)
+++ python/branches/py3k/PC/VS8.0/_ctypes.vcproj	Sat Jun 14 01:34:35 2008
@@ -1,705 +1,705 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="8.00"
-	Name="_ctypes"
-	ProjectGUID="{0E9791DB-593A-465F-98BC-681011311618}"
-	RootNamespace="_ctypes"
-	Keyword="Win32Proj"
-	TargetFrameworkVersion="196613"
-	>
-	<Platforms>
-		<Platform
-			Name="Win32"
-		/>
-		<Platform
-			Name="x64"
-		/>
-	</Platforms>
-	<ToolFiles>
-	</ToolFiles>
-	<Configurations>
-		<Configuration
-			Name="Debug|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd_d.vsprops"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="..\..\Modules\_ctypes\libffi_msvc"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				BaseAddress="0x1D1A0000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Debug|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd_d.vsprops;.\x64.vsprops"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="..\..\Modules\_ctypes\libffi_msvc"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				BaseAddress="0x1D1A0000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="..\..\Modules\_ctypes\libffi_msvc"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalOptions="/EXPORT:DllGetClassObject,PRIVATE /EXPORT:DllCanUnloadNow,PRIVATE"
-				SubSystem="0"
-				BaseAddress="0x1D1A0000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="..\..\Modules\_ctypes\libffi_msvc"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalOptions="/EXPORT:DllGetClassObject,PRIVATE /EXPORT:DllCanUnloadNow,PRIVATE"
-				SubSystem="0"
-				BaseAddress="0x1D1A0000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGInstrument|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\pginstrument.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="..\..\Modules\_ctypes\libffi_msvc"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalOptions="/EXPORT:DllGetClassObject,PRIVATE /EXPORT:DllCanUnloadNow,PRIVATE"
-				SubSystem="0"
-				BaseAddress="0x1D1A0000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGInstrument|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pginstrument.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="..\..\Modules\_ctypes\libffi_msvc"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalOptions="/EXPORT:DllGetClassObject,PRIVATE /EXPORT:DllCanUnloadNow,PRIVATE"
-				SubSystem="0"
-				BaseAddress="0x1D1A0000"
-				TargetMachine="17"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGUpdate|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\pgupdate.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="..\..\Modules\_ctypes\libffi_msvc"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalOptions="/EXPORT:DllGetClassObject,PRIVATE /EXPORT:DllCanUnloadNow,PRIVATE"
-				SubSystem="0"
-				BaseAddress="0x1D1A0000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGUpdate|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pgupdate.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="..\..\Modules\_ctypes\libffi_msvc"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalOptions="/EXPORT:DllGetClassObject,PRIVATE /EXPORT:DllCanUnloadNow,PRIVATE"
-				SubSystem="0"
-				BaseAddress="0x1D1A0000"
-				TargetMachine="17"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<Filter
-			Name="Header Files"
-			>
-			<File
-				RelativePath="..\..\Modules\_ctypes\ctypes.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\_ctypes\ctypes_dlfcn.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\_ctypes\libffi_msvc\ffi.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\_ctypes\libffi_msvc\ffi_common.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\_ctypes\libffi_msvc\fficonfig.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\_ctypes\libffi_msvc\ffitarget.h"
-				>
-			</File>
-		</Filter>
-		<Filter
-			Name="Source Files"
-			>
-			<File
-				RelativePath="..\..\Modules\_ctypes\_ctypes.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\_ctypes\callbacks.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\_ctypes\callproc.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\_ctypes\cfield.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\_ctypes\libffi_msvc\ffi.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\_ctypes\malloc_closure.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\_ctypes\libffi_msvc\prep_cif.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\_ctypes\stgdict.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\_ctypes\libffi_msvc\win32.c"
-				>
-				<FileConfiguration
-					Name="Debug|x64"
-					ExcludedFromBuild="true"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|x64"
-					ExcludedFromBuild="true"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="PGInstrument|x64"
-					ExcludedFromBuild="true"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="PGUpdate|x64"
-					ExcludedFromBuild="true"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-					/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="..\..\Modules\_ctypes\libffi_msvc\win64.asm"
-				>
-				<FileConfiguration
-					Name="Debug|Win32"
-					ExcludedFromBuild="true"
-					>
-					<Tool
-						Name="VCCustomBuildTool"
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Debug|x64"
-					>
-					<Tool
-						Name="VCCustomBuildTool"
-						CommandLine="ml64 /nologo /c /Fo &quot;$(IntDir)\win64.obj&quot; &quot;$(InputPath)&quot;&#x0D;&#x0A;"
-						Outputs="$(IntDir)\win64.obj"
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|Win32"
-					ExcludedFromBuild="true"
-					>
-					<Tool
-						Name="VCCustomBuildTool"
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|x64"
-					>
-					<Tool
-						Name="VCCustomBuildTool"
-						CommandLine="ml64 /nologo /c /Fo &quot;$(IntDir)\win64.obj&quot; &quot;$(InputPath)&quot;&#x0D;&#x0A;"
-						Outputs="$(IntDir)\win64.obj"
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="PGInstrument|Win32"
-					ExcludedFromBuild="true"
-					>
-					<Tool
-						Name="VCCustomBuildTool"
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="PGInstrument|x64"
-					>
-					<Tool
-						Name="VCCustomBuildTool"
-						CommandLine="ml64 /nologo /c /Fo &quot;$(IntDir)\win64.obj&quot; &quot;$(InputPath)&quot;&#x0D;&#x0A;"
-						Outputs="$(IntDir)\win64.obj"
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="PGUpdate|Win32"
-					ExcludedFromBuild="true"
-					>
-					<Tool
-						Name="VCCustomBuildTool"
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="PGUpdate|x64"
-					>
-					<Tool
-						Name="VCCustomBuildTool"
-						CommandLine="ml64 /nologo /c /Fo &quot;$(IntDir)\win64.obj&quot; &quot;$(InputPath)&quot;&#x0D;&#x0A;"
-						Outputs="$(IntDir)\win64.obj"
-					/>
-				</FileConfiguration>
-			</File>
-		</Filter>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="_ctypes"
+	ProjectGUID="{0E9791DB-593A-465F-98BC-681011311618}"
+	RootNamespace="_ctypes"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd_d.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\Modules\_ctypes\libffi_msvc"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				BaseAddress="0x1D1A0000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd_d.vsprops;.\x64.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\Modules\_ctypes\libffi_msvc"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				BaseAddress="0x1D1A0000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\Modules\_ctypes\libffi_msvc"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions="/EXPORT:DllGetClassObject,PRIVATE /EXPORT:DllCanUnloadNow,PRIVATE"
+				SubSystem="0"
+				BaseAddress="0x1D1A0000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\Modules\_ctypes\libffi_msvc"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions="/EXPORT:DllGetClassObject,PRIVATE /EXPORT:DllCanUnloadNow,PRIVATE"
+				SubSystem="0"
+				BaseAddress="0x1D1A0000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\pginstrument.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\Modules\_ctypes\libffi_msvc"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions="/EXPORT:DllGetClassObject,PRIVATE /EXPORT:DllCanUnloadNow,PRIVATE"
+				SubSystem="0"
+				BaseAddress="0x1D1A0000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pginstrument.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\Modules\_ctypes\libffi_msvc"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions="/EXPORT:DllGetClassObject,PRIVATE /EXPORT:DllCanUnloadNow,PRIVATE"
+				SubSystem="0"
+				BaseAddress="0x1D1A0000"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\pgupdate.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\Modules\_ctypes\libffi_msvc"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions="/EXPORT:DllGetClassObject,PRIVATE /EXPORT:DllCanUnloadNow,PRIVATE"
+				SubSystem="0"
+				BaseAddress="0x1D1A0000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pgupdate.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\Modules\_ctypes\libffi_msvc"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions="/EXPORT:DllGetClassObject,PRIVATE /EXPORT:DllCanUnloadNow,PRIVATE"
+				SubSystem="0"
+				BaseAddress="0x1D1A0000"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Header Files"
+			>
+			<File
+				RelativePath="..\..\Modules\_ctypes\ctypes.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_ctypes\ctypes_dlfcn.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_ctypes\libffi_msvc\ffi.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_ctypes\libffi_msvc\ffi_common.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_ctypes\libffi_msvc\fficonfig.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_ctypes\libffi_msvc\ffitarget.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Source Files"
+			>
+			<File
+				RelativePath="..\..\Modules\_ctypes\_ctypes.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_ctypes\callbacks.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_ctypes\callproc.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_ctypes\cfield.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_ctypes\libffi_msvc\ffi.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_ctypes\malloc_closure.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_ctypes\libffi_msvc\prep_cif.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_ctypes\stgdict.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_ctypes\libffi_msvc\win32.c"
+				>
+				<FileConfiguration
+					Name="Debug|x64"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="PGInstrument|x64"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="PGUpdate|x64"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_ctypes\libffi_msvc\win64.asm"
+				>
+				<FileConfiguration
+					Name="Debug|Win32"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="ml64 /nologo /c /Fo &quot;$(IntDir)\win64.obj&quot; &quot;$(InputPath)&quot;&#x0D;&#x0A;"
+						Outputs="$(IntDir)\win64.obj"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|Win32"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="ml64 /nologo /c /Fo &quot;$(IntDir)\win64.obj&quot; &quot;$(InputPath)&quot;&#x0D;&#x0A;"
+						Outputs="$(IntDir)\win64.obj"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="PGInstrument|Win32"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="PGInstrument|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="ml64 /nologo /c /Fo &quot;$(IntDir)\win64.obj&quot; &quot;$(InputPath)&quot;&#x0D;&#x0A;"
+						Outputs="$(IntDir)\win64.obj"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="PGUpdate|Win32"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="PGUpdate|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="ml64 /nologo /c /Fo &quot;$(IntDir)\win64.obj&quot; &quot;$(InputPath)&quot;&#x0D;&#x0A;"
+						Outputs="$(IntDir)\win64.obj"
+					/>
+				</FileConfiguration>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Modified: python/branches/py3k/PC/VS8.0/_ctypes_test.vcproj
==============================================================================
--- python/branches/py3k/PC/VS8.0/_ctypes_test.vcproj	(original)
+++ python/branches/py3k/PC/VS8.0/_ctypes_test.vcproj	Sat Jun 14 01:34:35 2008
@@ -1,521 +1,521 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="8.00"
-	Name="_ctypes_test"
-	ProjectGUID="{9EC7190A-249F-4180-A900-548FDCF3055F}"
-	RootNamespace="_ctypes_test"
-	Keyword="Win32Proj"
-	TargetFrameworkVersion="196613"
-	>
-	<Platforms>
-		<Platform
-			Name="Win32"
-		/>
-		<Platform
-			Name="x64"
-		/>
-	</Platforms>
-	<ToolFiles>
-	</ToolFiles>
-	<Configurations>
-		<Configuration
-			Name="Debug|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd_d.vsprops"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Debug|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd_d.vsprops;.\x64.vsprops"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGInstrument|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\pginstrument.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGInstrument|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pginstrument.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				TargetMachine="17"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGUpdate|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\pgupdate.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGUpdate|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pgupdate.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				TargetMachine="17"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<Filter
-			Name="Header Files"
-			>
-			<File
-				RelativePath="..\..\Modules\_ctypes\_ctypes_test.h"
-				>
-			</File>
-		</Filter>
-		<Filter
-			Name="Source Files"
-			>
-			<File
-				RelativePath="..\..\Modules\_ctypes\_ctypes_test.c"
-				>
-			</File>
-		</Filter>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="_ctypes_test"
+	ProjectGUID="{9EC7190A-249F-4180-A900-548FDCF3055F}"
+	RootNamespace="_ctypes_test"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd_d.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd_d.vsprops;.\x64.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\pginstrument.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pginstrument.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\pgupdate.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pgupdate.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Header Files"
+			>
+			<File
+				RelativePath="..\..\Modules\_ctypes\_ctypes_test.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Source Files"
+			>
+			<File
+				RelativePath="..\..\Modules\_ctypes\_ctypes_test.c"
+				>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Modified: python/branches/py3k/PC/VS8.0/_elementtree.vcproj
==============================================================================
--- python/branches/py3k/PC/VS8.0/_elementtree.vcproj	(original)
+++ python/branches/py3k/PC/VS8.0/_elementtree.vcproj	Sat Jun 14 01:34:35 2008
@@ -1,613 +1,613 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="8.00"
-	Name="_elementtree"
-	ProjectGUID="{17E1E049-C309-4D79-843F-AE483C264AEA}"
-	RootNamespace="_elementtree"
-	Keyword="Win32Proj"
-	TargetFrameworkVersion="196613"
-	>
-	<Platforms>
-		<Platform
-			Name="Win32"
-		/>
-		<Platform
-			Name="x64"
-		/>
-	</Platforms>
-	<ToolFiles>
-	</ToolFiles>
-	<Configurations>
-		<Configuration
-			Name="Debug|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd_d.vsprops"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="..\..\Modules\expat"
-				PreprocessorDefinitions="XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;USE_PYEXPAT_CAPI;XML_STATIC;HAVE_MEMMOVE"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				BaseAddress="0x1D100000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Debug|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd_d.vsprops;.\x64.vsprops"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="..\..\Modules\expat"
-				PreprocessorDefinitions="XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;USE_PYEXPAT_CAPI;XML_STATIC;HAVE_MEMMOVE"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				BaseAddress="0x1D100000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="..\..\Modules\expat"
-				PreprocessorDefinitions="XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;USE_PYEXPAT_CAPI;XML_STATIC;HAVE_MEMMOVE"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				BaseAddress="0x1D100000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="..\..\Modules\expat"
-				PreprocessorDefinitions="XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;USE_PYEXPAT_CAPI;XML_STATIC;HAVE_MEMMOVE"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				BaseAddress="0x1D100000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGInstrument|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\pginstrument.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="..\..\Modules\expat"
-				PreprocessorDefinitions="XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;USE_PYEXPAT_CAPI;XML_STATIC;HAVE_MEMMOVE"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				BaseAddress="0x1D100000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGInstrument|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pginstrument.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="..\..\Modules\expat"
-				PreprocessorDefinitions="XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;USE_PYEXPAT_CAPI;XML_STATIC;HAVE_MEMMOVE"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				BaseAddress="0x1D100000"
-				TargetMachine="17"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGUpdate|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\pgupdate.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="..\..\Modules\expat"
-				PreprocessorDefinitions="XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;USE_PYEXPAT_CAPI;XML_STATIC;HAVE_MEMMOVE"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				BaseAddress="0x1D100000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGUpdate|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pgupdate.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="..\..\Modules\expat"
-				PreprocessorDefinitions="XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;USE_PYEXPAT_CAPI;XML_STATIC;HAVE_MEMMOVE"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				BaseAddress="0x1D100000"
-				TargetMachine="17"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<Filter
-			Name="Header Files"
-			>
-			<File
-				RelativePath="..\..\Modules\expat\ascii.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\expat\asciitab.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\expat\expat.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\expat\expat_config.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\expat\expat_external.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\expat\iasciitab.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\expat\internal.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\expat\latin1tab.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\expat\macconfig.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\expat\nametab.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\expat\pyexpatns.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\expat\utf8tab.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\expat\winconfig.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\expat\xmlrole.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\expat\xmltok.h"
-				>
-			</File>
-		</Filter>
-		<Filter
-			Name="Source Files"
-			>
-			<File
-				RelativePath="..\..\Modules\_elementtree.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\expat\xmlparse.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\expat\xmlrole.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\expat\xmltok.c"
-				>
-			</File>
-		</Filter>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="_elementtree"
+	ProjectGUID="{17E1E049-C309-4D79-843F-AE483C264AEA}"
+	RootNamespace="_elementtree"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd_d.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\Modules\expat"
+				PreprocessorDefinitions="XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;USE_PYEXPAT_CAPI;XML_STATIC;HAVE_MEMMOVE"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				BaseAddress="0x1D100000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd_d.vsprops;.\x64.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\Modules\expat"
+				PreprocessorDefinitions="XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;USE_PYEXPAT_CAPI;XML_STATIC;HAVE_MEMMOVE"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				BaseAddress="0x1D100000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\Modules\expat"
+				PreprocessorDefinitions="XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;USE_PYEXPAT_CAPI;XML_STATIC;HAVE_MEMMOVE"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				BaseAddress="0x1D100000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\Modules\expat"
+				PreprocessorDefinitions="XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;USE_PYEXPAT_CAPI;XML_STATIC;HAVE_MEMMOVE"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				BaseAddress="0x1D100000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\pginstrument.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\Modules\expat"
+				PreprocessorDefinitions="XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;USE_PYEXPAT_CAPI;XML_STATIC;HAVE_MEMMOVE"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				BaseAddress="0x1D100000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pginstrument.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\Modules\expat"
+				PreprocessorDefinitions="XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;USE_PYEXPAT_CAPI;XML_STATIC;HAVE_MEMMOVE"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				BaseAddress="0x1D100000"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\pgupdate.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\Modules\expat"
+				PreprocessorDefinitions="XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;USE_PYEXPAT_CAPI;XML_STATIC;HAVE_MEMMOVE"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				BaseAddress="0x1D100000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pgupdate.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\Modules\expat"
+				PreprocessorDefinitions="XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;USE_PYEXPAT_CAPI;XML_STATIC;HAVE_MEMMOVE"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				BaseAddress="0x1D100000"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Header Files"
+			>
+			<File
+				RelativePath="..\..\Modules\expat\ascii.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\expat\asciitab.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\expat\expat.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\expat\expat_config.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\expat\expat_external.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\expat\iasciitab.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\expat\internal.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\expat\latin1tab.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\expat\macconfig.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\expat\nametab.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\expat\pyexpatns.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\expat\utf8tab.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\expat\winconfig.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\expat\xmlrole.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\expat\xmltok.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Source Files"
+			>
+			<File
+				RelativePath="..\..\Modules\_elementtree.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\expat\xmlparse.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\expat\xmlrole.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\expat\xmltok.c"
+				>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Modified: python/branches/py3k/PC/VS8.0/_hashlib.vcproj
==============================================================================
--- python/branches/py3k/PC/VS8.0/_hashlib.vcproj	(original)
+++ python/branches/py3k/PC/VS8.0/_hashlib.vcproj	Sat Jun 14 01:34:35 2008
@@ -1,545 +1,545 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="8.00"
-	Name="_hashlib"
-	ProjectGUID="{447F05A8-F581-4CAC-A466-5AC7936E207E}"
-	RootNamespace="_hashlib"
-	Keyword="Win32Proj"
-	TargetFrameworkVersion="196613"
-	>
-	<Platforms>
-		<Platform
-			Name="Win32"
-		/>
-		<Platform
-			Name="x64"
-		/>
-	</Platforms>
-	<ToolFiles>
-	</ToolFiles>
-	<Configurations>
-		<Configuration
-			Name="Debug|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd_d.vsprops"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-				CommandLine="cd &quot;$(SolutionDir)&quot;&#x0D;&#x0A;&quot;$(PythonExe)&quot; build_ssl.py Release $(PlatformName) -a&#x0D;&#x0A;"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(opensslDir)\inc32"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-				CommandLine=""
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="ws2_32.lib $(opensslDir)\out32\libeay32.lib $(opensslDir)\out32\ssleay32.lib"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Debug|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd_d.vsprops;.\x64.vsprops"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-				CommandLine="cd &quot;$(SolutionDir)&quot;&#x0D;&#x0A;&quot;$(PythonExe)&quot; build_ssl.py Release $(PlatformName) -a&#x0D;&#x0A;"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(opensslDir)\inc64"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-				CommandLine=""
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="ws2_32.lib $(opensslDir)\out64\libeay32.lib $(opensslDir)\out64\ssleay32.lib"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-				CommandLine="cd &quot;$(SolutionDir)&quot;&#x0D;&#x0A;&quot;$(PythonExe)&quot; build_ssl.py Release $(PlatformName) -a&#x0D;&#x0A;"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(opensslDir)\inc32"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-				CommandLine=""
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="ws2_32.lib $(opensslDir)\out32\libeay32.lib $(opensslDir)\out32\ssleay32.lib"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-				CommandLine="cd &quot;$(SolutionDir)&quot;&#x0D;&#x0A;&quot;$(PythonExe)&quot; build_ssl.py Release $(PlatformName) -a&#x0D;&#x0A;"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(opensslDir)\inc64"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-				CommandLine=""
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="ws2_32.lib $(opensslDir)\out64\libeay32.lib $(opensslDir)\out64\ssleay32.lib"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGInstrument|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\pginstrument.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-				CommandLine="cd &quot;$(SolutionDir)&quot;&#x0D;&#x0A;&quot;$(PythonExe)&quot; build_ssl.py Release $(PlatformName) -a&#x0D;&#x0A;"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(opensslDir)\inc32"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-				CommandLine=""
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="ws2_32.lib $(opensslDir)\out32\libeay32.lib $(opensslDir)\out32\ssleay32.lib"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGInstrument|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pginstrument.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-				CommandLine="cd &quot;$(SolutionDir)&quot;&#x0D;&#x0A;&quot;$(PythonExe)&quot; build_ssl.py Release $(PlatformName) -a&#x0D;&#x0A;"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(opensslDir)\inc64"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-				CommandLine=""
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="ws2_32.lib $(opensslDir)\out64\libeay32.lib $(opensslDir)\out64\ssleay32.lib"
-				TargetMachine="17"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGUpdate|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\pgupdate.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-				CommandLine="cd &quot;$(SolutionDir)&quot;&#x0D;&#x0A;&quot;$(PythonExe)&quot; build_ssl.py Release $(PlatformName) -a&#x0D;&#x0A;"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(opensslDir)\inc32"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-				CommandLine=""
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="ws2_32.lib $(opensslDir)\out32\libeay32.lib $(opensslDir)\out32\ssleay32.lib"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGUpdate|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pgupdate.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-				CommandLine="cd &quot;$(SolutionDir)&quot;&#x0D;&#x0A;&quot;$(PythonExe)&quot; build_ssl.py Release $(PlatformName) -a&#x0D;&#x0A;"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(opensslDir)\inc64"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-				CommandLine=""
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="ws2_32.lib $(opensslDir)\out64\libeay32.lib $(opensslDir)\out64\ssleay32.lib"
-				TargetMachine="17"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<Filter
-			Name="Source Files"
-			>
-			<File
-				RelativePath="..\..\Modules\_hashopenssl.c"
-				>
-			</File>
-		</Filter>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="_hashlib"
+	ProjectGUID="{447F05A8-F581-4CAC-A466-5AC7936E207E}"
+	RootNamespace="_hashlib"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd_d.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+				CommandLine="cd &quot;$(SolutionDir)&quot;&#x0D;&#x0A;&quot;$(PythonExe)&quot; build_ssl.py Release $(PlatformName) -a&#x0D;&#x0A;"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(opensslDir)\inc32"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				CommandLine=""
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ws2_32.lib $(opensslDir)\out32\libeay32.lib $(opensslDir)\out32\ssleay32.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd_d.vsprops;.\x64.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+				CommandLine="cd &quot;$(SolutionDir)&quot;&#x0D;&#x0A;&quot;$(PythonExe)&quot; build_ssl.py Release $(PlatformName) -a&#x0D;&#x0A;"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(opensslDir)\inc64"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				CommandLine=""
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ws2_32.lib $(opensslDir)\out64\libeay32.lib $(opensslDir)\out64\ssleay32.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+				CommandLine="cd &quot;$(SolutionDir)&quot;&#x0D;&#x0A;&quot;$(PythonExe)&quot; build_ssl.py Release $(PlatformName) -a&#x0D;&#x0A;"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(opensslDir)\inc32"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				CommandLine=""
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ws2_32.lib $(opensslDir)\out32\libeay32.lib $(opensslDir)\out32\ssleay32.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+				CommandLine="cd &quot;$(SolutionDir)&quot;&#x0D;&#x0A;&quot;$(PythonExe)&quot; build_ssl.py Release $(PlatformName) -a&#x0D;&#x0A;"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(opensslDir)\inc64"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				CommandLine=""
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ws2_32.lib $(opensslDir)\out64\libeay32.lib $(opensslDir)\out64\ssleay32.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\pginstrument.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+				CommandLine="cd &quot;$(SolutionDir)&quot;&#x0D;&#x0A;&quot;$(PythonExe)&quot; build_ssl.py Release $(PlatformName) -a&#x0D;&#x0A;"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(opensslDir)\inc32"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				CommandLine=""
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ws2_32.lib $(opensslDir)\out32\libeay32.lib $(opensslDir)\out32\ssleay32.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pginstrument.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+				CommandLine="cd &quot;$(SolutionDir)&quot;&#x0D;&#x0A;&quot;$(PythonExe)&quot; build_ssl.py Release $(PlatformName) -a&#x0D;&#x0A;"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(opensslDir)\inc64"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				CommandLine=""
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ws2_32.lib $(opensslDir)\out64\libeay32.lib $(opensslDir)\out64\ssleay32.lib"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\pgupdate.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+				CommandLine="cd &quot;$(SolutionDir)&quot;&#x0D;&#x0A;&quot;$(PythonExe)&quot; build_ssl.py Release $(PlatformName) -a&#x0D;&#x0A;"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(opensslDir)\inc32"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				CommandLine=""
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ws2_32.lib $(opensslDir)\out32\libeay32.lib $(opensslDir)\out32\ssleay32.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pgupdate.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+				CommandLine="cd &quot;$(SolutionDir)&quot;&#x0D;&#x0A;&quot;$(PythonExe)&quot; build_ssl.py Release $(PlatformName) -a&#x0D;&#x0A;"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(opensslDir)\inc64"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				CommandLine=""
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ws2_32.lib $(opensslDir)\out64\libeay32.lib $(opensslDir)\out64\ssleay32.lib"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			>
+			<File
+				RelativePath="..\..\Modules\_hashopenssl.c"
+				>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Modified: python/branches/py3k/PC/VS8.0/_msi.vcproj
==============================================================================
--- python/branches/py3k/PC/VS8.0/_msi.vcproj	(original)
+++ python/branches/py3k/PC/VS8.0/_msi.vcproj	Sat Jun 14 01:34:35 2008
@@ -1,529 +1,529 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="8.00"
-	Name="_msi"
-	ProjectGUID="{31FFC478-7B4A-43E8-9954-8D03E2187E9C}"
-	RootNamespace="_msi"
-	Keyword="Win32Proj"
-	TargetFrameworkVersion="196613"
-	>
-	<Platforms>
-		<Platform
-			Name="Win32"
-		/>
-		<Platform
-			Name="x64"
-		/>
-	</Platforms>
-	<ToolFiles>
-	</ToolFiles>
-	<Configurations>
-		<Configuration
-			Name="Debug|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd_d.vsprops"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="fci.lib msi.lib rpcrt4.lib"
-				BaseAddress="0x1D160000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Debug|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd_d.vsprops;.\x64.vsprops"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="fci.lib msi.lib rpcrt4.lib"
-				BaseAddress="0x1D160000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="fci.lib msi.lib rpcrt4.lib"
-				BaseAddress="0x1D160000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="fci.lib msi.lib rpcrt4.lib"
-				BaseAddress="0x1D160000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGInstrument|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\pginstrument.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="fci.lib msi.lib rpcrt4.lib"
-				BaseAddress="0x1D160000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGInstrument|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pginstrument.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="fci.lib msi.lib rpcrt4.lib"
-				BaseAddress="0x1D160000"
-				TargetMachine="17"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGUpdate|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\pgupdate.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="fci.lib msi.lib rpcrt4.lib"
-				BaseAddress="0x1D160000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGUpdate|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pgupdate.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="fci.lib msi.lib rpcrt4.lib"
-				BaseAddress="0x1D160000"
-				TargetMachine="17"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<Filter
-			Name="Source Files"
-			>
-			<File
-				RelativePath="..\..\PC\_msi.c"
-				>
-			</File>
-		</Filter>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="_msi"
+	ProjectGUID="{31FFC478-7B4A-43E8-9954-8D03E2187E9C}"
+	RootNamespace="_msi"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd_d.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="fci.lib msi.lib rpcrt4.lib"
+				BaseAddress="0x1D160000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd_d.vsprops;.\x64.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="fci.lib msi.lib rpcrt4.lib"
+				BaseAddress="0x1D160000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="fci.lib msi.lib rpcrt4.lib"
+				BaseAddress="0x1D160000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="fci.lib msi.lib rpcrt4.lib"
+				BaseAddress="0x1D160000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\pginstrument.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="fci.lib msi.lib rpcrt4.lib"
+				BaseAddress="0x1D160000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pginstrument.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="fci.lib msi.lib rpcrt4.lib"
+				BaseAddress="0x1D160000"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\pgupdate.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="fci.lib msi.lib rpcrt4.lib"
+				BaseAddress="0x1D160000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pgupdate.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="fci.lib msi.lib rpcrt4.lib"
+				BaseAddress="0x1D160000"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			>
+			<File
+				RelativePath="..\..\PC\_msi.c"
+				>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Modified: python/branches/py3k/PC/VS8.0/_multiprocessing.vcproj
==============================================================================
--- python/branches/py3k/PC/VS8.0/_multiprocessing.vcproj	(original)
+++ python/branches/py3k/PC/VS8.0/_multiprocessing.vcproj	Sat Jun 14 01:34:35 2008
@@ -1,557 +1,557 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="8.00"
-	Name="_multiprocessing"
-	ProjectGUID="{9e48b300-37d1-11dd-8c41-005056c00008}"
-	RootNamespace="_multiprocessing"
-	Keyword="Win32Proj"
-	TargetFrameworkVersion="196613"
-	>
-	<Platforms>
-		<Platform
-			Name="Win32"
-		/>
-		<Platform
-			Name="x64"
-		/>
-	</Platforms>
-	<ToolFiles>
-	</ToolFiles>
-	<Configurations>
-		<Configuration
-			Name="Debug|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd_d.vsprops"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="ws2_32.lib"
-				BaseAddress="0x1e1D0000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Debug|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd_d.vsprops;.\x64.vsprops"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="ws2_32.lib"
-				BaseAddress="0x1e1D0000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="ws2_32.lib"
-				BaseAddress="0x1e1D0000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="ws2_32.lib"
-				BaseAddress="0x1e1D0000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGInstrument|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\pginstrument.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="ws2_32.lib"
-				BaseAddress="0x1e1D0000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGInstrument|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pginstrument.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="ws2_32.lib"
-				BaseAddress="0x1e1D0000"
-				TargetMachine="17"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGUpdate|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\pgupdate.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="ws2_32.lib"
-				BaseAddress="0x1e1D0000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGUpdate|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pgupdate.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="ws2_32.lib"
-				BaseAddress="0x1e1D0000"
-				TargetMachine="17"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<Filter
-			Name="Header Files"
-			>
-			<File
-				RelativePath="..\..\Modules\_multiprocessing\multiprocessing.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\_multiprocessing\connection.h"
-				>
-			</File>
-		</Filter>
-		<Filter
-			Name="Source Files"
-			>
-			<File
-				RelativePath="..\..\Modules\_multiprocessing\multiprocessing.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\_multiprocessing\pipe_connection.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\_multiprocessing\semaphore.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\_multiprocessing\socket_connection.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\_multiprocessing\win32_functions.c"
-				>
-			</File>
-		</Filter>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="_multiprocessing"
+	ProjectGUID="{9e48b300-37d1-11dd-8c41-005056c00008}"
+	RootNamespace="_multiprocessing"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd_d.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ws2_32.lib"
+				BaseAddress="0x1e1D0000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd_d.vsprops;.\x64.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ws2_32.lib"
+				BaseAddress="0x1e1D0000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ws2_32.lib"
+				BaseAddress="0x1e1D0000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ws2_32.lib"
+				BaseAddress="0x1e1D0000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\pginstrument.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ws2_32.lib"
+				BaseAddress="0x1e1D0000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pginstrument.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ws2_32.lib"
+				BaseAddress="0x1e1D0000"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\pgupdate.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ws2_32.lib"
+				BaseAddress="0x1e1D0000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pgupdate.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ws2_32.lib"
+				BaseAddress="0x1e1D0000"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Header Files"
+			>
+			<File
+				RelativePath="..\..\Modules\_multiprocessing\multiprocessing.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_multiprocessing\connection.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Source Files"
+			>
+			<File
+				RelativePath="..\..\Modules\_multiprocessing\multiprocessing.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_multiprocessing\pipe_connection.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_multiprocessing\semaphore.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_multiprocessing\socket_connection.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_multiprocessing\win32_functions.c"
+				>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Modified: python/branches/py3k/PC/VS8.0/_socket.vcproj
==============================================================================
--- python/branches/py3k/PC/VS8.0/_socket.vcproj	(original)
+++ python/branches/py3k/PC/VS8.0/_socket.vcproj	Sat Jun 14 01:34:35 2008
@@ -1,537 +1,537 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="8.00"
-	Name="_socket"
-	ProjectGUID="{86937F53-C189-40EF-8CE8-8759D8E7D480}"
-	RootNamespace="_socket"
-	Keyword="Win32Proj"
-	TargetFrameworkVersion="196613"
-	>
-	<Platforms>
-		<Platform
-			Name="Win32"
-		/>
-		<Platform
-			Name="x64"
-		/>
-	</Platforms>
-	<ToolFiles>
-	</ToolFiles>
-	<Configurations>
-		<Configuration
-			Name="Debug|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd_d.vsprops"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="ws2_32.lib"
-				BaseAddress="0x1e1D0000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Debug|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd_d.vsprops;.\x64.vsprops"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="ws2_32.lib"
-				BaseAddress="0x1e1D0000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="ws2_32.lib"
-				BaseAddress="0x1e1D0000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="ws2_32.lib"
-				BaseAddress="0x1e1D0000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGInstrument|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\pginstrument.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="ws2_32.lib"
-				BaseAddress="0x1e1D0000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGInstrument|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pginstrument.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="ws2_32.lib"
-				BaseAddress="0x1e1D0000"
-				TargetMachine="17"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGUpdate|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\pgupdate.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="ws2_32.lib"
-				BaseAddress="0x1e1D0000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGUpdate|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pgupdate.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="ws2_32.lib"
-				BaseAddress="0x1e1D0000"
-				TargetMachine="17"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<Filter
-			Name="Header Files"
-			>
-			<File
-				RelativePath="..\..\Modules\socketmodule.h"
-				>
-			</File>
-		</Filter>
-		<Filter
-			Name="Source Files"
-			>
-			<File
-				RelativePath="..\..\Modules\socketmodule.c"
-				>
-			</File>
-		</Filter>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="_socket"
+	ProjectGUID="{86937F53-C189-40EF-8CE8-8759D8E7D480}"
+	RootNamespace="_socket"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd_d.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ws2_32.lib"
+				BaseAddress="0x1e1D0000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd_d.vsprops;.\x64.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ws2_32.lib"
+				BaseAddress="0x1e1D0000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ws2_32.lib"
+				BaseAddress="0x1e1D0000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ws2_32.lib"
+				BaseAddress="0x1e1D0000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\pginstrument.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ws2_32.lib"
+				BaseAddress="0x1e1D0000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pginstrument.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ws2_32.lib"
+				BaseAddress="0x1e1D0000"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\pgupdate.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ws2_32.lib"
+				BaseAddress="0x1e1D0000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pgupdate.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ws2_32.lib"
+				BaseAddress="0x1e1D0000"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Header Files"
+			>
+			<File
+				RelativePath="..\..\Modules\socketmodule.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Source Files"
+			>
+			<File
+				RelativePath="..\..\Modules\socketmodule.c"
+				>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Modified: python/branches/py3k/PC/VS8.0/_sqlite3.vcproj
==============================================================================
--- python/branches/py3k/PC/VS8.0/_sqlite3.vcproj	(original)
+++ python/branches/py3k/PC/VS8.0/_sqlite3.vcproj	Sat Jun 14 01:34:35 2008
@@ -1,613 +1,613 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="8.00"
-	Name="_sqlite3"
-	ProjectGUID="{13CECB97-4119-4316-9D42-8534019A5A44}"
-	RootNamespace="_sqlite3"
-	Keyword="Win32Proj"
-	TargetFrameworkVersion="196613"
-	>
-	<Platforms>
-		<Platform
-			Name="Win32"
-		/>
-		<Platform
-			Name="x64"
-		/>
-	</Platforms>
-	<ToolFiles>
-	</ToolFiles>
-	<Configurations>
-		<Configuration
-			Name="Debug|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd_d.vsprops"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="..\..\..\sqlite-source-3.3.4"
-				PreprocessorDefinitions="MODULE_NAME=\&quot;sqlite3\&quot;"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				BaseAddress="0x1e180000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Debug|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd_d.vsprops;.\x64.vsprops"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="..\..\..\sqlite-source-3.3.4"
-				PreprocessorDefinitions="MODULE_NAME=\&quot;sqlite3\&quot;"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				BaseAddress="0x1e180000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="..\..\..\sqlite-source-3.3.4"
-				PreprocessorDefinitions="MODULE_NAME=\&quot;sqlite3\&quot;"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				BaseAddress="0x1e180000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="..\..\..\sqlite-source-3.3.4"
-				PreprocessorDefinitions="MODULE_NAME=\&quot;sqlite3\&quot;"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				BaseAddress="0x1e180000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGInstrument|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\pginstrument.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="..\..\..\sqlite-source-3.3.4"
-				PreprocessorDefinitions="MODULE_NAME=\&quot;sqlite3\&quot;"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				BaseAddress="0x1e180000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGInstrument|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pginstrument.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="..\..\..\sqlite-source-3.3.4"
-				PreprocessorDefinitions="MODULE_NAME=\&quot;sqlite3\&quot;"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				BaseAddress="0x1e180000"
-				TargetMachine="17"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGUpdate|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\pgupdate.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="..\..\..\sqlite-source-3.3.4"
-				PreprocessorDefinitions="MODULE_NAME=\&quot;sqlite3\&quot;"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				BaseAddress="0x1e180000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGUpdate|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pgupdate.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="..\..\..\sqlite-source-3.3.4"
-				PreprocessorDefinitions="MODULE_NAME=\&quot;sqlite3\&quot;"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				BaseAddress="0x1e180000"
-				TargetMachine="17"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<Filter
-			Name="Header Files"
-			>
-			<File
-				RelativePath="..\..\Modules\_sqlite\cache.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\_sqlite\connection.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\_sqlite\cursor.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\_sqlite\microprotocols.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\_sqlite\module.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\_sqlite\prepare_protocol.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\_sqlite\row.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\_sqlite\sqlitecompat.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\_sqlite\statement.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\_sqlite\util.h"
-				>
-			</File>
-		</Filter>
-		<Filter
-			Name="Source Files"
-			>
-			<File
-				RelativePath="..\..\Modules\_sqlite\cache.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\_sqlite\connection.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\_sqlite\cursor.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\_sqlite\microprotocols.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\_sqlite\module.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\_sqlite\prepare_protocol.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\_sqlite\row.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\_sqlite\statement.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\_sqlite\util.c"
-				>
-			</File>
-		</Filter>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="_sqlite3"
+	ProjectGUID="{13CECB97-4119-4316-9D42-8534019A5A44}"
+	RootNamespace="_sqlite3"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd_d.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\..\sqlite-source-3.3.4"
+				PreprocessorDefinitions="MODULE_NAME=\&quot;sqlite3\&quot;"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				BaseAddress="0x1e180000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd_d.vsprops;.\x64.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\..\sqlite-source-3.3.4"
+				PreprocessorDefinitions="MODULE_NAME=\&quot;sqlite3\&quot;"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				BaseAddress="0x1e180000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\..\sqlite-source-3.3.4"
+				PreprocessorDefinitions="MODULE_NAME=\&quot;sqlite3\&quot;"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				BaseAddress="0x1e180000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\..\sqlite-source-3.3.4"
+				PreprocessorDefinitions="MODULE_NAME=\&quot;sqlite3\&quot;"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				BaseAddress="0x1e180000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\pginstrument.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\..\sqlite-source-3.3.4"
+				PreprocessorDefinitions="MODULE_NAME=\&quot;sqlite3\&quot;"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				BaseAddress="0x1e180000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pginstrument.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\..\sqlite-source-3.3.4"
+				PreprocessorDefinitions="MODULE_NAME=\&quot;sqlite3\&quot;"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				BaseAddress="0x1e180000"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\pgupdate.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\..\sqlite-source-3.3.4"
+				PreprocessorDefinitions="MODULE_NAME=\&quot;sqlite3\&quot;"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				BaseAddress="0x1e180000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pgupdate.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\..\sqlite-source-3.3.4"
+				PreprocessorDefinitions="MODULE_NAME=\&quot;sqlite3\&quot;"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				BaseAddress="0x1e180000"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Header Files"
+			>
+			<File
+				RelativePath="..\..\Modules\_sqlite\cache.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_sqlite\connection.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_sqlite\cursor.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_sqlite\microprotocols.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_sqlite\module.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_sqlite\prepare_protocol.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_sqlite\row.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_sqlite\sqlitecompat.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_sqlite\statement.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_sqlite\util.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Source Files"
+			>
+			<File
+				RelativePath="..\..\Modules\_sqlite\cache.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_sqlite\connection.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_sqlite\cursor.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_sqlite\microprotocols.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_sqlite\module.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_sqlite\prepare_protocol.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_sqlite\row.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_sqlite\statement.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_sqlite\util.c"
+				>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Modified: python/branches/py3k/PC/VS8.0/_ssl.vcproj
==============================================================================
--- python/branches/py3k/PC/VS8.0/_ssl.vcproj	(original)
+++ python/branches/py3k/PC/VS8.0/_ssl.vcproj	Sat Jun 14 01:34:35 2008
@@ -1,545 +1,545 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="8.00"
-	Name="_ssl"
-	ProjectGUID="{C6E20F84-3247-4AD6-B051-B073268F73BA}"
-	RootNamespace="_ssl"
-	Keyword="Win32Proj"
-	TargetFrameworkVersion="196613"
-	>
-	<Platforms>
-		<Platform
-			Name="Win32"
-		/>
-		<Platform
-			Name="x64"
-		/>
-	</Platforms>
-	<ToolFiles>
-	</ToolFiles>
-	<Configurations>
-		<Configuration
-			Name="Debug|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd_d.vsprops"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-				CommandLine="cd &quot;$(SolutionDir)&quot;&#x0D;&#x0A;&quot;$(PythonExe)&quot; build_ssl.py Release $(PlatformName) -a&#x0D;&#x0A;"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(opensslDir)\inc32"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-				CommandLine=""
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="ws2_32.lib $(opensslDir)\out32\libeay32.lib $(opensslDir)\out32\ssleay32.lib"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Debug|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd_d.vsprops;.\x64.vsprops"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-				CommandLine="cd &quot;$(SolutionDir)&quot;&#x0D;&#x0A;&quot;$(PythonExe)&quot; build_ssl.py Release $(PlatformName) -a&#x0D;&#x0A;"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(opensslDir)\inc64"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-				CommandLine=""
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="ws2_32.lib $(opensslDir)\out64\libeay32.lib $(opensslDir)\out64\ssleay32.lib"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-				CommandLine="cd &quot;$(SolutionDir)&quot;&#x0D;&#x0A;&quot;$(PythonExe)&quot; build_ssl.py Release $(PlatformName) -a&#x0D;&#x0A;"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(opensslDir)\inc32"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-				CommandLine=""
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="ws2_32.lib $(opensslDir)\out32\libeay32.lib $(opensslDir)\out32\ssleay32.lib"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-				CommandLine="cd &quot;$(SolutionDir)&quot;&#x0D;&#x0A;&quot;$(PythonExe)&quot; build_ssl.py Release $(PlatformName) -a&#x0D;&#x0A;"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(opensslDir)\inc64"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-				CommandLine=""
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="ws2_32.lib $(opensslDir)\out64\libeay32.lib $(opensslDir)\out64\ssleay32.lib"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGInstrument|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\pginstrument.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-				CommandLine="cd &quot;$(SolutionDir)&quot;&#x0D;&#x0A;&quot;$(PythonExe)&quot; build_ssl.py Release $(PlatformName) -a&#x0D;&#x0A;"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(opensslDir)\inc32"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-				CommandLine=""
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="ws2_32.lib $(opensslDir)\out32\libeay32.lib $(opensslDir)\out32\ssleay32.lib"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGInstrument|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pginstrument.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-				CommandLine="cd &quot;$(SolutionDir)&quot;&#x0D;&#x0A;&quot;$(PythonExe)&quot; build_ssl.py Release $(PlatformName) -a&#x0D;&#x0A;"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(opensslDir)\inc64"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-				CommandLine=""
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="ws2_32.lib $(opensslDir)\out64\libeay32.lib $(opensslDir)\out64\ssleay32.lib"
-				TargetMachine="17"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGUpdate|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\pgupdate.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-				CommandLine="cd &quot;$(SolutionDir)&quot;&#x0D;&#x0A;&quot;$(PythonExe)&quot; build_ssl.py Release $(PlatformName) -a&#x0D;&#x0A;"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(opensslDir)\inc32"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-				CommandLine=""
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="ws2_32.lib $(opensslDir)\out32\libeay32.lib $(opensslDir)\out32\ssleay32.lib"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGUpdate|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pgupdate.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-				CommandLine="cd &quot;$(SolutionDir)&quot;&#x0D;&#x0A;&quot;$(PythonExe)&quot; build_ssl.py Release $(PlatformName) -a&#x0D;&#x0A;"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(opensslDir)\inc64"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-				CommandLine=""
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="ws2_32.lib $(opensslDir)\out64\libeay32.lib $(opensslDir)\out64\ssleay32.lib"
-				TargetMachine="17"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<Filter
-			Name="Source Files"
-			>
-			<File
-				RelativePath="..\..\Modules\_ssl.c"
-				>
-			</File>
-		</Filter>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="_ssl"
+	ProjectGUID="{C6E20F84-3247-4AD6-B051-B073268F73BA}"
+	RootNamespace="_ssl"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd_d.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+				CommandLine="cd &quot;$(SolutionDir)&quot;&#x0D;&#x0A;&quot;$(PythonExe)&quot; build_ssl.py Release $(PlatformName) -a&#x0D;&#x0A;"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(opensslDir)\inc32"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				CommandLine=""
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ws2_32.lib $(opensslDir)\out32\libeay32.lib $(opensslDir)\out32\ssleay32.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd_d.vsprops;.\x64.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+				CommandLine="cd &quot;$(SolutionDir)&quot;&#x0D;&#x0A;&quot;$(PythonExe)&quot; build_ssl.py Release $(PlatformName) -a&#x0D;&#x0A;"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(opensslDir)\inc64"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				CommandLine=""
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ws2_32.lib $(opensslDir)\out64\libeay32.lib $(opensslDir)\out64\ssleay32.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+				CommandLine="cd &quot;$(SolutionDir)&quot;&#x0D;&#x0A;&quot;$(PythonExe)&quot; build_ssl.py Release $(PlatformName) -a&#x0D;&#x0A;"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(opensslDir)\inc32"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				CommandLine=""
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ws2_32.lib $(opensslDir)\out32\libeay32.lib $(opensslDir)\out32\ssleay32.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+				CommandLine="cd &quot;$(SolutionDir)&quot;&#x0D;&#x0A;&quot;$(PythonExe)&quot; build_ssl.py Release $(PlatformName) -a&#x0D;&#x0A;"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(opensslDir)\inc64"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				CommandLine=""
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ws2_32.lib $(opensslDir)\out64\libeay32.lib $(opensslDir)\out64\ssleay32.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\pginstrument.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+				CommandLine="cd &quot;$(SolutionDir)&quot;&#x0D;&#x0A;&quot;$(PythonExe)&quot; build_ssl.py Release $(PlatformName) -a&#x0D;&#x0A;"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(opensslDir)\inc32"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				CommandLine=""
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ws2_32.lib $(opensslDir)\out32\libeay32.lib $(opensslDir)\out32\ssleay32.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pginstrument.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+				CommandLine="cd &quot;$(SolutionDir)&quot;&#x0D;&#x0A;&quot;$(PythonExe)&quot; build_ssl.py Release $(PlatformName) -a&#x0D;&#x0A;"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(opensslDir)\inc64"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				CommandLine=""
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ws2_32.lib $(opensslDir)\out64\libeay32.lib $(opensslDir)\out64\ssleay32.lib"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\pgupdate.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+				CommandLine="cd &quot;$(SolutionDir)&quot;&#x0D;&#x0A;&quot;$(PythonExe)&quot; build_ssl.py Release $(PlatformName) -a&#x0D;&#x0A;"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(opensslDir)\inc32"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				CommandLine=""
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ws2_32.lib $(opensslDir)\out32\libeay32.lib $(opensslDir)\out32\ssleay32.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pgupdate.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+				CommandLine="cd &quot;$(SolutionDir)&quot;&#x0D;&#x0A;&quot;$(PythonExe)&quot; build_ssl.py Release $(PlatformName) -a&#x0D;&#x0A;"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(opensslDir)\inc64"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				CommandLine=""
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ws2_32.lib $(opensslDir)\out64\libeay32.lib $(opensslDir)\out64\ssleay32.lib"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			>
+			<File
+				RelativePath="..\..\Modules\_ssl.c"
+				>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Modified: python/branches/py3k/PC/VS8.0/_testcapi.vcproj
==============================================================================
--- python/branches/py3k/PC/VS8.0/_testcapi.vcproj	(original)
+++ python/branches/py3k/PC/VS8.0/_testcapi.vcproj	Sat Jun 14 01:34:35 2008
@@ -1,521 +1,521 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="8.00"
-	Name="_testcapi"
-	ProjectGUID="{6901D91C-6E48-4BB7-9FEC-700C8131DF1D}"
-	RootNamespace="_testcapi"
-	Keyword="Win32Proj"
-	TargetFrameworkVersion="196613"
-	>
-	<Platforms>
-		<Platform
-			Name="Win32"
-		/>
-		<Platform
-			Name="x64"
-		/>
-	</Platforms>
-	<ToolFiles>
-	</ToolFiles>
-	<Configurations>
-		<Configuration
-			Name="Debug|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd_d.vsprops"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				BaseAddress="0x1e1F0000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Debug|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd_d.vsprops;.\x64.vsprops"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				BaseAddress="0x1e1F0000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				BaseAddress="0x1e1F0000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				BaseAddress="0x1e1F0000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGInstrument|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\pginstrument.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				BaseAddress="0x1e1F0000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGInstrument|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pginstrument.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				BaseAddress="0x1e1F0000"
-				TargetMachine="17"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGUpdate|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\pgupdate.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				BaseAddress="0x1e1F0000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGUpdate|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pgupdate.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				BaseAddress="0x1e1F0000"
-				TargetMachine="17"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<Filter
-			Name="Source Files"
-			>
-			<File
-				RelativePath="..\..\Modules\_testcapimodule.c"
-				>
-			</File>
-		</Filter>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="_testcapi"
+	ProjectGUID="{6901D91C-6E48-4BB7-9FEC-700C8131DF1D}"
+	RootNamespace="_testcapi"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd_d.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				BaseAddress="0x1e1F0000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd_d.vsprops;.\x64.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				BaseAddress="0x1e1F0000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				BaseAddress="0x1e1F0000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				BaseAddress="0x1e1F0000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\pginstrument.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				BaseAddress="0x1e1F0000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pginstrument.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				BaseAddress="0x1e1F0000"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\pgupdate.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				BaseAddress="0x1e1F0000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pgupdate.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				BaseAddress="0x1e1F0000"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			>
+			<File
+				RelativePath="..\..\Modules\_testcapimodule.c"
+				>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Modified: python/branches/py3k/PC/VS8.0/_tkinter.vcproj
==============================================================================
--- python/branches/py3k/PC/VS8.0/_tkinter.vcproj	(original)
+++ python/branches/py3k/PC/VS8.0/_tkinter.vcproj	Sat Jun 14 01:34:35 2008
@@ -1,541 +1,541 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="8.00"
-	Name="_tkinter"
-	ProjectGUID="{4946ECAC-2E69-4BF8-A90A-F5136F5094DF}"
-	RootNamespace="_tkinter"
-	Keyword="Win32Proj"
-	TargetFrameworkVersion="196613"
-	>
-	<Platforms>
-		<Platform
-			Name="Win32"
-		/>
-		<Platform
-			Name="x64"
-		/>
-	</Platforms>
-	<ToolFiles>
-	</ToolFiles>
-	<Configurations>
-		<Configuration
-			Name="Debug|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd_d.vsprops"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(tcltkDir)\include"
-				PreprocessorDefinitions="WITH_APPINIT"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="$(tcltkLibDebug)"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Debug|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd_d.vsprops;.\x64.vsprops"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(tcltk64Dir)\include"
-				PreprocessorDefinitions="WITH_APPINIT"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="$(tcltk64LibDebug)"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(tcltkDir)\include"
-				PreprocessorDefinitions="WITH_APPINIT"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="$(tcltkLib)"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(tcltk64Dir)\include"
-				PreprocessorDefinitions="WITH_APPINIT"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="$(tcltk64Lib)"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGInstrument|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\pginstrument.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(tcltkDir)\include"
-				PreprocessorDefinitions="WITH_APPINIT"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="$(tcltkLib)"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGInstrument|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pginstrument.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(tcltk64Dir)\include"
-				PreprocessorDefinitions="WITH_APPINIT"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="$(tcltk64Lib)"
-				TargetMachine="17"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGUpdate|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\pgupdate.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(tcltkDir)\include"
-				PreprocessorDefinitions="WITH_APPINIT"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="$(tcltkLib)"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGUpdate|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pgupdate.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(tcltk64Dir)\include"
-				PreprocessorDefinitions="WITH_APPINIT"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="$(tcltk64Lib)"
-				TargetMachine="17"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<Filter
-			Name="Source Files"
-			>
-			<File
-				RelativePath="..\..\Modules\_tkinter.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\tkappinit.c"
-				>
-			</File>
-		</Filter>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="_tkinter"
+	ProjectGUID="{4946ECAC-2E69-4BF8-A90A-F5136F5094DF}"
+	RootNamespace="_tkinter"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd_d.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(tcltkDir)\include"
+				PreprocessorDefinitions="WITH_APPINIT"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="$(tcltkLibDebug)"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd_d.vsprops;.\x64.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(tcltk64Dir)\include"
+				PreprocessorDefinitions="WITH_APPINIT"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="$(tcltk64LibDebug)"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(tcltkDir)\include"
+				PreprocessorDefinitions="WITH_APPINIT"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="$(tcltkLib)"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(tcltk64Dir)\include"
+				PreprocessorDefinitions="WITH_APPINIT"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="$(tcltk64Lib)"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\pginstrument.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(tcltkDir)\include"
+				PreprocessorDefinitions="WITH_APPINIT"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="$(tcltkLib)"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pginstrument.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(tcltk64Dir)\include"
+				PreprocessorDefinitions="WITH_APPINIT"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="$(tcltk64Lib)"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\pgupdate.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(tcltkDir)\include"
+				PreprocessorDefinitions="WITH_APPINIT"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="$(tcltkLib)"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pgupdate.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(tcltk64Dir)\include"
+				PreprocessorDefinitions="WITH_APPINIT"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="$(tcltk64Lib)"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			>
+			<File
+				RelativePath="..\..\Modules\_tkinter.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\tkappinit.c"
+				>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Modified: python/branches/py3k/PC/VS8.0/bdist_wininst.vcproj
==============================================================================
--- python/branches/py3k/PC/VS8.0/bdist_wininst.vcproj	(original)
+++ python/branches/py3k/PC/VS8.0/bdist_wininst.vcproj	Sat Jun 14 01:34:35 2008
@@ -1,270 +1,270 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="8.00"
-	Name="bdist_wininst"
-	ProjectGUID="{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}"
-	RootNamespace="wininst"
-	TargetFrameworkVersion="131072"
-	>
-	<Platforms>
-		<Platform
-			Name="Win32"
-		/>
-		<Platform
-			Name="x64"
-		/>
-	</Platforms>
-	<ToolFiles>
-	</ToolFiles>
-	<Configurations>
-		<Configuration
-			Name="Release|Win32"
-			OutputDirectory="..\..\lib\distutils\command"
-			ConfigurationType="1"
-			InheritedPropertySheets=".\pyproject.vsprops;.\release.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				PreprocessorDefinitions="NDEBUG"
-				MkTypLibCompatible="true"
-				SuppressStartupBanner="true"
-				TargetEnvironment="1"
-				TypeLibraryName=".\..\..\lib\distutils\command\wininst.tlb"
-				HeaderFileName=""
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="1"
-				InlineFunctionExpansion="1"
-				AdditionalIncludeDirectories="..\..\PC\bdist_wininst;..\..\Include;..\..\Modules\zlib"
-				PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE"
-				StringPooling="true"
-				RuntimeLibrary="2"
-				EnableFunctionLevelLinking="true"
-				WarningLevel="3"
-				SuppressStartupBanner="true"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="NDEBUG"
-				Culture="0"
-				AdditionalIncludeDirectories="..\..\PC;..\..\PC\bdist_wininst;..\..\Include"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="comctl32.lib imagehlp.lib"
-				OutputFile="..\..\lib\distutils\command\wininst-8.0.exe"
-				LinkIncremental="1"
-				SuppressStartupBanner="true"
-				IgnoreDefaultLibraryNames="LIBC"
-				ProgramDatabaseFile="..\..\lib\distutils\command\wininst-8.0.pdb"
-				SubSystem="2"
-				RandomizedBaseAddress="1"
-				DataExecutionPrevention="0"
-				TargetMachine="1"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|x64"
-			OutputDirectory="$(PlatformName)\$(ConfigurationName)"
-			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
-			ConfigurationType="1"
-			InheritedPropertySheets=".\pyproject.vsprops;.\release.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				PreprocessorDefinitions="NDEBUG"
-				MkTypLibCompatible="true"
-				SuppressStartupBanner="true"
-				TargetEnvironment="3"
-				TypeLibraryName=".\..\..\lib\distutils\command\wininst.tlb"
-				HeaderFileName=""
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="1"
-				InlineFunctionExpansion="1"
-				AdditionalIncludeDirectories="..\..\PC\bdist_wininst;..\..\Include;..\..\Modules\zlib"
-				PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE"
-				StringPooling="true"
-				RuntimeLibrary="2"
-				EnableFunctionLevelLinking="true"
-				WarningLevel="3"
-				SuppressStartupBanner="true"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="NDEBUG"
-				Culture="0"
-				AdditionalIncludeDirectories="..\..\PC;..\..\PC\bdist_wininst;..\..\Include"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="comctl32.lib imagehlp.lib"
-				OutputFile="..\..\lib\distutils\command\wininst-8.0-amd64.exe"
-				LinkIncremental="1"
-				SuppressStartupBanner="true"
-				IgnoreDefaultLibraryNames="LIBC"
-				ProgramDatabaseFile="..\..\lib\distutils\command\wininst-8.0-amd64.pdb"
-				SubSystem="2"
-				RandomizedBaseAddress="1"
-				DataExecutionPrevention="0"
-				TargetMachine="17"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<Filter
-			Name="Source Files"
-			Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-			>
-			<File
-				RelativePath="..\..\PC\bdist_wininst\extract.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\PC\bdist_wininst\install.c"
-				>
-			</File>
-			<Filter
-				Name="zlib"
-				>
-				<File
-					RelativePath="..\..\Modules\zlib\adler32.c"
-					>
-				</File>
-				<File
-					RelativePath="..\..\Modules\zlib\crc32.c"
-					>
-				</File>
-				<File
-					RelativePath="..\..\Modules\zlib\inffast.c"
-					>
-				</File>
-				<File
-					RelativePath="..\..\Modules\zlib\inflate.c"
-					>
-				</File>
-				<File
-					RelativePath="..\..\Modules\zlib\inftrees.c"
-					>
-				</File>
-				<File
-					RelativePath="..\..\Modules\zlib\zutil.c"
-					>
-				</File>
-			</Filter>
-		</Filter>
-		<Filter
-			Name="Header Files"
-			Filter="h;hpp;hxx;hm;inl"
-			>
-			<File
-				RelativePath="..\..\PC\bdist_wininst\archive.h"
-				>
-			</File>
-		</Filter>
-		<Filter
-			Name="Resource Files"
-			Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-			>
-			<File
-				RelativePath="..\..\PC\bdist_wininst\install.rc"
-				>
-			</File>
-			<File
-				RelativePath="..\..\PC\bdist_wininst\PythonPowered.bmp"
-				>
-			</File>
-		</Filter>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="bdist_wininst"
+	ProjectGUID="{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}"
+	RootNamespace="wininst"
+	TargetFrameworkVersion="131072"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="..\..\lib\distutils\command"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\pyproject.vsprops;.\release.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				PreprocessorDefinitions="NDEBUG"
+				MkTypLibCompatible="true"
+				SuppressStartupBanner="true"
+				TargetEnvironment="1"
+				TypeLibraryName=".\..\..\lib\distutils\command\wininst.tlb"
+				HeaderFileName=""
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="1"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\..\PC\bdist_wininst;..\..\Include;..\..\Modules\zlib"
+				PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="0"
+				AdditionalIncludeDirectories="..\..\PC;..\..\PC\bdist_wininst;..\..\Include"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="comctl32.lib imagehlp.lib"
+				OutputFile="..\..\lib\distutils\command\wininst-8.0.exe"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				IgnoreDefaultLibraryNames="LIBC"
+				ProgramDatabaseFile="..\..\lib\distutils\command\wininst-8.0.pdb"
+				SubSystem="2"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			OutputDirectory="$(PlatformName)\$(ConfigurationName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\pyproject.vsprops;.\release.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				PreprocessorDefinitions="NDEBUG"
+				MkTypLibCompatible="true"
+				SuppressStartupBanner="true"
+				TargetEnvironment="3"
+				TypeLibraryName=".\..\..\lib\distutils\command\wininst.tlb"
+				HeaderFileName=""
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="1"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\..\PC\bdist_wininst;..\..\Include;..\..\Modules\zlib"
+				PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="0"
+				AdditionalIncludeDirectories="..\..\PC;..\..\PC\bdist_wininst;..\..\Include"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="comctl32.lib imagehlp.lib"
+				OutputFile="..\..\lib\distutils\command\wininst-8.0-amd64.exe"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				IgnoreDefaultLibraryNames="LIBC"
+				ProgramDatabaseFile="..\..\lib\distutils\command\wininst-8.0-amd64.pdb"
+				SubSystem="2"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+			>
+			<File
+				RelativePath="..\..\PC\bdist_wininst\extract.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\PC\bdist_wininst\install.c"
+				>
+			</File>
+			<Filter
+				Name="zlib"
+				>
+				<File
+					RelativePath="..\..\Modules\zlib\adler32.c"
+					>
+				</File>
+				<File
+					RelativePath="..\..\Modules\zlib\crc32.c"
+					>
+				</File>
+				<File
+					RelativePath="..\..\Modules\zlib\inffast.c"
+					>
+				</File>
+				<File
+					RelativePath="..\..\Modules\zlib\inflate.c"
+					>
+				</File>
+				<File
+					RelativePath="..\..\Modules\zlib\inftrees.c"
+					>
+				</File>
+				<File
+					RelativePath="..\..\Modules\zlib\zutil.c"
+					>
+				</File>
+			</Filter>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl"
+			>
+			<File
+				RelativePath="..\..\PC\bdist_wininst\archive.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+			>
+			<File
+				RelativePath="..\..\PC\bdist_wininst\install.rc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\PC\bdist_wininst\PythonPowered.bmp"
+				>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Modified: python/branches/py3k/PC/VS8.0/bz2.vcproj
==============================================================================
--- python/branches/py3k/PC/VS8.0/bz2.vcproj	(original)
+++ python/branches/py3k/PC/VS8.0/bz2.vcproj	Sat Jun 14 01:34:35 2008
@@ -1,545 +1,545 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="8.00"
-	Name="bz2"
-	ProjectGUID="{73FCD2BD-F133-46B7-8EC1-144CD82A59D5}"
-	RootNamespace="bz2"
-	Keyword="Win32Proj"
-	TargetFrameworkVersion="196613"
-	>
-	<Platforms>
-		<Platform
-			Name="Win32"
-		/>
-		<Platform
-			Name="x64"
-		/>
-	</Platforms>
-	<ToolFiles>
-	</ToolFiles>
-	<Configurations>
-		<Configuration
-			Name="Debug|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd_d.vsprops"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(bz2Dir)"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-				Description="Build libbz2"
-				CommandLine="cd $(bz2Dir)&#x0D;&#x0A;if exist $(PlatformName)-Debug\libbz2.lib exit 0&#x0D;&#x0A;if not exist $(PlatformName)-Debug mkdir $(PlatformName)-Debug&#x0D;&#x0A;nmake /nologo /f makefile.msc lib&#x0D;&#x0A;copy libbz2.lib $(PlatformName)-Debug&#x0D;&#x0A;nmake /nologo /f makefile.msc clean&#x0D;&#x0A;"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="$(bz2Dir)\$(PlatformName)-Debug\libbz2.lib"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Debug|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd_d.vsprops;.\x64.vsprops"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(bz2Dir)"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-				Description="Build libbz2"
-				CommandLine="cd $(bz2Dir)&#x0D;&#x0A;if exist $(PlatformName)-Debug\libbz2.lib exit 0&#x0D;&#x0A;if not exist $(PlatformName)-Debug mkdir $(PlatformName)-Debug&#x0D;&#x0A;nmake /nologo /f makefile.msc lib&#x0D;&#x0A;copy libbz2.lib $(PlatformName)-Debug&#x0D;&#x0A;nmake /nologo /f makefile.msc clean&#x0D;&#x0A;"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="$(bz2Dir)\$(PlatformName)-Debug\libbz2.lib"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(bz2Dir)"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-				Description="Build libbz2"
-				CommandLine="cd $(bz2Dir)&#x0D;&#x0A;if exist $(PlatformName)-Release\libbz2.lib exit 0&#x0D;&#x0A;if not exist $(PlatformName)-Release mkdir $(PlatformName)-Release&#x0D;&#x0A;nmake /nologo /f makefile.msc lib&#x0D;&#x0A;copy libbz2.lib $(PlatformName)-Release&#x0D;&#x0A;nmake /nologo /f makefile.msc clean&#x0D;&#x0A;"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="$(bz2Dir)\$(PlatformName)-Release\libbz2.lib"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(bz2Dir)"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-				Description="Build libbz2"
-				CommandLine="cd $(bz2Dir)&#x0D;&#x0A;if exist $(PlatformName)-Release\libbz2.lib exit 0&#x0D;&#x0A;if not exist $(PlatformName)-Release mkdir $(PlatformName)-Release&#x0D;&#x0A;nmake /nologo /f makefile.msc lib&#x0D;&#x0A;copy libbz2.lib $(PlatformName)-Release&#x0D;&#x0A;nmake /nologo /f makefile.msc clean&#x0D;&#x0A;"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="$(bz2Dir)\$(PlatformName)-Release\libbz2.lib"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGInstrument|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\pginstrument.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(bz2Dir)"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-				Description="Build libbz2"
-				CommandLine="cd $(bz2Dir)&#x0D;&#x0A;if exist $(PlatformName)-Release\libbz2.lib exit 0&#x0D;&#x0A;if not exist $(PlatformName)-Release mkdir $(PlatformName)-Release&#x0D;&#x0A;nmake /nologo /f makefile.msc lib&#x0D;&#x0A;copy libbz2.lib $(PlatformName)-Release&#x0D;&#x0A;nmake /nologo /f makefile.msc clean&#x0D;&#x0A;"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="$(bz2Dir)\$(PlatformName)-Release\libbz2.lib"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGInstrument|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pginstrument.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(bz2Dir)"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-				Description="Build libbz2"
-				CommandLine="cd $(bz2Dir)&#x0D;&#x0A;if exist $(PlatformName)-Release\libbz2.lib exit 0&#x0D;&#x0A;if not exist $(PlatformName)-Release mkdir $(PlatformName)-Release&#x0D;&#x0A;nmake /nologo /f makefile.msc lib&#x0D;&#x0A;copy libbz2.lib $(PlatformName)-Release&#x0D;&#x0A;nmake /nologo /f makefile.msc clean&#x0D;&#x0A;"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="$(bz2Dir)\$(PlatformName)-Release\libbz2.lib"
-				TargetMachine="17"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGUpdate|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\pgupdate.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(bz2Dir)"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-				Description="Build libbz2"
-				CommandLine="cd $(bz2Dir)&#x0D;&#x0A;if exist $(PlatformName)-Release\libbz2.lib exit 0&#x0D;&#x0A;if not exist $(PlatformName)-Release mkdir $(PlatformName)-Release&#x0D;&#x0A;nmake /nologo /f makefile.msc lib&#x0D;&#x0A;copy libbz2.lib $(PlatformName)-Release&#x0D;&#x0A;nmake /nologo /f makefile.msc clean&#x0D;&#x0A;"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="$(bz2Dir)\$(PlatformName)-Release\libbz2.lib"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGUpdate|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pgupdate.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(bz2Dir)"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-				Description="Build libbz2"
-				CommandLine="cd $(bz2Dir)&#x0D;&#x0A;if exist $(PlatformName)-Release\libbz2.lib exit 0&#x0D;&#x0A;if not exist $(PlatformName)-Release mkdir $(PlatformName)-Release&#x0D;&#x0A;nmake /nologo /f makefile.msc lib&#x0D;&#x0A;copy libbz2.lib $(PlatformName)-Release&#x0D;&#x0A;nmake /nologo /f makefile.msc clean&#x0D;&#x0A;"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="$(bz2Dir)\$(PlatformName)-Release\libbz2.lib"
-				TargetMachine="17"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<Filter
-			Name="Source Files"
-			>
-			<File
-				RelativePath="..\..\Modules\bz2module.c"
-				>
-			</File>
-		</Filter>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="bz2"
+	ProjectGUID="{73FCD2BD-F133-46B7-8EC1-144CD82A59D5}"
+	RootNamespace="bz2"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd_d.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(bz2Dir)"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				Description="Build libbz2"
+				CommandLine="cd $(bz2Dir)&#x0D;&#x0A;if exist $(PlatformName)-Debug\libbz2.lib exit 0&#x0D;&#x0A;if not exist $(PlatformName)-Debug mkdir $(PlatformName)-Debug&#x0D;&#x0A;nmake /nologo /f makefile.msc lib&#x0D;&#x0A;copy libbz2.lib $(PlatformName)-Debug&#x0D;&#x0A;nmake /nologo /f makefile.msc clean&#x0D;&#x0A;"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="$(bz2Dir)\$(PlatformName)-Debug\libbz2.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd_d.vsprops;.\x64.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(bz2Dir)"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				Description="Build libbz2"
+				CommandLine="cd $(bz2Dir)&#x0D;&#x0A;if exist $(PlatformName)-Debug\libbz2.lib exit 0&#x0D;&#x0A;if not exist $(PlatformName)-Debug mkdir $(PlatformName)-Debug&#x0D;&#x0A;nmake /nologo /f makefile.msc lib&#x0D;&#x0A;copy libbz2.lib $(PlatformName)-Debug&#x0D;&#x0A;nmake /nologo /f makefile.msc clean&#x0D;&#x0A;"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="$(bz2Dir)\$(PlatformName)-Debug\libbz2.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(bz2Dir)"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				Description="Build libbz2"
+				CommandLine="cd $(bz2Dir)&#x0D;&#x0A;if exist $(PlatformName)-Release\libbz2.lib exit 0&#x0D;&#x0A;if not exist $(PlatformName)-Release mkdir $(PlatformName)-Release&#x0D;&#x0A;nmake /nologo /f makefile.msc lib&#x0D;&#x0A;copy libbz2.lib $(PlatformName)-Release&#x0D;&#x0A;nmake /nologo /f makefile.msc clean&#x0D;&#x0A;"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="$(bz2Dir)\$(PlatformName)-Release\libbz2.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(bz2Dir)"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				Description="Build libbz2"
+				CommandLine="cd $(bz2Dir)&#x0D;&#x0A;if exist $(PlatformName)-Release\libbz2.lib exit 0&#x0D;&#x0A;if not exist $(PlatformName)-Release mkdir $(PlatformName)-Release&#x0D;&#x0A;nmake /nologo /f makefile.msc lib&#x0D;&#x0A;copy libbz2.lib $(PlatformName)-Release&#x0D;&#x0A;nmake /nologo /f makefile.msc clean&#x0D;&#x0A;"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="$(bz2Dir)\$(PlatformName)-Release\libbz2.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\pginstrument.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(bz2Dir)"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				Description="Build libbz2"
+				CommandLine="cd $(bz2Dir)&#x0D;&#x0A;if exist $(PlatformName)-Release\libbz2.lib exit 0&#x0D;&#x0A;if not exist $(PlatformName)-Release mkdir $(PlatformName)-Release&#x0D;&#x0A;nmake /nologo /f makefile.msc lib&#x0D;&#x0A;copy libbz2.lib $(PlatformName)-Release&#x0D;&#x0A;nmake /nologo /f makefile.msc clean&#x0D;&#x0A;"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="$(bz2Dir)\$(PlatformName)-Release\libbz2.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pginstrument.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(bz2Dir)"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				Description="Build libbz2"
+				CommandLine="cd $(bz2Dir)&#x0D;&#x0A;if exist $(PlatformName)-Release\libbz2.lib exit 0&#x0D;&#x0A;if not exist $(PlatformName)-Release mkdir $(PlatformName)-Release&#x0D;&#x0A;nmake /nologo /f makefile.msc lib&#x0D;&#x0A;copy libbz2.lib $(PlatformName)-Release&#x0D;&#x0A;nmake /nologo /f makefile.msc clean&#x0D;&#x0A;"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="$(bz2Dir)\$(PlatformName)-Release\libbz2.lib"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\pgupdate.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(bz2Dir)"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				Description="Build libbz2"
+				CommandLine="cd $(bz2Dir)&#x0D;&#x0A;if exist $(PlatformName)-Release\libbz2.lib exit 0&#x0D;&#x0A;if not exist $(PlatformName)-Release mkdir $(PlatformName)-Release&#x0D;&#x0A;nmake /nologo /f makefile.msc lib&#x0D;&#x0A;copy libbz2.lib $(PlatformName)-Release&#x0D;&#x0A;nmake /nologo /f makefile.msc clean&#x0D;&#x0A;"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="$(bz2Dir)\$(PlatformName)-Release\libbz2.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pgupdate.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(bz2Dir)"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				Description="Build libbz2"
+				CommandLine="cd $(bz2Dir)&#x0D;&#x0A;if exist $(PlatformName)-Release\libbz2.lib exit 0&#x0D;&#x0A;if not exist $(PlatformName)-Release mkdir $(PlatformName)-Release&#x0D;&#x0A;nmake /nologo /f makefile.msc lib&#x0D;&#x0A;copy libbz2.lib $(PlatformName)-Release&#x0D;&#x0A;nmake /nologo /f makefile.msc clean&#x0D;&#x0A;"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="$(bz2Dir)\$(PlatformName)-Release\libbz2.lib"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			>
+			<File
+				RelativePath="..\..\Modules\bz2module.c"
+				>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Modified: python/branches/py3k/PC/VS8.0/kill_python.c
==============================================================================
--- python/branches/py3k/PC/VS8.0/kill_python.c	(original)
+++ python/branches/py3k/PC/VS8.0/kill_python.c	Sat Jun 14 01:34:35 2008
@@ -1,178 +1,178 @@
-/*
- * Helper program for killing lingering python[_d].exe processes before
- * building, thus attempting to avoid build failures due to files being
- * locked.
- */
-
-#include <windows.h>
-#include <wchar.h>
-#include <tlhelp32.h>
-#include <stdio.h>
-
-#pragma comment(lib, "psapi")
-
-#ifdef _DEBUG
-#define PYTHON_EXE          (L"python_d.exe")
-#define PYTHON_EXE_LEN      (12)
-#define KILL_PYTHON_EXE     (L"kill_python_d.exe")
-#define KILL_PYTHON_EXE_LEN (17)
-#else
-#define PYTHON_EXE          (L"python.exe")
-#define PYTHON_EXE_LEN      (10)
-#define KILL_PYTHON_EXE     (L"kill_python.exe")
-#define KILL_PYTHON_EXE_LEN (15)
-#endif
-
-int
-main(int argc, char **argv)
-{
-    HANDLE   hp, hsp, hsm; /* process, snapshot processes, snapshot modules */
-    DWORD    dac, our_pid;
-    size_t   len;
-    wchar_t  path[MAX_PATH+1];
-
-    MODULEENTRY32W  me;
-    PROCESSENTRY32W pe;
-
-    me.dwSize = sizeof(MODULEENTRY32W);
-    pe.dwSize = sizeof(PROCESSENTRY32W);
-
-    memset(path, 0, MAX_PATH+1);
-
-    our_pid = GetCurrentProcessId();
-
-    hsm = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, our_pid);
-    if (hsm == INVALID_HANDLE_VALUE) {
-        printf("CreateToolhelp32Snapshot[1] failed: %d\n", GetLastError());
-        return 1;
-    }
-
-    if (!Module32FirstW(hsm, &me)) {
-        printf("Module32FirstW[1] failed: %d\n", GetLastError());
-        CloseHandle(hsm);
-        return 1;
-    }
-
-    /*
-     * Enumerate over the modules for the current process in order to find
-     * kill_process[_d].exe, then take a note of the directory it lives in.
-     */
-    do {
-        if (_wcsnicmp(me.szModule, KILL_PYTHON_EXE, KILL_PYTHON_EXE_LEN))
-            continue;
-
-        len = wcsnlen_s(me.szExePath, MAX_PATH) - KILL_PYTHON_EXE_LEN;
-        wcsncpy_s(path, MAX_PATH+1, me.szExePath, len); 
-
-        break;
-
-    } while (Module32NextW(hsm, &me));
-
-    CloseHandle(hsm);
-
-    if (path == NULL) {
-        printf("failed to discern directory of running process\n");
-        return 1;
-    }
-
-    /*
-     * Take a snapshot of system processes.  Enumerate over the snapshot,
-     * looking for python processes.  When we find one, verify it lives
-     * in the same directory we live in.  If it does, kill it.  If we're
-     * unable to kill it, treat this as a fatal error and return 1.
-     * 
-     * The rationale behind this is that we're called at the start of the 
-     * build process on the basis that we'll take care of killing any
-     * running instances, such that the build won't encounter permission
-     * denied errors during linking. If we can't kill one of the processes,
-     * we can't provide this assurance, and the build shouldn't start.
-     */
-
-    hsp = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
-    if (hsp == INVALID_HANDLE_VALUE) {
-        printf("CreateToolhelp32Snapshot[2] failed: %d\n", GetLastError());
-        return 1;
-    }
-
-    if (!Process32FirstW(hsp, &pe)) {
-        printf("Process32FirstW failed: %d\n", GetLastError());
-        CloseHandle(hsp);
-        return 1;
-    }
-
-    dac = PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_TERMINATE;
-    do {
-
-        /*
-         * XXX TODO: if we really wanted to be fancy, we could check the 
-         * modules for all processes (not just the python[_d].exe ones)
-         * and see if any of our DLLs are loaded (i.e. python30[_d].dll),
-         * as that would also inhibit our ability to rebuild the solution.
-         * Not worth loosing sleep over though; for now, a simple check 
-         * for just the python executable should be sufficient.
-         */
-
-        if (_wcsnicmp(pe.szExeFile, PYTHON_EXE, PYTHON_EXE_LEN))
-            /* This isn't a python process. */
-            continue;
-
-        /* It's a python process, so figure out which directory it's in... */
-        hsm = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pe.th32ProcessID);
-        if (hsm == INVALID_HANDLE_VALUE)
-            /* 
-             * If our module snapshot fails (which will happen if we don't own
-             * the process), just ignore it and continue.  (It seems different
-             * versions of Windows return different values for GetLastError()
-             * in this situation; it's easier to just ignore it and move on vs.
-             * stopping the build for what could be a false positive.)
-             */
-             continue;
-
-        if (!Module32FirstW(hsm, &me)) {
-            printf("Module32FirstW[2] failed: %d\n", GetLastError());
-            CloseHandle(hsp);
-            CloseHandle(hsm);
-            return 1;
-        }
-
-        do {
-            if (_wcsnicmp(me.szModule, PYTHON_EXE, PYTHON_EXE_LEN))
-                /* Wrong module, we're looking for python[_d].exe... */
-                continue;
-
-            if (_wcsnicmp(path, me.szExePath, len))
-                /* Process doesn't live in our directory. */
-                break;
-
-            /* Python process residing in the right directory, kill it!  */
-            hp = OpenProcess(dac, FALSE, pe.th32ProcessID);
-            if (!hp) {
-                printf("OpenProcess failed: %d\n", GetLastError());
-                CloseHandle(hsp);
-                CloseHandle(hsm);
-                return 1;
-            }
-
-            if (!TerminateProcess(hp, 1)) {
-                printf("TerminateProcess failed: %d\n", GetLastError());
-                CloseHandle(hsp);
-                CloseHandle(hsm);
-                CloseHandle(hp);
-                return 1;
-            }
-
-            CloseHandle(hp);
-            break;
-
-        } while (Module32NextW(hsm, &me));
-
-        CloseHandle(hsm);
-
-    } while (Process32NextW(hsp, &pe));
-
-    CloseHandle(hsp);
-
-    return 0;
-}
-
-/* vi: set ts=8 sw=4 sts=4 expandtab */
+/*
+ * Helper program for killing lingering python[_d].exe processes before
+ * building, thus attempting to avoid build failures due to files being
+ * locked.
+ */
+
+#include <windows.h>
+#include <wchar.h>
+#include <tlhelp32.h>
+#include <stdio.h>
+
+#pragma comment(lib, "psapi")
+
+#ifdef _DEBUG
+#define PYTHON_EXE          (L"python_d.exe")
+#define PYTHON_EXE_LEN      (12)
+#define KILL_PYTHON_EXE     (L"kill_python_d.exe")
+#define KILL_PYTHON_EXE_LEN (17)
+#else
+#define PYTHON_EXE          (L"python.exe")
+#define PYTHON_EXE_LEN      (10)
+#define KILL_PYTHON_EXE     (L"kill_python.exe")
+#define KILL_PYTHON_EXE_LEN (15)
+#endif
+
+int
+main(int argc, char **argv)
+{
+    HANDLE   hp, hsp, hsm; /* process, snapshot processes, snapshot modules */
+    DWORD    dac, our_pid;
+    size_t   len;
+    wchar_t  path[MAX_PATH+1];
+
+    MODULEENTRY32W  me;
+    PROCESSENTRY32W pe;
+
+    me.dwSize = sizeof(MODULEENTRY32W);
+    pe.dwSize = sizeof(PROCESSENTRY32W);
+
+    memset(path, 0, MAX_PATH+1);
+
+    our_pid = GetCurrentProcessId();
+
+    hsm = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, our_pid);
+    if (hsm == INVALID_HANDLE_VALUE) {
+        printf("CreateToolhelp32Snapshot[1] failed: %d\n", GetLastError());
+        return 1;
+    }
+
+    if (!Module32FirstW(hsm, &me)) {
+        printf("Module32FirstW[1] failed: %d\n", GetLastError());
+        CloseHandle(hsm);
+        return 1;
+    }
+
+    /*
+     * Enumerate over the modules for the current process in order to find
+     * kill_process[_d].exe, then take a note of the directory it lives in.
+     */
+    do {
+        if (_wcsnicmp(me.szModule, KILL_PYTHON_EXE, KILL_PYTHON_EXE_LEN))
+            continue;
+
+        len = wcsnlen_s(me.szExePath, MAX_PATH) - KILL_PYTHON_EXE_LEN;
+        wcsncpy_s(path, MAX_PATH+1, me.szExePath, len); 
+
+        break;
+
+    } while (Module32NextW(hsm, &me));
+
+    CloseHandle(hsm);
+
+    if (path == NULL) {
+        printf("failed to discern directory of running process\n");
+        return 1;
+    }
+
+    /*
+     * Take a snapshot of system processes.  Enumerate over the snapshot,
+     * looking for python processes.  When we find one, verify it lives
+     * in the same directory we live in.  If it does, kill it.  If we're
+     * unable to kill it, treat this as a fatal error and return 1.
+     * 
+     * The rationale behind this is that we're called at the start of the 
+     * build process on the basis that we'll take care of killing any
+     * running instances, such that the build won't encounter permission
+     * denied errors during linking. If we can't kill one of the processes,
+     * we can't provide this assurance, and the build shouldn't start.
+     */
+
+    hsp = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
+    if (hsp == INVALID_HANDLE_VALUE) {
+        printf("CreateToolhelp32Snapshot[2] failed: %d\n", GetLastError());
+        return 1;
+    }
+
+    if (!Process32FirstW(hsp, &pe)) {
+        printf("Process32FirstW failed: %d\n", GetLastError());
+        CloseHandle(hsp);
+        return 1;
+    }
+
+    dac = PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_TERMINATE;
+    do {
+
+        /*
+         * XXX TODO: if we really wanted to be fancy, we could check the 
+         * modules for all processes (not just the python[_d].exe ones)
+         * and see if any of our DLLs are loaded (i.e. python30[_d].dll),
+         * as that would also inhibit our ability to rebuild the solution.
+         * Not worth loosing sleep over though; for now, a simple check 
+         * for just the python executable should be sufficient.
+         */
+
+        if (_wcsnicmp(pe.szExeFile, PYTHON_EXE, PYTHON_EXE_LEN))
+            /* This isn't a python process. */
+            continue;
+
+        /* It's a python process, so figure out which directory it's in... */
+        hsm = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pe.th32ProcessID);
+        if (hsm == INVALID_HANDLE_VALUE)
+            /* 
+             * If our module snapshot fails (which will happen if we don't own
+             * the process), just ignore it and continue.  (It seems different
+             * versions of Windows return different values for GetLastError()
+             * in this situation; it's easier to just ignore it and move on vs.
+             * stopping the build for what could be a false positive.)
+             */
+             continue;
+
+        if (!Module32FirstW(hsm, &me)) {
+            printf("Module32FirstW[2] failed: %d\n", GetLastError());
+            CloseHandle(hsp);
+            CloseHandle(hsm);
+            return 1;
+        }
+
+        do {
+            if (_wcsnicmp(me.szModule, PYTHON_EXE, PYTHON_EXE_LEN))
+                /* Wrong module, we're looking for python[_d].exe... */
+                continue;
+
+            if (_wcsnicmp(path, me.szExePath, len))
+                /* Process doesn't live in our directory. */
+                break;
+
+            /* Python process residing in the right directory, kill it!  */
+            hp = OpenProcess(dac, FALSE, pe.th32ProcessID);
+            if (!hp) {
+                printf("OpenProcess failed: %d\n", GetLastError());
+                CloseHandle(hsp);
+                CloseHandle(hsm);
+                return 1;
+            }
+
+            if (!TerminateProcess(hp, 1)) {
+                printf("TerminateProcess failed: %d\n", GetLastError());
+                CloseHandle(hsp);
+                CloseHandle(hsm);
+                CloseHandle(hp);
+                return 1;
+            }
+
+            CloseHandle(hp);
+            break;
+
+        } while (Module32NextW(hsm, &me));
+
+        CloseHandle(hsm);
+
+    } while (Process32NextW(hsp, &pe));
+
+    CloseHandle(hsp);
+
+    return 0;
+}
+
+/* vi: set ts=8 sw=4 sts=4 expandtab */

Modified: python/branches/py3k/PC/VS8.0/kill_python.vcproj
==============================================================================
--- python/branches/py3k/PC/VS8.0/kill_python.vcproj	(original)
+++ python/branches/py3k/PC/VS8.0/kill_python.vcproj	Sat Jun 14 01:34:35 2008
@@ -1,279 +1,279 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="8.00"
-	Name="kill_python"
-	ProjectGUID="{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}"
-	RootNamespace="kill_python"
-	Keyword="Win32Proj"
-	TargetFrameworkVersion="196613"
-	>
-	<Platforms>
-		<Platform
-			Name="Win32"
-		/>
-		<Platform
-			Name="x64"
-		/>
-	</Platforms>
-	<ToolFiles>
-	</ToolFiles>
-	<Configurations>
-		<Configuration
-			Name="Debug|Win32"
-			ConfigurationType="1"
-			InheritedPropertySheets=".\pyproject.vsprops;.\debug.vsprops"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				OutputFile="$(OutDir)\$(ProjectName)_d.exe"
-				SubSystem="1"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Debug|x64"
-			ConfigurationType="1"
-			InheritedPropertySheets=".\pyproject.vsprops;.\debug.vsprops;.\x64.vsprops"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				OutputFile="$(OutDir)\$(ProjectName)_d.exe"
-				SubSystem="1"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|Win32"
-			ConfigurationType="1"
-			InheritedPropertySheets=".\pyproject.vsprops;.\release.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				SubSystem="1"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|x64"
-			ConfigurationType="1"
-			InheritedPropertySheets=".\pyproject.vsprops;.\release.vsprops;.\x64.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				SubSystem="1"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<Filter
-			Name="Source Files"
-			>
-			<File
-				RelativePath=".\kill_python.c"
-				>
-			</File>
-		</Filter>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="kill_python"
+	ProjectGUID="{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}"
+	RootNamespace="kill_python"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\pyproject.vsprops;.\debug.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\$(ProjectName)_d.exe"
+				SubSystem="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\pyproject.vsprops;.\debug.vsprops;.\x64.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\$(ProjectName)_d.exe"
+				SubSystem="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\pyproject.vsprops;.\release.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				SubSystem="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\pyproject.vsprops;.\release.vsprops;.\x64.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				SubSystem="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			>
+			<File
+				RelativePath=".\kill_python.c"
+				>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Modified: python/branches/py3k/PC/VS8.0/make_buildinfo.vcproj
==============================================================================
--- python/branches/py3k/PC/VS8.0/make_buildinfo.vcproj	(original)
+++ python/branches/py3k/PC/VS8.0/make_buildinfo.vcproj	Sat Jun 14 01:34:35 2008
@@ -1,162 +1,162 @@
-<?xml version="1.0" encoding="windows-1250"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="8.00"
-	Name="make_buildinfo"
-	ProjectGUID="{C73F0EC1-358B-4177-940F-0846AC8B04CD}"
-	RootNamespace="make_buildinfo"
-	Keyword="Win32Proj"
-	TargetFrameworkVersion="131072"
-	>
-	<Platforms>
-		<Platform
-			Name="Win32"
-		/>
-		<Platform
-			Name="x64"
-		/>
-	</Platforms>
-	<ToolFiles>
-	</ToolFiles>
-	<Configurations>
-		<Configuration
-			Name="Release|Win32"
-			ConfigurationType="1"
-			InheritedPropertySheets=".\pyproject.vsprops;.\release.vsprops"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="0"
-				InlineFunctionExpansion="1"
-				PreprocessorDefinitions="_CONSOLE"
-				RuntimeLibrary="0"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				OutputFile="$(OutDir)/make_buildinfo.exe"
-				ProgramDatabaseFile="$(TargetDir)$(TargetName).pdb"
-				SubSystem="1"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|x64"
-			ConfigurationType="1"
-			InheritedPropertySheets=".\pyproject.vsprops;.\x64.vsprops;.\release.vsprops"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				PreprocessorDefinitions="_CONSOLE"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<Filter
-			Name="Source Files"
-			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
-			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
-			>
-			<File
-				RelativePath=".\make_buildinfo.c"
-				>
-			</File>
-		</Filter>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
+<?xml version="1.0" encoding="windows-1250"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="make_buildinfo"
+	ProjectGUID="{C73F0EC1-358B-4177-940F-0846AC8B04CD}"
+	RootNamespace="make_buildinfo"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="131072"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Release|Win32"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\pyproject.vsprops;.\release.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				InlineFunctionExpansion="1"
+				PreprocessorDefinitions="_CONSOLE"
+				RuntimeLibrary="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)/make_buildinfo.exe"
+				ProgramDatabaseFile="$(TargetDir)$(TargetName).pdb"
+				SubSystem="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\pyproject.vsprops;.\x64.vsprops;.\release.vsprops"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				PreprocessorDefinitions="_CONSOLE"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+			>
+			<File
+				RelativePath=".\make_buildinfo.c"
+				>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Modified: python/branches/py3k/PC/VS8.0/make_versioninfo.vcproj
==============================================================================
--- python/branches/py3k/PC/VS8.0/make_versioninfo.vcproj	(original)
+++ python/branches/py3k/PC/VS8.0/make_versioninfo.vcproj	Sat Jun 14 01:34:35 2008
@@ -1,324 +1,324 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="8.00"
-	Name="make_versioninfo"
-	ProjectGUID="{F0E0541E-F17D-430B-97C4-93ADF0DD284E}"
-	RootNamespace="make_versioninfo"
-	TargetFrameworkVersion="131072"
-	>
-	<Platforms>
-		<Platform
-			Name="Win32"
-		/>
-		<Platform
-			Name="x64"
-		/>
-	</Platforms>
-	<ToolFiles>
-	</ToolFiles>
-	<Configurations>
-		<Configuration
-			Name="Release|Win32"
-			ConfigurationType="1"
-			InheritedPropertySheets=".\pyproject.vsprops;.\release.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="2"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-				Description="Build PC/pythonnt_rc(_d).h"
-				CommandLine="cd $(SolutionDir)&#x0D;&#x0A;make_versioninfo.exe &gt; ..\..\PC\pythonnt_rc.h&#x0D;&#x0A;"
-				Outputs="$(SolutionDir)..\..\PC\pythonnt_rc.h"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="2"
-				InlineFunctionExpansion="1"
-				EnableIntrinsicFunctions="true"
-				AdditionalIncludeDirectories=""
-				PreprocessorDefinitions="_CONSOLE"
-				StringPooling="true"
-				RuntimeLibrary="2"
-				EnableFunctionLevelLinking="true"
-				CompileAs="0"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				OutputFile="$(SolutionDir)make_versioninfo.exe"
-				ProgramDatabaseFile="$(TargetDir)$(TargetName).pdb"
-				SubSystem="1"
-				BaseAddress="0x1d000000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-				CommandLine="cd $(SolutionDir)&#x0D;&#x0A;make_versioninfo.exe &gt; ..\..\PC\python_nt.h&#x0D;&#x0A;"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|x64"
-			ConfigurationType="1"
-			InheritedPropertySheets=".\pyproject.vsprops;.\x64.vsprops;.\release.vsprops"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-				Description="Build PC/pythonnt_rc(_d).h"
-				CommandLine="cd $(SolutionDir)&#x0D;&#x0A;make_versioninfo.exe &gt; ..\..\PC\pythonnt_rc.h&#x0D;&#x0A;"
-				Outputs="$(SolutionDir)..\..\PC\pythonnt_rc.h"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="2"
-				InlineFunctionExpansion="1"
-				EnableIntrinsicFunctions="true"
-				PreprocessorDefinitions="_CONSOLE"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				OutputFile="$(SolutionDir)make_versioninfo.exe"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-				CommandLine="cd $(SolutionDir)&#x0D;&#x0A;make_versioninfo.exe &gt; ..\..\PC\python_nt.h&#x0D;&#x0A;"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Debug|Win32"
-			ConfigurationType="1"
-			InheritedPropertySheets=".\pyproject.vsprops;.\debug.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-				Description="Build PC/pythonnt_rc(_d).h"
-				CommandLine="cd $(SolutionDir)&#x0D;&#x0A;make_versioninfo_d.exe &gt; ..\..\PC\pythonnt_rc_d.h&#x0D;&#x0A;"
-				Outputs="$(SolutionDir)..\..\PC\pythonnt_rc_d.h"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="0"
-				InlineFunctionExpansion="1"
-				EnableIntrinsicFunctions="false"
-				AdditionalIncludeDirectories=""
-				PreprocessorDefinitions="_CONSOLE"
-				StringPooling="true"
-				RuntimeLibrary="2"
-				EnableFunctionLevelLinking="true"
-				CompileAs="0"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				OutputFile="$(SolutionDir)make_versioninfo_d.exe"
-				ProgramDatabaseFile="$(TargetDir)$(TargetName).pdb"
-				SubSystem="1"
-				BaseAddress="0x1d000000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-				CommandLine="cd $(SolutionDir)&#x0D;&#x0A;make_versioninfo_d.exe &gt; ..\..\PC\python_nt_d.h&#x0D;&#x0A;"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Debug|x64"
-			ConfigurationType="1"
-			InheritedPropertySheets=".\pyproject.vsprops;.\x64.vsprops;.\debug.vsprops"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-				Description="Build PC/pythonnt_rc(_d).h"
-				CommandLine="cd $(SolutionDir)&#x0D;&#x0A;make_versioninfo_d.exe &gt; ..\..\PC\pythonnt_rc_d.h&#x0D;&#x0A;"
-				Outputs="$(SolutionDir)..\..\PC\pythonnt_rc_d.h"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="0"
-				InlineFunctionExpansion="1"
-				EnableIntrinsicFunctions="false"
-				PreprocessorDefinitions="_CONSOLE"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				OutputFile="$(SolutionDir)make_versioninfo_d.exe"
-				TargetMachine="17"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-				CommandLine="cd $(SolutionDir)&#x0D;&#x0A;make_versioninfo_d.exe &gt; ..\..\PC\python_nt_d.h&#x0D;&#x0A;"
-			/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<Filter
-			Name="Source Files"
-			>
-			<File
-				RelativePath="..\..\PC\make_versioninfo.c"
-				>
-			</File>
-		</Filter>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="make_versioninfo"
+	ProjectGUID="{F0E0541E-F17D-430B-97C4-93ADF0DD284E}"
+	RootNamespace="make_versioninfo"
+	TargetFrameworkVersion="131072"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Release|Win32"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\pyproject.vsprops;.\release.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+				Description="Build PC/pythonnt_rc(_d).h"
+				CommandLine="cd $(SolutionDir)&#x0D;&#x0A;make_versioninfo.exe &gt; ..\..\PC\pythonnt_rc.h&#x0D;&#x0A;"
+				Outputs="$(SolutionDir)..\..\PC\pythonnt_rc.h"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				EnableIntrinsicFunctions="true"
+				AdditionalIncludeDirectories=""
+				PreprocessorDefinitions="_CONSOLE"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(SolutionDir)make_versioninfo.exe"
+				ProgramDatabaseFile="$(TargetDir)$(TargetName).pdb"
+				SubSystem="1"
+				BaseAddress="0x1d000000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+				CommandLine="cd $(SolutionDir)&#x0D;&#x0A;make_versioninfo.exe &gt; ..\..\PC\python_nt.h&#x0D;&#x0A;"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\pyproject.vsprops;.\x64.vsprops;.\release.vsprops"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+				Description="Build PC/pythonnt_rc(_d).h"
+				CommandLine="cd $(SolutionDir)&#x0D;&#x0A;make_versioninfo.exe &gt; ..\..\PC\pythonnt_rc.h&#x0D;&#x0A;"
+				Outputs="$(SolutionDir)..\..\PC\pythonnt_rc.h"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				EnableIntrinsicFunctions="true"
+				PreprocessorDefinitions="_CONSOLE"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(SolutionDir)make_versioninfo.exe"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+				CommandLine="cd $(SolutionDir)&#x0D;&#x0A;make_versioninfo.exe &gt; ..\..\PC\python_nt.h&#x0D;&#x0A;"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|Win32"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\pyproject.vsprops;.\debug.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+				Description="Build PC/pythonnt_rc(_d).h"
+				CommandLine="cd $(SolutionDir)&#x0D;&#x0A;make_versioninfo_d.exe &gt; ..\..\PC\pythonnt_rc_d.h&#x0D;&#x0A;"
+				Outputs="$(SolutionDir)..\..\PC\pythonnt_rc_d.h"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				InlineFunctionExpansion="1"
+				EnableIntrinsicFunctions="false"
+				AdditionalIncludeDirectories=""
+				PreprocessorDefinitions="_CONSOLE"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(SolutionDir)make_versioninfo_d.exe"
+				ProgramDatabaseFile="$(TargetDir)$(TargetName).pdb"
+				SubSystem="1"
+				BaseAddress="0x1d000000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+				CommandLine="cd $(SolutionDir)&#x0D;&#x0A;make_versioninfo_d.exe &gt; ..\..\PC\python_nt_d.h&#x0D;&#x0A;"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\pyproject.vsprops;.\x64.vsprops;.\debug.vsprops"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+				Description="Build PC/pythonnt_rc(_d).h"
+				CommandLine="cd $(SolutionDir)&#x0D;&#x0A;make_versioninfo_d.exe &gt; ..\..\PC\pythonnt_rc_d.h&#x0D;&#x0A;"
+				Outputs="$(SolutionDir)..\..\PC\pythonnt_rc_d.h"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				InlineFunctionExpansion="1"
+				EnableIntrinsicFunctions="false"
+				PreprocessorDefinitions="_CONSOLE"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(SolutionDir)make_versioninfo_d.exe"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+				CommandLine="cd $(SolutionDir)&#x0D;&#x0A;make_versioninfo_d.exe &gt; ..\..\PC\python_nt_d.h&#x0D;&#x0A;"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			>
+			<File
+				RelativePath="..\..\PC\make_versioninfo.c"
+				>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Modified: python/branches/py3k/PC/VS8.0/pcbuild.sln
==============================================================================
--- python/branches/py3k/PC/VS8.0/pcbuild.sln	(original)
+++ python/branches/py3k/PC/VS8.0/pcbuild.sln	Sat Jun 14 01:34:35 2008
@@ -1,581 +1,581 @@
-Microsoft Visual Studio Solution File, Format Version 9.00
-# Visual Studio 2005
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "python", "python.vcproj", "{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}"
-	ProjectSection(ProjectDependencies) = postProject
-		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
-		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058} = {E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "make_versioninfo", "make_versioninfo.vcproj", "{F0E0541E-F17D-430B-97C4-93ADF0DD284E}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pythoncore", "pythoncore.vcproj", "{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}"
-	ProjectSection(ProjectDependencies) = postProject
-		{F0E0541E-F17D-430B-97C4-93ADF0DD284E} = {F0E0541E-F17D-430B-97C4-93ADF0DD284E}
-		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31} = {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}
-		{C73F0EC1-358B-4177-940F-0846AC8B04CD} = {C73F0EC1-358B-4177-940F-0846AC8B04CD}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pythonw", "pythonw.vcproj", "{F4229CC3-873C-49AE-9729-DD308ED4CD4A}"
-	ProjectSection(ProjectDependencies) = postProject
-		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "w9xpopen", "w9xpopen.vcproj", "{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}"
-	ProjectSection(ProjectDependencies) = postProject
-		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31} = {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "make_buildinfo", "make_buildinfo.vcproj", "{C73F0EC1-358B-4177-940F-0846AC8B04CD}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{553EC33E-9816-4996-A660-5D6186A0B0B3}"
-	ProjectSection(SolutionItems) = preProject
-		..\..\Modules\getbuildinfo.c = ..\..\Modules\getbuildinfo.c
-		readme.txt = readme.txt
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "winsound", "winsound.vcproj", "{28B5D777-DDF2-4B6B-B34F-31D938813856}"
-	ProjectSection(ProjectDependencies) = postProject
-		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_bsddb", "_bsddb.vcproj", "{B4D38F3F-68FB-42EC-A45D-E00657BB3627}"
-	ProjectSection(ProjectDependencies) = postProject
-		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31} = {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}
-		{62172C7D-B39E-409A-B352-370FF5098C19} = {62172C7D-B39E-409A-B352-370FF5098C19}
-		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_ctypes", "_ctypes.vcproj", "{0E9791DB-593A-465F-98BC-681011311618}"
-	ProjectSection(ProjectDependencies) = postProject
-		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_ctypes_test", "_ctypes_test.vcproj", "{9EC7190A-249F-4180-A900-548FDCF3055F}"
-	ProjectSection(ProjectDependencies) = postProject
-		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_elementtree", "_elementtree.vcproj", "{17E1E049-C309-4D79-843F-AE483C264AEA}"
-	ProjectSection(ProjectDependencies) = postProject
-		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_msi", "_msi.vcproj", "{31FFC478-7B4A-43E8-9954-8D03E2187E9C}"
-	ProjectSection(ProjectDependencies) = postProject
-		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_socket", "_socket.vcproj", "{86937F53-C189-40EF-8CE8-8759D8E7D480}"
-	ProjectSection(ProjectDependencies) = postProject
-		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_sqlite3", "_sqlite3.vcproj", "{13CECB97-4119-4316-9D42-8534019A5A44}"
-	ProjectSection(ProjectDependencies) = postProject
-		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
-		{A1A295E5-463C-437F-81CA-1F32367685DA} = {A1A295E5-463C-437F-81CA-1F32367685DA}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_ssl", "_ssl.vcproj", "{C6E20F84-3247-4AD6-B051-B073268F73BA}"
-	ProjectSection(ProjectDependencies) = postProject
-		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9} = {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}
-		{86937F53-C189-40EF-8CE8-8759D8E7D480} = {86937F53-C189-40EF-8CE8-8759D8E7D480}
-		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testcapi", "_testcapi.vcproj", "{6901D91C-6E48-4BB7-9FEC-700C8131DF1D}"
-	ProjectSection(ProjectDependencies) = postProject
-		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_tkinter", "_tkinter.vcproj", "{4946ECAC-2E69-4BF8-A90A-F5136F5094DF}"
-	ProjectSection(ProjectDependencies) = postProject
-		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bz2", "bz2.vcproj", "{73FCD2BD-F133-46B7-8EC1-144CD82A59D5}"
-	ProjectSection(ProjectDependencies) = postProject
-		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "select", "select.vcproj", "{18CAE28C-B454-46C1-87A0-493D91D97F03}"
-	ProjectSection(ProjectDependencies) = postProject
-		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unicodedata", "unicodedata.vcproj", "{ECC7CEAC-A5E5-458E-BB9E-2413CC847881}"
-	ProjectSection(ProjectDependencies) = postProject
-		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pyexpat", "pyexpat.vcproj", "{D06B6426-4762-44CC-8BAD-D79052507F2F}"
-	ProjectSection(ProjectDependencies) = postProject
-		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bdist_wininst", "bdist_wininst.vcproj", "{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_hashlib", "_hashlib.vcproj", "{447F05A8-F581-4CAC-A466-5AC7936E207E}"
-	ProjectSection(ProjectDependencies) = postProject
-		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9} = {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}
-		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_bsddb44", "_bsddb44.vcproj", "{62172C7D-B39E-409A-B352-370FF5098C19}"
-	ProjectSection(ProjectDependencies) = postProject
-		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31} = {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sqlite3", "sqlite3.vcproj", "{A1A295E5-463C-437F-81CA-1F32367685DA}"
-	ProjectSection(ProjectDependencies) = postProject
-		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31} = {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_multiprocessing", "_multiprocessing.vcproj", "{9E48B300-37D1-11DD-8C41-005056C00008}"
-	ProjectSection(ProjectDependencies) = postProject
-		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "kill_python", "kill_python.vcproj", "{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}"
-EndProject
-Global
-	GlobalSection(SolutionConfigurationPlatforms) = preSolution
-		Debug|Win32 = Debug|Win32
-		Debug|x64 = Debug|x64
-		PGInstrument|Win32 = PGInstrument|Win32
-		PGInstrument|x64 = PGInstrument|x64
-		PGUpdate|Win32 = PGUpdate|Win32
-		PGUpdate|x64 = PGUpdate|x64
-		Release|Win32 = Release|Win32
-		Release|x64 = Release|x64
-	EndGlobalSection
-	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Debug|Win32.ActiveCfg = Debug|Win32
-		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Debug|Win32.Build.0 = Debug|Win32
-		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Debug|x64.ActiveCfg = Debug|x64
-		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Debug|x64.Build.0 = Debug|x64
-		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
-		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
-		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
-		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGInstrument|x64.Build.0 = PGInstrument|x64
-		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
-		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
-		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
-		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGUpdate|x64.Build.0 = PGUpdate|x64
-		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release|Win32.ActiveCfg = Release|Win32
-		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release|Win32.Build.0 = Release|Win32
-		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release|x64.ActiveCfg = Release|x64
-		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release|x64.Build.0 = Release|x64
-		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Debug|Win32.ActiveCfg = Debug|Win32
-		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Debug|Win32.Build.0 = Debug|Win32
-		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Debug|x64.ActiveCfg = Debug|Win32
-		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Debug|x64.Build.0 = Debug|Win32
-		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.PGInstrument|Win32.ActiveCfg = Release|Win32
-		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.PGInstrument|Win32.Build.0 = Release|Win32
-		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.PGInstrument|x64.ActiveCfg = Release|Win32
-		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.PGInstrument|x64.Build.0 = Release|Win32
-		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.PGUpdate|Win32.ActiveCfg = Release|Win32
-		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.PGUpdate|Win32.Build.0 = Release|Win32
-		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.PGUpdate|x64.ActiveCfg = Release|Win32
-		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.PGUpdate|x64.Build.0 = Release|Win32
-		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Release|Win32.ActiveCfg = Release|Win32
-		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Release|Win32.Build.0 = Release|Win32
-		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Release|x64.ActiveCfg = Release|Win32
-		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Release|x64.Build.0 = Release|Win32
-		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Debug|Win32.ActiveCfg = Debug|Win32
-		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Debug|Win32.Build.0 = Debug|Win32
-		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Debug|x64.ActiveCfg = Debug|x64
-		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Debug|x64.Build.0 = Debug|x64
-		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
-		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
-		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
-		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGInstrument|x64.Build.0 = PGInstrument|x64
-		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
-		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
-		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
-		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGUpdate|x64.Build.0 = PGUpdate|x64
-		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Release|Win32.ActiveCfg = Release|Win32
-		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Release|Win32.Build.0 = Release|Win32
-		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Release|x64.ActiveCfg = Release|x64
-		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Release|x64.Build.0 = Release|x64
-		{F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Debug|Win32.ActiveCfg = Debug|Win32
-		{F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Debug|Win32.Build.0 = Debug|Win32
-		{F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Debug|x64.ActiveCfg = Debug|x64
-		{F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Debug|x64.Build.0 = Debug|x64
-		{F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
-		{F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
-		{F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
-		{F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGInstrument|x64.Build.0 = PGInstrument|x64
-		{F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
-		{F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
-		{F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
-		{F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGUpdate|x64.Build.0 = PGUpdate|x64
-		{F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Release|Win32.ActiveCfg = Release|Win32
-		{F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Release|Win32.Build.0 = Release|Win32
-		{F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Release|x64.ActiveCfg = Release|x64
-		{F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Release|x64.Build.0 = Release|x64
-		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.Debug|Win32.ActiveCfg = Debug|Win32
-		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.Debug|Win32.Build.0 = Debug|Win32
-		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.Debug|x64.ActiveCfg = Debug|x64
-		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.Debug|x64.Build.0 = Debug|x64
-		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
-		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
-		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
-		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.PGInstrument|x64.Build.0 = PGInstrument|x64
-		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
-		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
-		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
-		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.PGUpdate|x64.Build.0 = PGUpdate|x64
-		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.Release|Win32.ActiveCfg = Release|Win32
-		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.Release|Win32.Build.0 = Release|Win32
-		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.Release|x64.ActiveCfg = Release|x64
-		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.Release|x64.Build.0 = Release|x64
-		{C73F0EC1-358B-4177-940F-0846AC8B04CD}.Debug|Win32.ActiveCfg = Release|Win32
-		{C73F0EC1-358B-4177-940F-0846AC8B04CD}.Debug|Win32.Build.0 = Release|Win32
-		{C73F0EC1-358B-4177-940F-0846AC8B04CD}.Debug|x64.ActiveCfg = Release|Win32
-		{C73F0EC1-358B-4177-940F-0846AC8B04CD}.Debug|x64.Build.0 = Release|Win32
-		{C73F0EC1-358B-4177-940F-0846AC8B04CD}.PGInstrument|Win32.ActiveCfg = Release|Win32
-		{C73F0EC1-358B-4177-940F-0846AC8B04CD}.PGInstrument|Win32.Build.0 = Release|Win32
-		{C73F0EC1-358B-4177-940F-0846AC8B04CD}.PGInstrument|x64.ActiveCfg = Release|Win32
-		{C73F0EC1-358B-4177-940F-0846AC8B04CD}.PGInstrument|x64.Build.0 = Release|Win32
-		{C73F0EC1-358B-4177-940F-0846AC8B04CD}.PGUpdate|Win32.ActiveCfg = Release|Win32
-		{C73F0EC1-358B-4177-940F-0846AC8B04CD}.PGUpdate|Win32.Build.0 = Release|Win32
-		{C73F0EC1-358B-4177-940F-0846AC8B04CD}.PGUpdate|x64.ActiveCfg = Release|Win32
-		{C73F0EC1-358B-4177-940F-0846AC8B04CD}.PGUpdate|x64.Build.0 = Release|Win32
-		{C73F0EC1-358B-4177-940F-0846AC8B04CD}.Release|Win32.ActiveCfg = Release|Win32
-		{C73F0EC1-358B-4177-940F-0846AC8B04CD}.Release|Win32.Build.0 = Release|Win32
-		{C73F0EC1-358B-4177-940F-0846AC8B04CD}.Release|x64.ActiveCfg = Release|Win32
-		{C73F0EC1-358B-4177-940F-0846AC8B04CD}.Release|x64.Build.0 = Release|Win32
-		{28B5D777-DDF2-4B6B-B34F-31D938813856}.Debug|Win32.ActiveCfg = Debug|Win32
-		{28B5D777-DDF2-4B6B-B34F-31D938813856}.Debug|Win32.Build.0 = Debug|Win32
-		{28B5D777-DDF2-4B6B-B34F-31D938813856}.Debug|x64.ActiveCfg = Debug|x64
-		{28B5D777-DDF2-4B6B-B34F-31D938813856}.Debug|x64.Build.0 = Debug|x64
-		{28B5D777-DDF2-4B6B-B34F-31D938813856}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
-		{28B5D777-DDF2-4B6B-B34F-31D938813856}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
-		{28B5D777-DDF2-4B6B-B34F-31D938813856}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
-		{28B5D777-DDF2-4B6B-B34F-31D938813856}.PGInstrument|x64.Build.0 = PGInstrument|x64
-		{28B5D777-DDF2-4B6B-B34F-31D938813856}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
-		{28B5D777-DDF2-4B6B-B34F-31D938813856}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
-		{28B5D777-DDF2-4B6B-B34F-31D938813856}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
-		{28B5D777-DDF2-4B6B-B34F-31D938813856}.PGUpdate|x64.Build.0 = PGUpdate|x64
-		{28B5D777-DDF2-4B6B-B34F-31D938813856}.Release|Win32.ActiveCfg = Release|Win32
-		{28B5D777-DDF2-4B6B-B34F-31D938813856}.Release|Win32.Build.0 = Release|Win32
-		{28B5D777-DDF2-4B6B-B34F-31D938813856}.Release|x64.ActiveCfg = Release|x64
-		{28B5D777-DDF2-4B6B-B34F-31D938813856}.Release|x64.Build.0 = Release|x64
-		{B4D38F3F-68FB-42EC-A45D-E00657BB3627}.Debug|Win32.ActiveCfg = Debug|Win32
-		{B4D38F3F-68FB-42EC-A45D-E00657BB3627}.Debug|Win32.Build.0 = Debug|Win32
-		{B4D38F3F-68FB-42EC-A45D-E00657BB3627}.Debug|x64.ActiveCfg = Debug|x64
-		{B4D38F3F-68FB-42EC-A45D-E00657BB3627}.Debug|x64.Build.0 = Debug|x64
-		{B4D38F3F-68FB-42EC-A45D-E00657BB3627}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
-		{B4D38F3F-68FB-42EC-A45D-E00657BB3627}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
-		{B4D38F3F-68FB-42EC-A45D-E00657BB3627}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
-		{B4D38F3F-68FB-42EC-A45D-E00657BB3627}.PGInstrument|x64.Build.0 = PGInstrument|x64
-		{B4D38F3F-68FB-42EC-A45D-E00657BB3627}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
-		{B4D38F3F-68FB-42EC-A45D-E00657BB3627}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
-		{B4D38F3F-68FB-42EC-A45D-E00657BB3627}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
-		{B4D38F3F-68FB-42EC-A45D-E00657BB3627}.PGUpdate|x64.Build.0 = PGUpdate|x64
-		{B4D38F3F-68FB-42EC-A45D-E00657BB3627}.Release|Win32.ActiveCfg = Release|Win32
-		{B4D38F3F-68FB-42EC-A45D-E00657BB3627}.Release|Win32.Build.0 = Release|Win32
-		{B4D38F3F-68FB-42EC-A45D-E00657BB3627}.Release|x64.ActiveCfg = Release|x64
-		{B4D38F3F-68FB-42EC-A45D-E00657BB3627}.Release|x64.Build.0 = Release|x64
-		{0E9791DB-593A-465F-98BC-681011311618}.Debug|Win32.ActiveCfg = Debug|Win32
-		{0E9791DB-593A-465F-98BC-681011311618}.Debug|Win32.Build.0 = Debug|Win32
-		{0E9791DB-593A-465F-98BC-681011311618}.Debug|x64.ActiveCfg = Debug|x64
-		{0E9791DB-593A-465F-98BC-681011311618}.Debug|x64.Build.0 = Debug|x64
-		{0E9791DB-593A-465F-98BC-681011311618}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
-		{0E9791DB-593A-465F-98BC-681011311618}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
-		{0E9791DB-593A-465F-98BC-681011311618}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
-		{0E9791DB-593A-465F-98BC-681011311618}.PGInstrument|x64.Build.0 = PGInstrument|x64
-		{0E9791DB-593A-465F-98BC-681011311618}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
-		{0E9791DB-593A-465F-98BC-681011311618}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
-		{0E9791DB-593A-465F-98BC-681011311618}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
-		{0E9791DB-593A-465F-98BC-681011311618}.PGUpdate|x64.Build.0 = PGUpdate|x64
-		{0E9791DB-593A-465F-98BC-681011311618}.Release|Win32.ActiveCfg = Release|Win32
-		{0E9791DB-593A-465F-98BC-681011311618}.Release|Win32.Build.0 = Release|Win32
-		{0E9791DB-593A-465F-98BC-681011311618}.Release|x64.ActiveCfg = Release|x64
-		{0E9791DB-593A-465F-98BC-681011311618}.Release|x64.Build.0 = Release|x64
-		{9EC7190A-249F-4180-A900-548FDCF3055F}.Debug|Win32.ActiveCfg = Debug|Win32
-		{9EC7190A-249F-4180-A900-548FDCF3055F}.Debug|Win32.Build.0 = Debug|Win32
-		{9EC7190A-249F-4180-A900-548FDCF3055F}.Debug|x64.ActiveCfg = Debug|x64
-		{9EC7190A-249F-4180-A900-548FDCF3055F}.Debug|x64.Build.0 = Debug|x64
-		{9EC7190A-249F-4180-A900-548FDCF3055F}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
-		{9EC7190A-249F-4180-A900-548FDCF3055F}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
-		{9EC7190A-249F-4180-A900-548FDCF3055F}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
-		{9EC7190A-249F-4180-A900-548FDCF3055F}.PGInstrument|x64.Build.0 = PGInstrument|x64
-		{9EC7190A-249F-4180-A900-548FDCF3055F}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
-		{9EC7190A-249F-4180-A900-548FDCF3055F}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
-		{9EC7190A-249F-4180-A900-548FDCF3055F}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
-		{9EC7190A-249F-4180-A900-548FDCF3055F}.PGUpdate|x64.Build.0 = PGUpdate|x64
-		{9EC7190A-249F-4180-A900-548FDCF3055F}.Release|Win32.ActiveCfg = Release|Win32
-		{9EC7190A-249F-4180-A900-548FDCF3055F}.Release|Win32.Build.0 = Release|Win32
-		{9EC7190A-249F-4180-A900-548FDCF3055F}.Release|x64.ActiveCfg = Release|x64
-		{9EC7190A-249F-4180-A900-548FDCF3055F}.Release|x64.Build.0 = Release|x64
-		{17E1E049-C309-4D79-843F-AE483C264AEA}.Debug|Win32.ActiveCfg = Debug|Win32
-		{17E1E049-C309-4D79-843F-AE483C264AEA}.Debug|Win32.Build.0 = Debug|Win32
-		{17E1E049-C309-4D79-843F-AE483C264AEA}.Debug|x64.ActiveCfg = Debug|x64
-		{17E1E049-C309-4D79-843F-AE483C264AEA}.Debug|x64.Build.0 = Debug|x64
-		{17E1E049-C309-4D79-843F-AE483C264AEA}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
-		{17E1E049-C309-4D79-843F-AE483C264AEA}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
-		{17E1E049-C309-4D79-843F-AE483C264AEA}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
-		{17E1E049-C309-4D79-843F-AE483C264AEA}.PGInstrument|x64.Build.0 = PGInstrument|x64
-		{17E1E049-C309-4D79-843F-AE483C264AEA}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
-		{17E1E049-C309-4D79-843F-AE483C264AEA}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
-		{17E1E049-C309-4D79-843F-AE483C264AEA}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
-		{17E1E049-C309-4D79-843F-AE483C264AEA}.PGUpdate|x64.Build.0 = PGUpdate|x64
-		{17E1E049-C309-4D79-843F-AE483C264AEA}.Release|Win32.ActiveCfg = Release|Win32
-		{17E1E049-C309-4D79-843F-AE483C264AEA}.Release|Win32.Build.0 = Release|Win32
-		{17E1E049-C309-4D79-843F-AE483C264AEA}.Release|x64.ActiveCfg = Release|x64
-		{17E1E049-C309-4D79-843F-AE483C264AEA}.Release|x64.Build.0 = Release|x64
-		{31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Debug|Win32.ActiveCfg = Debug|Win32
-		{31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Debug|Win32.Build.0 = Debug|Win32
-		{31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Debug|x64.ActiveCfg = Debug|x64
-		{31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Debug|x64.Build.0 = Debug|x64
-		{31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
-		{31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
-		{31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
-		{31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGInstrument|x64.Build.0 = PGInstrument|x64
-		{31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
-		{31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
-		{31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
-		{31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGUpdate|x64.Build.0 = PGUpdate|x64
-		{31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Release|Win32.ActiveCfg = Release|Win32
-		{31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Release|Win32.Build.0 = Release|Win32
-		{31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Release|x64.ActiveCfg = Release|x64
-		{31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Release|x64.Build.0 = Release|x64
-		{86937F53-C189-40EF-8CE8-8759D8E7D480}.Debug|Win32.ActiveCfg = Debug|Win32
-		{86937F53-C189-40EF-8CE8-8759D8E7D480}.Debug|Win32.Build.0 = Debug|Win32
-		{86937F53-C189-40EF-8CE8-8759D8E7D480}.Debug|x64.ActiveCfg = Debug|x64
-		{86937F53-C189-40EF-8CE8-8759D8E7D480}.Debug|x64.Build.0 = Debug|x64
-		{86937F53-C189-40EF-8CE8-8759D8E7D480}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
-		{86937F53-C189-40EF-8CE8-8759D8E7D480}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
-		{86937F53-C189-40EF-8CE8-8759D8E7D480}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
-		{86937F53-C189-40EF-8CE8-8759D8E7D480}.PGInstrument|x64.Build.0 = PGInstrument|x64
-		{86937F53-C189-40EF-8CE8-8759D8E7D480}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
-		{86937F53-C189-40EF-8CE8-8759D8E7D480}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
-		{86937F53-C189-40EF-8CE8-8759D8E7D480}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
-		{86937F53-C189-40EF-8CE8-8759D8E7D480}.PGUpdate|x64.Build.0 = PGUpdate|x64
-		{86937F53-C189-40EF-8CE8-8759D8E7D480}.Release|Win32.ActiveCfg = Release|Win32
-		{86937F53-C189-40EF-8CE8-8759D8E7D480}.Release|Win32.Build.0 = Release|Win32
-		{86937F53-C189-40EF-8CE8-8759D8E7D480}.Release|x64.ActiveCfg = Release|x64
-		{86937F53-C189-40EF-8CE8-8759D8E7D480}.Release|x64.Build.0 = Release|x64
-		{13CECB97-4119-4316-9D42-8534019A5A44}.Debug|Win32.ActiveCfg = Debug|Win32
-		{13CECB97-4119-4316-9D42-8534019A5A44}.Debug|Win32.Build.0 = Debug|Win32
-		{13CECB97-4119-4316-9D42-8534019A5A44}.Debug|x64.ActiveCfg = Debug|x64
-		{13CECB97-4119-4316-9D42-8534019A5A44}.Debug|x64.Build.0 = Debug|x64
-		{13CECB97-4119-4316-9D42-8534019A5A44}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
-		{13CECB97-4119-4316-9D42-8534019A5A44}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
-		{13CECB97-4119-4316-9D42-8534019A5A44}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
-		{13CECB97-4119-4316-9D42-8534019A5A44}.PGInstrument|x64.Build.0 = PGInstrument|x64
-		{13CECB97-4119-4316-9D42-8534019A5A44}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
-		{13CECB97-4119-4316-9D42-8534019A5A44}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
-		{13CECB97-4119-4316-9D42-8534019A5A44}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
-		{13CECB97-4119-4316-9D42-8534019A5A44}.PGUpdate|x64.Build.0 = PGUpdate|x64
-		{13CECB97-4119-4316-9D42-8534019A5A44}.Release|Win32.ActiveCfg = Release|Win32
-		{13CECB97-4119-4316-9D42-8534019A5A44}.Release|Win32.Build.0 = Release|Win32
-		{13CECB97-4119-4316-9D42-8534019A5A44}.Release|x64.ActiveCfg = Release|x64
-		{13CECB97-4119-4316-9D42-8534019A5A44}.Release|x64.Build.0 = Release|x64
-		{C6E20F84-3247-4AD6-B051-B073268F73BA}.Debug|Win32.ActiveCfg = Debug|Win32
-		{C6E20F84-3247-4AD6-B051-B073268F73BA}.Debug|Win32.Build.0 = Debug|Win32
-		{C6E20F84-3247-4AD6-B051-B073268F73BA}.Debug|x64.ActiveCfg = Debug|x64
-		{C6E20F84-3247-4AD6-B051-B073268F73BA}.Debug|x64.Build.0 = Debug|x64
-		{C6E20F84-3247-4AD6-B051-B073268F73BA}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
-		{C6E20F84-3247-4AD6-B051-B073268F73BA}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
-		{C6E20F84-3247-4AD6-B051-B073268F73BA}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
-		{C6E20F84-3247-4AD6-B051-B073268F73BA}.PGInstrument|x64.Build.0 = PGInstrument|x64
-		{C6E20F84-3247-4AD6-B051-B073268F73BA}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
-		{C6E20F84-3247-4AD6-B051-B073268F73BA}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
-		{C6E20F84-3247-4AD6-B051-B073268F73BA}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
-		{C6E20F84-3247-4AD6-B051-B073268F73BA}.PGUpdate|x64.Build.0 = PGUpdate|x64
-		{C6E20F84-3247-4AD6-B051-B073268F73BA}.Release|Win32.ActiveCfg = Release|Win32
-		{C6E20F84-3247-4AD6-B051-B073268F73BA}.Release|Win32.Build.0 = Release|Win32
-		{C6E20F84-3247-4AD6-B051-B073268F73BA}.Release|x64.ActiveCfg = Release|x64
-		{C6E20F84-3247-4AD6-B051-B073268F73BA}.Release|x64.Build.0 = Release|x64
-		{6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Debug|Win32.ActiveCfg = Debug|Win32
-		{6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Debug|Win32.Build.0 = Debug|Win32
-		{6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Debug|x64.ActiveCfg = Debug|x64
-		{6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Debug|x64.Build.0 = Debug|x64
-		{6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
-		{6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
-		{6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
-		{6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGInstrument|x64.Build.0 = PGInstrument|x64
-		{6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
-		{6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
-		{6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
-		{6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGUpdate|x64.Build.0 = PGUpdate|x64
-		{6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Release|Win32.ActiveCfg = Release|Win32
-		{6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Release|Win32.Build.0 = Release|Win32
-		{6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Release|x64.ActiveCfg = Release|x64
-		{6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Release|x64.Build.0 = Release|x64
-		{4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Debug|Win32.ActiveCfg = Debug|Win32
-		{4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Debug|Win32.Build.0 = Debug|Win32
-		{4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Debug|x64.ActiveCfg = Debug|x64
-		{4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Debug|x64.Build.0 = Debug|x64
-		{4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
-		{4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
-		{4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
-		{4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGInstrument|x64.Build.0 = PGInstrument|x64
-		{4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
-		{4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
-		{4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
-		{4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGUpdate|x64.Build.0 = PGUpdate|x64
-		{4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Release|Win32.ActiveCfg = Release|Win32
-		{4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Release|Win32.Build.0 = Release|Win32
-		{4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Release|x64.ActiveCfg = Release|x64
-		{4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Release|x64.Build.0 = Release|x64
-		{73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Debug|Win32.ActiveCfg = Debug|Win32
-		{73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Debug|Win32.Build.0 = Debug|Win32
-		{73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Debug|x64.ActiveCfg = Debug|x64
-		{73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Debug|x64.Build.0 = Debug|x64
-		{73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
-		{73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
-		{73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
-		{73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGInstrument|x64.Build.0 = PGInstrument|x64
-		{73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
-		{73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
-		{73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
-		{73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGUpdate|x64.Build.0 = PGUpdate|x64
-		{73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Release|Win32.ActiveCfg = Release|Win32
-		{73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Release|Win32.Build.0 = Release|Win32
-		{73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Release|x64.ActiveCfg = Release|x64
-		{73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Release|x64.Build.0 = Release|x64
-		{18CAE28C-B454-46C1-87A0-493D91D97F03}.Debug|Win32.ActiveCfg = Debug|Win32
-		{18CAE28C-B454-46C1-87A0-493D91D97F03}.Debug|Win32.Build.0 = Debug|Win32
-		{18CAE28C-B454-46C1-87A0-493D91D97F03}.Debug|x64.ActiveCfg = Debug|x64
-		{18CAE28C-B454-46C1-87A0-493D91D97F03}.Debug|x64.Build.0 = Debug|x64
-		{18CAE28C-B454-46C1-87A0-493D91D97F03}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
-		{18CAE28C-B454-46C1-87A0-493D91D97F03}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
-		{18CAE28C-B454-46C1-87A0-493D91D97F03}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
-		{18CAE28C-B454-46C1-87A0-493D91D97F03}.PGInstrument|x64.Build.0 = PGInstrument|x64
-		{18CAE28C-B454-46C1-87A0-493D91D97F03}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
-		{18CAE28C-B454-46C1-87A0-493D91D97F03}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
-		{18CAE28C-B454-46C1-87A0-493D91D97F03}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
-		{18CAE28C-B454-46C1-87A0-493D91D97F03}.PGUpdate|x64.Build.0 = PGUpdate|x64
-		{18CAE28C-B454-46C1-87A0-493D91D97F03}.Release|Win32.ActiveCfg = Release|Win32
-		{18CAE28C-B454-46C1-87A0-493D91D97F03}.Release|Win32.Build.0 = Release|Win32
-		{18CAE28C-B454-46C1-87A0-493D91D97F03}.Release|x64.ActiveCfg = Release|x64
-		{18CAE28C-B454-46C1-87A0-493D91D97F03}.Release|x64.Build.0 = Release|x64
-		{ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Debug|Win32.ActiveCfg = Debug|Win32
-		{ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Debug|Win32.Build.0 = Debug|Win32
-		{ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Debug|x64.ActiveCfg = Debug|x64
-		{ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Debug|x64.Build.0 = Debug|x64
-		{ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
-		{ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
-		{ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
-		{ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGInstrument|x64.Build.0 = PGInstrument|x64
-		{ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
-		{ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
-		{ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
-		{ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGUpdate|x64.Build.0 = PGUpdate|x64
-		{ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Release|Win32.ActiveCfg = Release|Win32
-		{ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Release|Win32.Build.0 = Release|Win32
-		{ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Release|x64.ActiveCfg = Release|x64
-		{ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Release|x64.Build.0 = Release|x64
-		{D06B6426-4762-44CC-8BAD-D79052507F2F}.Debug|Win32.ActiveCfg = Debug|Win32
-		{D06B6426-4762-44CC-8BAD-D79052507F2F}.Debug|Win32.Build.0 = Debug|Win32
-		{D06B6426-4762-44CC-8BAD-D79052507F2F}.Debug|x64.ActiveCfg = Debug|x64
-		{D06B6426-4762-44CC-8BAD-D79052507F2F}.Debug|x64.Build.0 = Debug|x64
-		{D06B6426-4762-44CC-8BAD-D79052507F2F}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
-		{D06B6426-4762-44CC-8BAD-D79052507F2F}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
-		{D06B6426-4762-44CC-8BAD-D79052507F2F}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
-		{D06B6426-4762-44CC-8BAD-D79052507F2F}.PGInstrument|x64.Build.0 = PGInstrument|x64
-		{D06B6426-4762-44CC-8BAD-D79052507F2F}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
-		{D06B6426-4762-44CC-8BAD-D79052507F2F}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
-		{D06B6426-4762-44CC-8BAD-D79052507F2F}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
-		{D06B6426-4762-44CC-8BAD-D79052507F2F}.PGUpdate|x64.Build.0 = PGUpdate|x64
-		{D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|Win32.ActiveCfg = Release|Win32
-		{D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|Win32.Build.0 = Release|Win32
-		{D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|x64.ActiveCfg = Release|x64
-		{D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|x64.Build.0 = Release|x64
-		{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Debug|Win32.ActiveCfg = Release|Win32
-		{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Debug|x64.ActiveCfg = Release|x64
-		{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGInstrument|Win32.ActiveCfg = Release|Win32
-		{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGInstrument|x64.ActiveCfg = Release|x64
-		{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGUpdate|Win32.ActiveCfg = Release|Win32
-		{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGUpdate|x64.ActiveCfg = Release|x64
-		{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Release|Win32.ActiveCfg = Release|Win32
-		{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Release|x64.ActiveCfg = Release|x64
-		{447F05A8-F581-4CAC-A466-5AC7936E207E}.Debug|Win32.ActiveCfg = Debug|Win32
-		{447F05A8-F581-4CAC-A466-5AC7936E207E}.Debug|Win32.Build.0 = Debug|Win32
-		{447F05A8-F581-4CAC-A466-5AC7936E207E}.Debug|x64.ActiveCfg = Debug|x64
-		{447F05A8-F581-4CAC-A466-5AC7936E207E}.Debug|x64.Build.0 = Debug|x64
-		{447F05A8-F581-4CAC-A466-5AC7936E207E}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
-		{447F05A8-F581-4CAC-A466-5AC7936E207E}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
-		{447F05A8-F581-4CAC-A466-5AC7936E207E}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
-		{447F05A8-F581-4CAC-A466-5AC7936E207E}.PGInstrument|x64.Build.0 = PGInstrument|x64
-		{447F05A8-F581-4CAC-A466-5AC7936E207E}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
-		{447F05A8-F581-4CAC-A466-5AC7936E207E}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
-		{447F05A8-F581-4CAC-A466-5AC7936E207E}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
-		{447F05A8-F581-4CAC-A466-5AC7936E207E}.PGUpdate|x64.Build.0 = PGUpdate|x64
-		{447F05A8-F581-4CAC-A466-5AC7936E207E}.Release|Win32.ActiveCfg = Release|Win32
-		{447F05A8-F581-4CAC-A466-5AC7936E207E}.Release|Win32.Build.0 = Release|Win32
-		{447F05A8-F581-4CAC-A466-5AC7936E207E}.Release|x64.ActiveCfg = Release|x64
-		{447F05A8-F581-4CAC-A466-5AC7936E207E}.Release|x64.Build.0 = Release|x64
-		{62172C7D-B39E-409A-B352-370FF5098C19}.Debug|Win32.ActiveCfg = Debug|Win32
-		{62172C7D-B39E-409A-B352-370FF5098C19}.Debug|Win32.Build.0 = Debug|Win32
-		{62172C7D-B39E-409A-B352-370FF5098C19}.Debug|x64.ActiveCfg = Debug|x64
-		{62172C7D-B39E-409A-B352-370FF5098C19}.Debug|x64.Build.0 = Debug|x64
-		{62172C7D-B39E-409A-B352-370FF5098C19}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
-		{62172C7D-B39E-409A-B352-370FF5098C19}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
-		{62172C7D-B39E-409A-B352-370FF5098C19}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
-		{62172C7D-B39E-409A-B352-370FF5098C19}.PGInstrument|x64.Build.0 = PGInstrument|x64
-		{62172C7D-B39E-409A-B352-370FF5098C19}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
-		{62172C7D-B39E-409A-B352-370FF5098C19}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
-		{62172C7D-B39E-409A-B352-370FF5098C19}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
-		{62172C7D-B39E-409A-B352-370FF5098C19}.PGUpdate|x64.Build.0 = PGUpdate|x64
-		{62172C7D-B39E-409A-B352-370FF5098C19}.Release|Win32.ActiveCfg = Release|Win32
-		{62172C7D-B39E-409A-B352-370FF5098C19}.Release|Win32.Build.0 = Release|Win32
-		{62172C7D-B39E-409A-B352-370FF5098C19}.Release|x64.ActiveCfg = Release|x64
-		{62172C7D-B39E-409A-B352-370FF5098C19}.Release|x64.Build.0 = Release|x64
-		{A1A295E5-463C-437F-81CA-1F32367685DA}.Debug|Win32.ActiveCfg = Debug|Win32
-		{A1A295E5-463C-437F-81CA-1F32367685DA}.Debug|Win32.Build.0 = Debug|Win32
-		{A1A295E5-463C-437F-81CA-1F32367685DA}.Debug|x64.ActiveCfg = Debug|x64
-		{A1A295E5-463C-437F-81CA-1F32367685DA}.Debug|x64.Build.0 = Debug|x64
-		{A1A295E5-463C-437F-81CA-1F32367685DA}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
-		{A1A295E5-463C-437F-81CA-1F32367685DA}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
-		{A1A295E5-463C-437F-81CA-1F32367685DA}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
-		{A1A295E5-463C-437F-81CA-1F32367685DA}.PGInstrument|x64.Build.0 = PGInstrument|x64
-		{A1A295E5-463C-437F-81CA-1F32367685DA}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
-		{A1A295E5-463C-437F-81CA-1F32367685DA}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
-		{A1A295E5-463C-437F-81CA-1F32367685DA}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
-		{A1A295E5-463C-437F-81CA-1F32367685DA}.PGUpdate|x64.Build.0 = PGUpdate|x64
-		{A1A295E5-463C-437F-81CA-1F32367685DA}.Release|Win32.ActiveCfg = Release|Win32
-		{A1A295E5-463C-437F-81CA-1F32367685DA}.Release|Win32.Build.0 = Release|Win32
-		{A1A295E5-463C-437F-81CA-1F32367685DA}.Release|x64.ActiveCfg = Release|x64
-		{A1A295E5-463C-437F-81CA-1F32367685DA}.Release|x64.Build.0 = Release|x64
-		{9E48B300-37D1-11DD-8C41-005056C00008}.Debug|Win32.ActiveCfg = Debug|Win32
-		{9E48B300-37D1-11DD-8C41-005056C00008}.Debug|Win32.Build.0 = Debug|Win32
-		{9E48B300-37D1-11DD-8C41-005056C00008}.Debug|x64.ActiveCfg = Debug|x64
-		{9E48B300-37D1-11DD-8C41-005056C00008}.Debug|x64.Build.0 = Debug|x64
-		{9E48B300-37D1-11DD-8C41-005056C00008}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
-		{9E48B300-37D1-11DD-8C41-005056C00008}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
-		{9E48B300-37D1-11DD-8C41-005056C00008}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
-		{9E48B300-37D1-11DD-8C41-005056C00008}.PGInstrument|x64.Build.0 = PGInstrument|x64
-		{9E48B300-37D1-11DD-8C41-005056C00008}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
-		{9E48B300-37D1-11DD-8C41-005056C00008}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
-		{9E48B300-37D1-11DD-8C41-005056C00008}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
-		{9E48B300-37D1-11DD-8C41-005056C00008}.PGUpdate|x64.Build.0 = PGUpdate|x64
-		{9E48B300-37D1-11DD-8C41-005056C00008}.Release|Win32.ActiveCfg = Release|Win32
-		{9E48B300-37D1-11DD-8C41-005056C00008}.Release|Win32.Build.0 = Release|Win32
-		{9E48B300-37D1-11DD-8C41-005056C00008}.Release|x64.ActiveCfg = Release|x64
-		{9E48B300-37D1-11DD-8C41-005056C00008}.Release|x64.Build.0 = Release|x64
-		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Debug|Win32.ActiveCfg = Debug|Win32
-		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Debug|Win32.Build.0 = Debug|Win32
-		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Debug|x64.ActiveCfg = Debug|x64
-		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Debug|x64.Build.0 = Debug|x64
-		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.PGInstrument|Win32.ActiveCfg = Release|Win32
-		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.PGInstrument|Win32.Build.0 = Release|Win32
-		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.PGInstrument|x64.ActiveCfg = Release|x64
-		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.PGInstrument|x64.Build.0 = Release|x64
-		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.PGUpdate|Win32.ActiveCfg = Release|Win32
-		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.PGUpdate|Win32.Build.0 = Release|Win32
-		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.PGUpdate|x64.ActiveCfg = Release|x64
-		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.PGUpdate|x64.Build.0 = Release|x64
-		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Release|Win32.ActiveCfg = Release|Win32
-		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Release|Win32.Build.0 = Release|Win32
-		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Release|x64.ActiveCfg = Release|x64
-		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Release|x64.Build.0 = Release|x64
-	EndGlobalSection
-	GlobalSection(SolutionProperties) = preSolution
-		HideSolutionNode = FALSE
-	EndGlobalSection
-EndGlobal
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "python", "python.vcproj", "{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}"
+	ProjectSection(ProjectDependencies) = postProject
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
+		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058} = {E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "make_versioninfo", "make_versioninfo.vcproj", "{F0E0541E-F17D-430B-97C4-93ADF0DD284E}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pythoncore", "pythoncore.vcproj", "{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}"
+	ProjectSection(ProjectDependencies) = postProject
+		{F0E0541E-F17D-430B-97C4-93ADF0DD284E} = {F0E0541E-F17D-430B-97C4-93ADF0DD284E}
+		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31} = {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}
+		{C73F0EC1-358B-4177-940F-0846AC8B04CD} = {C73F0EC1-358B-4177-940F-0846AC8B04CD}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pythonw", "pythonw.vcproj", "{F4229CC3-873C-49AE-9729-DD308ED4CD4A}"
+	ProjectSection(ProjectDependencies) = postProject
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "w9xpopen", "w9xpopen.vcproj", "{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}"
+	ProjectSection(ProjectDependencies) = postProject
+		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31} = {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "make_buildinfo", "make_buildinfo.vcproj", "{C73F0EC1-358B-4177-940F-0846AC8B04CD}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{553EC33E-9816-4996-A660-5D6186A0B0B3}"
+	ProjectSection(SolutionItems) = preProject
+		..\..\Modules\getbuildinfo.c = ..\..\Modules\getbuildinfo.c
+		readme.txt = readme.txt
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "winsound", "winsound.vcproj", "{28B5D777-DDF2-4B6B-B34F-31D938813856}"
+	ProjectSection(ProjectDependencies) = postProject
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_bsddb", "_bsddb.vcproj", "{B4D38F3F-68FB-42EC-A45D-E00657BB3627}"
+	ProjectSection(ProjectDependencies) = postProject
+		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31} = {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}
+		{62172C7D-B39E-409A-B352-370FF5098C19} = {62172C7D-B39E-409A-B352-370FF5098C19}
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_ctypes", "_ctypes.vcproj", "{0E9791DB-593A-465F-98BC-681011311618}"
+	ProjectSection(ProjectDependencies) = postProject
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_ctypes_test", "_ctypes_test.vcproj", "{9EC7190A-249F-4180-A900-548FDCF3055F}"
+	ProjectSection(ProjectDependencies) = postProject
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_elementtree", "_elementtree.vcproj", "{17E1E049-C309-4D79-843F-AE483C264AEA}"
+	ProjectSection(ProjectDependencies) = postProject
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_msi", "_msi.vcproj", "{31FFC478-7B4A-43E8-9954-8D03E2187E9C}"
+	ProjectSection(ProjectDependencies) = postProject
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_socket", "_socket.vcproj", "{86937F53-C189-40EF-8CE8-8759D8E7D480}"
+	ProjectSection(ProjectDependencies) = postProject
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_sqlite3", "_sqlite3.vcproj", "{13CECB97-4119-4316-9D42-8534019A5A44}"
+	ProjectSection(ProjectDependencies) = postProject
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
+		{A1A295E5-463C-437F-81CA-1F32367685DA} = {A1A295E5-463C-437F-81CA-1F32367685DA}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_ssl", "_ssl.vcproj", "{C6E20F84-3247-4AD6-B051-B073268F73BA}"
+	ProjectSection(ProjectDependencies) = postProject
+		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9} = {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}
+		{86937F53-C189-40EF-8CE8-8759D8E7D480} = {86937F53-C189-40EF-8CE8-8759D8E7D480}
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testcapi", "_testcapi.vcproj", "{6901D91C-6E48-4BB7-9FEC-700C8131DF1D}"
+	ProjectSection(ProjectDependencies) = postProject
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_tkinter", "_tkinter.vcproj", "{4946ECAC-2E69-4BF8-A90A-F5136F5094DF}"
+	ProjectSection(ProjectDependencies) = postProject
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bz2", "bz2.vcproj", "{73FCD2BD-F133-46B7-8EC1-144CD82A59D5}"
+	ProjectSection(ProjectDependencies) = postProject
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "select", "select.vcproj", "{18CAE28C-B454-46C1-87A0-493D91D97F03}"
+	ProjectSection(ProjectDependencies) = postProject
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unicodedata", "unicodedata.vcproj", "{ECC7CEAC-A5E5-458E-BB9E-2413CC847881}"
+	ProjectSection(ProjectDependencies) = postProject
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pyexpat", "pyexpat.vcproj", "{D06B6426-4762-44CC-8BAD-D79052507F2F}"
+	ProjectSection(ProjectDependencies) = postProject
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bdist_wininst", "bdist_wininst.vcproj", "{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_hashlib", "_hashlib.vcproj", "{447F05A8-F581-4CAC-A466-5AC7936E207E}"
+	ProjectSection(ProjectDependencies) = postProject
+		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9} = {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_bsddb44", "_bsddb44.vcproj", "{62172C7D-B39E-409A-B352-370FF5098C19}"
+	ProjectSection(ProjectDependencies) = postProject
+		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31} = {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sqlite3", "sqlite3.vcproj", "{A1A295E5-463C-437F-81CA-1F32367685DA}"
+	ProjectSection(ProjectDependencies) = postProject
+		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31} = {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_multiprocessing", "_multiprocessing.vcproj", "{9E48B300-37D1-11DD-8C41-005056C00008}"
+	ProjectSection(ProjectDependencies) = postProject
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "kill_python", "kill_python.vcproj", "{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Debug|x64 = Debug|x64
+		PGInstrument|Win32 = PGInstrument|Win32
+		PGInstrument|x64 = PGInstrument|x64
+		PGUpdate|Win32 = PGUpdate|Win32
+		PGUpdate|x64 = PGUpdate|x64
+		Release|Win32 = Release|Win32
+		Release|x64 = Release|x64
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Debug|Win32.ActiveCfg = Debug|Win32
+		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Debug|Win32.Build.0 = Debug|Win32
+		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Debug|x64.ActiveCfg = Debug|x64
+		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Debug|x64.Build.0 = Debug|x64
+		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
+		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
+		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
+		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGInstrument|x64.Build.0 = PGInstrument|x64
+		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
+		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
+		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
+		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGUpdate|x64.Build.0 = PGUpdate|x64
+		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release|Win32.ActiveCfg = Release|Win32
+		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release|Win32.Build.0 = Release|Win32
+		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release|x64.ActiveCfg = Release|x64
+		{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release|x64.Build.0 = Release|x64
+		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Debug|Win32.ActiveCfg = Debug|Win32
+		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Debug|Win32.Build.0 = Debug|Win32
+		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Debug|x64.ActiveCfg = Debug|Win32
+		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Debug|x64.Build.0 = Debug|Win32
+		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.PGInstrument|Win32.ActiveCfg = Release|Win32
+		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.PGInstrument|Win32.Build.0 = Release|Win32
+		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.PGInstrument|x64.ActiveCfg = Release|Win32
+		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.PGInstrument|x64.Build.0 = Release|Win32
+		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.PGUpdate|Win32.ActiveCfg = Release|Win32
+		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.PGUpdate|Win32.Build.0 = Release|Win32
+		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.PGUpdate|x64.ActiveCfg = Release|Win32
+		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.PGUpdate|x64.Build.0 = Release|Win32
+		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Release|Win32.ActiveCfg = Release|Win32
+		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Release|Win32.Build.0 = Release|Win32
+		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Release|x64.ActiveCfg = Release|Win32
+		{F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Release|x64.Build.0 = Release|Win32
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Debug|Win32.ActiveCfg = Debug|Win32
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Debug|Win32.Build.0 = Debug|Win32
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Debug|x64.ActiveCfg = Debug|x64
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Debug|x64.Build.0 = Debug|x64
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGInstrument|x64.Build.0 = PGInstrument|x64
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGUpdate|x64.Build.0 = PGUpdate|x64
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Release|Win32.ActiveCfg = Release|Win32
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Release|Win32.Build.0 = Release|Win32
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Release|x64.ActiveCfg = Release|x64
+		{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Release|x64.Build.0 = Release|x64
+		{F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Debug|Win32.ActiveCfg = Debug|Win32
+		{F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Debug|Win32.Build.0 = Debug|Win32
+		{F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Debug|x64.ActiveCfg = Debug|x64
+		{F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Debug|x64.Build.0 = Debug|x64
+		{F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
+		{F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
+		{F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
+		{F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGInstrument|x64.Build.0 = PGInstrument|x64
+		{F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
+		{F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
+		{F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
+		{F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGUpdate|x64.Build.0 = PGUpdate|x64
+		{F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Release|Win32.ActiveCfg = Release|Win32
+		{F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Release|Win32.Build.0 = Release|Win32
+		{F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Release|x64.ActiveCfg = Release|x64
+		{F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Release|x64.Build.0 = Release|x64
+		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.Debug|Win32.ActiveCfg = Debug|Win32
+		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.Debug|Win32.Build.0 = Debug|Win32
+		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.Debug|x64.ActiveCfg = Debug|x64
+		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.Debug|x64.Build.0 = Debug|x64
+		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
+		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
+		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
+		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.PGInstrument|x64.Build.0 = PGInstrument|x64
+		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
+		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
+		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
+		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.PGUpdate|x64.Build.0 = PGUpdate|x64
+		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.Release|Win32.ActiveCfg = Release|Win32
+		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.Release|Win32.Build.0 = Release|Win32
+		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.Release|x64.ActiveCfg = Release|x64
+		{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.Release|x64.Build.0 = Release|x64
+		{C73F0EC1-358B-4177-940F-0846AC8B04CD}.Debug|Win32.ActiveCfg = Release|Win32
+		{C73F0EC1-358B-4177-940F-0846AC8B04CD}.Debug|Win32.Build.0 = Release|Win32
+		{C73F0EC1-358B-4177-940F-0846AC8B04CD}.Debug|x64.ActiveCfg = Release|Win32
+		{C73F0EC1-358B-4177-940F-0846AC8B04CD}.Debug|x64.Build.0 = Release|Win32
+		{C73F0EC1-358B-4177-940F-0846AC8B04CD}.PGInstrument|Win32.ActiveCfg = Release|Win32
+		{C73F0EC1-358B-4177-940F-0846AC8B04CD}.PGInstrument|Win32.Build.0 = Release|Win32
+		{C73F0EC1-358B-4177-940F-0846AC8B04CD}.PGInstrument|x64.ActiveCfg = Release|Win32
+		{C73F0EC1-358B-4177-940F-0846AC8B04CD}.PGInstrument|x64.Build.0 = Release|Win32
+		{C73F0EC1-358B-4177-940F-0846AC8B04CD}.PGUpdate|Win32.ActiveCfg = Release|Win32
+		{C73F0EC1-358B-4177-940F-0846AC8B04CD}.PGUpdate|Win32.Build.0 = Release|Win32
+		{C73F0EC1-358B-4177-940F-0846AC8B04CD}.PGUpdate|x64.ActiveCfg = Release|Win32
+		{C73F0EC1-358B-4177-940F-0846AC8B04CD}.PGUpdate|x64.Build.0 = Release|Win32
+		{C73F0EC1-358B-4177-940F-0846AC8B04CD}.Release|Win32.ActiveCfg = Release|Win32
+		{C73F0EC1-358B-4177-940F-0846AC8B04CD}.Release|Win32.Build.0 = Release|Win32
+		{C73F0EC1-358B-4177-940F-0846AC8B04CD}.Release|x64.ActiveCfg = Release|Win32
+		{C73F0EC1-358B-4177-940F-0846AC8B04CD}.Release|x64.Build.0 = Release|Win32
+		{28B5D777-DDF2-4B6B-B34F-31D938813856}.Debug|Win32.ActiveCfg = Debug|Win32
+		{28B5D777-DDF2-4B6B-B34F-31D938813856}.Debug|Win32.Build.0 = Debug|Win32
+		{28B5D777-DDF2-4B6B-B34F-31D938813856}.Debug|x64.ActiveCfg = Debug|x64
+		{28B5D777-DDF2-4B6B-B34F-31D938813856}.Debug|x64.Build.0 = Debug|x64
+		{28B5D777-DDF2-4B6B-B34F-31D938813856}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
+		{28B5D777-DDF2-4B6B-B34F-31D938813856}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
+		{28B5D777-DDF2-4B6B-B34F-31D938813856}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
+		{28B5D777-DDF2-4B6B-B34F-31D938813856}.PGInstrument|x64.Build.0 = PGInstrument|x64
+		{28B5D777-DDF2-4B6B-B34F-31D938813856}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
+		{28B5D777-DDF2-4B6B-B34F-31D938813856}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
+		{28B5D777-DDF2-4B6B-B34F-31D938813856}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
+		{28B5D777-DDF2-4B6B-B34F-31D938813856}.PGUpdate|x64.Build.0 = PGUpdate|x64
+		{28B5D777-DDF2-4B6B-B34F-31D938813856}.Release|Win32.ActiveCfg = Release|Win32
+		{28B5D777-DDF2-4B6B-B34F-31D938813856}.Release|Win32.Build.0 = Release|Win32
+		{28B5D777-DDF2-4B6B-B34F-31D938813856}.Release|x64.ActiveCfg = Release|x64
+		{28B5D777-DDF2-4B6B-B34F-31D938813856}.Release|x64.Build.0 = Release|x64
+		{B4D38F3F-68FB-42EC-A45D-E00657BB3627}.Debug|Win32.ActiveCfg = Debug|Win32
+		{B4D38F3F-68FB-42EC-A45D-E00657BB3627}.Debug|Win32.Build.0 = Debug|Win32
+		{B4D38F3F-68FB-42EC-A45D-E00657BB3627}.Debug|x64.ActiveCfg = Debug|x64
+		{B4D38F3F-68FB-42EC-A45D-E00657BB3627}.Debug|x64.Build.0 = Debug|x64
+		{B4D38F3F-68FB-42EC-A45D-E00657BB3627}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
+		{B4D38F3F-68FB-42EC-A45D-E00657BB3627}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
+		{B4D38F3F-68FB-42EC-A45D-E00657BB3627}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
+		{B4D38F3F-68FB-42EC-A45D-E00657BB3627}.PGInstrument|x64.Build.0 = PGInstrument|x64
+		{B4D38F3F-68FB-42EC-A45D-E00657BB3627}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
+		{B4D38F3F-68FB-42EC-A45D-E00657BB3627}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
+		{B4D38F3F-68FB-42EC-A45D-E00657BB3627}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
+		{B4D38F3F-68FB-42EC-A45D-E00657BB3627}.PGUpdate|x64.Build.0 = PGUpdate|x64
+		{B4D38F3F-68FB-42EC-A45D-E00657BB3627}.Release|Win32.ActiveCfg = Release|Win32
+		{B4D38F3F-68FB-42EC-A45D-E00657BB3627}.Release|Win32.Build.0 = Release|Win32
+		{B4D38F3F-68FB-42EC-A45D-E00657BB3627}.Release|x64.ActiveCfg = Release|x64
+		{B4D38F3F-68FB-42EC-A45D-E00657BB3627}.Release|x64.Build.0 = Release|x64
+		{0E9791DB-593A-465F-98BC-681011311618}.Debug|Win32.ActiveCfg = Debug|Win32
+		{0E9791DB-593A-465F-98BC-681011311618}.Debug|Win32.Build.0 = Debug|Win32
+		{0E9791DB-593A-465F-98BC-681011311618}.Debug|x64.ActiveCfg = Debug|x64
+		{0E9791DB-593A-465F-98BC-681011311618}.Debug|x64.Build.0 = Debug|x64
+		{0E9791DB-593A-465F-98BC-681011311618}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
+		{0E9791DB-593A-465F-98BC-681011311618}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
+		{0E9791DB-593A-465F-98BC-681011311618}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
+		{0E9791DB-593A-465F-98BC-681011311618}.PGInstrument|x64.Build.0 = PGInstrument|x64
+		{0E9791DB-593A-465F-98BC-681011311618}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
+		{0E9791DB-593A-465F-98BC-681011311618}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
+		{0E9791DB-593A-465F-98BC-681011311618}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
+		{0E9791DB-593A-465F-98BC-681011311618}.PGUpdate|x64.Build.0 = PGUpdate|x64
+		{0E9791DB-593A-465F-98BC-681011311618}.Release|Win32.ActiveCfg = Release|Win32
+		{0E9791DB-593A-465F-98BC-681011311618}.Release|Win32.Build.0 = Release|Win32
+		{0E9791DB-593A-465F-98BC-681011311618}.Release|x64.ActiveCfg = Release|x64
+		{0E9791DB-593A-465F-98BC-681011311618}.Release|x64.Build.0 = Release|x64
+		{9EC7190A-249F-4180-A900-548FDCF3055F}.Debug|Win32.ActiveCfg = Debug|Win32
+		{9EC7190A-249F-4180-A900-548FDCF3055F}.Debug|Win32.Build.0 = Debug|Win32
+		{9EC7190A-249F-4180-A900-548FDCF3055F}.Debug|x64.ActiveCfg = Debug|x64
+		{9EC7190A-249F-4180-A900-548FDCF3055F}.Debug|x64.Build.0 = Debug|x64
+		{9EC7190A-249F-4180-A900-548FDCF3055F}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
+		{9EC7190A-249F-4180-A900-548FDCF3055F}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
+		{9EC7190A-249F-4180-A900-548FDCF3055F}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
+		{9EC7190A-249F-4180-A900-548FDCF3055F}.PGInstrument|x64.Build.0 = PGInstrument|x64
+		{9EC7190A-249F-4180-A900-548FDCF3055F}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
+		{9EC7190A-249F-4180-A900-548FDCF3055F}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
+		{9EC7190A-249F-4180-A900-548FDCF3055F}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
+		{9EC7190A-249F-4180-A900-548FDCF3055F}.PGUpdate|x64.Build.0 = PGUpdate|x64
+		{9EC7190A-249F-4180-A900-548FDCF3055F}.Release|Win32.ActiveCfg = Release|Win32
+		{9EC7190A-249F-4180-A900-548FDCF3055F}.Release|Win32.Build.0 = Release|Win32
+		{9EC7190A-249F-4180-A900-548FDCF3055F}.Release|x64.ActiveCfg = Release|x64
+		{9EC7190A-249F-4180-A900-548FDCF3055F}.Release|x64.Build.0 = Release|x64
+		{17E1E049-C309-4D79-843F-AE483C264AEA}.Debug|Win32.ActiveCfg = Debug|Win32
+		{17E1E049-C309-4D79-843F-AE483C264AEA}.Debug|Win32.Build.0 = Debug|Win32
+		{17E1E049-C309-4D79-843F-AE483C264AEA}.Debug|x64.ActiveCfg = Debug|x64
+		{17E1E049-C309-4D79-843F-AE483C264AEA}.Debug|x64.Build.0 = Debug|x64
+		{17E1E049-C309-4D79-843F-AE483C264AEA}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
+		{17E1E049-C309-4D79-843F-AE483C264AEA}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
+		{17E1E049-C309-4D79-843F-AE483C264AEA}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
+		{17E1E049-C309-4D79-843F-AE483C264AEA}.PGInstrument|x64.Build.0 = PGInstrument|x64
+		{17E1E049-C309-4D79-843F-AE483C264AEA}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
+		{17E1E049-C309-4D79-843F-AE483C264AEA}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
+		{17E1E049-C309-4D79-843F-AE483C264AEA}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
+		{17E1E049-C309-4D79-843F-AE483C264AEA}.PGUpdate|x64.Build.0 = PGUpdate|x64
+		{17E1E049-C309-4D79-843F-AE483C264AEA}.Release|Win32.ActiveCfg = Release|Win32
+		{17E1E049-C309-4D79-843F-AE483C264AEA}.Release|Win32.Build.0 = Release|Win32
+		{17E1E049-C309-4D79-843F-AE483C264AEA}.Release|x64.ActiveCfg = Release|x64
+		{17E1E049-C309-4D79-843F-AE483C264AEA}.Release|x64.Build.0 = Release|x64
+		{31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Debug|Win32.ActiveCfg = Debug|Win32
+		{31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Debug|Win32.Build.0 = Debug|Win32
+		{31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Debug|x64.ActiveCfg = Debug|x64
+		{31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Debug|x64.Build.0 = Debug|x64
+		{31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
+		{31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
+		{31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
+		{31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGInstrument|x64.Build.0 = PGInstrument|x64
+		{31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
+		{31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
+		{31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
+		{31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGUpdate|x64.Build.0 = PGUpdate|x64
+		{31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Release|Win32.ActiveCfg = Release|Win32
+		{31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Release|Win32.Build.0 = Release|Win32
+		{31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Release|x64.ActiveCfg = Release|x64
+		{31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Release|x64.Build.0 = Release|x64
+		{86937F53-C189-40EF-8CE8-8759D8E7D480}.Debug|Win32.ActiveCfg = Debug|Win32
+		{86937F53-C189-40EF-8CE8-8759D8E7D480}.Debug|Win32.Build.0 = Debug|Win32
+		{86937F53-C189-40EF-8CE8-8759D8E7D480}.Debug|x64.ActiveCfg = Debug|x64
+		{86937F53-C189-40EF-8CE8-8759D8E7D480}.Debug|x64.Build.0 = Debug|x64
+		{86937F53-C189-40EF-8CE8-8759D8E7D480}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
+		{86937F53-C189-40EF-8CE8-8759D8E7D480}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
+		{86937F53-C189-40EF-8CE8-8759D8E7D480}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
+		{86937F53-C189-40EF-8CE8-8759D8E7D480}.PGInstrument|x64.Build.0 = PGInstrument|x64
+		{86937F53-C189-40EF-8CE8-8759D8E7D480}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
+		{86937F53-C189-40EF-8CE8-8759D8E7D480}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
+		{86937F53-C189-40EF-8CE8-8759D8E7D480}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
+		{86937F53-C189-40EF-8CE8-8759D8E7D480}.PGUpdate|x64.Build.0 = PGUpdate|x64
+		{86937F53-C189-40EF-8CE8-8759D8E7D480}.Release|Win32.ActiveCfg = Release|Win32
+		{86937F53-C189-40EF-8CE8-8759D8E7D480}.Release|Win32.Build.0 = Release|Win32
+		{86937F53-C189-40EF-8CE8-8759D8E7D480}.Release|x64.ActiveCfg = Release|x64
+		{86937F53-C189-40EF-8CE8-8759D8E7D480}.Release|x64.Build.0 = Release|x64
+		{13CECB97-4119-4316-9D42-8534019A5A44}.Debug|Win32.ActiveCfg = Debug|Win32
+		{13CECB97-4119-4316-9D42-8534019A5A44}.Debug|Win32.Build.0 = Debug|Win32
+		{13CECB97-4119-4316-9D42-8534019A5A44}.Debug|x64.ActiveCfg = Debug|x64
+		{13CECB97-4119-4316-9D42-8534019A5A44}.Debug|x64.Build.0 = Debug|x64
+		{13CECB97-4119-4316-9D42-8534019A5A44}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
+		{13CECB97-4119-4316-9D42-8534019A5A44}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
+		{13CECB97-4119-4316-9D42-8534019A5A44}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
+		{13CECB97-4119-4316-9D42-8534019A5A44}.PGInstrument|x64.Build.0 = PGInstrument|x64
+		{13CECB97-4119-4316-9D42-8534019A5A44}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
+		{13CECB97-4119-4316-9D42-8534019A5A44}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
+		{13CECB97-4119-4316-9D42-8534019A5A44}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
+		{13CECB97-4119-4316-9D42-8534019A5A44}.PGUpdate|x64.Build.0 = PGUpdate|x64
+		{13CECB97-4119-4316-9D42-8534019A5A44}.Release|Win32.ActiveCfg = Release|Win32
+		{13CECB97-4119-4316-9D42-8534019A5A44}.Release|Win32.Build.0 = Release|Win32
+		{13CECB97-4119-4316-9D42-8534019A5A44}.Release|x64.ActiveCfg = Release|x64
+		{13CECB97-4119-4316-9D42-8534019A5A44}.Release|x64.Build.0 = Release|x64
+		{C6E20F84-3247-4AD6-B051-B073268F73BA}.Debug|Win32.ActiveCfg = Debug|Win32
+		{C6E20F84-3247-4AD6-B051-B073268F73BA}.Debug|Win32.Build.0 = Debug|Win32
+		{C6E20F84-3247-4AD6-B051-B073268F73BA}.Debug|x64.ActiveCfg = Debug|x64
+		{C6E20F84-3247-4AD6-B051-B073268F73BA}.Debug|x64.Build.0 = Debug|x64
+		{C6E20F84-3247-4AD6-B051-B073268F73BA}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
+		{C6E20F84-3247-4AD6-B051-B073268F73BA}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
+		{C6E20F84-3247-4AD6-B051-B073268F73BA}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
+		{C6E20F84-3247-4AD6-B051-B073268F73BA}.PGInstrument|x64.Build.0 = PGInstrument|x64
+		{C6E20F84-3247-4AD6-B051-B073268F73BA}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
+		{C6E20F84-3247-4AD6-B051-B073268F73BA}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
+		{C6E20F84-3247-4AD6-B051-B073268F73BA}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
+		{C6E20F84-3247-4AD6-B051-B073268F73BA}.PGUpdate|x64.Build.0 = PGUpdate|x64
+		{C6E20F84-3247-4AD6-B051-B073268F73BA}.Release|Win32.ActiveCfg = Release|Win32
+		{C6E20F84-3247-4AD6-B051-B073268F73BA}.Release|Win32.Build.0 = Release|Win32
+		{C6E20F84-3247-4AD6-B051-B073268F73BA}.Release|x64.ActiveCfg = Release|x64
+		{C6E20F84-3247-4AD6-B051-B073268F73BA}.Release|x64.Build.0 = Release|x64
+		{6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Debug|Win32.ActiveCfg = Debug|Win32
+		{6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Debug|Win32.Build.0 = Debug|Win32
+		{6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Debug|x64.ActiveCfg = Debug|x64
+		{6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Debug|x64.Build.0 = Debug|x64
+		{6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
+		{6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
+		{6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
+		{6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGInstrument|x64.Build.0 = PGInstrument|x64
+		{6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
+		{6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
+		{6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
+		{6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGUpdate|x64.Build.0 = PGUpdate|x64
+		{6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Release|Win32.ActiveCfg = Release|Win32
+		{6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Release|Win32.Build.0 = Release|Win32
+		{6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Release|x64.ActiveCfg = Release|x64
+		{6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Release|x64.Build.0 = Release|x64
+		{4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Debug|Win32.ActiveCfg = Debug|Win32
+		{4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Debug|Win32.Build.0 = Debug|Win32
+		{4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Debug|x64.ActiveCfg = Debug|x64
+		{4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Debug|x64.Build.0 = Debug|x64
+		{4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
+		{4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
+		{4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
+		{4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGInstrument|x64.Build.0 = PGInstrument|x64
+		{4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
+		{4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
+		{4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
+		{4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGUpdate|x64.Build.0 = PGUpdate|x64
+		{4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Release|Win32.ActiveCfg = Release|Win32
+		{4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Release|Win32.Build.0 = Release|Win32
+		{4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Release|x64.ActiveCfg = Release|x64
+		{4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Release|x64.Build.0 = Release|x64
+		{73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Debug|Win32.ActiveCfg = Debug|Win32
+		{73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Debug|Win32.Build.0 = Debug|Win32
+		{73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Debug|x64.ActiveCfg = Debug|x64
+		{73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Debug|x64.Build.0 = Debug|x64
+		{73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
+		{73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
+		{73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
+		{73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGInstrument|x64.Build.0 = PGInstrument|x64
+		{73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
+		{73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
+		{73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
+		{73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGUpdate|x64.Build.0 = PGUpdate|x64
+		{73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Release|Win32.ActiveCfg = Release|Win32
+		{73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Release|Win32.Build.0 = Release|Win32
+		{73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Release|x64.ActiveCfg = Release|x64
+		{73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Release|x64.Build.0 = Release|x64
+		{18CAE28C-B454-46C1-87A0-493D91D97F03}.Debug|Win32.ActiveCfg = Debug|Win32
+		{18CAE28C-B454-46C1-87A0-493D91D97F03}.Debug|Win32.Build.0 = Debug|Win32
+		{18CAE28C-B454-46C1-87A0-493D91D97F03}.Debug|x64.ActiveCfg = Debug|x64
+		{18CAE28C-B454-46C1-87A0-493D91D97F03}.Debug|x64.Build.0 = Debug|x64
+		{18CAE28C-B454-46C1-87A0-493D91D97F03}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
+		{18CAE28C-B454-46C1-87A0-493D91D97F03}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
+		{18CAE28C-B454-46C1-87A0-493D91D97F03}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
+		{18CAE28C-B454-46C1-87A0-493D91D97F03}.PGInstrument|x64.Build.0 = PGInstrument|x64
+		{18CAE28C-B454-46C1-87A0-493D91D97F03}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
+		{18CAE28C-B454-46C1-87A0-493D91D97F03}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
+		{18CAE28C-B454-46C1-87A0-493D91D97F03}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
+		{18CAE28C-B454-46C1-87A0-493D91D97F03}.PGUpdate|x64.Build.0 = PGUpdate|x64
+		{18CAE28C-B454-46C1-87A0-493D91D97F03}.Release|Win32.ActiveCfg = Release|Win32
+		{18CAE28C-B454-46C1-87A0-493D91D97F03}.Release|Win32.Build.0 = Release|Win32
+		{18CAE28C-B454-46C1-87A0-493D91D97F03}.Release|x64.ActiveCfg = Release|x64
+		{18CAE28C-B454-46C1-87A0-493D91D97F03}.Release|x64.Build.0 = Release|x64
+		{ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Debug|Win32.ActiveCfg = Debug|Win32
+		{ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Debug|Win32.Build.0 = Debug|Win32
+		{ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Debug|x64.ActiveCfg = Debug|x64
+		{ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Debug|x64.Build.0 = Debug|x64
+		{ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
+		{ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
+		{ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
+		{ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGInstrument|x64.Build.0 = PGInstrument|x64
+		{ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
+		{ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
+		{ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
+		{ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGUpdate|x64.Build.0 = PGUpdate|x64
+		{ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Release|Win32.ActiveCfg = Release|Win32
+		{ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Release|Win32.Build.0 = Release|Win32
+		{ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Release|x64.ActiveCfg = Release|x64
+		{ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Release|x64.Build.0 = Release|x64
+		{D06B6426-4762-44CC-8BAD-D79052507F2F}.Debug|Win32.ActiveCfg = Debug|Win32
+		{D06B6426-4762-44CC-8BAD-D79052507F2F}.Debug|Win32.Build.0 = Debug|Win32
+		{D06B6426-4762-44CC-8BAD-D79052507F2F}.Debug|x64.ActiveCfg = Debug|x64
+		{D06B6426-4762-44CC-8BAD-D79052507F2F}.Debug|x64.Build.0 = Debug|x64
+		{D06B6426-4762-44CC-8BAD-D79052507F2F}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
+		{D06B6426-4762-44CC-8BAD-D79052507F2F}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
+		{D06B6426-4762-44CC-8BAD-D79052507F2F}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
+		{D06B6426-4762-44CC-8BAD-D79052507F2F}.PGInstrument|x64.Build.0 = PGInstrument|x64
+		{D06B6426-4762-44CC-8BAD-D79052507F2F}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
+		{D06B6426-4762-44CC-8BAD-D79052507F2F}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
+		{D06B6426-4762-44CC-8BAD-D79052507F2F}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
+		{D06B6426-4762-44CC-8BAD-D79052507F2F}.PGUpdate|x64.Build.0 = PGUpdate|x64
+		{D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|Win32.ActiveCfg = Release|Win32
+		{D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|Win32.Build.0 = Release|Win32
+		{D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|x64.ActiveCfg = Release|x64
+		{D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|x64.Build.0 = Release|x64
+		{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Debug|Win32.ActiveCfg = Release|Win32
+		{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Debug|x64.ActiveCfg = Release|x64
+		{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGInstrument|Win32.ActiveCfg = Release|Win32
+		{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGInstrument|x64.ActiveCfg = Release|x64
+		{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGUpdate|Win32.ActiveCfg = Release|Win32
+		{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGUpdate|x64.ActiveCfg = Release|x64
+		{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Release|Win32.ActiveCfg = Release|Win32
+		{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Release|x64.ActiveCfg = Release|x64
+		{447F05A8-F581-4CAC-A466-5AC7936E207E}.Debug|Win32.ActiveCfg = Debug|Win32
+		{447F05A8-F581-4CAC-A466-5AC7936E207E}.Debug|Win32.Build.0 = Debug|Win32
+		{447F05A8-F581-4CAC-A466-5AC7936E207E}.Debug|x64.ActiveCfg = Debug|x64
+		{447F05A8-F581-4CAC-A466-5AC7936E207E}.Debug|x64.Build.0 = Debug|x64
+		{447F05A8-F581-4CAC-A466-5AC7936E207E}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
+		{447F05A8-F581-4CAC-A466-5AC7936E207E}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
+		{447F05A8-F581-4CAC-A466-5AC7936E207E}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
+		{447F05A8-F581-4CAC-A466-5AC7936E207E}.PGInstrument|x64.Build.0 = PGInstrument|x64
+		{447F05A8-F581-4CAC-A466-5AC7936E207E}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
+		{447F05A8-F581-4CAC-A466-5AC7936E207E}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
+		{447F05A8-F581-4CAC-A466-5AC7936E207E}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
+		{447F05A8-F581-4CAC-A466-5AC7936E207E}.PGUpdate|x64.Build.0 = PGUpdate|x64
+		{447F05A8-F581-4CAC-A466-5AC7936E207E}.Release|Win32.ActiveCfg = Release|Win32
+		{447F05A8-F581-4CAC-A466-5AC7936E207E}.Release|Win32.Build.0 = Release|Win32
+		{447F05A8-F581-4CAC-A466-5AC7936E207E}.Release|x64.ActiveCfg = Release|x64
+		{447F05A8-F581-4CAC-A466-5AC7936E207E}.Release|x64.Build.0 = Release|x64
+		{62172C7D-B39E-409A-B352-370FF5098C19}.Debug|Win32.ActiveCfg = Debug|Win32
+		{62172C7D-B39E-409A-B352-370FF5098C19}.Debug|Win32.Build.0 = Debug|Win32
+		{62172C7D-B39E-409A-B352-370FF5098C19}.Debug|x64.ActiveCfg = Debug|x64
+		{62172C7D-B39E-409A-B352-370FF5098C19}.Debug|x64.Build.0 = Debug|x64
+		{62172C7D-B39E-409A-B352-370FF5098C19}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
+		{62172C7D-B39E-409A-B352-370FF5098C19}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
+		{62172C7D-B39E-409A-B352-370FF5098C19}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
+		{62172C7D-B39E-409A-B352-370FF5098C19}.PGInstrument|x64.Build.0 = PGInstrument|x64
+		{62172C7D-B39E-409A-B352-370FF5098C19}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
+		{62172C7D-B39E-409A-B352-370FF5098C19}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
+		{62172C7D-B39E-409A-B352-370FF5098C19}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
+		{62172C7D-B39E-409A-B352-370FF5098C19}.PGUpdate|x64.Build.0 = PGUpdate|x64
+		{62172C7D-B39E-409A-B352-370FF5098C19}.Release|Win32.ActiveCfg = Release|Win32
+		{62172C7D-B39E-409A-B352-370FF5098C19}.Release|Win32.Build.0 = Release|Win32
+		{62172C7D-B39E-409A-B352-370FF5098C19}.Release|x64.ActiveCfg = Release|x64
+		{62172C7D-B39E-409A-B352-370FF5098C19}.Release|x64.Build.0 = Release|x64
+		{A1A295E5-463C-437F-81CA-1F32367685DA}.Debug|Win32.ActiveCfg = Debug|Win32
+		{A1A295E5-463C-437F-81CA-1F32367685DA}.Debug|Win32.Build.0 = Debug|Win32
+		{A1A295E5-463C-437F-81CA-1F32367685DA}.Debug|x64.ActiveCfg = Debug|x64
+		{A1A295E5-463C-437F-81CA-1F32367685DA}.Debug|x64.Build.0 = Debug|x64
+		{A1A295E5-463C-437F-81CA-1F32367685DA}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
+		{A1A295E5-463C-437F-81CA-1F32367685DA}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
+		{A1A295E5-463C-437F-81CA-1F32367685DA}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
+		{A1A295E5-463C-437F-81CA-1F32367685DA}.PGInstrument|x64.Build.0 = PGInstrument|x64
+		{A1A295E5-463C-437F-81CA-1F32367685DA}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
+		{A1A295E5-463C-437F-81CA-1F32367685DA}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
+		{A1A295E5-463C-437F-81CA-1F32367685DA}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
+		{A1A295E5-463C-437F-81CA-1F32367685DA}.PGUpdate|x64.Build.0 = PGUpdate|x64
+		{A1A295E5-463C-437F-81CA-1F32367685DA}.Release|Win32.ActiveCfg = Release|Win32
+		{A1A295E5-463C-437F-81CA-1F32367685DA}.Release|Win32.Build.0 = Release|Win32
+		{A1A295E5-463C-437F-81CA-1F32367685DA}.Release|x64.ActiveCfg = Release|x64
+		{A1A295E5-463C-437F-81CA-1F32367685DA}.Release|x64.Build.0 = Release|x64
+		{9E48B300-37D1-11DD-8C41-005056C00008}.Debug|Win32.ActiveCfg = Debug|Win32
+		{9E48B300-37D1-11DD-8C41-005056C00008}.Debug|Win32.Build.0 = Debug|Win32
+		{9E48B300-37D1-11DD-8C41-005056C00008}.Debug|x64.ActiveCfg = Debug|x64
+		{9E48B300-37D1-11DD-8C41-005056C00008}.Debug|x64.Build.0 = Debug|x64
+		{9E48B300-37D1-11DD-8C41-005056C00008}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
+		{9E48B300-37D1-11DD-8C41-005056C00008}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
+		{9E48B300-37D1-11DD-8C41-005056C00008}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
+		{9E48B300-37D1-11DD-8C41-005056C00008}.PGInstrument|x64.Build.0 = PGInstrument|x64
+		{9E48B300-37D1-11DD-8C41-005056C00008}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
+		{9E48B300-37D1-11DD-8C41-005056C00008}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
+		{9E48B300-37D1-11DD-8C41-005056C00008}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
+		{9E48B300-37D1-11DD-8C41-005056C00008}.PGUpdate|x64.Build.0 = PGUpdate|x64
+		{9E48B300-37D1-11DD-8C41-005056C00008}.Release|Win32.ActiveCfg = Release|Win32
+		{9E48B300-37D1-11DD-8C41-005056C00008}.Release|Win32.Build.0 = Release|Win32
+		{9E48B300-37D1-11DD-8C41-005056C00008}.Release|x64.ActiveCfg = Release|x64
+		{9E48B300-37D1-11DD-8C41-005056C00008}.Release|x64.Build.0 = Release|x64
+		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Debug|Win32.ActiveCfg = Debug|Win32
+		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Debug|Win32.Build.0 = Debug|Win32
+		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Debug|x64.ActiveCfg = Debug|x64
+		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Debug|x64.Build.0 = Debug|x64
+		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.PGInstrument|Win32.ActiveCfg = Release|Win32
+		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.PGInstrument|Win32.Build.0 = Release|Win32
+		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.PGInstrument|x64.ActiveCfg = Release|x64
+		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.PGInstrument|x64.Build.0 = Release|x64
+		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.PGUpdate|Win32.ActiveCfg = Release|Win32
+		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.PGUpdate|Win32.Build.0 = Release|Win32
+		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.PGUpdate|x64.ActiveCfg = Release|x64
+		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.PGUpdate|x64.Build.0 = Release|x64
+		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Release|Win32.ActiveCfg = Release|Win32
+		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Release|Win32.Build.0 = Release|Win32
+		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Release|x64.ActiveCfg = Release|x64
+		{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Release|x64.Build.0 = Release|x64
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal

Modified: python/branches/py3k/PC/VS8.0/pyexpat.vcproj
==============================================================================
--- python/branches/py3k/PC/VS8.0/pyexpat.vcproj	(original)
+++ python/branches/py3k/PC/VS8.0/pyexpat.vcproj	Sat Jun 14 01:34:35 2008
@@ -1,553 +1,553 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="8.00"
-	Name="pyexpat"
-	ProjectGUID="{D06B6426-4762-44CC-8BAD-D79052507F2F}"
-	RootNamespace="pyexpat"
-	Keyword="Win32Proj"
-	TargetFrameworkVersion="196613"
-	>
-	<Platforms>
-		<Platform
-			Name="Win32"
-		/>
-		<Platform
-			Name="x64"
-		/>
-	</Platforms>
-	<ToolFiles>
-	</ToolFiles>
-	<Configurations>
-		<Configuration
-			Name="Debug|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd_d.vsprops"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories=".\..\..\Modules\expat"
-				PreprocessorDefinitions="PYEXPAT_EXPORTS;HAVE_EXPAT_H;XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;XML_STATIC;HAVE_MEMMOVE"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Debug|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd_d.vsprops;.\x64.vsprops"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories=".\..\..\Modules\expat"
-				PreprocessorDefinitions="PYEXPAT_EXPORTS;HAVE_EXPAT_H;XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;XML_STATIC;HAVE_MEMMOVE"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories=".\..\..\Modules\expat"
-				PreprocessorDefinitions="PYEXPAT_EXPORTS;HAVE_EXPAT_H;XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;XML_STATIC;HAVE_MEMMOVE"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories=".\..\..\Modules\expat"
-				PreprocessorDefinitions="PYEXPAT_EXPORTS;HAVE_EXPAT_H;XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;XML_STATIC;HAVE_MEMMOVE"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGInstrument|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\pginstrument.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories=".\..\..\Modules\expat"
-				PreprocessorDefinitions="PYEXPAT_EXPORTS;HAVE_EXPAT_H;XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;XML_STATIC;HAVE_MEMMOVE"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGInstrument|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pginstrument.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories=".\..\..\Modules\expat"
-				PreprocessorDefinitions="PYEXPAT_EXPORTS;HAVE_EXPAT_H;XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;XML_STATIC;HAVE_MEMMOVE"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				TargetMachine="17"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGUpdate|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\pgupdate.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories=".\..\..\Modules\expat"
-				PreprocessorDefinitions="PYEXPAT_EXPORTS;HAVE_EXPAT_H;XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;XML_STATIC;HAVE_MEMMOVE"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGUpdate|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pgupdate.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories=".\..\..\Modules\expat"
-				PreprocessorDefinitions="PYEXPAT_EXPORTS;HAVE_EXPAT_H;XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;XML_STATIC;HAVE_MEMMOVE"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				TargetMachine="17"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<Filter
-			Name="Header Files"
-			>
-			<File
-				RelativePath="..\..\Modules\expat\xmlrole.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\expat\xmltok.h"
-				>
-			</File>
-		</Filter>
-		<Filter
-			Name="Source Files"
-			>
-			<File
-				RelativePath="..\..\Modules\pyexpat.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\expat\xmlparse.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\expat\xmlrole.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\expat\xmltok.c"
-				>
-			</File>
-		</Filter>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="pyexpat"
+	ProjectGUID="{D06B6426-4762-44CC-8BAD-D79052507F2F}"
+	RootNamespace="pyexpat"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd_d.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories=".\..\..\Modules\expat"
+				PreprocessorDefinitions="PYEXPAT_EXPORTS;HAVE_EXPAT_H;XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;XML_STATIC;HAVE_MEMMOVE"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd_d.vsprops;.\x64.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories=".\..\..\Modules\expat"
+				PreprocessorDefinitions="PYEXPAT_EXPORTS;HAVE_EXPAT_H;XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;XML_STATIC;HAVE_MEMMOVE"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories=".\..\..\Modules\expat"
+				PreprocessorDefinitions="PYEXPAT_EXPORTS;HAVE_EXPAT_H;XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;XML_STATIC;HAVE_MEMMOVE"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories=".\..\..\Modules\expat"
+				PreprocessorDefinitions="PYEXPAT_EXPORTS;HAVE_EXPAT_H;XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;XML_STATIC;HAVE_MEMMOVE"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\pginstrument.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories=".\..\..\Modules\expat"
+				PreprocessorDefinitions="PYEXPAT_EXPORTS;HAVE_EXPAT_H;XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;XML_STATIC;HAVE_MEMMOVE"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pginstrument.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories=".\..\..\Modules\expat"
+				PreprocessorDefinitions="PYEXPAT_EXPORTS;HAVE_EXPAT_H;XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;XML_STATIC;HAVE_MEMMOVE"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\pgupdate.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories=".\..\..\Modules\expat"
+				PreprocessorDefinitions="PYEXPAT_EXPORTS;HAVE_EXPAT_H;XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;XML_STATIC;HAVE_MEMMOVE"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pgupdate.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories=".\..\..\Modules\expat"
+				PreprocessorDefinitions="PYEXPAT_EXPORTS;HAVE_EXPAT_H;XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;XML_STATIC;HAVE_MEMMOVE"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Header Files"
+			>
+			<File
+				RelativePath="..\..\Modules\expat\xmlrole.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\expat\xmltok.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Source Files"
+			>
+			<File
+				RelativePath="..\..\Modules\pyexpat.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\expat\xmlparse.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\expat\xmlrole.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\expat\xmltok.c"
+				>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Modified: python/branches/py3k/PC/VS8.0/python.vcproj
==============================================================================
--- python/branches/py3k/PC/VS8.0/python.vcproj	(original)
+++ python/branches/py3k/PC/VS8.0/python.vcproj	Sat Jun 14 01:34:35 2008
@@ -1,637 +1,637 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="8.00"
-	Name="python"
-	ProjectGUID="{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}"
-	TargetFrameworkVersion="131072"
-	>
-	<Platforms>
-		<Platform
-			Name="Win32"
-		/>
-		<Platform
-			Name="x64"
-		/>
-	</Platforms>
-	<ToolFiles>
-	</ToolFiles>
-	<Configurations>
-		<Configuration
-			Name="Release|Win32"
-			ConfigurationType="1"
-			InheritedPropertySheets=".\pyproject.vsprops;.\release.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="2"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories=""
-				PreprocessorDefinitions="_CONSOLE"
-				StringPooling="true"
-				RuntimeLibrary="2"
-				EnableFunctionLevelLinking="true"
-				CompileAs="0"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="NDEBUG"
-				Culture="1033"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				OutputFile="$(OutDir)\python.exe"
-				SubSystem="1"
-				StackReserveSize="2000000"
-				BaseAddress="0x1d000000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|x64"
-			ConfigurationType="1"
-			InheritedPropertySheets=".\pyproject.vsprops;.\x64.vsprops;.\release.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="2"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories=""
-				PreprocessorDefinitions="_CONSOLE"
-				StringPooling="true"
-				RuntimeLibrary="2"
-				EnableFunctionLevelLinking="true"
-				CompileAs="0"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="NDEBUG"
-				Culture="1033"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				OutputFile="$(OutDir)\python.exe"
-				SubSystem="1"
-				StackReserveSize="2000000"
-				BaseAddress="0x1d000000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Debug|Win32"
-			ConfigurationType="1"
-			InheritedPropertySheets=".\pyproject.vsprops;.\debug.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="0"
-				EnableIntrinsicFunctions="false"
-				AdditionalIncludeDirectories=""
-				PreprocessorDefinitions="_CONSOLE"
-				RuntimeLibrary="3"
-				BrowseInformation="1"
-				CompileAs="0"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="_DEBUG"
-				Culture="1033"
-				AdditionalIncludeDirectories="..\..\Include"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				OutputFile="$(OutDir)\python_d.exe"
-				SubSystem="1"
-				StackReserveSize="2000000"
-				BaseAddress="0x1d000000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Debug|x64"
-			ConfigurationType="1"
-			InheritedPropertySheets=".\pyproject.vsprops;.\x64.vsprops;.\debug.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="2"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="0"
-				EnableIntrinsicFunctions="false"
-				AdditionalIncludeDirectories=""
-				PreprocessorDefinitions="_CONSOLE"
-				RuntimeLibrary="3"
-				BrowseInformation="1"
-				CompileAs="0"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="_DEBUG"
-				Culture="1033"
-				AdditionalIncludeDirectories="..\..\Include"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				OutputFile="$(OutDir)\python_d.exe"
-				SubSystem="1"
-				StackReserveSize="2100000"
-				BaseAddress="0x1d000000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGInstrument|Win32"
-			ConfigurationType="1"
-			InheritedPropertySheets=".\pyproject.vsprops;.\release.vsprops;.\pginstrument.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="2"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories=""
-				PreprocessorDefinitions="_CONSOLE"
-				StringPooling="true"
-				RuntimeLibrary="2"
-				EnableFunctionLevelLinking="true"
-				CompileAs="0"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="NDEBUG"
-				Culture="1033"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				OutputFile="$(OutDir)\python.exe"
-				SubSystem="1"
-				StackReserveSize="2000000"
-				BaseAddress="0x1d000000"
-				ImportLibrary=""
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGInstrument|x64"
-			ConfigurationType="1"
-			InheritedPropertySheets=".\pyproject.vsprops;.\x64.vsprops;.\release.vsprops;.\pginstrument.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="2"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories=""
-				PreprocessorDefinitions="_CONSOLE"
-				StringPooling="true"
-				RuntimeLibrary="2"
-				EnableFunctionLevelLinking="true"
-				CompileAs="0"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="NDEBUG"
-				Culture="1033"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				OutputFile="$(OutDir)\python.exe"
-				SubSystem="1"
-				StackReserveSize="2000000"
-				BaseAddress="0x1d000000"
-				ImportLibrary=""
-				TargetMachine="17"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGUpdate|Win32"
-			ConfigurationType="1"
-			InheritedPropertySheets=".\pyproject.vsprops;.\release.vsprops;.\pgupdate.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="2"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories=""
-				PreprocessorDefinitions="_CONSOLE"
-				StringPooling="true"
-				RuntimeLibrary="2"
-				EnableFunctionLevelLinking="true"
-				CompileAs="0"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="NDEBUG"
-				Culture="1033"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				OutputFile="$(OutDir)\python.exe"
-				SubSystem="1"
-				StackReserveSize="2000000"
-				BaseAddress="0x1d000000"
-				ImportLibrary=""
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGUpdate|x64"
-			ConfigurationType="1"
-			InheritedPropertySheets=".\pyproject.vsprops;.\x64.vsprops;.\release.vsprops;.\pgupdate.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="2"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories=""
-				PreprocessorDefinitions="_CONSOLE"
-				StringPooling="true"
-				RuntimeLibrary="2"
-				EnableFunctionLevelLinking="true"
-				CompileAs="0"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="NDEBUG"
-				Culture="1033"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				OutputFile="$(OutDir)\python.exe"
-				SubSystem="1"
-				StackReserveSize="2000000"
-				BaseAddress="0x1d000000"
-				ImportLibrary=""
-				TargetMachine="17"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<Filter
-			Name="Resource Files"
-			>
-			<File
-				RelativePath="..\..\PC\pycon.ico"
-				>
-			</File>
-			<File
-				RelativePath="..\..\PC\python_exe.rc"
-				>
-			</File>
-		</Filter>
-		<Filter
-			Name="Source Files"
-			>
-			<File
-				RelativePath="..\..\Modules\python.c"
-				>
-			</File>
-		</Filter>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="python"
+	ProjectGUID="{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}"
+	TargetFrameworkVersion="131072"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Release|Win32"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\pyproject.vsprops;.\release.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories=""
+				PreprocessorDefinitions="_CONSOLE"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1033"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\python.exe"
+				SubSystem="1"
+				StackReserveSize="2000000"
+				BaseAddress="0x1d000000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\pyproject.vsprops;.\x64.vsprops;.\release.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories=""
+				PreprocessorDefinitions="_CONSOLE"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1033"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\python.exe"
+				SubSystem="1"
+				StackReserveSize="2000000"
+				BaseAddress="0x1d000000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|Win32"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\pyproject.vsprops;.\debug.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				EnableIntrinsicFunctions="false"
+				AdditionalIncludeDirectories=""
+				PreprocessorDefinitions="_CONSOLE"
+				RuntimeLibrary="3"
+				BrowseInformation="1"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="_DEBUG"
+				Culture="1033"
+				AdditionalIncludeDirectories="..\..\Include"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\python_d.exe"
+				SubSystem="1"
+				StackReserveSize="2000000"
+				BaseAddress="0x1d000000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\pyproject.vsprops;.\x64.vsprops;.\debug.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				EnableIntrinsicFunctions="false"
+				AdditionalIncludeDirectories=""
+				PreprocessorDefinitions="_CONSOLE"
+				RuntimeLibrary="3"
+				BrowseInformation="1"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="_DEBUG"
+				Culture="1033"
+				AdditionalIncludeDirectories="..\..\Include"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\python_d.exe"
+				SubSystem="1"
+				StackReserveSize="2100000"
+				BaseAddress="0x1d000000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|Win32"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\pyproject.vsprops;.\release.vsprops;.\pginstrument.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories=""
+				PreprocessorDefinitions="_CONSOLE"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1033"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\python.exe"
+				SubSystem="1"
+				StackReserveSize="2000000"
+				BaseAddress="0x1d000000"
+				ImportLibrary=""
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|x64"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\pyproject.vsprops;.\x64.vsprops;.\release.vsprops;.\pginstrument.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories=""
+				PreprocessorDefinitions="_CONSOLE"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1033"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\python.exe"
+				SubSystem="1"
+				StackReserveSize="2000000"
+				BaseAddress="0x1d000000"
+				ImportLibrary=""
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|Win32"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\pyproject.vsprops;.\release.vsprops;.\pgupdate.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories=""
+				PreprocessorDefinitions="_CONSOLE"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1033"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\python.exe"
+				SubSystem="1"
+				StackReserveSize="2000000"
+				BaseAddress="0x1d000000"
+				ImportLibrary=""
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|x64"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\pyproject.vsprops;.\x64.vsprops;.\release.vsprops;.\pgupdate.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories=""
+				PreprocessorDefinitions="_CONSOLE"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1033"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\python.exe"
+				SubSystem="1"
+				StackReserveSize="2000000"
+				BaseAddress="0x1d000000"
+				ImportLibrary=""
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Resource Files"
+			>
+			<File
+				RelativePath="..\..\PC\pycon.ico"
+				>
+			</File>
+			<File
+				RelativePath="..\..\PC\python_exe.rc"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Source Files"
+			>
+			<File
+				RelativePath="..\..\Modules\python.c"
+				>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Modified: python/branches/py3k/PC/VS8.0/pythoncore.vcproj
==============================================================================
--- python/branches/py3k/PC/VS8.0/pythoncore.vcproj	(original)
+++ python/branches/py3k/PC/VS8.0/pythoncore.vcproj	Sat Jun 14 01:34:35 2008
@@ -1,1781 +1,1781 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="8.00"
-	Name="pythoncore"
-	ProjectGUID="{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}"
-	RootNamespace="pythoncore"
-	TargetFrameworkVersion="131072"
-	>
-	<Platforms>
-		<Platform
-			Name="Win32"
-		/>
-		<Platform
-			Name="x64"
-		/>
-	</Platforms>
-	<ToolFiles>
-	</ToolFiles>
-	<Configurations>
-		<Configuration
-			Name="Release|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyproject.vsprops;.\release.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalOptions="/Zm200 "
-				AdditionalIncludeDirectories="..\..\Python;..\..\Modules\zlib"
-				PreprocessorDefinitions="_USRDLL;Py_BUILD_CORE;Py_ENABLE_SHARED;WIN32"
-				RuntimeLibrary="2"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="NDEBUG"
-				Culture="1033"
-				AdditionalIncludeDirectories="..\..\Include"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-				Description="Generate build information..."
-				CommandLine="&quot;$(SolutionDir)make_buildinfo.exe&quot; Release"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="getbuildinfo.o"
-				OutputFile="$(OutDir)\$(PyDllName).dll"
-				IgnoreDefaultLibraryNames="libc"
-				ProgramDatabaseFile="$(OutDir)$(PyDllName).pdb"
-				BaseAddress="0x1e000000"
-				ImportLibrary="$(OutDir)$(PyDllName).lib"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyproject.vsprops;.\x64.vsprops;.\release.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalOptions="/Zm200 "
-				AdditionalIncludeDirectories="..\..\Python;..\..\Modules\zlib"
-				PreprocessorDefinitions="_USRDLL;Py_BUILD_CORE;Py_ENABLE_SHARED;WIN32"
-				RuntimeLibrary="2"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="NDEBUG"
-				Culture="1033"
-				AdditionalIncludeDirectories="..\..\Include"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-				Description="Generate build information..."
-				CommandLine="&quot;$(SolutionDir)make_buildinfo.exe&quot; Release"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="getbuildinfo.o"
-				OutputFile="$(OutDir)\$(PyDllName).dll"
-				IgnoreDefaultLibraryNames="libc"
-				ProgramDatabaseFile="$(OutDir)$(PyDllName).pdb"
-				BaseAddress="0x1e000000"
-				ImportLibrary="$(OutDir)$(PyDllName).lib"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Debug|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyproject.vsprops;.\debug.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalOptions="/Zm200 "
-				Optimization="0"
-				InlineFunctionExpansion="0"
-				EnableIntrinsicFunctions="false"
-				AdditionalIncludeDirectories="..\..\Python;..\..\Modules\zlib"
-				PreprocessorDefinitions="_USRDLL;Py_BUILD_CORE;Py_ENABLE_SHARED;WIN32"
-				RuntimeLibrary="3"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="_DEBUG"
-				Culture="1033"
-				AdditionalIncludeDirectories="..\..\Include"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-				Description="Generate build information..."
-				CommandLine="&quot;$(SolutionDir)make_buildinfo.exe&quot; Debug"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="getbuildinfo.o"
-				OutputFile="$(OutDir)\$(PyDllName)_d.dll"
-				IgnoreDefaultLibraryNames="libc"
-				ProgramDatabaseFile="$(OutDir)$(PyDllName)_d.pdb"
-				BaseAddress="0x1e000000"
-				ImportLibrary="$(OutDir)$(PyDllName)_d.lib"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Debug|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyproject.vsprops;.\x64.vsprops;.\debug.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalOptions="/Zm200 "
-				Optimization="0"
-				InlineFunctionExpansion="0"
-				EnableIntrinsicFunctions="false"
-				AdditionalIncludeDirectories="..\..\Python;..\..\Modules\zlib"
-				PreprocessorDefinitions="_USRDLL;Py_BUILD_CORE;Py_ENABLE_SHARED;WIN32"
-				RuntimeLibrary="3"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="_DEBUG"
-				Culture="1033"
-				AdditionalIncludeDirectories="..\..\Include"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-				Description="Generate build information..."
-				CommandLine="&quot;$(SolutionDir)make_buildinfo.exe&quot; Debug"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="getbuildinfo.o"
-				OutputFile="$(OutDir)\$(PyDllName)_d.dll"
-				IgnoreDefaultLibraryNames="libc"
-				ProgramDatabaseFile="$(OutDir)$(PyDllName)_d.pdb"
-				BaseAddress="0x1e000000"
-				ImportLibrary="$(OutDir)$(PyDllName)_d.lib"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGInstrument|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyproject.vsprops;.\release.vsprops;.\pginstrument.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalOptions="/Zm200 "
-				AdditionalIncludeDirectories="..\..\Python;..\..\Modules\zlib"
-				PreprocessorDefinitions="_USRDLL;Py_BUILD_CORE;Py_ENABLE_SHARED;WIN32"
-				RuntimeLibrary="2"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="NDEBUG"
-				Culture="1033"
-				AdditionalIncludeDirectories="..\..\Include"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-				Description="Generate build information..."
-				CommandLine="&quot;$(SolutionDir)make_buildinfo.exe&quot; Release"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="getbuildinfo.o"
-				OutputFile="$(OutDir)\$(PyDllName).dll"
-				IgnoreDefaultLibraryNames="libc"
-				ProgramDatabaseFile="$(OutDir)$(PyDllName).pdb"
-				BaseAddress="0x1e000000"
-				ImportLibrary="$(OutDirPGI)$(PyDllName).lib"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGInstrument|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyproject.vsprops;.\x64.vsprops;.\release.vsprops;.\pginstrument.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalOptions="/Zm200 "
-				AdditionalIncludeDirectories="..\..\Python;..\..\Modules\zlib"
-				PreprocessorDefinitions="_USRDLL;Py_BUILD_CORE;Py_ENABLE_SHARED;WIN32"
-				RuntimeLibrary="2"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="NDEBUG"
-				Culture="1033"
-				AdditionalIncludeDirectories="..\..\Include"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-				Description="Generate build information..."
-				CommandLine="&quot;$(SolutionDir)make_buildinfo.exe&quot; Release"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="getbuildinfo.o"
-				OutputFile="$(OutDir)\$(PyDllName).dll"
-				IgnoreDefaultLibraryNames="libc"
-				ProgramDatabaseFile="$(OutDir)$(PyDllName).pdb"
-				BaseAddress="0x1e000000"
-				ImportLibrary="$(OutDirPGI)$(PyDllName).lib"
-				TargetMachine="17"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGUpdate|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyproject.vsprops;.\release.vsprops;.\pgupdate.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalOptions="/Zm200 "
-				AdditionalIncludeDirectories="..\..\Python;..\..\Modules\zlib"
-				PreprocessorDefinitions="_USRDLL;Py_BUILD_CORE;Py_ENABLE_SHARED;WIN32"
-				RuntimeLibrary="2"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="NDEBUG"
-				Culture="1033"
-				AdditionalIncludeDirectories="..\..\Include"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-				Description="Generate build information..."
-				CommandLine="&quot;$(SolutionDir)make_buildinfo.exe&quot; Release"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="getbuildinfo.o"
-				OutputFile="$(OutDir)\$(PyDllName).dll"
-				IgnoreDefaultLibraryNames="libc"
-				ProgramDatabaseFile="$(OutDir)$(PyDllName).pdb"
-				BaseAddress="0x1e000000"
-				ImportLibrary="$(OutDirPGI)$(PyDllName).lib"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGUpdate|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyproject.vsprops;.\x64.vsprops;.\release.vsprops;.\pgupdate.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalOptions="/Zm200 "
-				AdditionalIncludeDirectories="..\..\Python;..\..\Modules\zlib"
-				PreprocessorDefinitions="_USRDLL;Py_BUILD_CORE;Py_ENABLE_SHARED;WIN32"
-				RuntimeLibrary="2"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="NDEBUG"
-				Culture="1033"
-				AdditionalIncludeDirectories="..\..\Include"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-				Description="Generate build information..."
-				CommandLine="&quot;$(SolutionDir)make_buildinfo.exe&quot; Release"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="getbuildinfo.o"
-				OutputFile="$(OutDir)\$(PyDllName).dll"
-				IgnoreDefaultLibraryNames="libc"
-				ProgramDatabaseFile="$(OutDir)$(PyDllName).pdb"
-				BaseAddress="0x1e000000"
-				ImportLibrary="$(OutDirPGI)$(PyDllName).lib"
-				TargetMachine="17"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<Filter
-			Name="Include"
-			>
-			<File
-				RelativePath="..\..\Include\abstract.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\asdl.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\ast.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\bitset.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\boolobject.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\bytes_methods.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\bytearrayobject.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\bytesobject.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\cellobject.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\ceval.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\classobject.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\cobject.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\code.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\codecs.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\compile.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\complexobject.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\datetime.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\descrobject.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\dictobject.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\enumobject.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\errcode.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\eval.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\fileobject.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\floatobject.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\formatter_unicode.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\frameobject.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\funcobject.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\genobject.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\graminit.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\grammar.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\import.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\intobject.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\intrcheck.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\iterobject.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\listobject.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\longintrepr.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\longobject.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\marshal.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\memoryobject.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\metagrammar.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\methodobject.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\modsupport.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\moduleobject.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\node.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\object.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\objimpl.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\opcode.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\osdefs.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\parsetok.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\patchlevel.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\pgen.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\pgenheaders.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\py_curses.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\pyarena.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\pydebug.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\pyerrors.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\pyexpat.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\pyfpe.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\pygetopt.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\pymactoolbox.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\pymath.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\pymem.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\pyport.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\pystate.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\pystrcmp.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\pystrtod.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\Python-ast.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\Python.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\pythonrun.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\pythread.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\rangeobject.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\setobject.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\sliceobject.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\structmember.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\structseq.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\symtable.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\sysmodule.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\timefuncs.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\token.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\traceback.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\tupleobject.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\ucnhash.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\unicodeobject.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Include\weakrefobject.h"
-				>
-			</File>
-		</Filter>
-		<Filter
-			Name="Modules"
-			>
-			<File
-				RelativePath="..\..\Modules\_bisectmodule.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\_codecsmodule.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\_collectionsmodule.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\_csv.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\_fileio.c"
-				>
-			</File>
-                        <File
-                                RelativePath="..\..\Modules\_bytesio.c"
-                                >
-                        </File>
-			<File
-				RelativePath="..\..\Modules\_functoolsmodule.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\_heapqmodule.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\_json.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\_localemodule.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\_lsprof.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\_pickle.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\_randommodule.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\_sre.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\_stringio.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\_struct.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\_weakref.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\arraymodule.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\atexitmodule.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\audioop.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\binascii.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\cmathmodule.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\datetimemodule.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\errnomodule.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\gcmodule.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\itertoolsmodule.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\main.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\mathmodule.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\md5module.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\mmapmodule.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\operator.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\parsermodule.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\posixmodule.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\rotatingtree.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\rotatingtree.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\sha1module.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\sha256module.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\sha512module.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\signalmodule.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\symtablemodule.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\_threadmodule.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\timemodule.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\xxsubtype.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\yuv.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\yuvconvert.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\zipimport.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\zlibmodule.c"
-				>
-			</File>
-			<Filter
-				Name="zlib"
-				>
-				<File
-					RelativePath="..\..\Modules\zlib\adler32.c"
-					>
-				</File>
-				<File
-					RelativePath="..\..\Modules\zlib\compress.c"
-					>
-				</File>
-				<File
-					RelativePath="..\..\Modules\zlib\crc32.c"
-					>
-				</File>
-				<File
-					RelativePath="..\..\Modules\zlib\crc32.h"
-					>
-				</File>
-				<File
-					RelativePath="..\..\Modules\zlib\deflate.c"
-					>
-				</File>
-				<File
-					RelativePath="..\..\Modules\zlib\deflate.h"
-					>
-				</File>
-				<File
-					RelativePath="..\..\Modules\zlib\gzio.c"
-					>
-				</File>
-				<File
-					RelativePath="..\..\Modules\zlib\infback.c"
-					>
-				</File>
-				<File
-					RelativePath="..\..\Modules\zlib\inffast.c"
-					>
-				</File>
-				<File
-					RelativePath="..\..\Modules\zlib\inffast.h"
-					>
-				</File>
-				<File
-					RelativePath="..\..\Modules\zlib\inffixed.h"
-					>
-				</File>
-				<File
-					RelativePath="..\..\Modules\zlib\inflate.c"
-					>
-				</File>
-				<File
-					RelativePath="..\..\Modules\zlib\inflate.h"
-					>
-				</File>
-				<File
-					RelativePath="..\..\Modules\zlib\inftrees.c"
-					>
-				</File>
-				<File
-					RelativePath="..\..\Modules\zlib\inftrees.h"
-					>
-				</File>
-				<File
-					RelativePath="..\..\Modules\zlib\trees.c"
-					>
-				</File>
-				<File
-					RelativePath="..\..\Modules\zlib\trees.h"
-					>
-				</File>
-				<File
-					RelativePath="..\..\Modules\zlib\uncompr.c"
-					>
-				</File>
-				<File
-					RelativePath="..\..\Modules\zlib\zconf.h"
-					>
-				</File>
-				<File
-					RelativePath="..\..\Modules\zlib\zconf.in.h"
-					>
-				</File>
-				<File
-					RelativePath="..\..\Modules\zlib\zlib.h"
-					>
-				</File>
-				<File
-					RelativePath="..\..\Modules\zlib\zutil.c"
-					>
-				</File>
-				<File
-					RelativePath="..\..\Modules\zlib\zutil.h"
-					>
-				</File>
-			</Filter>
-			<Filter
-				Name="cjkcodecs"
-				>
-				<File
-					RelativePath="..\..\Modules\cjkcodecs\_codecs_cn.c"
-					>
-				</File>
-				<File
-					RelativePath="..\..\Modules\cjkcodecs\_codecs_hk.c"
-					>
-				</File>
-				<File
-					RelativePath="..\..\Modules\cjkcodecs\_codecs_iso2022.c"
-					>
-				</File>
-				<File
-					RelativePath="..\..\Modules\cjkcodecs\_codecs_jp.c"
-					>
-				</File>
-				<File
-					RelativePath="..\..\Modules\cjkcodecs\_codecs_kr.c"
-					>
-				</File>
-				<File
-					RelativePath="..\..\Modules\cjkcodecs\_codecs_tw.c"
-					>
-				</File>
-				<File
-					RelativePath="..\..\Modules\cjkcodecs\alg_jisx0201.h"
-					>
-				</File>
-				<File
-					RelativePath="..\..\Modules\cjkcodecs\cjkcodecs.h"
-					>
-				</File>
-				<File
-					RelativePath="..\..\Modules\cjkcodecs\emu_jisx0213_2000.h"
-					>
-				</File>
-				<File
-					RelativePath="..\..\Modules\cjkcodecs\mappings_cn.h"
-					>
-				</File>
-				<File
-					RelativePath="..\..\Modules\cjkcodecs\mappings_hk.h"
-					>
-				</File>
-				<File
-					RelativePath="..\..\Modules\cjkcodecs\mappings_jisx0213_pair.h"
-					>
-				</File>
-				<File
-					RelativePath="..\..\Modules\cjkcodecs\mappings_jp.h"
-					>
-				</File>
-				<File
-					RelativePath="..\..\Modules\cjkcodecs\mappings_kr.h"
-					>
-				</File>
-				<File
-					RelativePath="..\..\Modules\cjkcodecs\mappings_tw.h"
-					>
-				</File>
-				<File
-					RelativePath="..\..\Modules\cjkcodecs\multibytecodec.c"
-					>
-				</File>
-				<File
-					RelativePath="..\..\Modules\cjkcodecs\multibytecodec.h"
-					>
-				</File>
-			</Filter>
-		</Filter>
-		<Filter
-			Name="Objects"
-			>
-			<File
-				RelativePath="..\..\Objects\abstract.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Objects\boolobject.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Objects\bytes_methods.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Objects\bytearrayobject.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Objects\bytesobject.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Objects\cellobject.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Objects\classobject.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Objects\cobject.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Objects\codeobject.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Objects\complexobject.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Objects\stringlib\count.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Objects\descrobject.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Objects\dictobject.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Objects\enumobject.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Objects\exceptions.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Objects\stringlib\fastsearch.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Objects\fileobject.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Objects\stringlib\find.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Objects\floatobject.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Objects\frameobject.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Objects\funcobject.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Objects\genobject.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Objects\iterobject.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Objects\listobject.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Objects\longobject.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Objects\memoryobject.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Objects\methodobject.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Objects\moduleobject.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Objects\object.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Objects\obmalloc.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Objects\stringlib\partition.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Objects\rangeobject.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Objects\setobject.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Objects\sliceobject.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Objects\structseq.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Objects\tupleobject.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Objects\typeobject.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Objects\unicodectype.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Objects\unicodeobject.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Objects\unicodetype_db.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Objects\weakrefobject.c"
-				>
-			</File>
-		</Filter>
-		<Filter
-			Name="Parser"
-			>
-			<File
-				RelativePath="..\..\Parser\acceler.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Parser\bitset.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Parser\firstsets.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Parser\grammar.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Parser\grammar1.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Parser\listnode.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Parser\metagrammar.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Parser\myreadline.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Parser\node.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Parser\parser.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Parser\parser.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Parser\parsetok.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Parser\tokenizer.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Parser\tokenizer.h"
-				>
-			</File>
-		</Filter>
-		<Filter
-			Name="PC"
-			>
-			<File
-				RelativePath="..\..\PC\_subprocess.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\PC\winreg.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\PC\config.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\PC\dl_nt.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\PC\errmap.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\PC\getpathp.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\PC\import_nt.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\PC\msvcrtmodule.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\PC\pyconfig.h"
-				>
-			</File>
-		</Filter>
-		<Filter
-			Name="Python"
-			>
-			<File
-				RelativePath="..\..\Python\_warnings.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Python\asdl.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Python\ast.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Python\bltinmodule.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Python\ceval.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Python\codecs.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Python\compile.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Python\dynload_win.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Python\errors.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Python\formatter_unicode.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Python\frozen.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Python\future.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Python\getargs.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Python\getcompiler.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Python\getcopyright.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Python\getmtime.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Python\getopt.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Python\getplatform.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Python\getversion.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Python\graminit.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Python\import.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Python\importdl.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Python\importdl.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Python\marshal.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Python\modsupport.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Python\mysnprintf.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Python\mystrtoul.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Python\peephole.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Python\pyarena.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Python\pyfpe.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Python\pymath.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Python\pystate.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Python\pystrcmp.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Python\pystrtod.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Python\Python-ast.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Python\pythonrun.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Python\structmember.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Python\symtable.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Python\sysmodule.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Python\thread.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Python\thread_nt.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Python\traceback.c"
-				>
-			</File>
-		</Filter>
-		<Filter
-			Name="Resource Files"
-			>
-			<File
-				RelativePath="..\..\PC\python_nt.rc"
-				>
-			</File>
-		</Filter>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="pythoncore"
+	ProjectGUID="{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}"
+	RootNamespace="pythoncore"
+	TargetFrameworkVersion="131072"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Release|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyproject.vsprops;.\release.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions="/Zm200 "
+				AdditionalIncludeDirectories="..\..\Python;..\..\Modules\zlib"
+				PreprocessorDefinitions="_USRDLL;Py_BUILD_CORE;Py_ENABLE_SHARED;WIN32"
+				RuntimeLibrary="2"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1033"
+				AdditionalIncludeDirectories="..\..\Include"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				Description="Generate build information..."
+				CommandLine="&quot;$(SolutionDir)make_buildinfo.exe&quot; Release"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="getbuildinfo.o"
+				OutputFile="$(OutDir)\$(PyDllName).dll"
+				IgnoreDefaultLibraryNames="libc"
+				ProgramDatabaseFile="$(OutDir)$(PyDllName).pdb"
+				BaseAddress="0x1e000000"
+				ImportLibrary="$(OutDir)$(PyDllName).lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyproject.vsprops;.\x64.vsprops;.\release.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions="/Zm200 "
+				AdditionalIncludeDirectories="..\..\Python;..\..\Modules\zlib"
+				PreprocessorDefinitions="_USRDLL;Py_BUILD_CORE;Py_ENABLE_SHARED;WIN32"
+				RuntimeLibrary="2"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1033"
+				AdditionalIncludeDirectories="..\..\Include"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				Description="Generate build information..."
+				CommandLine="&quot;$(SolutionDir)make_buildinfo.exe&quot; Release"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="getbuildinfo.o"
+				OutputFile="$(OutDir)\$(PyDllName).dll"
+				IgnoreDefaultLibraryNames="libc"
+				ProgramDatabaseFile="$(OutDir)$(PyDllName).pdb"
+				BaseAddress="0x1e000000"
+				ImportLibrary="$(OutDir)$(PyDllName).lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyproject.vsprops;.\debug.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions="/Zm200 "
+				Optimization="0"
+				InlineFunctionExpansion="0"
+				EnableIntrinsicFunctions="false"
+				AdditionalIncludeDirectories="..\..\Python;..\..\Modules\zlib"
+				PreprocessorDefinitions="_USRDLL;Py_BUILD_CORE;Py_ENABLE_SHARED;WIN32"
+				RuntimeLibrary="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="_DEBUG"
+				Culture="1033"
+				AdditionalIncludeDirectories="..\..\Include"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				Description="Generate build information..."
+				CommandLine="&quot;$(SolutionDir)make_buildinfo.exe&quot; Debug"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="getbuildinfo.o"
+				OutputFile="$(OutDir)\$(PyDllName)_d.dll"
+				IgnoreDefaultLibraryNames="libc"
+				ProgramDatabaseFile="$(OutDir)$(PyDllName)_d.pdb"
+				BaseAddress="0x1e000000"
+				ImportLibrary="$(OutDir)$(PyDllName)_d.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyproject.vsprops;.\x64.vsprops;.\debug.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions="/Zm200 "
+				Optimization="0"
+				InlineFunctionExpansion="0"
+				EnableIntrinsicFunctions="false"
+				AdditionalIncludeDirectories="..\..\Python;..\..\Modules\zlib"
+				PreprocessorDefinitions="_USRDLL;Py_BUILD_CORE;Py_ENABLE_SHARED;WIN32"
+				RuntimeLibrary="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="_DEBUG"
+				Culture="1033"
+				AdditionalIncludeDirectories="..\..\Include"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				Description="Generate build information..."
+				CommandLine="&quot;$(SolutionDir)make_buildinfo.exe&quot; Debug"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="getbuildinfo.o"
+				OutputFile="$(OutDir)\$(PyDllName)_d.dll"
+				IgnoreDefaultLibraryNames="libc"
+				ProgramDatabaseFile="$(OutDir)$(PyDllName)_d.pdb"
+				BaseAddress="0x1e000000"
+				ImportLibrary="$(OutDir)$(PyDllName)_d.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyproject.vsprops;.\release.vsprops;.\pginstrument.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions="/Zm200 "
+				AdditionalIncludeDirectories="..\..\Python;..\..\Modules\zlib"
+				PreprocessorDefinitions="_USRDLL;Py_BUILD_CORE;Py_ENABLE_SHARED;WIN32"
+				RuntimeLibrary="2"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1033"
+				AdditionalIncludeDirectories="..\..\Include"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				Description="Generate build information..."
+				CommandLine="&quot;$(SolutionDir)make_buildinfo.exe&quot; Release"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="getbuildinfo.o"
+				OutputFile="$(OutDir)\$(PyDllName).dll"
+				IgnoreDefaultLibraryNames="libc"
+				ProgramDatabaseFile="$(OutDir)$(PyDllName).pdb"
+				BaseAddress="0x1e000000"
+				ImportLibrary="$(OutDirPGI)$(PyDllName).lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyproject.vsprops;.\x64.vsprops;.\release.vsprops;.\pginstrument.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions="/Zm200 "
+				AdditionalIncludeDirectories="..\..\Python;..\..\Modules\zlib"
+				PreprocessorDefinitions="_USRDLL;Py_BUILD_CORE;Py_ENABLE_SHARED;WIN32"
+				RuntimeLibrary="2"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1033"
+				AdditionalIncludeDirectories="..\..\Include"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				Description="Generate build information..."
+				CommandLine="&quot;$(SolutionDir)make_buildinfo.exe&quot; Release"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="getbuildinfo.o"
+				OutputFile="$(OutDir)\$(PyDllName).dll"
+				IgnoreDefaultLibraryNames="libc"
+				ProgramDatabaseFile="$(OutDir)$(PyDllName).pdb"
+				BaseAddress="0x1e000000"
+				ImportLibrary="$(OutDirPGI)$(PyDllName).lib"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyproject.vsprops;.\release.vsprops;.\pgupdate.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions="/Zm200 "
+				AdditionalIncludeDirectories="..\..\Python;..\..\Modules\zlib"
+				PreprocessorDefinitions="_USRDLL;Py_BUILD_CORE;Py_ENABLE_SHARED;WIN32"
+				RuntimeLibrary="2"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1033"
+				AdditionalIncludeDirectories="..\..\Include"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				Description="Generate build information..."
+				CommandLine="&quot;$(SolutionDir)make_buildinfo.exe&quot; Release"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="getbuildinfo.o"
+				OutputFile="$(OutDir)\$(PyDllName).dll"
+				IgnoreDefaultLibraryNames="libc"
+				ProgramDatabaseFile="$(OutDir)$(PyDllName).pdb"
+				BaseAddress="0x1e000000"
+				ImportLibrary="$(OutDirPGI)$(PyDllName).lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyproject.vsprops;.\x64.vsprops;.\release.vsprops;.\pgupdate.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions="/Zm200 "
+				AdditionalIncludeDirectories="..\..\Python;..\..\Modules\zlib"
+				PreprocessorDefinitions="_USRDLL;Py_BUILD_CORE;Py_ENABLE_SHARED;WIN32"
+				RuntimeLibrary="2"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1033"
+				AdditionalIncludeDirectories="..\..\Include"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+				Description="Generate build information..."
+				CommandLine="&quot;$(SolutionDir)make_buildinfo.exe&quot; Release"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="getbuildinfo.o"
+				OutputFile="$(OutDir)\$(PyDllName).dll"
+				IgnoreDefaultLibraryNames="libc"
+				ProgramDatabaseFile="$(OutDir)$(PyDllName).pdb"
+				BaseAddress="0x1e000000"
+				ImportLibrary="$(OutDirPGI)$(PyDllName).lib"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Include"
+			>
+			<File
+				RelativePath="..\..\Include\abstract.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\asdl.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\ast.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\bitset.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\boolobject.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\bytes_methods.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\bytearrayobject.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\bytesobject.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\cellobject.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\ceval.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\classobject.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\cobject.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\code.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\codecs.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\compile.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\complexobject.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\datetime.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\descrobject.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\dictobject.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\enumobject.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\errcode.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\eval.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\fileobject.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\floatobject.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\formatter_unicode.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\frameobject.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\funcobject.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\genobject.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\graminit.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\grammar.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\import.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\intobject.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\intrcheck.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\iterobject.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\listobject.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\longintrepr.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\longobject.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\marshal.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\memoryobject.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\metagrammar.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\methodobject.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\modsupport.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\moduleobject.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\node.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\object.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\objimpl.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\opcode.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\osdefs.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\parsetok.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\patchlevel.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\pgen.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\pgenheaders.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\py_curses.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\pyarena.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\pydebug.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\pyerrors.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\pyexpat.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\pyfpe.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\pygetopt.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\pymactoolbox.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\pymath.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\pymem.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\pyport.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\pystate.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\pystrcmp.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\pystrtod.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\Python-ast.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\Python.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\pythonrun.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\pythread.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\rangeobject.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\setobject.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\sliceobject.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\structmember.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\structseq.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\symtable.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\sysmodule.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\timefuncs.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\token.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\traceback.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\tupleobject.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\ucnhash.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\unicodeobject.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Include\weakrefobject.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Modules"
+			>
+			<File
+				RelativePath="..\..\Modules\_bisectmodule.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_codecsmodule.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_collectionsmodule.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_csv.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_fileio.c"
+				>
+			</File>
+                        <File
+                                RelativePath="..\..\Modules\_bytesio.c"
+                                >
+                        </File>
+			<File
+				RelativePath="..\..\Modules\_functoolsmodule.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_heapqmodule.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_json.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_localemodule.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_lsprof.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_pickle.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_randommodule.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_sre.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_stringio.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_struct.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_weakref.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\arraymodule.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\atexitmodule.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\audioop.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\binascii.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\cmathmodule.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\datetimemodule.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\errnomodule.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\gcmodule.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\itertoolsmodule.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\main.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\mathmodule.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\md5module.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\mmapmodule.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\operator.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\parsermodule.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\posixmodule.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\rotatingtree.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\rotatingtree.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\sha1module.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\sha256module.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\sha512module.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\signalmodule.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\symtablemodule.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\_threadmodule.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\timemodule.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\xxsubtype.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\yuv.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\yuvconvert.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\zipimport.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\zlibmodule.c"
+				>
+			</File>
+			<Filter
+				Name="zlib"
+				>
+				<File
+					RelativePath="..\..\Modules\zlib\adler32.c"
+					>
+				</File>
+				<File
+					RelativePath="..\..\Modules\zlib\compress.c"
+					>
+				</File>
+				<File
+					RelativePath="..\..\Modules\zlib\crc32.c"
+					>
+				</File>
+				<File
+					RelativePath="..\..\Modules\zlib\crc32.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\Modules\zlib\deflate.c"
+					>
+				</File>
+				<File
+					RelativePath="..\..\Modules\zlib\deflate.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\Modules\zlib\gzio.c"
+					>
+				</File>
+				<File
+					RelativePath="..\..\Modules\zlib\infback.c"
+					>
+				</File>
+				<File
+					RelativePath="..\..\Modules\zlib\inffast.c"
+					>
+				</File>
+				<File
+					RelativePath="..\..\Modules\zlib\inffast.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\Modules\zlib\inffixed.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\Modules\zlib\inflate.c"
+					>
+				</File>
+				<File
+					RelativePath="..\..\Modules\zlib\inflate.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\Modules\zlib\inftrees.c"
+					>
+				</File>
+				<File
+					RelativePath="..\..\Modules\zlib\inftrees.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\Modules\zlib\trees.c"
+					>
+				</File>
+				<File
+					RelativePath="..\..\Modules\zlib\trees.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\Modules\zlib\uncompr.c"
+					>
+				</File>
+				<File
+					RelativePath="..\..\Modules\zlib\zconf.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\Modules\zlib\zconf.in.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\Modules\zlib\zlib.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\Modules\zlib\zutil.c"
+					>
+				</File>
+				<File
+					RelativePath="..\..\Modules\zlib\zutil.h"
+					>
+				</File>
+			</Filter>
+			<Filter
+				Name="cjkcodecs"
+				>
+				<File
+					RelativePath="..\..\Modules\cjkcodecs\_codecs_cn.c"
+					>
+				</File>
+				<File
+					RelativePath="..\..\Modules\cjkcodecs\_codecs_hk.c"
+					>
+				</File>
+				<File
+					RelativePath="..\..\Modules\cjkcodecs\_codecs_iso2022.c"
+					>
+				</File>
+				<File
+					RelativePath="..\..\Modules\cjkcodecs\_codecs_jp.c"
+					>
+				</File>
+				<File
+					RelativePath="..\..\Modules\cjkcodecs\_codecs_kr.c"
+					>
+				</File>
+				<File
+					RelativePath="..\..\Modules\cjkcodecs\_codecs_tw.c"
+					>
+				</File>
+				<File
+					RelativePath="..\..\Modules\cjkcodecs\alg_jisx0201.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\Modules\cjkcodecs\cjkcodecs.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\Modules\cjkcodecs\emu_jisx0213_2000.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\Modules\cjkcodecs\mappings_cn.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\Modules\cjkcodecs\mappings_hk.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\Modules\cjkcodecs\mappings_jisx0213_pair.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\Modules\cjkcodecs\mappings_jp.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\Modules\cjkcodecs\mappings_kr.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\Modules\cjkcodecs\mappings_tw.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\Modules\cjkcodecs\multibytecodec.c"
+					>
+				</File>
+				<File
+					RelativePath="..\..\Modules\cjkcodecs\multibytecodec.h"
+					>
+				</File>
+			</Filter>
+		</Filter>
+		<Filter
+			Name="Objects"
+			>
+			<File
+				RelativePath="..\..\Objects\abstract.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Objects\boolobject.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Objects\bytes_methods.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Objects\bytearrayobject.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Objects\bytesobject.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Objects\cellobject.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Objects\classobject.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Objects\cobject.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Objects\codeobject.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Objects\complexobject.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Objects\stringlib\count.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Objects\descrobject.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Objects\dictobject.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Objects\enumobject.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Objects\exceptions.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Objects\stringlib\fastsearch.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Objects\fileobject.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Objects\stringlib\find.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Objects\floatobject.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Objects\frameobject.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Objects\funcobject.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Objects\genobject.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Objects\iterobject.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Objects\listobject.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Objects\longobject.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Objects\memoryobject.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Objects\methodobject.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Objects\moduleobject.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Objects\object.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Objects\obmalloc.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Objects\stringlib\partition.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Objects\rangeobject.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Objects\setobject.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Objects\sliceobject.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Objects\structseq.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Objects\tupleobject.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Objects\typeobject.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Objects\unicodectype.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Objects\unicodeobject.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Objects\unicodetype_db.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Objects\weakrefobject.c"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Parser"
+			>
+			<File
+				RelativePath="..\..\Parser\acceler.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Parser\bitset.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Parser\firstsets.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Parser\grammar.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Parser\grammar1.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Parser\listnode.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Parser\metagrammar.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Parser\myreadline.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Parser\node.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Parser\parser.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Parser\parser.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Parser\parsetok.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Parser\tokenizer.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Parser\tokenizer.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="PC"
+			>
+			<File
+				RelativePath="..\..\PC\_subprocess.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\PC\winreg.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\PC\config.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\PC\dl_nt.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\PC\errmap.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\PC\getpathp.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\PC\import_nt.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\PC\msvcrtmodule.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\PC\pyconfig.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Python"
+			>
+			<File
+				RelativePath="..\..\Python\_warnings.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Python\asdl.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Python\ast.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Python\bltinmodule.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Python\ceval.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Python\codecs.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Python\compile.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Python\dynload_win.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Python\errors.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Python\formatter_unicode.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Python\frozen.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Python\future.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Python\getargs.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Python\getcompiler.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Python\getcopyright.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Python\getmtime.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Python\getopt.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Python\getplatform.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Python\getversion.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Python\graminit.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Python\import.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Python\importdl.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Python\importdl.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Python\marshal.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Python\modsupport.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Python\mysnprintf.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Python\mystrtoul.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Python\peephole.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Python\pyarena.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Python\pyfpe.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Python\pymath.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Python\pystate.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Python\pystrcmp.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Python\pystrtod.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Python\Python-ast.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Python\pythonrun.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Python\structmember.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Python\symtable.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Python\sysmodule.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Python\thread.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Python\thread_nt.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Python\traceback.c"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			>
+			<File
+				RelativePath="..\..\PC\python_nt.rc"
+				>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Modified: python/branches/py3k/PC/VS8.0/pythonw.vcproj
==============================================================================
--- python/branches/py3k/PC/VS8.0/pythonw.vcproj	(original)
+++ python/branches/py3k/PC/VS8.0/pythonw.vcproj	Sat Jun 14 01:34:35 2008
@@ -1,618 +1,618 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="8.00"
-	Name="pythonw"
-	ProjectGUID="{F4229CC3-873C-49AE-9729-DD308ED4CD4A}"
-	TargetFrameworkVersion="131072"
-	>
-	<Platforms>
-		<Platform
-			Name="Win32"
-		/>
-		<Platform
-			Name="x64"
-		/>
-	</Platforms>
-	<ToolFiles>
-	</ToolFiles>
-	<Configurations>
-		<Configuration
-			Name="Debug|Win32"
-			ConfigurationType="1"
-			InheritedPropertySheets=".\pyproject.vsprops;.\debug.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="0"
-				EnableIntrinsicFunctions="false"
-				AdditionalIncludeDirectories=""
-				PreprocessorDefinitions="_WINDOWS"
-				RuntimeLibrary="3"
-				CompileAs="0"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="_DEBUG"
-				Culture="1033"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				OutputFile="$(OutDir)\pythonw_d.exe"
-				StackReserveSize="2000000"
-				BaseAddress="0x1d000000"
-				TargetMachine="1"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Debug|x64"
-			ConfigurationType="1"
-			InheritedPropertySheets=".\pyproject.vsprops;.\x64.vsprops;.\debug.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="0"
-				EnableIntrinsicFunctions="false"
-				AdditionalIncludeDirectories=""
-				PreprocessorDefinitions="_WINDOWS"
-				RuntimeLibrary="3"
-				CompileAs="0"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="_DEBUG"
-				Culture="1033"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				OutputFile="$(OutDir)\pythonw_d.exe"
-				StackReserveSize="2000000"
-				BaseAddress="0x1d000000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|Win32"
-			ConfigurationType="1"
-			InheritedPropertySheets=".\pyproject.vsprops;.\release.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories=""
-				PreprocessorDefinitions="_WINDOWS"
-				StringPooling="true"
-				RuntimeLibrary="2"
-				EnableFunctionLevelLinking="true"
-				CompileAs="0"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="NDEBUG"
-				Culture="1033"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				OutputFile="$(OutDir)\pythonw.exe"
-				StackReserveSize="2000000"
-				BaseAddress="0x1d000000"
-				TargetMachine="1"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|x64"
-			ConfigurationType="1"
-			InheritedPropertySheets=".\pyproject.vsprops;.\x64.vsprops;.\release.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories=""
-				PreprocessorDefinitions="_WINDOWS"
-				StringPooling="true"
-				RuntimeLibrary="2"
-				EnableFunctionLevelLinking="true"
-				CompileAs="0"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="NDEBUG"
-				Culture="1033"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				OutputFile="$(OutDir)\pythonw.exe"
-				StackReserveSize="2000000"
-				BaseAddress="0x1d000000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGInstrument|Win32"
-			ConfigurationType="1"
-			InheritedPropertySheets=".\pyproject.vsprops;.\release.vsprops;.\pginstrument.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories=""
-				PreprocessorDefinitions="_WINDOWS"
-				StringPooling="true"
-				RuntimeLibrary="2"
-				EnableFunctionLevelLinking="true"
-				CompileAs="0"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="NDEBUG"
-				Culture="1033"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				OutputFile="$(OutDir)\pythonw.exe"
-				StackReserveSize="2000000"
-				BaseAddress="0x1d000000"
-				ImportLibrary=""
-				TargetMachine="1"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGInstrument|x64"
-			ConfigurationType="1"
-			InheritedPropertySheets=".\pyproject.vsprops;.\x64.vsprops;.\release.vsprops;.\pginstrument.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories=""
-				PreprocessorDefinitions="_WINDOWS"
-				StringPooling="true"
-				RuntimeLibrary="2"
-				EnableFunctionLevelLinking="true"
-				CompileAs="0"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="NDEBUG"
-				Culture="1033"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				OutputFile="$(OutDir)\pythonw.exe"
-				StackReserveSize="2000000"
-				BaseAddress="0x1d000000"
-				ImportLibrary=""
-				TargetMachine="17"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGUpdate|Win32"
-			ConfigurationType="1"
-			InheritedPropertySheets=".\pyproject.vsprops;.\release.vsprops;.\pgupdate.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories=""
-				PreprocessorDefinitions="_WINDOWS"
-				StringPooling="true"
-				RuntimeLibrary="2"
-				EnableFunctionLevelLinking="true"
-				CompileAs="0"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="NDEBUG"
-				Culture="1033"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				OutputFile="$(OutDir)\pythonw.exe"
-				StackReserveSize="2000000"
-				BaseAddress="0x1d000000"
-				ImportLibrary=""
-				TargetMachine="1"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGUpdate|x64"
-			ConfigurationType="1"
-			InheritedPropertySheets=".\pyproject.vsprops;.\x64.vsprops;.\release.vsprops;.\pgupdate.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories=""
-				PreprocessorDefinitions="_WINDOWS"
-				StringPooling="true"
-				RuntimeLibrary="2"
-				EnableFunctionLevelLinking="true"
-				CompileAs="0"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="NDEBUG"
-				Culture="1033"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				OutputFile="$(OutDir)\pythonw.exe"
-				StackReserveSize="2000000"
-				BaseAddress="0x1d000000"
-				ImportLibrary=""
-				TargetMachine="17"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<Filter
-			Name="Resource Files"
-			>
-			<File
-				RelativePath="..\..\PC\python_exe.rc"
-				>
-			</File>
-		</Filter>
-		<Filter
-			Name="Source Files"
-			>
-			<File
-				RelativePath="..\..\PC\WinMain.c"
-				>
-			</File>
-		</Filter>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="pythonw"
+	ProjectGUID="{F4229CC3-873C-49AE-9729-DD308ED4CD4A}"
+	TargetFrameworkVersion="131072"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\pyproject.vsprops;.\debug.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				EnableIntrinsicFunctions="false"
+				AdditionalIncludeDirectories=""
+				PreprocessorDefinitions="_WINDOWS"
+				RuntimeLibrary="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="_DEBUG"
+				Culture="1033"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\pythonw_d.exe"
+				StackReserveSize="2000000"
+				BaseAddress="0x1d000000"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\pyproject.vsprops;.\x64.vsprops;.\debug.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				EnableIntrinsicFunctions="false"
+				AdditionalIncludeDirectories=""
+				PreprocessorDefinitions="_WINDOWS"
+				RuntimeLibrary="3"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="_DEBUG"
+				Culture="1033"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\pythonw_d.exe"
+				StackReserveSize="2000000"
+				BaseAddress="0x1d000000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\pyproject.vsprops;.\release.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories=""
+				PreprocessorDefinitions="_WINDOWS"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1033"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\pythonw.exe"
+				StackReserveSize="2000000"
+				BaseAddress="0x1d000000"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\pyproject.vsprops;.\x64.vsprops;.\release.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories=""
+				PreprocessorDefinitions="_WINDOWS"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1033"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\pythonw.exe"
+				StackReserveSize="2000000"
+				BaseAddress="0x1d000000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|Win32"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\pyproject.vsprops;.\release.vsprops;.\pginstrument.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories=""
+				PreprocessorDefinitions="_WINDOWS"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1033"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\pythonw.exe"
+				StackReserveSize="2000000"
+				BaseAddress="0x1d000000"
+				ImportLibrary=""
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|x64"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\pyproject.vsprops;.\x64.vsprops;.\release.vsprops;.\pginstrument.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories=""
+				PreprocessorDefinitions="_WINDOWS"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1033"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\pythonw.exe"
+				StackReserveSize="2000000"
+				BaseAddress="0x1d000000"
+				ImportLibrary=""
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|Win32"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\pyproject.vsprops;.\release.vsprops;.\pgupdate.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories=""
+				PreprocessorDefinitions="_WINDOWS"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1033"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\pythonw.exe"
+				StackReserveSize="2000000"
+				BaseAddress="0x1d000000"
+				ImportLibrary=""
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|x64"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\pyproject.vsprops;.\x64.vsprops;.\release.vsprops;.\pgupdate.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories=""
+				PreprocessorDefinitions="_WINDOWS"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				CompileAs="0"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1033"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\pythonw.exe"
+				StackReserveSize="2000000"
+				BaseAddress="0x1d000000"
+				ImportLibrary=""
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Resource Files"
+			>
+			<File
+				RelativePath="..\..\PC\python_exe.rc"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Source Files"
+			>
+			<File
+				RelativePath="..\..\PC\WinMain.c"
+				>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Modified: python/branches/py3k/PC/VS8.0/select.vcproj
==============================================================================
--- python/branches/py3k/PC/VS8.0/select.vcproj	(original)
+++ python/branches/py3k/PC/VS8.0/select.vcproj	Sat Jun 14 01:34:35 2008
@@ -1,537 +1,537 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="8.00"
-	Name="select"
-	ProjectGUID="{18CAE28C-B454-46C1-87A0-493D91D97F03}"
-	RootNamespace="select"
-	Keyword="Win32Proj"
-	TargetFrameworkVersion="196613"
-	>
-	<Platforms>
-		<Platform
-			Name="Win32"
-		/>
-		<Platform
-			Name="x64"
-		/>
-	</Platforms>
-	<ToolFiles>
-	</ToolFiles>
-	<Configurations>
-		<Configuration
-			Name="Debug|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd_d.vsprops"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="wsock32.lib"
-				IgnoreDefaultLibraryNames="libc"
-				BaseAddress="0x1D110000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Debug|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd_d.vsprops;.\x64.vsprops"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="wsock32.lib"
-				IgnoreDefaultLibraryNames="libc"
-				BaseAddress="0x1D110000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="wsock32.lib"
-				IgnoreDefaultLibraryNames="libc"
-				BaseAddress="0x1D110000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="wsock32.lib"
-				IgnoreDefaultLibraryNames="libc"
-				BaseAddress="0x1D110000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGInstrument|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\pginstrument.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="wsock32.lib"
-				IgnoreDefaultLibraryNames="libc"
-				BaseAddress="0x1D110000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGInstrument|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pginstrument.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="wsock32.lib"
-				IgnoreDefaultLibraryNames="libc"
-				BaseAddress="0x1D110000"
-				TargetMachine="17"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGUpdate|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\pgupdate.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="wsock32.lib"
-				IgnoreDefaultLibraryNames="libc"
-				BaseAddress="0x1D110000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGUpdate|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pgupdate.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="wsock32.lib"
-				IgnoreDefaultLibraryNames="libc"
-				BaseAddress="0x1D110000"
-				TargetMachine="17"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<Filter
-			Name="Source Files"
-			>
-			<File
-				RelativePath="..\..\Modules\selectmodule.c"
-				>
-			</File>
-		</Filter>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="select"
+	ProjectGUID="{18CAE28C-B454-46C1-87A0-493D91D97F03}"
+	RootNamespace="select"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd_d.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="wsock32.lib"
+				IgnoreDefaultLibraryNames="libc"
+				BaseAddress="0x1D110000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd_d.vsprops;.\x64.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="wsock32.lib"
+				IgnoreDefaultLibraryNames="libc"
+				BaseAddress="0x1D110000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="wsock32.lib"
+				IgnoreDefaultLibraryNames="libc"
+				BaseAddress="0x1D110000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="wsock32.lib"
+				IgnoreDefaultLibraryNames="libc"
+				BaseAddress="0x1D110000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\pginstrument.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="wsock32.lib"
+				IgnoreDefaultLibraryNames="libc"
+				BaseAddress="0x1D110000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pginstrument.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="wsock32.lib"
+				IgnoreDefaultLibraryNames="libc"
+				BaseAddress="0x1D110000"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\pgupdate.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="wsock32.lib"
+				IgnoreDefaultLibraryNames="libc"
+				BaseAddress="0x1D110000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pgupdate.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="wsock32.lib"
+				IgnoreDefaultLibraryNames="libc"
+				BaseAddress="0x1D110000"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			>
+			<File
+				RelativePath="..\..\Modules\selectmodule.c"
+				>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Modified: python/branches/py3k/PC/VS8.0/sqlite3.vcproj
==============================================================================
--- python/branches/py3k/PC/VS8.0/sqlite3.vcproj	(original)
+++ python/branches/py3k/PC/VS8.0/sqlite3.vcproj	Sat Jun 14 01:34:35 2008
@@ -1,743 +1,743 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="8.00"
-	Name="sqlite3"
-	ProjectGUID="{A1A295E5-463C-437F-81CA-1F32367685DA}"
-	RootNamespace="sqlite3"
-	Keyword="Win32Proj"
-	TargetFrameworkVersion="196613"
-	>
-	<Platforms>
-		<Platform
-			Name="Win32"
-		/>
-		<Platform
-			Name="x64"
-		/>
-	</Platforms>
-	<ToolFiles>
-	</ToolFiles>
-	<Configurations>
-		<Configuration
-			Name="Debug|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd_d.vsprops"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="..\..\..\sqlite-source-3.3.4"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				OutputFile="$(OutDir)\$(ProjectName)_d.dll"
-				ModuleDefinitionFile="..\..\..\sqlite-source-3.3.4\sqlite3.def"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Debug|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd_d.vsprops;.\x64.vsprops"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="..\..\..\sqlite-source-3.3.4"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				OutputFile="$(OutDir)\$(ProjectName)_d.dll"
-				ModuleDefinitionFile="..\..\..\sqlite-source-3.3.4\sqlite3.def"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="..\..\..\sqlite-source-3.3.4"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				OutputFile="$(OutDir)\$(ProjectName).dll"
-				ModuleDefinitionFile="..\..\..\sqlite-source-3.3.4\sqlite3.def"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="..\..\..\sqlite-source-3.3.4"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				OutputFile="$(OutDir)\$(ProjectName).dll"
-				ModuleDefinitionFile="..\..\..\sqlite-source-3.3.4\sqlite3.def"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGInstrument|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\pginstrument.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="..\..\..\sqlite-source-3.3.4"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				ModuleDefinitionFile="..\..\..\sqlite-source-3.3.4\sqlite3.def"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGInstrument|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pginstrument.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="..\..\..\sqlite-source-3.3.4"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				ModuleDefinitionFile="..\..\..\sqlite-source-3.3.4\sqlite3.def"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGUpdate|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\pgupdate.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="..\..\..\sqlite-source-3.3.4"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				ModuleDefinitionFile="..\..\..\sqlite-source-3.3.4\sqlite3.def"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGUpdate|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pgupdate.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="..\..\..\sqlite-source-3.3.4"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				ModuleDefinitionFile="..\..\..\sqlite-source-3.3.4\sqlite3.def"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<Filter
-			Name="Header Files"
-			>
-			<File
-				RelativePath="..\..\..\sqlite-source-3.3.4\btree.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\sqlite-source-3.3.4\hash.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\sqlite-source-3.3.4\keywordhash.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\sqlite-source-3.3.4\opcodes.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\sqlite-source-3.3.4\os.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\sqlite-source-3.3.4\os_common.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\sqlite-source-3.3.4\pager.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\sqlite-source-3.3.4\parse.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\sqlite-source-3.3.4\sqlite3.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\sqlite-source-3.3.4\sqliteInt.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\sqlite-source-3.3.4\vdbe.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\sqlite-source-3.3.4\vdbeInt.h"
-				>
-			</File>
-		</Filter>
-		<Filter
-			Name="Source Files"
-			>
-			<File
-				RelativePath="..\..\..\sqlite-source-3.3.4\alter.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\sqlite-source-3.3.4\analyze.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\sqlite-source-3.3.4\attach.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\sqlite-source-3.3.4\auth.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\sqlite-source-3.3.4\btree.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\sqlite-source-3.3.4\build.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\sqlite-source-3.3.4\callback.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\sqlite-source-3.3.4\complete.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\sqlite-source-3.3.4\date.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\sqlite-source-3.3.4\delete.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\sqlite-source-3.3.4\expr.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\sqlite-source-3.3.4\func.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\sqlite-source-3.3.4\hash.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\sqlite-source-3.3.4\insert.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\sqlite-source-3.3.4\legacy.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\sqlite-source-3.3.4\main.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\sqlite-source-3.3.4\opcodes.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\sqlite-source-3.3.4\os.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\sqlite-source-3.3.4\os_unix.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\sqlite-source-3.3.4\os_win.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\sqlite-source-3.3.4\pager.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\sqlite-source-3.3.4\parse.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\sqlite-source-3.3.4\pragma.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\sqlite-source-3.3.4\prepare.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\sqlite-source-3.3.4\printf.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\sqlite-source-3.3.4\random.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\sqlite-source-3.3.4\select.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\sqlite-source-3.3.4\shell.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\sqlite-source-3.3.4\table.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\sqlite-source-3.3.4\tokenize.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\sqlite-source-3.3.4\trigger.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\sqlite-source-3.3.4\update.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\sqlite-source-3.3.4\utf.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\sqlite-source-3.3.4\util.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\sqlite-source-3.3.4\vacuum.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\sqlite-source-3.3.4\vdbe.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\sqlite-source-3.3.4\vdbeapi.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\sqlite-source-3.3.4\vdbeaux.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\sqlite-source-3.3.4\vdbefifo.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\sqlite-source-3.3.4\vdbemem.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\..\sqlite-source-3.3.4\where.c"
-				>
-			</File>
-		</Filter>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="sqlite3"
+	ProjectGUID="{A1A295E5-463C-437F-81CA-1F32367685DA}"
+	RootNamespace="sqlite3"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd_d.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\..\sqlite-source-3.3.4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\$(ProjectName)_d.dll"
+				ModuleDefinitionFile="..\..\..\sqlite-source-3.3.4\sqlite3.def"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd_d.vsprops;.\x64.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\..\sqlite-source-3.3.4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\$(ProjectName)_d.dll"
+				ModuleDefinitionFile="..\..\..\sqlite-source-3.3.4\sqlite3.def"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\..\sqlite-source-3.3.4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\$(ProjectName).dll"
+				ModuleDefinitionFile="..\..\..\sqlite-source-3.3.4\sqlite3.def"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\..\sqlite-source-3.3.4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\$(ProjectName).dll"
+				ModuleDefinitionFile="..\..\..\sqlite-source-3.3.4\sqlite3.def"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\pginstrument.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\..\sqlite-source-3.3.4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				ModuleDefinitionFile="..\..\..\sqlite-source-3.3.4\sqlite3.def"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pginstrument.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\..\sqlite-source-3.3.4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				ModuleDefinitionFile="..\..\..\sqlite-source-3.3.4\sqlite3.def"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\pgupdate.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\..\sqlite-source-3.3.4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				ModuleDefinitionFile="..\..\..\sqlite-source-3.3.4\sqlite3.def"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pgupdate.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\..\sqlite-source-3.3.4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				ModuleDefinitionFile="..\..\..\sqlite-source-3.3.4\sqlite3.def"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Header Files"
+			>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\btree.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\hash.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\keywordhash.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\opcodes.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\os.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\os_common.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\pager.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\parse.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\sqlite3.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\sqliteInt.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\vdbe.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\vdbeInt.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Source Files"
+			>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\alter.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\analyze.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\attach.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\auth.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\btree.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\build.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\callback.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\complete.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\date.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\delete.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\expr.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\func.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\hash.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\insert.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\legacy.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\main.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\opcodes.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\os.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\os_unix.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\os_win.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\pager.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\parse.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\pragma.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\prepare.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\printf.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\random.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\select.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\shell.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\table.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\tokenize.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\trigger.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\update.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\utf.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\util.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\vacuum.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\vdbe.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\vdbeapi.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\vdbeaux.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\vdbefifo.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\vdbemem.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\sqlite-source-3.3.4\where.c"
+				>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Modified: python/branches/py3k/PC/VS8.0/unicodedata.vcproj
==============================================================================
--- python/branches/py3k/PC/VS8.0/unicodedata.vcproj	(original)
+++ python/branches/py3k/PC/VS8.0/unicodedata.vcproj	Sat Jun 14 01:34:35 2008
@@ -1,533 +1,533 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="8.00"
-	Name="unicodedata"
-	ProjectGUID="{ECC7CEAC-A5E5-458E-BB9E-2413CC847881}"
-	RootNamespace="unicodedata"
-	Keyword="Win32Proj"
-	TargetFrameworkVersion="196613"
-	>
-	<Platforms>
-		<Platform
-			Name="Win32"
-		/>
-		<Platform
-			Name="x64"
-		/>
-	</Platforms>
-	<ToolFiles>
-	</ToolFiles>
-	<Configurations>
-		<Configuration
-			Name="Debug|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd_d.vsprops"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				BaseAddress="0x1D120000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Debug|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd_d.vsprops;.\x64.vsprops"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				BaseAddress="0x1D120000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				BaseAddress="0x1D120000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				BaseAddress="0x1D120000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGInstrument|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\pginstrument.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				BaseAddress="0x1D120000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGInstrument|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pginstrument.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				BaseAddress="0x1D120000"
-				TargetMachine="17"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGUpdate|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\pgupdate.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				BaseAddress="0x1D120000"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGUpdate|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pgupdate.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				BaseAddress="0x1D120000"
-				TargetMachine="17"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<Filter
-			Name="Header Files"
-			>
-			<File
-				RelativePath="..\..\Modules\unicodedata_db.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\Modules\unicodename_db.h"
-				>
-			</File>
-		</Filter>
-		<Filter
-			Name="Source Files"
-			>
-			<File
-				RelativePath="..\..\Modules\unicodedata.c"
-				>
-			</File>
-		</Filter>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="unicodedata"
+	ProjectGUID="{ECC7CEAC-A5E5-458E-BB9E-2413CC847881}"
+	RootNamespace="unicodedata"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd_d.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				BaseAddress="0x1D120000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd_d.vsprops;.\x64.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				BaseAddress="0x1D120000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				BaseAddress="0x1D120000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				BaseAddress="0x1D120000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\pginstrument.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				BaseAddress="0x1D120000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pginstrument.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				BaseAddress="0x1D120000"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\pgupdate.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				BaseAddress="0x1D120000"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pgupdate.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				BaseAddress="0x1D120000"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Header Files"
+			>
+			<File
+				RelativePath="..\..\Modules\unicodedata_db.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\Modules\unicodename_db.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Source Files"
+			>
+			<File
+				RelativePath="..\..\Modules\unicodedata.c"
+				>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Modified: python/branches/py3k/PC/VS8.0/w9xpopen.vcproj
==============================================================================
--- python/branches/py3k/PC/VS8.0/w9xpopen.vcproj	(original)
+++ python/branches/py3k/PC/VS8.0/w9xpopen.vcproj	Sat Jun 14 01:34:35 2008
@@ -1,576 +1,576 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="8.00"
-	Name="w9xpopen"
-	ProjectGUID="{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}"
-	RootNamespace="w9xpopen"
-	TargetFrameworkVersion="131072"
-	>
-	<Platforms>
-		<Platform
-			Name="Win32"
-		/>
-		<Platform
-			Name="x64"
-		/>
-	</Platforms>
-	<ToolFiles>
-	</ToolFiles>
-	<Configurations>
-		<Configuration
-			Name="Debug|Win32"
-			ConfigurationType="1"
-			InheritedPropertySheets=".\pyproject.vsprops;.\debug.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="0"
-				BasicRuntimeChecks="3"
-				RuntimeLibrary="1"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				SubSystem="1"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Debug|x64"
-			ConfigurationType="1"
-			InheritedPropertySheets=".\pyproject.vsprops;.\x64.vsprops;.\debug.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="2"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="0"
-				BasicRuntimeChecks="3"
-				RuntimeLibrary="1"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				SubSystem="1"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|Win32"
-			ConfigurationType="1"
-			InheritedPropertySheets=".\pyproject.vsprops;.\release.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="2"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="2"
-				InlineFunctionExpansion="1"
-				StringPooling="true"
-				RuntimeLibrary="0"
-				EnableFunctionLevelLinking="true"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				GenerateDebugInformation="false"
-				SubSystem="1"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|x64"
-			ConfigurationType="1"
-			InheritedPropertySheets=".\pyproject.vsprops;.\x64.vsprops;.\release.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="2"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="2"
-				InlineFunctionExpansion="1"
-				StringPooling="true"
-				RuntimeLibrary="0"
-				EnableFunctionLevelLinking="true"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				GenerateDebugInformation="false"
-				SubSystem="1"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGInstrument|Win32"
-			ConfigurationType="1"
-			InheritedPropertySheets=".\pyproject.vsprops;.\release.vsprops;.\pginstrument.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="2"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="2"
-				InlineFunctionExpansion="1"
-				StringPooling="true"
-				RuntimeLibrary="0"
-				EnableFunctionLevelLinking="true"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				GenerateDebugInformation="false"
-				SubSystem="1"
-				ImportLibrary=""
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGInstrument|x64"
-			ConfigurationType="1"
-			InheritedPropertySheets=".\pyproject.vsprops;.\x64.vsprops;.\release.vsprops;.\pginstrument.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="2"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="2"
-				InlineFunctionExpansion="1"
-				StringPooling="true"
-				RuntimeLibrary="0"
-				EnableFunctionLevelLinking="true"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				GenerateDebugInformation="false"
-				SubSystem="1"
-				ImportLibrary=""
-				TargetMachine="17"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGUpdate|Win32"
-			ConfigurationType="1"
-			InheritedPropertySheets=".\pyproject.vsprops;.\release.vsprops;.\pgupdate.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="2"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="2"
-				InlineFunctionExpansion="1"
-				StringPooling="true"
-				RuntimeLibrary="0"
-				EnableFunctionLevelLinking="true"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				GenerateDebugInformation="false"
-				SubSystem="1"
-				ImportLibrary=""
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGUpdate|x64"
-			ConfigurationType="1"
-			InheritedPropertySheets=".\pyproject.vsprops;.\x64.vsprops;.\release.vsprops;.\pgupdate.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="2"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="2"
-				InlineFunctionExpansion="1"
-				StringPooling="true"
-				RuntimeLibrary="0"
-				EnableFunctionLevelLinking="true"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				GenerateDebugInformation="false"
-				SubSystem="1"
-				ImportLibrary=""
-				TargetMachine="17"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<Filter
-			Name="Source Files"
-			>
-			<File
-				RelativePath="..\..\PC\w9xpopen.c"
-				>
-			</File>
-		</Filter>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="w9xpopen"
+	ProjectGUID="{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}"
+	RootNamespace="w9xpopen"
+	TargetFrameworkVersion="131072"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\pyproject.vsprops;.\debug.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="1"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				SubSystem="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\pyproject.vsprops;.\x64.vsprops;.\debug.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="1"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				SubSystem="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\pyproject.vsprops;.\release.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				StringPooling="true"
+				RuntimeLibrary="0"
+				EnableFunctionLevelLinking="true"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				GenerateDebugInformation="false"
+				SubSystem="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\pyproject.vsprops;.\x64.vsprops;.\release.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				StringPooling="true"
+				RuntimeLibrary="0"
+				EnableFunctionLevelLinking="true"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				GenerateDebugInformation="false"
+				SubSystem="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|Win32"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\pyproject.vsprops;.\release.vsprops;.\pginstrument.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				StringPooling="true"
+				RuntimeLibrary="0"
+				EnableFunctionLevelLinking="true"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				GenerateDebugInformation="false"
+				SubSystem="1"
+				ImportLibrary=""
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|x64"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\pyproject.vsprops;.\x64.vsprops;.\release.vsprops;.\pginstrument.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				StringPooling="true"
+				RuntimeLibrary="0"
+				EnableFunctionLevelLinking="true"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				GenerateDebugInformation="false"
+				SubSystem="1"
+				ImportLibrary=""
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|Win32"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\pyproject.vsprops;.\release.vsprops;.\pgupdate.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				StringPooling="true"
+				RuntimeLibrary="0"
+				EnableFunctionLevelLinking="true"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				GenerateDebugInformation="false"
+				SubSystem="1"
+				ImportLibrary=""
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|x64"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\pyproject.vsprops;.\x64.vsprops;.\release.vsprops;.\pgupdate.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				StringPooling="true"
+				RuntimeLibrary="0"
+				EnableFunctionLevelLinking="true"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				GenerateDebugInformation="false"
+				SubSystem="1"
+				ImportLibrary=""
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			>
+			<File
+				RelativePath="..\..\PC\w9xpopen.c"
+				>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Modified: python/branches/py3k/PC/VS8.0/winsound.vcproj
==============================================================================
--- python/branches/py3k/PC/VS8.0/winsound.vcproj	(original)
+++ python/branches/py3k/PC/VS8.0/winsound.vcproj	Sat Jun 14 01:34:35 2008
@@ -1,523 +1,523 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="8.00"
-	Name="winsound"
-	ProjectGUID="{28B5D777-DDF2-4B6B-B34F-31D938813856}"
-	RootNamespace="winsound"
-	Keyword="Win32Proj"
-	TargetFrameworkVersion="196613"
-	>
-	<Platforms>
-		<Platform
-			Name="Win32"
-		/>
-		<Platform
-			Name="x64"
-		/>
-	</Platforms>
-	<ToolFiles>
-	</ToolFiles>
-	<Configurations>
-		<Configuration
-			Name="Debug|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd_d.vsprops"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="winmm.lib"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Debug|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd_d.vsprops;.\x64.vsprops"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="winmm.lib"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="winmm.lib"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="winmm.lib"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGInstrument|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\pginstrument.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="winmm.lib"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGInstrument|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pginstrument.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="winmm.lib"
-				TargetMachine="17"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGUpdate|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\pgupdate.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="winmm.lib"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGUpdate|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pgupdate.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="winmm.lib"
-				TargetMachine="17"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<Filter
-			Name="Source Files"
-			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
-			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
-			>
-			<File
-				RelativePath="..\..\PC\winsound.c"
-				>
-			</File>
-		</Filter>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="winsound"
+	ProjectGUID="{28B5D777-DDF2-4B6B-B34F-31D938813856}"
+	RootNamespace="winsound"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd_d.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd_d.vsprops;.\x64.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\pginstrument.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pginstrument.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\pgupdate.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pgupdate.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+			>
+			<File
+				RelativePath="..\..\PC\winsound.c"
+				>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Modified: python/branches/py3k/PCbuild/_bsddb44.vcproj
==============================================================================
--- python/branches/py3k/PCbuild/_bsddb44.vcproj	(original)
+++ python/branches/py3k/PCbuild/_bsddb44.vcproj	Sat Jun 14 01:34:35 2008
@@ -1,1252 +1,1252 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="9.00"
-	Name="_bsddb44"
-	ProjectGUID="{62172C7D-B39E-409A-B352-370FF5098C19}"
-	RootNamespace="_bsddb44"
-	Keyword="Win32Proj"
-	TargetFrameworkVersion="196613"
-	>
-	<Platforms>
-		<Platform
-			Name="Win32"
-		/>
-		<Platform
-			Name="x64"
-		/>
-	</Platforms>
-	<ToolFiles>
-	</ToolFiles>
-	<Configurations>
-		<Configuration
-			Name="Debug|Win32"
-			ConfigurationType="4"
-			InheritedPropertySheets=".\pyd_d.vsprops"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(bsddbDir);$(bsddbDir)\.."
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Debug|x64"
-			ConfigurationType="4"
-			InheritedPropertySheets=".\pyd_d.vsprops;.\x64.vsprops"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(bsddbDir);$(bsddbDir)\.."
-				PreprocessorDefinitions="DIAGNOSTIC"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|Win32"
-			ConfigurationType="4"
-			InheritedPropertySheets=".\pyd.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(bsddbDir);$(bsddbDir)\.."
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|x64"
-			ConfigurationType="4"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(bsddbDir);$(bsddbDir)\.."
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGInstrument|Win32"
-			ConfigurationType="4"
-			InheritedPropertySheets=".\pyd.vsprops;.\pginstrument.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(bsddbDir);$(bsddbDir)\.."
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGInstrument|x64"
-			ConfigurationType="4"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pginstrument.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(bsddbDir);$(bsddbDir)\.."
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGUpdate|Win32"
-			ConfigurationType="4"
-			InheritedPropertySheets=".\pyd.vsprops;.\pgupdate.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(bsddbDir);$(bsddbDir)\.."
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGUpdate|x64"
-			ConfigurationType="4"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pgupdate.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(bsddbDir);$(bsddbDir)\.."
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<Filter
-			Name="Source Files"
-			>
-			<File
-				RelativePath="$(bsddbDir)\..\btree\bt_compact.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\btree\bt_compare.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\btree\bt_conv.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\btree\bt_curadj.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\btree\bt_cursor.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\btree\bt_delete.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\btree\bt_method.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\btree\bt_open.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\btree\bt_put.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\btree\bt_rec.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\btree\bt_reclaim.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\btree\bt_recno.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\btree\bt_rsearch.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\btree\bt_search.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\btree\bt_split.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\btree\bt_stat.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\btree\bt_upgrade.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\btree\bt_verify.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\btree\btree_auto.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\db\crdel_auto.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\db\crdel_rec.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\common\crypto_stub.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\db\db.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\db\db_am.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\db\db_auto.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\common\db_byteorder.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\db\db_cam.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\common\db_clock.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\db\db_conv.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\db\db_dispatch.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\db\db_dup.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\common\db_err.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\common\db_getlong.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\common\db_idspace.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\db\db_iface.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\db\db_join.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\common\db_log2.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\db\db_meta.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\db\db_method.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\db\db_open.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\db\db_overflow.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\db\db_ovfl_vrfy.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\db\db_pr.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\db\db_rec.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\db\db_reclaim.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\db\db_remove.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\db\db_rename.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\db\db_ret.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\env\db_salloc.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\db\db_setid.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\db\db_setlsn.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\env\db_shash.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\db\db_stati.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\db\db_truncate.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\db\db_upg.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\db\db_upg_opd.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\db\db_vrfy.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\db\db_vrfyutil.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\dbm\dbm.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\dbreg\dbreg.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\dbreg\dbreg_auto.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\dbreg\dbreg_rec.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\dbreg\dbreg_stat.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\dbreg\dbreg_util.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\env\env_failchk.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\env\env_file.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\env\env_method.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\env\env_open.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\env\env_recover.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\env\env_region.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\env\env_register.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\env\env_stat.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\fileops\fileops_auto.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\fileops\fop_basic.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\fileops\fop_rec.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\fileops\fop_util.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\hash\hash.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\hash\hash_auto.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\hash\hash_conv.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\hash\hash_dup.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\hash\hash_func.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\hash\hash_meta.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\hash\hash_method.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\hash\hash_open.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\hash\hash_page.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\hash\hash_rec.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\hash\hash_reclaim.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\hash\hash_stat.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\hash\hash_upgrade.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\hash\hash_verify.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\hmac\hmac.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\hsearch\hsearch.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\lock\lock.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\lock\lock_deadlock.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\lock\lock_failchk.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\lock\lock_id.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\lock\lock_list.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\lock\lock_method.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\lock\lock_region.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\lock\lock_stat.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\lock\lock_timer.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\lock\lock_util.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\log\log.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\log\log_archive.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\log\log_compare.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\log\log_debug.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\log\log_get.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\log\log_method.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\log\log_put.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\log\log_stat.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\mp\mp_alloc.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\mp\mp_bh.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\mp\mp_fget.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\mp\mp_fmethod.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\mp\mp_fopen.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\mp\mp_fput.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\mp\mp_fset.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\mp\mp_method.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\mp\mp_region.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\mp\mp_register.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\mp\mp_stat.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\mp\mp_sync.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\mp\mp_trickle.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\mutex\mut_alloc.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\mutex\mut_method.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\mutex\mut_region.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\mutex\mut_stat.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\mutex\mut_win32.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\os_win32\os_abs.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\os\os_alloc.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\os_win32\os_clock.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\os_win32\os_config.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\os_win32\os_dir.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\os_win32\os_errno.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\os_win32\os_fid.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\os_win32\os_flock.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\os_win32\os_fsync.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\os_win32\os_handle.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\os\os_id.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\os_win32\os_map.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\os\os_method.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\os\os_mkdir.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\os\os_oflags.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\os_win32\os_open.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\os\os_region.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\os_win32\os_rename.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\os\os_root.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\os\os_rpath.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\os_win32\os_rw.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\os_win32\os_seek.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\os_win32\os_sleep.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\os_win32\os_spin.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\os_win32\os_stat.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\os\os_tmpdir.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\os_win32\os_truncate.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\os_win32\os_unlink.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\qam\qam.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\qam\qam_auto.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\qam\qam_conv.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\qam\qam_files.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\qam\qam_method.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\qam\qam_open.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\qam\qam_rec.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\qam\qam_stat.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\qam\qam_upgrade.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\qam\qam_verify.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\rep\rep_auto.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\rep\rep_backup.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\rep\rep_elect.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\rep\rep_log.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\rep\rep_method.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\rep\rep_record.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\rep\rep_region.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\rep\rep_stat.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\rep\rep_util.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\rep\rep_verify.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\sequence\seq_stat.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\sequence\sequence.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\hmac\sha1.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\clib\strcasecmp.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\txn\txn.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\txn\txn_auto.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\txn\txn_chkpt.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\txn\txn_failchk.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\txn\txn_method.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\txn\txn_rec.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\txn\txn_recover.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\txn\txn_region.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\txn\txn_stat.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\txn\txn_util.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\common\util_cache.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\common\util_log.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\common\util_sig.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\xa\xa.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\xa\xa_db.c"
-				>
-			</File>
-			<File
-				RelativePath="$(bsddbDir)\..\xa\xa_map.c"
-				>
-			</File>
-		</Filter>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9.00"
+	Name="_bsddb44"
+	ProjectGUID="{62172C7D-B39E-409A-B352-370FF5098C19}"
+	RootNamespace="_bsddb44"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			ConfigurationType="4"
+			InheritedPropertySheets=".\pyd_d.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(bsddbDir);$(bsddbDir)\.."
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			ConfigurationType="4"
+			InheritedPropertySheets=".\pyd_d.vsprops;.\x64.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(bsddbDir);$(bsddbDir)\.."
+				PreprocessorDefinitions="DIAGNOSTIC"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			ConfigurationType="4"
+			InheritedPropertySheets=".\pyd.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(bsddbDir);$(bsddbDir)\.."
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			ConfigurationType="4"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(bsddbDir);$(bsddbDir)\.."
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|Win32"
+			ConfigurationType="4"
+			InheritedPropertySheets=".\pyd.vsprops;.\pginstrument.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(bsddbDir);$(bsddbDir)\.."
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|x64"
+			ConfigurationType="4"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pginstrument.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(bsddbDir);$(bsddbDir)\.."
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|Win32"
+			ConfigurationType="4"
+			InheritedPropertySheets=".\pyd.vsprops;.\pgupdate.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(bsddbDir);$(bsddbDir)\.."
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|x64"
+			ConfigurationType="4"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pgupdate.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(bsddbDir);$(bsddbDir)\.."
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			>
+			<File
+				RelativePath="$(bsddbDir)\..\btree\bt_compact.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\btree\bt_compare.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\btree\bt_conv.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\btree\bt_curadj.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\btree\bt_cursor.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\btree\bt_delete.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\btree\bt_method.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\btree\bt_open.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\btree\bt_put.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\btree\bt_rec.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\btree\bt_reclaim.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\btree\bt_recno.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\btree\bt_rsearch.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\btree\bt_search.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\btree\bt_split.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\btree\bt_stat.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\btree\bt_upgrade.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\btree\bt_verify.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\btree\btree_auto.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\db\crdel_auto.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\db\crdel_rec.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\common\crypto_stub.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\db\db.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\db\db_am.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\db\db_auto.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\common\db_byteorder.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\db\db_cam.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\common\db_clock.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\db\db_conv.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\db\db_dispatch.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\db\db_dup.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\common\db_err.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\common\db_getlong.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\common\db_idspace.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\db\db_iface.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\db\db_join.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\common\db_log2.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\db\db_meta.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\db\db_method.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\db\db_open.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\db\db_overflow.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\db\db_ovfl_vrfy.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\db\db_pr.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\db\db_rec.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\db\db_reclaim.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\db\db_remove.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\db\db_rename.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\db\db_ret.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\env\db_salloc.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\db\db_setid.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\db\db_setlsn.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\env\db_shash.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\db\db_stati.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\db\db_truncate.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\db\db_upg.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\db\db_upg_opd.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\db\db_vrfy.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\db\db_vrfyutil.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\dbm\dbm.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\dbreg\dbreg.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\dbreg\dbreg_auto.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\dbreg\dbreg_rec.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\dbreg\dbreg_stat.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\dbreg\dbreg_util.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\env\env_failchk.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\env\env_file.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\env\env_method.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\env\env_open.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\env\env_recover.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\env\env_region.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\env\env_register.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\env\env_stat.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\fileops\fileops_auto.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\fileops\fop_basic.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\fileops\fop_rec.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\fileops\fop_util.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\hash\hash.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\hash\hash_auto.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\hash\hash_conv.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\hash\hash_dup.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\hash\hash_func.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\hash\hash_meta.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\hash\hash_method.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\hash\hash_open.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\hash\hash_page.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\hash\hash_rec.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\hash\hash_reclaim.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\hash\hash_stat.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\hash\hash_upgrade.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\hash\hash_verify.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\hmac\hmac.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\hsearch\hsearch.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\lock\lock.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\lock\lock_deadlock.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\lock\lock_failchk.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\lock\lock_id.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\lock\lock_list.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\lock\lock_method.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\lock\lock_region.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\lock\lock_stat.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\lock\lock_timer.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\lock\lock_util.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\log\log.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\log\log_archive.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\log\log_compare.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\log\log_debug.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\log\log_get.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\log\log_method.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\log\log_put.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\log\log_stat.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\mp\mp_alloc.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\mp\mp_bh.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\mp\mp_fget.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\mp\mp_fmethod.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\mp\mp_fopen.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\mp\mp_fput.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\mp\mp_fset.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\mp\mp_method.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\mp\mp_region.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\mp\mp_register.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\mp\mp_stat.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\mp\mp_sync.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\mp\mp_trickle.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\mutex\mut_alloc.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\mutex\mut_method.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\mutex\mut_region.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\mutex\mut_stat.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\mutex\mut_win32.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\os_win32\os_abs.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\os\os_alloc.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\os_win32\os_clock.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\os_win32\os_config.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\os_win32\os_dir.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\os_win32\os_errno.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\os_win32\os_fid.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\os_win32\os_flock.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\os_win32\os_fsync.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\os_win32\os_handle.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\os\os_id.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\os_win32\os_map.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\os\os_method.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\os\os_mkdir.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\os\os_oflags.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\os_win32\os_open.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\os\os_region.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\os_win32\os_rename.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\os\os_root.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\os\os_rpath.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\os_win32\os_rw.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\os_win32\os_seek.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\os_win32\os_sleep.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\os_win32\os_spin.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\os_win32\os_stat.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\os\os_tmpdir.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\os_win32\os_truncate.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\os_win32\os_unlink.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\qam\qam.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\qam\qam_auto.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\qam\qam_conv.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\qam\qam_files.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\qam\qam_method.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\qam\qam_open.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\qam\qam_rec.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\qam\qam_stat.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\qam\qam_upgrade.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\qam\qam_verify.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\rep\rep_auto.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\rep\rep_backup.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\rep\rep_elect.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\rep\rep_log.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\rep\rep_method.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\rep\rep_record.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\rep\rep_region.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\rep\rep_stat.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\rep\rep_util.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\rep\rep_verify.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\sequence\seq_stat.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\sequence\sequence.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\hmac\sha1.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\clib\strcasecmp.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\txn\txn.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\txn\txn_auto.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\txn\txn_chkpt.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\txn\txn_failchk.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\txn\txn_method.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\txn\txn_rec.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\txn\txn_recover.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\txn\txn_region.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\txn\txn_stat.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\txn\txn_util.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\common\util_cache.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\common\util_log.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\common\util_sig.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\xa\xa.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\xa\xa_db.c"
+				>
+			</File>
+			<File
+				RelativePath="$(bsddbDir)\..\xa\xa_map.c"
+				>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Modified: python/branches/py3k/PCbuild/bdist_wininst.vcproj
==============================================================================
--- python/branches/py3k/PCbuild/bdist_wininst.vcproj	(original)
+++ python/branches/py3k/PCbuild/bdist_wininst.vcproj	Sat Jun 14 01:34:35 2008
@@ -1,270 +1,270 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="9.00"
-	Name="bdist_wininst"
-	ProjectGUID="{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}"
-	RootNamespace="wininst"
-	TargetFrameworkVersion="131072"
-	>
-	<Platforms>
-		<Platform
-			Name="Win32"
-		/>
-		<Platform
-			Name="x64"
-		/>
-	</Platforms>
-	<ToolFiles>
-	</ToolFiles>
-	<Configurations>
-		<Configuration
-			Name="Release|Win32"
-			OutputDirectory="..\lib\distutils\command"
-			ConfigurationType="1"
-			InheritedPropertySheets=".\pyproject.vsprops;.\release.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				PreprocessorDefinitions="NDEBUG"
-				MkTypLibCompatible="true"
-				SuppressStartupBanner="true"
-				TargetEnvironment="1"
-				TypeLibraryName=".\..\lib\distutils\command\wininst.tlb"
-				HeaderFileName=""
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="1"
-				InlineFunctionExpansion="1"
-				AdditionalIncludeDirectories="..\PC\bdist_wininst;..\Include;..\Modules\zlib"
-				PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE"
-				StringPooling="true"
-				RuntimeLibrary="2"
-				EnableFunctionLevelLinking="true"
-				WarningLevel="3"
-				SuppressStartupBanner="true"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="NDEBUG"
-				Culture="0"
-				AdditionalIncludeDirectories="..\PC;..\PC\bdist_wininst;..\Include"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="comctl32.lib imagehlp.lib"
-				OutputFile="..\lib\distutils\command\wininst-9.0.exe"
-				LinkIncremental="1"
-				SuppressStartupBanner="true"
-				IgnoreDefaultLibraryNames="LIBC"
-				ProgramDatabaseFile="..\lib\distutils\command\wininst-9.0.pdb"
-				SubSystem="2"
-				RandomizedBaseAddress="1"
-				DataExecutionPrevention="0"
-				TargetMachine="1"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|x64"
-			OutputDirectory="$(PlatformName)\$(ConfigurationName)"
-			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
-			ConfigurationType="1"
-			InheritedPropertySheets=".\pyproject.vsprops;.\release.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				PreprocessorDefinitions="NDEBUG"
-				MkTypLibCompatible="true"
-				SuppressStartupBanner="true"
-				TargetEnvironment="3"
-				TypeLibraryName=".\..\lib\distutils\command\wininst.tlb"
-				HeaderFileName=""
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="1"
-				InlineFunctionExpansion="1"
-				AdditionalIncludeDirectories="..\PC\bdist_wininst;..\Include;..\Modules\zlib"
-				PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE"
-				StringPooling="true"
-				RuntimeLibrary="2"
-				EnableFunctionLevelLinking="true"
-				WarningLevel="3"
-				SuppressStartupBanner="true"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="NDEBUG"
-				Culture="0"
-				AdditionalIncludeDirectories="..\PC;..\PC\bdist_wininst;..\Include"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="comctl32.lib imagehlp.lib"
-				OutputFile="..\lib\distutils\command\wininst-9.0-amd64.exe"
-				LinkIncremental="1"
-				SuppressStartupBanner="true"
-				IgnoreDefaultLibraryNames="LIBC"
-				ProgramDatabaseFile="..\lib\distutils\command\wininst-9.0-amd64.pdb"
-				SubSystem="2"
-				RandomizedBaseAddress="1"
-				DataExecutionPrevention="0"
-				TargetMachine="17"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<Filter
-			Name="Source Files"
-			Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-			>
-			<File
-				RelativePath="..\PC\bdist_wininst\extract.c"
-				>
-			</File>
-			<File
-				RelativePath="..\PC\bdist_wininst\install.c"
-				>
-			</File>
-			<Filter
-				Name="zlib"
-				>
-				<File
-					RelativePath="..\Modules\zlib\adler32.c"
-					>
-				</File>
-				<File
-					RelativePath="..\Modules\zlib\crc32.c"
-					>
-				</File>
-				<File
-					RelativePath="..\Modules\zlib\inffast.c"
-					>
-				</File>
-				<File
-					RelativePath="..\Modules\zlib\inflate.c"
-					>
-				</File>
-				<File
-					RelativePath="..\Modules\zlib\inftrees.c"
-					>
-				</File>
-				<File
-					RelativePath="..\Modules\zlib\zutil.c"
-					>
-				</File>
-			</Filter>
-		</Filter>
-		<Filter
-			Name="Header Files"
-			Filter="h;hpp;hxx;hm;inl"
-			>
-			<File
-				RelativePath="..\PC\bdist_wininst\archive.h"
-				>
-			</File>
-		</Filter>
-		<Filter
-			Name="Resource Files"
-			Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-			>
-			<File
-				RelativePath="..\PC\bdist_wininst\install.rc"
-				>
-			</File>
-			<File
-				RelativePath="..\PC\bdist_wininst\PythonPowered.bmp"
-				>
-			</File>
-		</Filter>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9.00"
+	Name="bdist_wininst"
+	ProjectGUID="{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}"
+	RootNamespace="wininst"
+	TargetFrameworkVersion="131072"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="..\lib\distutils\command"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\pyproject.vsprops;.\release.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				PreprocessorDefinitions="NDEBUG"
+				MkTypLibCompatible="true"
+				SuppressStartupBanner="true"
+				TargetEnvironment="1"
+				TypeLibraryName=".\..\lib\distutils\command\wininst.tlb"
+				HeaderFileName=""
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="1"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\PC\bdist_wininst;..\Include;..\Modules\zlib"
+				PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="0"
+				AdditionalIncludeDirectories="..\PC;..\PC\bdist_wininst;..\Include"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="comctl32.lib imagehlp.lib"
+				OutputFile="..\lib\distutils\command\wininst-9.0.exe"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				IgnoreDefaultLibraryNames="LIBC"
+				ProgramDatabaseFile="..\lib\distutils\command\wininst-9.0.pdb"
+				SubSystem="2"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			OutputDirectory="$(PlatformName)\$(ConfigurationName)"
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\pyproject.vsprops;.\release.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				PreprocessorDefinitions="NDEBUG"
+				MkTypLibCompatible="true"
+				SuppressStartupBanner="true"
+				TargetEnvironment="3"
+				TypeLibraryName=".\..\lib\distutils\command\wininst.tlb"
+				HeaderFileName=""
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="1"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\PC\bdist_wininst;..\Include;..\Modules\zlib"
+				PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="0"
+				AdditionalIncludeDirectories="..\PC;..\PC\bdist_wininst;..\Include"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="comctl32.lib imagehlp.lib"
+				OutputFile="..\lib\distutils\command\wininst-9.0-amd64.exe"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				IgnoreDefaultLibraryNames="LIBC"
+				ProgramDatabaseFile="..\lib\distutils\command\wininst-9.0-amd64.pdb"
+				SubSystem="2"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+			>
+			<File
+				RelativePath="..\PC\bdist_wininst\extract.c"
+				>
+			</File>
+			<File
+				RelativePath="..\PC\bdist_wininst\install.c"
+				>
+			</File>
+			<Filter
+				Name="zlib"
+				>
+				<File
+					RelativePath="..\Modules\zlib\adler32.c"
+					>
+				</File>
+				<File
+					RelativePath="..\Modules\zlib\crc32.c"
+					>
+				</File>
+				<File
+					RelativePath="..\Modules\zlib\inffast.c"
+					>
+				</File>
+				<File
+					RelativePath="..\Modules\zlib\inflate.c"
+					>
+				</File>
+				<File
+					RelativePath="..\Modules\zlib\inftrees.c"
+					>
+				</File>
+				<File
+					RelativePath="..\Modules\zlib\zutil.c"
+					>
+				</File>
+			</Filter>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl"
+			>
+			<File
+				RelativePath="..\PC\bdist_wininst\archive.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+			>
+			<File
+				RelativePath="..\PC\bdist_wininst\install.rc"
+				>
+			</File>
+			<File
+				RelativePath="..\PC\bdist_wininst\PythonPowered.bmp"
+				>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Modified: python/branches/py3k/PCbuild/kill_python.c
==============================================================================
--- python/branches/py3k/PCbuild/kill_python.c	(original)
+++ python/branches/py3k/PCbuild/kill_python.c	Sat Jun 14 01:34:35 2008
@@ -1,178 +1,178 @@
-/*
- * Helper program for killing lingering python[_d].exe processes before
- * building, thus attempting to avoid build failures due to files being
- * locked.
- */
-
-#include <windows.h>
-#include <wchar.h>
-#include <tlhelp32.h>
-#include <stdio.h>
-
-#pragma comment(lib, "psapi")
-
-#ifdef _DEBUG
-#define PYTHON_EXE          (L"python_d.exe")
-#define PYTHON_EXE_LEN      (12)
-#define KILL_PYTHON_EXE     (L"kill_python_d.exe")
-#define KILL_PYTHON_EXE_LEN (17)
-#else
-#define PYTHON_EXE          (L"python.exe")
-#define PYTHON_EXE_LEN      (10)
-#define KILL_PYTHON_EXE     (L"kill_python.exe")
-#define KILL_PYTHON_EXE_LEN (15)
-#endif
-
-int
-main(int argc, char **argv)
-{
-    HANDLE   hp, hsp, hsm; /* process, snapshot processes, snapshot modules */
-    DWORD    dac, our_pid;
-    size_t   len;
-    wchar_t  path[MAX_PATH+1];
-
-    MODULEENTRY32W  me;
-    PROCESSENTRY32W pe;
-
-    me.dwSize = sizeof(MODULEENTRY32W);
-    pe.dwSize = sizeof(PROCESSENTRY32W);
-
-    memset(path, 0, MAX_PATH+1);
-
-    our_pid = GetCurrentProcessId();
-
-    hsm = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, our_pid);
-    if (hsm == INVALID_HANDLE_VALUE) {
-        printf("CreateToolhelp32Snapshot[1] failed: %d\n", GetLastError());
-        return 1;
-    }
-
-    if (!Module32FirstW(hsm, &me)) {
-        printf("Module32FirstW[1] failed: %d\n", GetLastError());
-        CloseHandle(hsm);
-        return 1;
-    }
-
-    /*
-     * Enumerate over the modules for the current process in order to find
-     * kill_process[_d].exe, then take a note of the directory it lives in.
-     */
-    do {
-        if (_wcsnicmp(me.szModule, KILL_PYTHON_EXE, KILL_PYTHON_EXE_LEN))
-            continue;
-
-        len = wcsnlen_s(me.szExePath, MAX_PATH) - KILL_PYTHON_EXE_LEN;
-        wcsncpy_s(path, MAX_PATH+1, me.szExePath, len); 
-
-        break;
-
-    } while (Module32NextW(hsm, &me));
-
-    CloseHandle(hsm);
-
-    if (path == NULL) {
-        printf("failed to discern directory of running process\n");
-        return 1;
-    }
-
-    /*
-     * Take a snapshot of system processes.  Enumerate over the snapshot,
-     * looking for python processes.  When we find one, verify it lives
-     * in the same directory we live in.  If it does, kill it.  If we're
-     * unable to kill it, treat this as a fatal error and return 1.
-     * 
-     * The rationale behind this is that we're called at the start of the 
-     * build process on the basis that we'll take care of killing any
-     * running instances, such that the build won't encounter permission
-     * denied errors during linking. If we can't kill one of the processes,
-     * we can't provide this assurance, and the build shouldn't start.
-     */
-
-    hsp = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
-    if (hsp == INVALID_HANDLE_VALUE) {
-        printf("CreateToolhelp32Snapshot[2] failed: %d\n", GetLastError());
-        return 1;
-    }
-
-    if (!Process32FirstW(hsp, &pe)) {
-        printf("Process32FirstW failed: %d\n", GetLastError());
-        CloseHandle(hsp);
-        return 1;
-    }
-
-    dac = PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_TERMINATE;
-    do {
-
-        /*
-         * XXX TODO: if we really wanted to be fancy, we could check the 
-         * modules for all processes (not just the python[_d].exe ones)
-         * and see if any of our DLLs are loaded (i.e. python30[_d].dll),
-         * as that would also inhibit our ability to rebuild the solution.
-         * Not worth loosing sleep over though; for now, a simple check 
-         * for just the python executable should be sufficient.
-         */
-
-        if (_wcsnicmp(pe.szExeFile, PYTHON_EXE, PYTHON_EXE_LEN))
-            /* This isn't a python process. */
-            continue;
-
-        /* It's a python process, so figure out which directory it's in... */
-        hsm = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pe.th32ProcessID);
-        if (hsm == INVALID_HANDLE_VALUE)
-            /* 
-             * If our module snapshot fails (which will happen if we don't own
-             * the process), just ignore it and continue.  (It seems different
-             * versions of Windows return different values for GetLastError()
-             * in this situation; it's easier to just ignore it and move on vs.
-             * stopping the build for what could be a false positive.)
-             */
-             continue;
-
-        if (!Module32FirstW(hsm, &me)) {
-            printf("Module32FirstW[2] failed: %d\n", GetLastError());
-            CloseHandle(hsp);
-            CloseHandle(hsm);
-            return 1;
-        }
-
-        do {
-            if (_wcsnicmp(me.szModule, PYTHON_EXE, PYTHON_EXE_LEN))
-                /* Wrong module, we're looking for python[_d].exe... */
-                continue;
-
-            if (_wcsnicmp(path, me.szExePath, len))
-                /* Process doesn't live in our directory. */
-                break;
-
-            /* Python process residing in the right directory, kill it!  */
-            hp = OpenProcess(dac, FALSE, pe.th32ProcessID);
-            if (!hp) {
-                printf("OpenProcess failed: %d\n", GetLastError());
-                CloseHandle(hsp);
-                CloseHandle(hsm);
-                return 1;
-            }
-
-            if (!TerminateProcess(hp, 1)) {
-                printf("TerminateProcess failed: %d\n", GetLastError());
-                CloseHandle(hsp);
-                CloseHandle(hsm);
-                CloseHandle(hp);
-                return 1;
-            }
-
-            CloseHandle(hp);
-            break;
-
-        } while (Module32NextW(hsm, &me));
-
-        CloseHandle(hsm);
-
-    } while (Process32NextW(hsp, &pe));
-
-    CloseHandle(hsp);
-
-    return 0;
-}
-
-/* vi: set ts=8 sw=4 sts=4 expandtab */
+/*
+ * Helper program for killing lingering python[_d].exe processes before
+ * building, thus attempting to avoid build failures due to files being
+ * locked.
+ */
+
+#include <windows.h>
+#include <wchar.h>
+#include <tlhelp32.h>
+#include <stdio.h>
+
+#pragma comment(lib, "psapi")
+
+#ifdef _DEBUG
+#define PYTHON_EXE          (L"python_d.exe")
+#define PYTHON_EXE_LEN      (12)
+#define KILL_PYTHON_EXE     (L"kill_python_d.exe")
+#define KILL_PYTHON_EXE_LEN (17)
+#else
+#define PYTHON_EXE          (L"python.exe")
+#define PYTHON_EXE_LEN      (10)
+#define KILL_PYTHON_EXE     (L"kill_python.exe")
+#define KILL_PYTHON_EXE_LEN (15)
+#endif
+
+int
+main(int argc, char **argv)
+{
+    HANDLE   hp, hsp, hsm; /* process, snapshot processes, snapshot modules */
+    DWORD    dac, our_pid;
+    size_t   len;
+    wchar_t  path[MAX_PATH+1];
+
+    MODULEENTRY32W  me;
+    PROCESSENTRY32W pe;
+
+    me.dwSize = sizeof(MODULEENTRY32W);
+    pe.dwSize = sizeof(PROCESSENTRY32W);
+
+    memset(path, 0, MAX_PATH+1);
+
+    our_pid = GetCurrentProcessId();
+
+    hsm = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, our_pid);
+    if (hsm == INVALID_HANDLE_VALUE) {
+        printf("CreateToolhelp32Snapshot[1] failed: %d\n", GetLastError());
+        return 1;
+    }
+
+    if (!Module32FirstW(hsm, &me)) {
+        printf("Module32FirstW[1] failed: %d\n", GetLastError());
+        CloseHandle(hsm);
+        return 1;
+    }
+
+    /*
+     * Enumerate over the modules for the current process in order to find
+     * kill_process[_d].exe, then take a note of the directory it lives in.
+     */
+    do {
+        if (_wcsnicmp(me.szModule, KILL_PYTHON_EXE, KILL_PYTHON_EXE_LEN))
+            continue;
+
+        len = wcsnlen_s(me.szExePath, MAX_PATH) - KILL_PYTHON_EXE_LEN;
+        wcsncpy_s(path, MAX_PATH+1, me.szExePath, len); 
+
+        break;
+
+    } while (Module32NextW(hsm, &me));
+
+    CloseHandle(hsm);
+
+    if (path == NULL) {
+        printf("failed to discern directory of running process\n");
+        return 1;
+    }
+
+    /*
+     * Take a snapshot of system processes.  Enumerate over the snapshot,
+     * looking for python processes.  When we find one, verify it lives
+     * in the same directory we live in.  If it does, kill it.  If we're
+     * unable to kill it, treat this as a fatal error and return 1.
+     * 
+     * The rationale behind this is that we're called at the start of the 
+     * build process on the basis that we'll take care of killing any
+     * running instances, such that the build won't encounter permission
+     * denied errors during linking. If we can't kill one of the processes,
+     * we can't provide this assurance, and the build shouldn't start.
+     */
+
+    hsp = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
+    if (hsp == INVALID_HANDLE_VALUE) {
+        printf("CreateToolhelp32Snapshot[2] failed: %d\n", GetLastError());
+        return 1;
+    }
+
+    if (!Process32FirstW(hsp, &pe)) {
+        printf("Process32FirstW failed: %d\n", GetLastError());
+        CloseHandle(hsp);
+        return 1;
+    }
+
+    dac = PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_TERMINATE;
+    do {
+
+        /*
+         * XXX TODO: if we really wanted to be fancy, we could check the 
+         * modules for all processes (not just the python[_d].exe ones)
+         * and see if any of our DLLs are loaded (i.e. python30[_d].dll),
+         * as that would also inhibit our ability to rebuild the solution.
+         * Not worth loosing sleep over though; for now, a simple check 
+         * for just the python executable should be sufficient.
+         */
+
+        if (_wcsnicmp(pe.szExeFile, PYTHON_EXE, PYTHON_EXE_LEN))
+            /* This isn't a python process. */
+            continue;
+
+        /* It's a python process, so figure out which directory it's in... */
+        hsm = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pe.th32ProcessID);
+        if (hsm == INVALID_HANDLE_VALUE)
+            /* 
+             * If our module snapshot fails (which will happen if we don't own
+             * the process), just ignore it and continue.  (It seems different
+             * versions of Windows return different values for GetLastError()
+             * in this situation; it's easier to just ignore it and move on vs.
+             * stopping the build for what could be a false positive.)
+             */
+             continue;
+
+        if (!Module32FirstW(hsm, &me)) {
+            printf("Module32FirstW[2] failed: %d\n", GetLastError());
+            CloseHandle(hsp);
+            CloseHandle(hsm);
+            return 1;
+        }
+
+        do {
+            if (_wcsnicmp(me.szModule, PYTHON_EXE, PYTHON_EXE_LEN))
+                /* Wrong module, we're looking for python[_d].exe... */
+                continue;
+
+            if (_wcsnicmp(path, me.szExePath, len))
+                /* Process doesn't live in our directory. */
+                break;
+
+            /* Python process residing in the right directory, kill it!  */
+            hp = OpenProcess(dac, FALSE, pe.th32ProcessID);
+            if (!hp) {
+                printf("OpenProcess failed: %d\n", GetLastError());
+                CloseHandle(hsp);
+                CloseHandle(hsm);
+                return 1;
+            }
+
+            if (!TerminateProcess(hp, 1)) {
+                printf("TerminateProcess failed: %d\n", GetLastError());
+                CloseHandle(hsp);
+                CloseHandle(hsm);
+                CloseHandle(hp);
+                return 1;
+            }
+
+            CloseHandle(hp);
+            break;
+
+        } while (Module32NextW(hsm, &me));
+
+        CloseHandle(hsm);
+
+    } while (Process32NextW(hsp, &pe));
+
+    CloseHandle(hsp);
+
+    return 0;
+}
+
+/* vi: set ts=8 sw=4 sts=4 expandtab */

Modified: python/branches/py3k/PCbuild/kill_python.vcproj
==============================================================================
--- python/branches/py3k/PCbuild/kill_python.vcproj	(original)
+++ python/branches/py3k/PCbuild/kill_python.vcproj	Sat Jun 14 01:34:35 2008
@@ -1,279 +1,279 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="9.00"
-	Name="kill_python"
-	ProjectGUID="{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}"
-	RootNamespace="kill_python"
-	Keyword="Win32Proj"
-	TargetFrameworkVersion="196613"
-	>
-	<Platforms>
-		<Platform
-			Name="Win32"
-		/>
-		<Platform
-			Name="x64"
-		/>
-	</Platforms>
-	<ToolFiles>
-	</ToolFiles>
-	<Configurations>
-		<Configuration
-			Name="Debug|Win32"
-			ConfigurationType="1"
-			InheritedPropertySheets=".\pyproject.vsprops;.\debug.vsprops"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				OutputFile="$(OutDir)\$(ProjectName)_d.exe"
-				SubSystem="1"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Debug|x64"
-			ConfigurationType="1"
-			InheritedPropertySheets=".\pyproject.vsprops;.\debug.vsprops;.\x64.vsprops"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				OutputFile="$(OutDir)\$(ProjectName)_d.exe"
-				SubSystem="1"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|Win32"
-			ConfigurationType="1"
-			InheritedPropertySheets=".\pyproject.vsprops;.\release.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				SubSystem="1"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|x64"
-			ConfigurationType="1"
-			InheritedPropertySheets=".\pyproject.vsprops;.\release.vsprops;.\x64.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				SubSystem="1"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<Filter
-			Name="Source Files"
-			>
-			<File
-				RelativePath=".\kill_python.c"
-				>
-			</File>
-		</Filter>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9.00"
+	Name="kill_python"
+	ProjectGUID="{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}"
+	RootNamespace="kill_python"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\pyproject.vsprops;.\debug.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\$(ProjectName)_d.exe"
+				SubSystem="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\pyproject.vsprops;.\debug.vsprops;.\x64.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\$(ProjectName)_d.exe"
+				SubSystem="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\pyproject.vsprops;.\release.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				SubSystem="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\pyproject.vsprops;.\release.vsprops;.\x64.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				SubSystem="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			>
+			<File
+				RelativePath=".\kill_python.c"
+				>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

Modified: python/branches/py3k/PCbuild/sqlite3.vcproj
==============================================================================
--- python/branches/py3k/PCbuild/sqlite3.vcproj	(original)
+++ python/branches/py3k/PCbuild/sqlite3.vcproj	Sat Jun 14 01:34:35 2008
@@ -1,543 +1,543 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="9,00"
-	Name="sqlite3"
-	ProjectGUID="{A1A295E5-463C-437F-81CA-1F32367685DA}"
-	RootNamespace="sqlite3"
-	Keyword="Win32Proj"
-	TargetFrameworkVersion="196613"
-	>
-	<Platforms>
-		<Platform
-			Name="Win32"
-		/>
-		<Platform
-			Name="x64"
-		/>
-	</Platforms>
-	<ToolFiles>
-	</ToolFiles>
-	<Configurations>
-		<Configuration
-			Name="Debug|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd_d.vsprops"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(sqlite3Dir)"
-				PreprocessorDefinitions="SQLITE_API=__declspec(dllexport)"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				OutputFile="$(OutDir)\$(ProjectName)_d.dll"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Debug|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd_d.vsprops;.\x64.vsprops"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(sqlite3Dir)"
-				PreprocessorDefinitions="SQLITE_API=__declspec(dllexport)"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				OutputFile="$(OutDir)\$(ProjectName)_d.dll"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(sqlite3Dir)"
-				PreprocessorDefinitions="SQLITE_API=__declspec(dllexport)"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				OutputFile="$(OutDir)\$(ProjectName).dll"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(sqlite3Dir)"
-				PreprocessorDefinitions="SQLITE_API=__declspec(dllexport)"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				OutputFile="$(OutDir)\$(ProjectName).dll"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGInstrument|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\pginstrument.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(sqlite3Dir)"
-				PreprocessorDefinitions="SQLITE_API=__declspec(dllexport)"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGInstrument|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pginstrument.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(sqlite3Dir)"
-				PreprocessorDefinitions="SQLITE_API=__declspec(dllexport)"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGUpdate|Win32"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\pgupdate.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(sqlite3Dir)"
-				PreprocessorDefinitions="SQLITE_API=__declspec(dllexport)"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="PGUpdate|x64"
-			ConfigurationType="2"
-			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pgupdate.vsprops"
-			CharacterSet="0"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				TargetEnvironment="3"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				AdditionalIncludeDirectories="$(sqlite3Dir)"
-				PreprocessorDefinitions="SQLITE_API=__declspec(dllexport)"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<Filter
-			Name="Header Files"
-			>
-			<File
-				RelativePath="$(sqlite3Dir)\sqlite3.h"
-				>
-			</File>
-			<File
-				RelativePath="$(sqlite3Dir)\sqlite3ext.h"
-				>
-			</File>
-		</Filter>
-		<Filter
-			Name="Source Files"
-			>
-			<File
-				RelativePath="$(sqlite3Dir)\sqlite3.c"
-				>
-			</File>
-		</Filter>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9,00"
+	Name="sqlite3"
+	ProjectGUID="{A1A295E5-463C-437F-81CA-1F32367685DA}"
+	RootNamespace="sqlite3"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd_d.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(sqlite3Dir)"
+				PreprocessorDefinitions="SQLITE_API=__declspec(dllexport)"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\$(ProjectName)_d.dll"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd_d.vsprops;.\x64.vsprops"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(sqlite3Dir)"
+				PreprocessorDefinitions="SQLITE_API=__declspec(dllexport)"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\$(ProjectName)_d.dll"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(sqlite3Dir)"
+				PreprocessorDefinitions="SQLITE_API=__declspec(dllexport)"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\$(ProjectName).dll"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(sqlite3Dir)"
+				PreprocessorDefinitions="SQLITE_API=__declspec(dllexport)"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\$(ProjectName).dll"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\pginstrument.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(sqlite3Dir)"
+				PreprocessorDefinitions="SQLITE_API=__declspec(dllexport)"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGInstrument|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pginstrument.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(sqlite3Dir)"
+				PreprocessorDefinitions="SQLITE_API=__declspec(dllexport)"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|Win32"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\pgupdate.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(sqlite3Dir)"
+				PreprocessorDefinitions="SQLITE_API=__declspec(dllexport)"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="PGUpdate|x64"
+			ConfigurationType="2"
+			InheritedPropertySheets=".\pyd.vsprops;.\x64.vsprops;.\pgupdate.vsprops"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(sqlite3Dir)"
+				PreprocessorDefinitions="SQLITE_API=__declspec(dllexport)"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Header Files"
+			>
+			<File
+				RelativePath="$(sqlite3Dir)\sqlite3.h"
+				>
+			</File>
+			<File
+				RelativePath="$(sqlite3Dir)\sqlite3ext.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Source Files"
+			>
+			<File
+				RelativePath="$(sqlite3Dir)\sqlite3.c"
+				>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

From python-3000-checkins at python.org  Sat Jun 14 02:49:05 2008
From: python-3000-checkins at python.org (martin.v.loewis)
Date: Sat, 14 Jun 2008 02:49:05 +0200 (CEST)
Subject: [Python-3000-checkins] r64261 - in python/branches/py3k:
	Lib/email/test/data/msg_26.txt
Message-ID: <20080614004905.5722A1E4006@bag.python.org>

Author: martin.v.loewis
Date: Sat Jun 14 02:49:05 2008
New Revision: 64261

Log:
Merged revisions 64260 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/trunk

........
  r64260 | martin.v.loewis | 2008-06-14 02:41:41 +0200 (Sa, 14 Jun 2008) | 2 lines
  
  Revert eol-style to CRLF.
........


Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Lib/email/test/data/msg_26.txt   (contents, props changed)

Modified: python/branches/py3k/Lib/email/test/data/msg_26.txt
==============================================================================
--- python/branches/py3k/Lib/email/test/data/msg_26.txt	(original)
+++ python/branches/py3k/Lib/email/test/data/msg_26.txt	Sat Jun 14 02:49:05 2008
@@ -1,45 +1,45 @@
-Received: from xcar [192.168.0.2] by jeeves.wooster.local
-  (SMTPD32-7.07 EVAL) id AFF92F0214; Sun, 12 May 2002 08:55:37 +0100
-Date: Sun, 12 May 2002 08:56:15 +0100
-From: Father Time <father.time at xcar.wooster.local>
-To: timbo at jeeves.wooster.local
-Subject: IMAP file test
-Message-ID: <6df65d354b.father.time at rpc.wooster.local>
-X-Organization: Home
-User-Agent: Messenger-Pro/2.50a (MsgServe/1.50) (RISC-OS/4.02) POPstar/2.03
-MIME-Version: 1.0
-Content-Type: multipart/mixed; boundary="1618492860--2051301190--113853680"
-Status: R
-X-UIDL: 319998302
-
-This message is in MIME format which your mailer apparently does not support.
-You either require a newer version of your software which supports MIME, or
-a separate MIME decoding utility.  Alternatively, ask the sender of this
-message to resend it in a different format.
-
---1618492860--2051301190--113853680
-Content-Type: text/plain; charset=us-ascii
-
-Simple email with attachment.
-
-
---1618492860--2051301190--113853680
-Content-Type: application/riscos; name="clock.bmp,69c"; type=BMP; load=&fff69c4b; exec=&355dd4d1; access=&03
-Content-Disposition: attachment; filename="clock.bmp"
-Content-Transfer-Encoding: base64
-
-Qk12AgAAAAAAAHYAAAAoAAAAIAAAACAAAAABAAQAAAAAAAAAAADXDQAA1w0AAAAAAAAA
-AAAAAAAAAAAAiAAAiAAAAIiIAIgAAACIAIgAiIgAALu7uwCIiIgAERHdACLuIgAz//8A
-zAAAAN0R3QDu7iIA////AAAAAAAAAAAAAAAAAAAAAAAAAAi3AAAAAAAAADeAAAAAAAAA
-C3ADMzMzMANwAAAAAAAAAAAHMAAAAANwAAAAAAAAAACAMAd3zPfwAwgAAAAAAAAIAwd/
-f8x/f3AwgAAAAAAAgDB0x/f3//zPAwgAAAAAAAcHfM9////8z/AwAAAAAAiwd/f3////
-////A4AAAAAAcEx/f///////zAMAAAAAiwfM9////3///8zwOAAAAAcHf3////B/////
-8DAAAAALB/f3///wd3d3//AwAAAABwTPf//wCQAAD/zAMAAAAAsEx/f///B////8wDAA
-AAAHB39////wf/////AwAAAACwf39///8H/////wMAAAAIcHfM9///B////M8DgAAAAA
-sHTH///wf///xAMAAAAACHB3f3//8H////cDgAAAAAALB3zH//D//M9wMAAAAAAAgLB0
-z39///xHAwgAAAAAAAgLB3d3RHd3cDCAAAAAAAAAgLAHd0R3cAMIAAAAAAAAgAgLcAAA
-AAMwgAgAAAAACDAAAAu7t7cwAAgDgAAAAABzcIAAAAAAAAgDMwAAAAAAN7uwgAAAAAgH
-MzMAAAAACH97tzAAAAALu3c3gAAAAAAL+7tzDABAu7f7cAAAAAAACA+3MA7EQAv/sIAA
-AAAAAAAIAAAAAAAAAIAAAAAA
-
---1618492860--2051301190--113853680--
+Received: from xcar [192.168.0.2] by jeeves.wooster.local
+  (SMTPD32-7.07 EVAL) id AFF92F0214; Sun, 12 May 2002 08:55:37 +0100
+Date: Sun, 12 May 2002 08:56:15 +0100
+From: Father Time <father.time at xcar.wooster.local>
+To: timbo at jeeves.wooster.local
+Subject: IMAP file test
+Message-ID: <6df65d354b.father.time at rpc.wooster.local>
+X-Organization: Home
+User-Agent: Messenger-Pro/2.50a (MsgServe/1.50) (RISC-OS/4.02) POPstar/2.03
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary="1618492860--2051301190--113853680"
+Status: R
+X-UIDL: 319998302
+
+This message is in MIME format which your mailer apparently does not support.
+You either require a newer version of your software which supports MIME, or
+a separate MIME decoding utility.  Alternatively, ask the sender of this
+message to resend it in a different format.
+
+--1618492860--2051301190--113853680
+Content-Type: text/plain; charset=us-ascii
+
+Simple email with attachment.
+
+
+--1618492860--2051301190--113853680
+Content-Type: application/riscos; name="clock.bmp,69c"; type=BMP; load=&fff69c4b; exec=&355dd4d1; access=&03
+Content-Disposition: attachment; filename="clock.bmp"
+Content-Transfer-Encoding: base64
+
+Qk12AgAAAAAAAHYAAAAoAAAAIAAAACAAAAABAAQAAAAAAAAAAADXDQAA1w0AAAAAAAAA
+AAAAAAAAAAAAiAAAiAAAAIiIAIgAAACIAIgAiIgAALu7uwCIiIgAERHdACLuIgAz//8A
+zAAAAN0R3QDu7iIA////AAAAAAAAAAAAAAAAAAAAAAAAAAi3AAAAAAAAADeAAAAAAAAA
+C3ADMzMzMANwAAAAAAAAAAAHMAAAAANwAAAAAAAAAACAMAd3zPfwAwgAAAAAAAAIAwd/
+f8x/f3AwgAAAAAAAgDB0x/f3//zPAwgAAAAAAAcHfM9////8z/AwAAAAAAiwd/f3////
+////A4AAAAAAcEx/f///////zAMAAAAAiwfM9////3///8zwOAAAAAcHf3////B/////
+8DAAAAALB/f3///wd3d3//AwAAAABwTPf//wCQAAD/zAMAAAAAsEx/f///B////8wDAA
+AAAHB39////wf/////AwAAAACwf39///8H/////wMAAAAIcHfM9///B////M8DgAAAAA
+sHTH///wf///xAMAAAAACHB3f3//8H////cDgAAAAAALB3zH//D//M9wMAAAAAAAgLB0
+z39///xHAwgAAAAAAAgLB3d3RHd3cDCAAAAAAAAAgLAHd0R3cAMIAAAAAAAAgAgLcAAA
+AAMwgAgAAAAACDAAAAu7t7cwAAgDgAAAAABzcIAAAAAAAAgDMwAAAAAAN7uwgAAAAAgH
+MzMAAAAACH97tzAAAAALu3c3gAAAAAAL+7tzDABAu7f7cAAAAAAACA+3MA7EQAv/sIAA
+AAAAAAAIAAAAAAAAAIAAAAAA
+
+--1618492860--2051301190--113853680--

From python-3000-checkins at python.org  Sat Jun 14 03:51:58 2008
From: python-3000-checkins at python.org (martin.v.loewis)
Date: Sat, 14 Jun 2008 03:51:58 +0200 (CEST)
Subject: [Python-3000-checkins] r64263 - in python/branches/py3k:
	Tools/scripts/svneol.py
Message-ID: <20080614015158.8BA491E400A@bag.python.org>

Author: martin.v.loewis
Date: Sat Jun 14 03:51:58 2008
New Revision: 64263

Log:
Merged revisions 64262 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/trunk

........
  r64262 | martin.v.loewis | 2008-06-14 03:50:46 +0200 (Sa, 14 Jun 2008) | 2 lines
  
  Support subversion repositories of version 8.
........


Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Tools/scripts/svneol.py

Modified: python/branches/py3k/Tools/scripts/svneol.py
==============================================================================
--- python/branches/py3k/Tools/scripts/svneol.py	(original)
+++ python/branches/py3k/Tools/scripts/svneol.py	Sat Jun 14 03:51:58 2008
@@ -33,9 +33,21 @@
 import re
 import os
 
+def propfile(root, fn):
+    default = os.path.join(root, ".svn", "props", fn+".svn-work")
+    try:
+        format = int(open(os.path.join(root, ".svn", "format")).read().strip())
+    except IOError:
+        return default
+    # XXX I don't know what version uses what format;
+    # this condition is just anecdotal
+    if format >= 8:
+        return os.path.join(root, ".svn", "prop-base", fn+".svn-base")
+    return default
+
 def proplist(root, fn):
     "Return a list of property names for file fn in directory root"
-    path = os.path.join(root, ".svn", "props", fn+".svn-work")
+    path = propfile(root, fn)
     try:
         f = open(path)
     except IOError:

From python-3000-checkins at python.org  Sat Jun 14 04:23:30 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Sat, 14 Jun 2008 04:23:30 +0200 (CEST)
Subject: [Python-3000-checkins] r64264 -
	python/branches/py3k/Doc/library/multiprocessing.rst
Message-ID: <20080614022330.206431E4006@bag.python.org>

Author: benjamin.peterson
Date: Sat Jun 14 04:23:29 2008
New Revision: 64264

Log:
remove a versionadded

Modified:
   python/branches/py3k/Doc/library/multiprocessing.rst

Modified: python/branches/py3k/Doc/library/multiprocessing.rst
==============================================================================
--- python/branches/py3k/Doc/library/multiprocessing.rst	(original)
+++ python/branches/py3k/Doc/library/multiprocessing.rst	Sat Jun 14 04:23:29 2008
@@ -4,8 +4,6 @@
 .. module:: multiprocessing
    :synopsis: Process-based "threading" interface.
 
-.. versionadded:: 2.6
-
 :mod:`multiprocessing` is a package for the Python language which supports the
 spawning of processes using a similar API of the :mod:`threading` module.  It
 runs on both Unix and Windows.
@@ -2105,4 +2103,4 @@
 You will need to have private key authentication for all hosts configured for
 this to work.
 
-.. literalinclude:: ../includes/mp_distributing.py
\ No newline at end of file
+.. literalinclude:: ../includes/mp_distributing.py

From python-3000-checkins at python.org  Sat Jun 14 08:25:37 2008
From: python-3000-checkins at python.org (martin.v.loewis)
Date: Sat, 14 Jun 2008 08:25:37 +0200 (CEST)
Subject: [Python-3000-checkins] r64266 - in python/branches/py3k:
	Tools/scripts/svneol.py
Message-ID: <20080614062537.58B521E4007@bag.python.org>

Author: martin.v.loewis
Date: Sat Jun 14 08:25:37 2008
New Revision: 64266

Log:
Merged revisions 64265 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/trunk

........
  r64265 | martin.v.loewis | 2008-06-14 08:24:44 +0200 (Sa, 14 Jun 2008) | 2 lines
  
  Conservatively restrict support to format 8 repositories.
........


Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Tools/scripts/svneol.py

Modified: python/branches/py3k/Tools/scripts/svneol.py
==============================================================================
--- python/branches/py3k/Tools/scripts/svneol.py	(original)
+++ python/branches/py3k/Tools/scripts/svneol.py	Sat Jun 14 08:25:37 2008
@@ -33,48 +33,50 @@
 import re
 import os
 
-def propfile(root, fn):
+def propfiles(root, fn):
     default = os.path.join(root, ".svn", "props", fn+".svn-work")
     try:
         format = int(open(os.path.join(root, ".svn", "format")).read().strip())
     except IOError:
-        return default
-    # XXX I don't know what version uses what format;
-    # this condition is just anecdotal
-    if format >= 8:
-        return os.path.join(root, ".svn", "prop-base", fn+".svn-base")
-    return default
+        return []
+    if format == 8:
+        # In version 8, committed props are stored in prop-base,
+        # local modifications in props
+        return [os.path.join(root, ".svn", "prop-base", fn+".svn-base"),
+                os.path.join(root, ".svn", "props", fn+".svn-work")]
+    raise ValueError, "Unknown repository format"
 
 def proplist(root, fn):
     "Return a list of property names for file fn in directory root"
-    path = propfile(root, fn)
-    try:
-        f = open(path)
-    except IOError:
-        # no properties file: not under version control
-        return []
     result = []
-    while 1:
-        # key-value pairs, of the form
-        # K <length>
-        # <keyname>NL
-        # V length
-        # <value>NL
-        # END
-        line = f.readline()
-        if line.startswith("END"):
-            break
-        assert line.startswith("K ")
-        L = int(line.split()[1])
-        key = f.read(L)
-        result.append(key)
-        f.readline()
-        line = f.readline()
-        assert line.startswith("V ")
-        L = int(line.split()[1])
-        value = f.read(L)
-        f.readline()
-    f.close()
+    for path in propfiles(root, fn):
+        try:
+            f = open(path)
+        except IOError:
+            # no properties file: not under version control,
+            # or no properties set
+            continue
+        while 1:
+            # key-value pairs, of the form
+            # K <length>
+            # <keyname>NL
+            # V length
+            # <value>NL
+            # END
+            line = f.readline()
+            if line.startswith("END"):
+                break
+            assert line.startswith("K ")
+            L = int(line.split()[1])
+            key = f.read(L)
+            result.append(key)
+            f.readline()
+            line = f.readline()
+            assert line.startswith("V ")
+            L = int(line.split()[1])
+            value = f.read(L)
+            f.readline()
+        f.close()
     return result
 
 possible_text_file = re.compile(r"\.([hc]|py|txt|sln|vcproj)$").search

From python-3000-checkins at python.org  Sat Jun 14 13:59:52 2008
From: python-3000-checkins at python.org (martin.v.loewis)
Date: Sat, 14 Jun 2008 13:59:52 +0200 (CEST)
Subject: [Python-3000-checkins] r64273 - in python/branches/py3k:
	Modules/socketmodule.h Tools/buildbot/build-amd64.bat
	Tools/buildbot/build.bat Tools/buildbot/buildmsi.bat
	Tools/buildbot/clean-amd64.bat Tools/buildbot/clean.bat
	Tools/buildbot/external-amd64.bat Tools/buildbot/external-common.bat
	Tools/buildbot/external.bat Tools/buildbot/test-amd64.bat
	Tools/buildbot/test.bat
Message-ID: <20080614115952.CABFB1E4009@bag.python.org>

Author: martin.v.loewis
Date: Sat Jun 14 13:59:52 2008
New Revision: 64273

Log:
Merged revisions 64267-64272 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/trunk

........
  r64267 | amaury.forgeotdarc | 2008-06-14 09:40:32 +0200 (Sa, 14 Jun 2008) | 2 lines
  
  Use the correct URL for sqlite3 sources, and try to fix windows buildbots.
........
  r64269 | amaury.forgeotdarc | 2008-06-14 10:36:07 +0200 (Sa, 14 Jun 2008) | 3 lines
  
  on windows, r64214 broke compilation with some recent SDKs,
  because IPPROTO_IPV6 may be an enumeration member...
........
  r64270 | amaury.forgeotdarc | 2008-06-14 11:44:41 +0200 (Sa, 14 Jun 2008) | 4 lines
  
  Since python2.6 must run on Windows 2000,
  explicitely disable the use of Windows XP themes when compiling tk.
  This is also consistent with the WINVER=0x0500 option.
........
  r64271 | martin.v.loewis | 2008-06-14 13:50:59 +0200 (Sa, 14 Jun 2008) | 3 lines
  
  Avoid rebuilding tcl/tk.
  Merge x86 changes into AMD64.
........
  r64272 | martin.v.loewis | 2008-06-14 13:51:54 +0200 (Sa, 14 Jun 2008) | 2 lines
  
  Set eol-style to CRLF for all batch files.
........


Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Modules/socketmodule.h
   python/branches/py3k/Tools/buildbot/build-amd64.bat   (contents, props changed)
   python/branches/py3k/Tools/buildbot/build.bat   (contents, props changed)
   python/branches/py3k/Tools/buildbot/buildmsi.bat   (contents, props changed)
   python/branches/py3k/Tools/buildbot/clean-amd64.bat   (contents, props changed)
   python/branches/py3k/Tools/buildbot/clean.bat   (contents, props changed)
   python/branches/py3k/Tools/buildbot/external-amd64.bat   (contents, props changed)
   python/branches/py3k/Tools/buildbot/external-common.bat   (contents, props changed)
   python/branches/py3k/Tools/buildbot/external.bat   (contents, props changed)
   python/branches/py3k/Tools/buildbot/test-amd64.bat   (contents, props changed)
   python/branches/py3k/Tools/buildbot/test.bat   (contents, props changed)

Modified: python/branches/py3k/Modules/socketmodule.h
==============================================================================
--- python/branches/py3k/Modules/socketmodule.h	(original)
+++ python/branches/py3k/Modules/socketmodule.h	Sat Jun 14 13:59:52 2008
@@ -17,9 +17,10 @@
 # include <ws2tcpip.h>
 /* VC6 is shipped with old platform headers, and does not have MSTcpIP.h
  * Separate SDKs have all the functions we want, but older ones don't have
- * any version information. I use IPPROTO_IPV6 to detect a decent SDK.
+ * any version information. 
+ * I use SIO_GET_MULTICAST_FILTER to detect a decent SDK.
  */
-# ifdef IPPROTO_IPV6
+# ifdef SIO_GET_MULTICAST_FILTER
 #  include <MSTcpIP.h> /* for SIO_RCVALL */
 #  define HAVE_ADDRINFO
 #  define HAVE_SOCKADDR_STORAGE

Modified: python/branches/py3k/Tools/buildbot/build-amd64.bat
==============================================================================
--- python/branches/py3k/Tools/buildbot/build-amd64.bat	(original)
+++ python/branches/py3k/Tools/buildbot/build-amd64.bat	Sat Jun 14 13:59:52 2008
@@ -1,6 +1,6 @@
- at rem Used by the buildbot "compile" step.
-cmd /c Tools\buildbot\external-amd64.bat
-call "%VS90COMNTOOLS%\..\..\VC\vcvarsall.bat" x86_amd64
-cmd /c Tools\buildbot\clean-amd64.bat
-vcbuild /useenv PCbuild\kill_python.vcproj "Debug|x64" && PCbuild\amd64\kill_python_d.exe
-vcbuild PCbuild\pcbuild.sln "Debug|x64"
+ at rem Used by the buildbot "compile" step.
+cmd /c Tools\buildbot\external-amd64.bat
+call "%VS90COMNTOOLS%\..\..\VC\vcvarsall.bat" x86_amd64
+cmd /c Tools\buildbot\clean-amd64.bat
+vcbuild /useenv PCbuild\kill_python.vcproj "Debug|x64" && PCbuild\amd64\kill_python_d.exe
+vcbuild PCbuild\pcbuild.sln "Debug|x64"

Modified: python/branches/py3k/Tools/buildbot/build.bat
==============================================================================
--- python/branches/py3k/Tools/buildbot/build.bat	(original)
+++ python/branches/py3k/Tools/buildbot/build.bat	Sat Jun 14 13:59:52 2008
@@ -1,7 +1,7 @@
- at rem Used by the buildbot "compile" step.
-cmd /c Tools\buildbot\external.bat
-call "%VS90COMNTOOLS%vsvars32.bat"
-cmd /c Tools\buildbot\clean.bat
-vcbuild /useenv PCbuild\kill_python.vcproj "Debug|Win32" && PCbuild\kill_python_d.exe
-vcbuild /useenv PCbuild\pcbuild.sln "Debug|Win32"
-
+ at rem Used by the buildbot "compile" step.
+cmd /c Tools\buildbot\external.bat
+call "%VS90COMNTOOLS%vsvars32.bat"
+cmd /c Tools\buildbot\clean.bat
+vcbuild /useenv PCbuild\kill_python.vcproj "Debug|Win32" && PCbuild\kill_python_d.exe
+vcbuild /useenv PCbuild\pcbuild.sln "Debug|Win32"
+

Modified: python/branches/py3k/Tools/buildbot/buildmsi.bat
==============================================================================
--- python/branches/py3k/Tools/buildbot/buildmsi.bat	(original)
+++ python/branches/py3k/Tools/buildbot/buildmsi.bat	Sat Jun 14 13:59:52 2008
@@ -1,20 +1,21 @@
- at rem Used by the buildbot "buildmsi" step.
-
-cmd /c Tools\buildbot\external.bat
- at rem build release versions of things
-call "%VS90COMNTOOLS%vsvars32.bat"
-
- at rem build Python
-vcbuild /useenv PCbuild\pcbuild.sln "Release|Win32"
-
- at rem build the documentation
-bash.exe -c 'cd Doc;make PYTHON=python2.5 update htmlhelp'
-"%ProgramFiles%\HTML Help Workshop\hhc.exe" Doc\build\htmlhelp\python30a5.hhp
-
- at rem buold the MSI file
-cd PC
-nmake /f icons.mak
-cd ..\Tools\msi
-del *.msi
-nmake /f msisupport.mak
-%HOST_PYTHON% msi.py
+ at rem Used by the buildbot "buildmsi" step.
+
+cmd /c Tools\buildbot\external.bat
+ at rem build release versions of things
+call "%VS90COMNTOOLS%vsvars32.bat"
+
+ at rem build Python
+vcbuild /useenv PCbuild\pcbuild.sln "Release|Win32"
+
+ at rem build the documentation
+bash.exe -c 'cd Doc;make PYTHON=python2.5 update htmlhelp'
+"%ProgramFiles%\HTML Help Workshop\hhc.exe" Doc\build\htmlhelp\python26a3.hhp
+
+ at rem build the MSI file
+cd PC
+nmake /f icons.mak
+cd ..\Tools\msi
+del *.msi
+nmake /f msisupport.mak
+%HOST_PYTHON% msi.py
+

Modified: python/branches/py3k/Tools/buildbot/clean-amd64.bat
==============================================================================
--- python/branches/py3k/Tools/buildbot/clean-amd64.bat	(original)
+++ python/branches/py3k/Tools/buildbot/clean-amd64.bat	Sat Jun 14 13:59:52 2008
@@ -1,7 +1,7 @@
- at rem Used by the buildbot "clean" step.
-call "%VS90COMNTOOLS%\..\..\VC\vcvarsall.bat" x86_amd64
-cd PCbuild
- at echo Deleting .pyc/.pyo files ...
-del /s Lib\*.pyc Lib\*.pyo
-vcbuild /clean pcbuild.sln "Release|x64"
-vcbuild /clean pcbuild.sln "Debug|x64"
+ at rem Used by the buildbot "clean" step.
+call "%VS90COMNTOOLS%\..\..\VC\vcvarsall.bat" x86_amd64
+cd PCbuild
+ at echo Deleting .pyc/.pyo files ...
+del /s Lib\*.pyc Lib\*.pyo
+vcbuild /clean pcbuild.sln "Release|x64"
+vcbuild /clean pcbuild.sln "Debug|x64"

Modified: python/branches/py3k/Tools/buildbot/clean.bat
==============================================================================
--- python/branches/py3k/Tools/buildbot/clean.bat	(original)
+++ python/branches/py3k/Tools/buildbot/clean.bat	Sat Jun 14 13:59:52 2008
@@ -1,7 +1,7 @@
- at rem Used by the buildbot "clean" step.
-call "%VS90COMNTOOLS%vsvars32.bat"
- at echo Deleting .pyc/.pyo files ...
-del /s Lib\*.pyc Lib\*.pyo
-cd PCbuild
-vcbuild /clean pcbuild.sln "Release|Win32"
-vcbuild /clean pcbuild.sln "Debug|Win32"
+ at rem Used by the buildbot "clean" step.
+call "%VS90COMNTOOLS%vsvars32.bat"
+ at echo Deleting .pyc/.pyo files ...
+del /s Lib\*.pyc Lib\*.pyo
+cd PCbuild
+vcbuild /clean pcbuild.sln "Release|Win32"
+vcbuild /clean pcbuild.sln "Debug|Win32"

Modified: python/branches/py3k/Tools/buildbot/external-amd64.bat
==============================================================================
--- python/branches/py3k/Tools/buildbot/external-amd64.bat	(original)
+++ python/branches/py3k/Tools/buildbot/external-amd64.bat	Sat Jun 14 13:59:52 2008
@@ -1,17 +1,21 @@
- at rem Fetches (and builds if necessary) external dependencies
-
- at rem Assume we start inside the Python source directory
-call "Tools\buildbot\external-common.bat"
-call "%VS90COMNTOOLS%\..\..\VC\vcvarsall.bat" x86_amd64
-
-if not exist tcltk64\bin\tcl85g.dll (
-    cd tcl-8.5.2.1\win
-    nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 DEBUG=1 MACHINE=AMD64 INSTALLDIR=..\..\tcltk64 clean all install
-    cd ..\..
-)
-
-if not exist tcltk64\bin\tk85g.dll (
-    cd tk-8.5.2.1\win    
-    nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 DEBUG=1 MACHINE=AMD64 INSTALLDIR=..\..\tcltk64 TCLDIR=..\..\tcl-8.5.2.1 clean all install
-    cd ..\..
-)
+ at rem Fetches (and builds if necessary) external dependencies
+
+ at rem Assume we start inside the Python source directory
+call "Tools\buildbot\external-common.bat"
+call "%VS90COMNTOOLS%\..\..\VC\vcvarsall.bat" x86_amd64
+
+if not exist tcltk64\bin\tcl85g.dll (
+    cd tcl-8.5.2.1\win
+    nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 DEBUG=1 MACHINE=AMD64 INSTALLDIR=..\..\tcltk64 clean all
+    nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 DEBUG=1 MACHINE=AMD64 INSTALLDIR=..\..\tcltk64 install
+    cd ..\..
+)
+
+if not exist tcltk64\bin\tk85g.dll (
+    cd tk-8.5.2.1\win    
+    nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 OPTS=noxp DEBUG=1 MACHINE=AMD64 INSTALLDIR=..\..\tcltk64 TCLDIR=..\..\tcl-8.5.2.1 clean
+    nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 OPTS=noxp DEBUG=1 MACHINE=AMD64 INSTALLDIR=..\..\tcltk64 TCLDIR=..\..\tcl-8.5.2.1 all
+    nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 OPTS=noxp DEBUG=1 MACHINE=AMD64 INSTALLDIR=..\..\tcltk64 TCLDIR=..\..\tcl-8.5.2.1 install
+    cd ..\..
+)
+

Modified: python/branches/py3k/Tools/buildbot/external-common.bat
==============================================================================
--- python/branches/py3k/Tools/buildbot/external-common.bat	(original)
+++ python/branches/py3k/Tools/buildbot/external-common.bat	Sat Jun 14 13:59:52 2008
@@ -15,7 +15,7 @@
 @rem if exist tk-8.4.18.1 rd /s/q tk-8.4.18.1
 @rem if exist db-4.4.20 rd /s/q db-4.4.20
 @rem if exist openssl-0.9.8g rd /s/q openssl-0.9.8g
- at rem if exist sqlite-source-3.5.9 rd /s/q sqlite-source-3.5.9    
+ at rem if exist sqlite-3.5.9 rd /s/q sqlite-3.5.9    
 
 @rem bzip
 if not exist bzip2-1.0.5 (
@@ -37,7 +37,7 @@
 if not exist tk-8.5.2.0 svn export http://svn.python.org/projects/external/tk-8.5.2.0
 
 @rem sqlite3
-if not exist sqlite-source-3.5.9 (
+if not exist sqlite-3.5.9 (
   rd /s/q sqlite-source-3.3.4
-  svn export http://svn.python.org/projects/external/sqlite-source-3.5.9
+  svn export http://svn.python.org/projects/external/sqlite-3.5.9
 )

Modified: python/branches/py3k/Tools/buildbot/external.bat
==============================================================================
--- python/branches/py3k/Tools/buildbot/external.bat	(original)
+++ python/branches/py3k/Tools/buildbot/external.bat	Sat Jun 14 13:59:52 2008
@@ -4,7 +4,7 @@
 call "Tools\buildbot\external-common.bat"
 call "%VS90COMNTOOLS%\vsvars32.bat"
 
-if not exist tcltk\bin\tcl85.dll (
+if not exist tcltk\bin\tcl85g.dll (
     @rem all and install need to be separate invocations, otherwise nmakehlp is not found on install
     cd tcl-8.5.2.1\win
     nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 DEBUG=1 INSTALLDIR=..\..\tcltk clean all 
@@ -12,10 +12,10 @@
     cd ..\..
 )
 
-if not exist tcltk\bin\tk85.dll (
+if not exist tcltk\bin\tk85g.dll (
     cd tk-8.5.2.0\win    
-    nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 DEBUG=1 INSTALLDIR=..\..\tcltk TCLDIR=..\..\tcl-8.5.2.1 clean
-    nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 DEBUG=1 INSTALLDIR=..\..\tcltk TCLDIR=..\..\tcl-8.5.2.1 all
-    nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 DEBUG=1 INSTALLDIR=..\..\tcltk TCLDIR=..\..\tcl-8.5.2.1 install
+    nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 OPTS=noxp DEBUG=1 INSTALLDIR=..\..\tcltk TCLDIR=..\..\tcl-8.5.2.1 clean
+    nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 OPTS=noxp DEBUG=1 INSTALLDIR=..\..\tcltk TCLDIR=..\..\tcl-8.5.2.1 all
+    nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 OPTS=noxp DEBUG=1 INSTALLDIR=..\..\tcltk TCLDIR=..\..\tcl-8.5.2.1 install
     cd ..\..
 )

Modified: python/branches/py3k/Tools/buildbot/test-amd64.bat
==============================================================================
--- python/branches/py3k/Tools/buildbot/test-amd64.bat	(original)
+++ python/branches/py3k/Tools/buildbot/test-amd64.bat	Sat Jun 14 13:59:52 2008
@@ -1,3 +1,3 @@
- at rem Used by the buildbot "test" step.
-cd PCbuild
-call rt.bat -q -d -x64 -uall -rw
+ at rem Used by the buildbot "test" step.
+cd PCbuild
+call rt.bat -q -d -x64 -uall -rw

Modified: python/branches/py3k/Tools/buildbot/test.bat
==============================================================================
--- python/branches/py3k/Tools/buildbot/test.bat	(original)
+++ python/branches/py3k/Tools/buildbot/test.bat	Sat Jun 14 13:59:52 2008
@@ -1,3 +1,4 @@
- at rem Used by the buildbot "test" step.
-cd PCbuild
-call rt.bat -d -q -uall -rw -n
+ at rem Used by the buildbot "test" step.
+cd PCbuild
+call rt.bat -d -q -uall -rw
+

From python-3000-checkins at python.org  Sat Jun 14 14:03:33 2008
From: python-3000-checkins at python.org (martin.v.loewis)
Date: Sat, 14 Jun 2008 14:03:33 +0200 (CEST)
Subject: [Python-3000-checkins] r64274 - python/branches/py3k
Message-ID: <20080614120333.E2DE71E4009@bag.python.org>

Author: martin.v.loewis
Date: Sat Jun 14 14:03:33 2008
New Revision: 64274

Log:
Recorded merge of revisions 64257 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/trunk

........
  r64257 | martin.v.loewis | 2008-06-14 00:38:33 +0200 (Sa, 14 Jun 2008) | 2 lines
  
  Run svneol.py on all sources.
........


Modified:
   python/branches/py3k/   (props changed)

From python-3000-checkins at python.org  Sat Jun 14 22:20:25 2008
From: python-3000-checkins at python.org (guido.van.rossum)
Date: Sat, 14 Jun 2008 22:20:25 +0200 (CEST)
Subject: [Python-3000-checkins] r64281 - in python/branches/py3k:
	Lib/test/test_exceptions.py Lib/test/test_raise.py
	Python/ceval.c Python/errors.c
Message-ID: <20080614202025.448C91E400A@bag.python.org>

Author: guido.van.rossum
Date: Sat Jun 14 22:20:24 2008
New Revision: 64281

Log:
Implicit exception chaining via __context__ (PEP 3134).
Patch 3108 by Antooine Pitrou.


Modified:
   python/branches/py3k/Lib/test/test_exceptions.py
   python/branches/py3k/Lib/test/test_raise.py
   python/branches/py3k/Python/ceval.c
   python/branches/py3k/Python/errors.c

Modified: python/branches/py3k/Lib/test/test_exceptions.py
==============================================================================
--- python/branches/py3k/Lib/test/test_exceptions.py	(original)
+++ python/branches/py3k/Lib/test/test_exceptions.py	Sat Jun 14 22:20:24 2008
@@ -480,7 +480,12 @@
                 inner_raising_func()
             except:
                 raise KeyError
-        except KeyError:
+        except KeyError as e:
+            # We want to test that the except block above got rid of
+            # the exception raised in inner_raising_func(), but it
+            # also ends up in the __context__ of the KeyError, so we
+            # must clear the latter manually for our test to succeed.
+            e.__context__ = None
             obj = None
             obj = wr()
             self.failUnless(obj is None, "%s" % obj)

Modified: python/branches/py3k/Lib/test/test_raise.py
==============================================================================
--- python/branches/py3k/Lib/test/test_raise.py	(original)
+++ python/branches/py3k/Lib/test/test_raise.py	Sat Jun 14 22:20:24 2008
@@ -181,32 +181,102 @@
             self.fail("No exception raised")
 
 
-# Disabled until context is implemented
-# class TestContext(object):
-#     def test_instance_context_bare_raise(self):
-#         context = IndexError()
-#         try:
-#             try:
-#                 raise context
-#             except:
-#                 raise OSError()
-#         except OSError as e:
-#             self.assertEqual(e.__context__, context)
-#         else:
-#             self.fail("No exception raised")
-#
-#     def test_class_context_bare_raise(self):
-#         context = IndexError
-#         try:
-#             try:
-#                 raise context
-#             except:
-#                 raise OSError()
-#         except OSError as e:
-#             self.assertNotEqual(e.__context__, context)
-#             self.failUnless(isinstance(e.__context__, context))
-#         else:
-#             self.fail("No exception raised")
+class TestContext(unittest.TestCase):
+    def test_instance_context_instance_raise(self):
+        context = IndexError()
+        try:
+            try:
+                raise context
+            except:
+                raise OSError()
+        except OSError as e:
+            self.assertEqual(e.__context__, context)
+        else:
+            self.fail("No exception raised")
+
+    def test_class_context_instance_raise(self):
+        context = IndexError
+        try:
+            try:
+                raise context
+            except:
+                raise OSError()
+        except OSError as e:
+            self.assertNotEqual(e.__context__, context)
+            self.failUnless(isinstance(e.__context__, context))
+        else:
+            self.fail("No exception raised")
+
+    def test_class_context_class_raise(self):
+        context = IndexError
+        try:
+            try:
+                raise context
+            except:
+                raise OSError
+        except OSError as e:
+            self.assertNotEqual(e.__context__, context)
+            self.failUnless(isinstance(e.__context__, context))
+        else:
+            self.fail("No exception raised")
+
+    def test_c_exception_context(self):
+        try:
+            try:
+                1/0
+            except:
+                raise OSError
+        except OSError as e:
+            self.failUnless(isinstance(e.__context__, ZeroDivisionError))
+        else:
+            self.fail("No exception raised")
+
+    def test_c_exception_raise(self):
+        try:
+            try:
+                1/0
+            except:
+                xyzzy
+        except NameError as e:
+            self.failUnless(isinstance(e.__context__, ZeroDivisionError))
+        else:
+            self.fail("No exception raised")
+
+    def test_noraise_finally(self):
+        try:
+            try:
+                pass
+            finally:
+                raise OSError
+        except OSError as e:
+            self.failUnless(e.__context__ is None)
+        else:
+            self.fail("No exception raised")
+
+    def test_raise_finally(self):
+        try:
+            try:
+                1/0
+            finally:
+                raise OSError
+        except OSError as e:
+            self.failUnless(isinstance(e.__context__, ZeroDivisionError))
+        else:
+            self.fail("No exception raised")
+
+    def test_context_manager(self):
+        class ContextManager:
+            def __enter__(self):
+                pass
+            def __exit__(self, t, v, tb):
+                xyzzy
+        try:
+            with ContextManager():
+                1/0
+        except NameError as e:
+            self.failUnless(isinstance(e.__context__, ZeroDivisionError))
+        else:
+            self.fail("No exception raised")
 
 
 class TestRemovedFunctionality(unittest.TestCase):

Modified: python/branches/py3k/Python/ceval.c
==============================================================================
--- python/branches/py3k/Python/ceval.c	(original)
+++ python/branches/py3k/Python/ceval.c	Sat Jun 14 22:20:24 2008
@@ -2817,11 +2817,12 @@
 static enum why_code
 do_raise(PyObject *exc, PyObject *cause)
 {
-	PyObject *type = NULL, *value = NULL, *tb = NULL;
+	PyObject *type = NULL, *value = NULL;
 
 	if (exc == NULL) {
 		/* Reraise */
 		PyThreadState *tstate = PyThreadState_GET();
+		PyObject *tb;
 		type = tstate->exc_type;
 		value = tstate->exc_value;
 		tb = tstate->exc_traceback;
@@ -2862,7 +2863,6 @@
 		goto raise_error;
 	}
 
-	tb = PyException_GetTraceback(value);
 	if (cause) {
 		PyObject *fixed_cause;
 		if (PyExceptionClass_Check(cause)) {
@@ -2883,13 +2883,15 @@
 		PyException_SetCause(value, fixed_cause);
 	}
 
-	PyErr_Restore(type, value, tb);
+	PyErr_SetObject(type, value);
+	/* PyErr_SetObject incref's its arguments */
+	Py_XDECREF(value);
+	Py_XDECREF(type);
 	return WHY_EXCEPTION;
 
 raise_error:
 	Py_XDECREF(value);
 	Py_XDECREF(type);
-	Py_XDECREF(tb);
 	Py_XDECREF(cause);
 	return WHY_EXCEPTION;
 }

Modified: python/branches/py3k/Python/errors.c
==============================================================================
--- python/branches/py3k/Python/errors.c	(original)
+++ python/branches/py3k/Python/errors.c	Sat Jun 14 22:20:24 2008
@@ -52,6 +52,9 @@
 void
 PyErr_SetObject(PyObject *exception, PyObject *value)
 {
+	PyThreadState *tstate = PyThreadState_GET();
+	PyObject *tb = NULL;
+
 	if (exception != NULL &&
 	    !PyExceptionClass_Check(exception)) {
 		PyErr_Format(PyExc_SystemError,
@@ -59,9 +62,35 @@
 			     exception);
 		return;
 	}
-	Py_XINCREF(exception);
 	Py_XINCREF(value);
-	PyErr_Restore(exception, value, (PyObject *)NULL);
+	if (tstate->exc_value != NULL && tstate->exc_value != Py_None) {
+		/* Implicit exception chaining */
+		if (value == NULL || !PyExceptionInstance_Check(value)) {
+			/* We must normalize the value right now */
+			PyObject *args, *fixed_value;
+			if (value == NULL || value == Py_None)
+				args = PyTuple_New(0);
+			else if (PyTuple_Check(value)) {
+				Py_INCREF(value);
+				args = value;
+			}
+			else
+				args = PyTuple_Pack(1, value);
+			fixed_value = args ?
+				PyEval_CallObject(exception, args) : NULL;
+			Py_XDECREF(args);
+			Py_XDECREF(value);
+			if (fixed_value == NULL)
+				return;
+			value = fixed_value;
+		}
+		Py_INCREF(tstate->exc_value);
+		PyException_SetContext(value, tstate->exc_value);
+	}
+	if (value != NULL && PyExceptionInstance_Check(value))
+		tb = PyException_GetTraceback(value);
+	Py_XINCREF(exception);
+	PyErr_Restore(exception, value, tb);
 }
 
 void

From python-3000-checkins at python.org  Sun Jun 15 01:04:47 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Sun, 15 Jun 2008 01:04:47 +0200 (CEST)
Subject: [Python-3000-checkins] r64283 - in python/branches/py3k:
	Lib/test/test_pydoc.py
Message-ID: <20080614230447.3CEDC1E4009@bag.python.org>

Author: benjamin.peterson
Date: Sun Jun 15 01:04:46 2008
New Revision: 64283

Log:
Merged revisions 64095 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/trunk

........
  r64095 | amaury.forgeotdarc | 2008-06-10 16:37:15 -0500 (Tue, 10 Jun 2008) | 3 lines
  
  Correct test_pydoc for win32 platforms, to account for normalized URLs:
  C:\temp => file:///C|temp/
........


Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Lib/test/test_pydoc.py

Modified: python/branches/py3k/Lib/test/test_pydoc.py
==============================================================================
--- python/branches/py3k/Lib/test/test_pydoc.py	(original)
+++ python/branches/py3k/Lib/test/test_pydoc.py	Sun Jun 15 01:04:46 2008
@@ -231,7 +231,12 @@
     def test_html_doc(self):
         result, doc_loc = get_pydoc_html(pydoc_mod)
         mod_file = inspect.getabsfile(pydoc_mod)
-        expected_html = expected_html_pattern % (mod_file, mod_file, doc_loc)
+        if sys.platform == 'win32':
+            import nturl2path
+            mod_url = nturl2path.pathname2url(mod_file)
+        else:
+            mod_url = mod_file
+        expected_html = expected_html_pattern % (mod_url, mod_file, doc_loc)
         if result != expected_html:
             print_diffs(expected_html, result)
             self.fail("outputs are not equal, see diff above")

From python-3000-checkins at python.org  Sun Jun 15 02:05:44 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Sun, 15 Jun 2008 02:05:44 +0200 (CEST)
Subject: [Python-3000-checkins] r64284 - in python/branches/py3k:
	Lib/test/test_exceptions.py Python/ceval.c
Message-ID: <20080615000544.B72DA1E4009@bag.python.org>

Author: benjamin.peterson
Date: Sun Jun 15 02:05:44 2008
New Revision: 64284

Log:
#3114 fix a bus error when deallocated exceptions were used


Modified:
   python/branches/py3k/Lib/test/test_exceptions.py
   python/branches/py3k/Python/ceval.c

Modified: python/branches/py3k/Lib/test/test_exceptions.py
==============================================================================
--- python/branches/py3k/Lib/test/test_exceptions.py	(original)
+++ python/branches/py3k/Lib/test/test_exceptions.py	Sun Jun 15 02:05:44 2008
@@ -5,6 +5,8 @@
 import unittest
 import pickle
 import weakref
+import gc
+import traceback
 
 from test.support import TESTFN, unlink, run_unittest
 
@@ -551,6 +553,23 @@
             del g
             self.assertEquals(sys.exc_info()[0], TypeError)
 
+    def test_crash_3114(self):
+        # Bug #3114: in its destructor, MyObject retrieves a pointer to a
+        # deallocated exception instance or traceback.
+        class MyObject:
+            def __del__(self):
+                nonlocal e
+                e = sys.exc_info()
+        e = ()
+        try:
+            raise Exception(MyObject())
+        except:
+            pass
+        gc.collect()
+        [0]*10000
+        # Do something with the exception and its traceback
+        traceback.format_exception(*e)
+
 def test_main():
     run_unittest(ExceptionTests)
 

Modified: python/branches/py3k/Python/ceval.c
==============================================================================
--- python/branches/py3k/Python/ceval.c	(original)
+++ python/branches/py3k/Python/ceval.c	Sun Jun 15 02:05:44 2008
@@ -704,11 +704,11 @@
 		PyObject *v = POP(); \
 		Py_XDECREF(v); \
 	} \
-	Py_XDECREF(tstate->exc_type); \
+	Py_CLEAR(tstate->exc_type); \
+	Py_CLEAR(tstate->exc_value); \
+	Py_CLEAR(tstate->exc_traceback); \
 	tstate->exc_type = POP(); \
-	Py_XDECREF(tstate->exc_value); \
 	tstate->exc_value = POP(); \
-	Py_XDECREF(tstate->exc_traceback); \
 	tstate->exc_traceback = POP();
 
 #define SAVE_EXC_STATE() \
@@ -716,9 +716,9 @@
 		Py_XINCREF(tstate->exc_type); \
 		Py_XINCREF(tstate->exc_value); \
 		Py_XINCREF(tstate->exc_traceback); \
-		Py_XDECREF(f->f_exc_type); \
-		Py_XDECREF(f->f_exc_value); \
-		Py_XDECREF(f->f_exc_traceback); \
+		Py_CLEAR(f->f_exc_type); \
+		Py_CLEAR(f->f_exc_value); \
+		Py_CLEAR(f->f_exc_traceback); \
 		f->f_exc_type = tstate->exc_type; \
 		f->f_exc_value = tstate->exc_value; \
 		f->f_exc_traceback = tstate->exc_traceback; \

From python-3000-checkins at python.org  Sun Jun 15 04:57:42 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Sun, 15 Jun 2008 04:57:42 +0200 (CEST)
Subject: [Python-3000-checkins] r64287 - in python/branches/py3k:
	Lib/lib2to3 Lib/lib2to3/fixer_base.py
	Lib/lib2to3/fixer_util.py Lib/lib2to3/fixes/basefix.py
	Lib/lib2to3/fixes/fix_apply.py Lib/lib2to3/fixes/fix_basestring.py
	Lib/lib2to3/fixes/fix_buffer.py Lib/lib2to3/fixes/fix_callable.py
	Lib/lib2to3/fixes/fix_dict.py Lib/lib2to3/fixes/fix_except.py
	Lib/lib2to3/fixes/fix_exec.py Lib/lib2to3/fixes/fix_execfile.py
	Lib/lib2to3/fixes/fix_filter.py Lib/lib2to3/fixes/fix_funcattrs.py
	Lib/lib2to3/fixes/fix_future.py Lib/lib2to3/fixes/fix_has_key.py
	Lib/lib2to3/fixes/fix_idioms.py Lib/lib2to3/fixes/fix_import.py
	Lib/lib2to3/fixes/fix_imports.py Lib/lib2to3/fixes/fix_input.py
	Lib/lib2to3/fixes/fix_intern.py Lib/lib2to3/fixes/fix_itertools.py
	Lib/lib2to3/fixes/fix_itertools_imports.py
	Lib/lib2to3/fixes/fix_long.py Lib/lib2to3/fixes/fix_map.py
	Lib/lib2to3/fixes/fix_methodattrs.py
	Lib/lib2to3/fixes/fix_ne.py Lib/lib2to3/fixes/fix_next.py
	Lib/lib2to3/fixes/fix_nonzero.py
	Lib/lib2to3/fixes/fix_numliterals.py
	Lib/lib2to3/fixes/fix_print.py Lib/lib2to3/fixes/fix_raise.py
	Lib/lib2to3/fixes/fix_raw_input.py Lib/lib2to3/fixes/fix_renames.py
	Lib/lib2to3/fixes/fix_repr.py Lib/lib2to3/fixes/fix_standarderror.py
	Lib/lib2to3/fixes/fix_throw.py Lib/lib2to3/fixes/fix_tuple_params.py
	Lib/lib2to3/fixes/fix_types.py Lib/lib2to3/fixes/fix_unicode.py
	Lib/lib2to3/fixes/fix_ws_comma.py Lib/lib2to3/fixes/fix_xrange.py
	Lib/lib2to3/fixes/fix_xreadlines.py
	Lib/lib2to3/fixes/fix_zip.py Lib/lib2to3/fixes/util.py
	Lib/lib2to3/refactor.py Lib/lib2to3/tests/test_all_fixers.py
	Lib/lib2to3/tests/test_fixers.py Lib/lib2to3/tests/test_util.py
Message-ID: <20080615025742.23E8E1E4009@bag.python.org>

Author: benjamin.peterson
Date: Sun Jun 15 04:57:40 2008
New Revision: 64287

Log:
Merged revisions 64286 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/trunk

................
  r64286 | benjamin.peterson | 2008-06-14 21:31:05 -0500 (Sat, 14 Jun 2008) | 49 lines
  
  Merged revisions 63661,63666,63695,63711,63729,63769,63790,63880,63886 via svnmerge from 
  svn+ssh://pythondev at svn.python.org/sandbox/trunk/2to3/lib2to3
  
  ........
    r63661 | georg.brandl | 2008-05-26 05:26:20 -0500 (Mon, 26 May 2008) | 2 lines
    
    Add import fixes for dbm package.
  ........
    r63666 | georg.brandl | 2008-05-26 05:49:09 -0500 (Mon, 26 May 2008) | 2 lines
    
    Add xmlrpc package fixes.
  ........
    r63695 | georg.brandl | 2008-05-26 10:14:33 -0500 (Mon, 26 May 2008) | 2 lines
    
    Add fixer entries for http package.
  ........
    r63711 | benjamin.peterson | 2008-05-26 13:43:51 -0500 (Mon, 26 May 2008) | 2 lines
    
    add import mapping for test.test_support -> test.support
  ........
    r63729 | benjamin.peterson | 2008-05-26 16:31:03 -0500 (Mon, 26 May 2008) | 2 lines
    
    mapping for commands module -> subprocess
  ........
    r63769 | brett.cannon | 2008-05-29 00:13:13 -0500 (Thu, 29 May 2008) | 1 line
    
    Fixer for UserString.UserString over to the collections module.
  ........
    r63790 | brett.cannon | 2008-05-29 14:13:51 -0500 (Thu, 29 May 2008) | 4 lines
    
    Add a fixer for UserList.
    
    Closes issue #2878. Thanks to Quentin Gallet-Gilles for the patch.
  ........
    r63880 | collin.winter | 2008-06-01 18:09:38 -0500 (Sun, 01 Jun 2008) | 6 lines
    
    Move lib2to3/fixes/{basefix,util}.py down to lib2to3/.
    
    This is step 1 of turning lib2to3/ into a general-purpose refactoring
    library, reusable by other projects.
  ........
    r63886 | collin.winter | 2008-06-01 22:15:01 -0500 (Sun, 01 Jun 2008) | 5 lines
    
    Allow refactoring tools to specify a directory for fixer modules.
    
    This is step 2 of turning lib2to3/ into a general-purpose refactoring
    library, reusable by other projects. Step 1: r63880.
  ........
................


Added:
   python/branches/py3k/Lib/lib2to3/fixer_base.py
      - copied, changed from r64286, /python/trunk/Lib/lib2to3/fixer_base.py
   python/branches/py3k/Lib/lib2to3/fixer_util.py
      - copied, changed from r64286, /python/trunk/Lib/lib2to3/fixer_util.py
Removed:
   python/branches/py3k/Lib/lib2to3/fixes/basefix.py
   python/branches/py3k/Lib/lib2to3/fixes/util.py
Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Lib/lib2to3/   (props changed)
   python/branches/py3k/Lib/lib2to3/fixes/fix_apply.py
   python/branches/py3k/Lib/lib2to3/fixes/fix_basestring.py
   python/branches/py3k/Lib/lib2to3/fixes/fix_buffer.py
   python/branches/py3k/Lib/lib2to3/fixes/fix_callable.py
   python/branches/py3k/Lib/lib2to3/fixes/fix_dict.py
   python/branches/py3k/Lib/lib2to3/fixes/fix_except.py
   python/branches/py3k/Lib/lib2to3/fixes/fix_exec.py
   python/branches/py3k/Lib/lib2to3/fixes/fix_execfile.py
   python/branches/py3k/Lib/lib2to3/fixes/fix_filter.py
   python/branches/py3k/Lib/lib2to3/fixes/fix_funcattrs.py
   python/branches/py3k/Lib/lib2to3/fixes/fix_future.py
   python/branches/py3k/Lib/lib2to3/fixes/fix_has_key.py
   python/branches/py3k/Lib/lib2to3/fixes/fix_idioms.py
   python/branches/py3k/Lib/lib2to3/fixes/fix_import.py
   python/branches/py3k/Lib/lib2to3/fixes/fix_imports.py
   python/branches/py3k/Lib/lib2to3/fixes/fix_input.py
   python/branches/py3k/Lib/lib2to3/fixes/fix_intern.py
   python/branches/py3k/Lib/lib2to3/fixes/fix_itertools.py
   python/branches/py3k/Lib/lib2to3/fixes/fix_itertools_imports.py
   python/branches/py3k/Lib/lib2to3/fixes/fix_long.py
   python/branches/py3k/Lib/lib2to3/fixes/fix_map.py
   python/branches/py3k/Lib/lib2to3/fixes/fix_methodattrs.py
   python/branches/py3k/Lib/lib2to3/fixes/fix_ne.py
   python/branches/py3k/Lib/lib2to3/fixes/fix_next.py
   python/branches/py3k/Lib/lib2to3/fixes/fix_nonzero.py
   python/branches/py3k/Lib/lib2to3/fixes/fix_numliterals.py
   python/branches/py3k/Lib/lib2to3/fixes/fix_print.py
   python/branches/py3k/Lib/lib2to3/fixes/fix_raise.py
   python/branches/py3k/Lib/lib2to3/fixes/fix_raw_input.py
   python/branches/py3k/Lib/lib2to3/fixes/fix_renames.py
   python/branches/py3k/Lib/lib2to3/fixes/fix_repr.py
   python/branches/py3k/Lib/lib2to3/fixes/fix_standarderror.py
   python/branches/py3k/Lib/lib2to3/fixes/fix_throw.py
   python/branches/py3k/Lib/lib2to3/fixes/fix_tuple_params.py
   python/branches/py3k/Lib/lib2to3/fixes/fix_types.py
   python/branches/py3k/Lib/lib2to3/fixes/fix_unicode.py
   python/branches/py3k/Lib/lib2to3/fixes/fix_ws_comma.py
   python/branches/py3k/Lib/lib2to3/fixes/fix_xrange.py
   python/branches/py3k/Lib/lib2to3/fixes/fix_xreadlines.py
   python/branches/py3k/Lib/lib2to3/fixes/fix_zip.py
   python/branches/py3k/Lib/lib2to3/refactor.py
   python/branches/py3k/Lib/lib2to3/tests/test_all_fixers.py
   python/branches/py3k/Lib/lib2to3/tests/test_fixers.py
   python/branches/py3k/Lib/lib2to3/tests/test_util.py

Copied: python/branches/py3k/Lib/lib2to3/fixer_base.py (from r64286, /python/trunk/Lib/lib2to3/fixer_base.py)
==============================================================================
--- /python/trunk/Lib/lib2to3/fixer_base.py	(original)
+++ python/branches/py3k/Lib/lib2to3/fixer_base.py	Sun Jun 15 04:57:40 2008
@@ -111,7 +111,7 @@
         """
         name = template
         while name in self.used_names:
-            name = template + str(self.numbers.next())
+            name = template + str(next(self.numbers))
         self.used_names.add(name)
         return name
 

Copied: python/branches/py3k/Lib/lib2to3/fixer_util.py (from r64286, /python/trunk/Lib/lib2to3/fixer_util.py)
==============================================================================
--- /python/trunk/Lib/lib2to3/fixer_util.py	(original)
+++ python/branches/py3k/Lib/lib2to3/fixer_util.py	Sun Jun 15 04:57:40 2008
@@ -345,9 +345,9 @@
         elif imp.type == token.NAME and imp.value == name:
             return node
     elif node.type == syms.import_from:
-        # unicode(...) is used to make life easier here, because
+        # str(...) is used to make life easier here, because
         # from a.b import parses to ['import', ['a', '.', 'b'], ...]
-        if package and unicode(node.children[1]).strip() != package:
+        if package and str(node.children[1]).strip() != package:
             return None
         n = node.children[3]
         if package and _find('as', n):

Deleted: python/branches/py3k/Lib/lib2to3/fixes/basefix.py
==============================================================================
--- python/branches/py3k/Lib/lib2to3/fixes/basefix.py	Sun Jun 15 04:57:40 2008
+++ (empty file)
@@ -1,188 +0,0 @@
-# Copyright 2006 Google, Inc. All Rights Reserved.
-# Licensed to PSF under a Contributor Agreement.
-
-"""Base class for fixers (optional, but recommended)."""
-
-# Python imports
-import logging
-import itertools
-
-# Get a usable 'set' constructor
-try:
-    set
-except NameError:
-    from sets import Set as set
-
-# Local imports
-from ..patcomp import PatternCompiler
-from .. import pygram
-from .util import does_tree_import
-
-class BaseFix(object):
-
-    """Optional base class for fixers.
-
-    The subclass name must be FixFooBar where FooBar is the result of
-    removing underscores and capitalizing the words of the fix name.
-    For example, the class name for a fixer named 'has_key' should be
-    FixHasKey.
-    """
-
-    PATTERN = None  # Most subclasses should override with a string literal
-    pattern = None  # Compiled pattern, set by compile_pattern()
-    options = None  # Options object passed to initializer
-    filename = None # The filename (set by set_filename)
-    logger = None   # A logger (set by set_filename)
-    numbers = itertools.count(1) # For new_name()
-    used_names = set() # A set of all used NAMEs
-    order = "post" # Does the fixer prefer pre- or post-order traversal
-    explicit = False # Is this ignored by refactor.py -f all?
-    run_order = 5   # Fixers will be sorted by run order before execution
-                    # Lower numbers will be run first.
-
-    # Shortcut for access to Python grammar symbols
-    syms = pygram.python_symbols
-
-    def __init__(self, options, log):
-        """Initializer.  Subclass may override.
-
-        Args:
-            options: an optparse.Values instance which can be used
-                to inspect the command line options.
-            log: a list to append warnings and other messages to.
-        """
-        self.options = options
-        self.log = log
-        self.compile_pattern()
-
-    def compile_pattern(self):
-        """Compiles self.PATTERN into self.pattern.
-
-        Subclass may override if it doesn't want to use
-        self.{pattern,PATTERN} in .match().
-        """
-        if self.PATTERN is not None:
-            self.pattern = PatternCompiler().compile_pattern(self.PATTERN)
-
-    def set_filename(self, filename):
-        """Set the filename, and a logger derived from it.
-
-        The main refactoring tool should call this.
-        """
-        self.filename = filename
-        self.logger = logging.getLogger(filename)
-
-    def match(self, node):
-        """Returns match for a given parse tree node.
-
-        Should return a true or false object (not necessarily a bool).
-        It may return a non-empty dict of matching sub-nodes as
-        returned by a matching pattern.
-
-        Subclass may override.
-        """
-        results = {"node": node}
-        return self.pattern.match(node, results) and results
-
-    def transform(self, node, results):
-        """Returns the transformation for a given parse tree node.
-
-        Args:
-          node: the root of the parse tree that matched the fixer.
-          results: a dict mapping symbolic names to part of the match.
-
-        Returns:
-          None, or a node that is a modified copy of the
-          argument node.  The node argument may also be modified in-place to
-          effect the same change.
-
-        Subclass *must* override.
-        """
-        raise NotImplementedError()
-
-    def parenthesize(self, node):
-        """Wrapper around pygram.parenthesize()."""
-        return pygram.parenthesize(node)
-
-    def new_name(self, template="xxx_todo_changeme"):
-        """Return a string suitable for use as an identifier
-
-        The new name is guaranteed not to conflict with other identifiers.
-        """
-        name = template
-        while name in self.used_names:
-            name = template + str(next(self.numbers))
-        self.used_names.add(name)
-        return name
-
-    def log_message(self, message):
-        if self.first_log:
-            self.first_log = False
-            self.log.append("### In file %s ###" % self.filename)
-        self.log.append(message)
-
-    def cannot_convert(self, node, reason=None):
-        """Warn the user that a given chunk of code is not valid Python 3,
-        but that it cannot be converted automatically.
-
-        First argument is the top-level node for the code in question.
-        Optional second argument is why it can't be converted.
-        """
-        lineno = node.get_lineno()
-        for_output = node.clone()
-        for_output.set_prefix("")
-        msg = "Line %d: could not convert: %s"
-        self.log_message(msg % (lineno, for_output))
-        if reason:
-            self.log_message(reason)
-
-    def warning(self, node, reason):
-        """Used for warning the user about possible uncertainty in the
-        translation.
-
-        First argument is the top-level node for the code in question.
-        Optional second argument is why it can't be converted.
-        """
-        lineno = node.get_lineno()
-        self.log_message("Line %d: %s" % (lineno, reason))
-
-    def start_tree(self, tree, filename):
-        """Some fixers need to maintain tree-wide state.
-        This method is called once, at the start of tree fix-up.
-
-        tree - the root node of the tree to be processed.
-        filename - the name of the file the tree came from.
-        """
-        self.used_names = tree.used_names
-        self.set_filename(filename)
-        self.numbers = itertools.count(1)
-        self.first_log = True
-
-    def finish_tree(self, tree, filename):
-        """Some fixers need to maintain tree-wide state.
-        This method is called once, at the conclusion of tree fix-up.
-
-        tree - the root node of the tree to be processed.
-        filename - the name of the file the tree came from.
-        """
-        pass
-
-
-class ConditionalFix(BaseFix):
-    """ Base class for fixers which not execute if an import is found. """
-
-    # This is the name of the import which, if found, will cause the test to be skipped
-    skip_on = None
-
-    def start_tree(self, *args):
-        super(ConditionalFix, self).start_tree(*args)
-        self._should_skip = None
-
-    def should_skip(self, node):
-        if self._should_skip is not None:
-            return self._should_skip
-        pkg = self.skip_on.split(".")
-        name = pkg[-1]
-        pkg = ".".join(pkg[:-1])
-        self._should_skip = does_tree_import(pkg, name, node)
-        return self._should_skip

Modified: python/branches/py3k/Lib/lib2to3/fixes/fix_apply.py
==============================================================================
--- python/branches/py3k/Lib/lib2to3/fixes/fix_apply.py	(original)
+++ python/branches/py3k/Lib/lib2to3/fixes/fix_apply.py	Sun Jun 15 04:57:40 2008
@@ -8,10 +8,10 @@
 # Local imports
 from .. import pytree
 from ..pgen2 import token
-from . import basefix
-from .util import Call, Comma
+from .. import fixer_base
+from ..fixer_util import Call, Comma
 
-class FixApply(basefix.BaseFix):
+class FixApply(fixer_base.BaseFix):
 
     PATTERN = """
     power< 'apply'

Modified: python/branches/py3k/Lib/lib2to3/fixes/fix_basestring.py
==============================================================================
--- python/branches/py3k/Lib/lib2to3/fixes/fix_basestring.py	(original)
+++ python/branches/py3k/Lib/lib2to3/fixes/fix_basestring.py	Sun Jun 15 04:57:40 2008
@@ -2,10 +2,10 @@
 # Author: Christian Heimes
 
 # Local imports
-from . import basefix
-from .util import Name
+from .. import fixer_base
+from ..fixer_util import Name
 
-class FixBasestring(basefix.BaseFix):
+class FixBasestring(fixer_base.BaseFix):
 
     PATTERN = "'basestring'"
 

Modified: python/branches/py3k/Lib/lib2to3/fixes/fix_buffer.py
==============================================================================
--- python/branches/py3k/Lib/lib2to3/fixes/fix_buffer.py	(original)
+++ python/branches/py3k/Lib/lib2to3/fixes/fix_buffer.py	Sun Jun 15 04:57:40 2008
@@ -4,11 +4,11 @@
 """Fixer that changes buffer(...) into memoryview(...)."""
 
 # Local imports
-from . import basefix
-from .util import Name
+from .. import fixer_base
+from ..fixer_util import Name
 
 
-class FixBuffer(basefix.BaseFix):
+class FixBuffer(fixer_base.BaseFix):
 
     explicit = True # The user must ask for this fixer
 

Modified: python/branches/py3k/Lib/lib2to3/fixes/fix_callable.py
==============================================================================
--- python/branches/py3k/Lib/lib2to3/fixes/fix_callable.py	(original)
+++ python/branches/py3k/Lib/lib2to3/fixes/fix_callable.py	Sun Jun 15 04:57:40 2008
@@ -7,10 +7,10 @@
 
 # Local imports
 from .. import pytree
-from . import basefix
-from .util import Call, Name, String
+from .. import fixer_base
+from ..fixer_util import Call, Name, String
 
-class FixCallable(basefix.BaseFix):
+class FixCallable(fixer_base.BaseFix):
 
     # Ignore callable(*args) or use of keywords.
     # Either could be a hint that the builtin callable() is not being used.

Modified: python/branches/py3k/Lib/lib2to3/fixes/fix_dict.py
==============================================================================
--- python/branches/py3k/Lib/lib2to3/fixes/fix_dict.py	(original)
+++ python/branches/py3k/Lib/lib2to3/fixes/fix_dict.py	Sun Jun 15 04:57:40 2008
@@ -27,15 +27,15 @@
 from .. import pytree
 from .. import patcomp
 from ..pgen2 import token
-from . import basefix
-from .util import Name, Call, LParen, RParen, ArgList, Dot, set
-from . import util
+from .. import fixer_base
+from ..fixer_util import Name, Call, LParen, RParen, ArgList, Dot, set
+from .. import fixer_util
 
 
-iter_exempt = util.consuming_calls | set(["iter"])
+iter_exempt = fixer_util.consuming_calls | set(["iter"])
 
 
-class FixDict(basefix.BaseFix):
+class FixDict(fixer_base.BaseFix):
     PATTERN = """
     power< head=any+
          trailer< '.' method=('keys'|'items'|'values'|
@@ -92,7 +92,7 @@
                 return results["func"].value in iter_exempt
             else:
                 # list(d.keys()) -> list(d.keys()), etc.
-                return results["func"].value in util.consuming_calls
+                return results["func"].value in fixer_util.consuming_calls
         if not isiter:
             return False
         # for ... in d.iterkeys() -> for ... in d.keys(), etc.

Modified: python/branches/py3k/Lib/lib2to3/fixes/fix_except.py
==============================================================================
--- python/branches/py3k/Lib/lib2to3/fixes/fix_except.py	(original)
+++ python/branches/py3k/Lib/lib2to3/fixes/fix_except.py	Sun Jun 15 04:57:40 2008
@@ -24,8 +24,8 @@
 # Local imports
 from .. import pytree
 from ..pgen2 import token
-from . import basefix
-from .util import Assign, Attr, Name, is_tuple, is_list, reversed
+from .. import fixer_base
+from ..fixer_util import Assign, Attr, Name, is_tuple, is_list, reversed
 
 def find_excepts(nodes):
     for i, n in enumerate(nodes):
@@ -33,7 +33,7 @@
             if n.children[0].value == 'except':
                 yield (n, nodes[i+2])
 
-class FixExcept(basefix.BaseFix):
+class FixExcept(fixer_base.BaseFix):
 
     PATTERN = """
     try_stmt< 'try' ':' suite

Modified: python/branches/py3k/Lib/lib2to3/fixes/fix_exec.py
==============================================================================
--- python/branches/py3k/Lib/lib2to3/fixes/fix_exec.py	(original)
+++ python/branches/py3k/Lib/lib2to3/fixes/fix_exec.py	Sun Jun 15 04:57:40 2008
@@ -11,11 +11,11 @@
 
 # Local imports
 from .. import pytree
-from . import basefix
-from .util import Comma, Name, Call
+from .. import fixer_base
+from ..fixer_util import Comma, Name, Call
 
 
-class FixExec(basefix.BaseFix):
+class FixExec(fixer_base.BaseFix):
 
     PATTERN = """
     exec_stmt< 'exec' a=any 'in' b=any [',' c=any] >

Modified: python/branches/py3k/Lib/lib2to3/fixes/fix_execfile.py
==============================================================================
--- python/branches/py3k/Lib/lib2to3/fixes/fix_execfile.py	(original)
+++ python/branches/py3k/Lib/lib2to3/fixes/fix_execfile.py	Sun Jun 15 04:57:40 2008
@@ -8,11 +8,11 @@
 """
 
 from .. import pytree
-from . import basefix
-from .util import Comma, Name, Call, LParen, RParen, Dot
+from .. import fixer_base
+from ..fixer_util import Comma, Name, Call, LParen, RParen, Dot
 
 
-class FixExecfile(basefix.BaseFix):
+class FixExecfile(fixer_base.BaseFix):
 
     PATTERN = """
     power< 'execfile' trailer< '(' arglist< filename=any [',' globals=any [',' locals=any ] ] > ')' > >

Modified: python/branches/py3k/Lib/lib2to3/fixes/fix_filter.py
==============================================================================
--- python/branches/py3k/Lib/lib2to3/fixes/fix_filter.py	(original)
+++ python/branches/py3k/Lib/lib2to3/fixes/fix_filter.py	Sun Jun 15 04:57:40 2008
@@ -15,10 +15,10 @@
 
 # Local imports
 from ..pgen2 import token
-from . import basefix
-from .util import Name, Call, ListComp, in_special_context
+from .. import fixer_base
+from ..fixer_util import Name, Call, ListComp, in_special_context
 
-class FixFilter(basefix.ConditionalFix):
+class FixFilter(fixer_base.ConditionalFix):
 
     PATTERN = """
     filter_lambda=power<

Modified: python/branches/py3k/Lib/lib2to3/fixes/fix_funcattrs.py
==============================================================================
--- python/branches/py3k/Lib/lib2to3/fixes/fix_funcattrs.py	(original)
+++ python/branches/py3k/Lib/lib2to3/fixes/fix_funcattrs.py	Sun Jun 15 04:57:40 2008
@@ -2,11 +2,11 @@
 # Author: Collin Winter
 
 # Local imports
-from . import basefix
-from .util import Name
+from .. import fixer_base
+from ..fixer_util import Name
 
 
-class FixFuncattrs(basefix.BaseFix):
+class FixFuncattrs(fixer_base.BaseFix):
     PATTERN = """
     power< any+ trailer< '.' attr=('func_closure' | 'func_doc' | 'func_globals'
                                   | 'func_name' | 'func_defaults' | 'func_code'

Modified: python/branches/py3k/Lib/lib2to3/fixes/fix_future.py
==============================================================================
--- python/branches/py3k/Lib/lib2to3/fixes/fix_future.py	(original)
+++ python/branches/py3k/Lib/lib2to3/fixes/fix_future.py	Sun Jun 15 04:57:40 2008
@@ -5,10 +5,10 @@
 # Author: Christian Heimes
 
 # Local imports
-from . import basefix
-from .util import BlankLine
+from .. import fixer_base
+from ..fixer_util import BlankLine
 
-class FixFuture(basefix.BaseFix):
+class FixFuture(fixer_base.BaseFix):
     PATTERN = """import_from< 'from' module_name="__future__" 'import' any >"""
 
     # This should be run last -- some things check for the import

Modified: python/branches/py3k/Lib/lib2to3/fixes/fix_has_key.py
==============================================================================
--- python/branches/py3k/Lib/lib2to3/fixes/fix_has_key.py	(original)
+++ python/branches/py3k/Lib/lib2to3/fixes/fix_has_key.py	Sun Jun 15 04:57:40 2008
@@ -32,11 +32,11 @@
 # Local imports
 from .. import pytree
 from ..pgen2 import token
-from . import basefix
-from .util import Name
+from .. import fixer_base
+from ..fixer_util import Name
 
 
-class FixHasKey(basefix.BaseFix):
+class FixHasKey(fixer_base.BaseFix):
 
     PATTERN = """
     anchor=power<

Modified: python/branches/py3k/Lib/lib2to3/fixes/fix_idioms.py
==============================================================================
--- python/branches/py3k/Lib/lib2to3/fixes/fix_idioms.py	(original)
+++ python/branches/py3k/Lib/lib2to3/fixes/fix_idioms.py	Sun Jun 15 04:57:40 2008
@@ -28,13 +28,13 @@
 # Author: Jacques Frechet, Collin Winter
 
 # Local imports
-from . import basefix
-from .util import Call, Comma, Name, Node, syms
+from .. import fixer_base
+from ..fixer_util import Call, Comma, Name, Node, syms
 
 CMP = "(n='!=' | '==' | 'is' | n=comp_op< 'is' 'not' >)"
 TYPE = "power< 'type' trailer< '(' x=any ')' > >"
 
-class FixIdioms(basefix.BaseFix):
+class FixIdioms(fixer_base.BaseFix):
 
     explicit = True # The user must ask for this fixer
 

Modified: python/branches/py3k/Lib/lib2to3/fixes/fix_import.py
==============================================================================
--- python/branches/py3k/Lib/lib2to3/fixes/fix_import.py	(original)
+++ python/branches/py3k/Lib/lib2to3/fixes/fix_import.py	Sun Jun 15 04:57:40 2008
@@ -11,11 +11,11 @@
 """
 
 # Local imports
-from . import basefix
+from .. import fixer_base
 from os.path import dirname, join, exists, pathsep
-from .util import FromImport
+from ..fixer_util import FromImport
 
-class FixImport(basefix.BaseFix):
+class FixImport(fixer_base.BaseFix):
 
     PATTERN = """
     import_from< type='from' imp=any 'import' any >

Modified: python/branches/py3k/Lib/lib2to3/fixes/fix_imports.py
==============================================================================
--- python/branches/py3k/Lib/lib2to3/fixes/fix_imports.py	(original)
+++ python/branches/py3k/Lib/lib2to3/fixes/fix_imports.py	Sun Jun 15 04:57:40 2008
@@ -8,8 +8,8 @@
 # Author: Collin Winter
 
 # Local imports
-from . import basefix
-from .util import Name, attr_chain, any, set
+from .. import fixer_base
+from ..fixer_util import Name, attr_chain, any, set
 import builtins
 builtin_names = [name for name in dir(builtins)
                  if name not in ("__name__", "__doc__")]
@@ -150,6 +150,123 @@
                        'error', 'exit', 'exit_thread', 'get_ident',
                        'interrupt_main', 'stack_size', 'start_new',
                        'start_new_thread']),
+           'whichdb': ('dbm', ['whichdb']),
+           'anydbm': ('dbm', ['error', 'open']),
+           'dbhash': ('dbm.bsd', ['error', 'open']),
+           'dumbdbm': ('dbm.dumb', ['error', 'open', '_Database']),
+           'dbm': ('dbm.ndbm', ['error', 'open', 'library']),
+           'gdbm': ('dbm.gnu', ['error', 'open', 'open_flags']),
+           'xmlrpclib': ('xmlrpc.client',
+                         ['Error', 'ProtocolError', 'ResponseError', 'Fault',
+                          'ServerProxy', 'Boolean', 'DateTime', 'Binary',
+                          'ExpatParser', 'FastMarshaller', 'FastParser',
+                          'FastUnmarshaller', 'MultiCall', 'MultiCallIterator',
+                          'SlowParser', 'Marshaller', 'Unmarshaller', 'Server',
+                          'Transport', 'SafeTransport', 'SgmlopParser',
+                          'boolean', 'getparser', 'dumps', 'loads', 'escape',
+                          'PARSE_ERROR', 'SERVER_ERROR', 'WRAPPERS',
+                          'APPLICATION_ERROR', 'SYSTEM_ERROR',
+                          'TRANSPORT_ERROR', 'NOT_WELLFORMED_ERROR',
+                          'UNSUPPORTED_ENCODING', 'INVALID_ENCODING_CHAR',
+                          'INVALID_XMLRPC', 'METHOD_NOT_FOUND',
+                          'INVALID_METHOD_PARAMS', 'INTERNAL_ERROR',
+                          'MININT', 'MAXINT']),
+           'DocXMLRPCServer': ('xmlrpc.server',
+                               ['CGIXMLRPCRequestHandler',
+                               'DocCGIXMLRPCRequestHandler',
+                               'DocXMLRPCRequestHandler', 'DocXMLRPCServer',
+                               'ServerHTMLDoc', 'SimpleXMLRPCRequestHandler',
+                               'SimpleXMLRPCServer', 'XMLRPCDocGenerator',
+                               'resolve_dotted_attribute']),
+           'SimpleXMLRPCServer': ('xmlrpc.server',
+                                  ['CGIXMLRPCRequestHandler',
+                                   'Fault', 'SimpleXMLRPCDispatcher',
+                                   'SimpleXMLRPCRequestHandler',
+                                   'SimpleXMLRPCServer', 'SocketServer',
+                                   'list_public_methods',
+                                   'remove_duplicates',
+                                   'resolve_dotted_attribute']),
+           'httplib': ('http.client',
+                       ['ACCEPTED', 'BAD_GATEWAY', 'BAD_REQUEST',
+                        'BadStatusLine', 'CONFLICT', 'CONTINUE', 'CREATED',
+                        'CannotSendHeader', 'CannotSendRequest',
+                        'EXPECTATION_FAILED', 'FAILED_DEPENDENCY', 'FORBIDDEN',
+                        'FOUND', 'FakeSocket', 'GATEWAY_TIMEOUT', 'GONE',
+                        'HTTP', 'HTTPConnection', 'HTTPException',
+                        'HTTPMessage', 'HTTPResponse', 'HTTPS',
+                        'HTTPSConnection', 'HTTPS_PORT', 'HTTP_PORT',
+                        'HTTP_VERSION_NOT_SUPPORTED', 'IM_USED',
+                        'INSUFFICIENT_STORAGE', 'INTERNAL_SERVER_ERROR',
+                        'ImproperConnectionState', 'IncompleteRead',
+                        'InvalidURL', 'LENGTH_REQUIRED', 'LOCKED',
+                        'LineAndFileWrapper', 'MAXAMOUNT', 'METHOD_NOT_ALLOWED',
+                        'MOVED_PERMANENTLY', 'MULTIPLE_CHOICES', 'MULTI_STATUS',
+                        'NON_AUTHORITATIVE_INFORMATION', 'NOT_ACCEPTABLE',
+                        'NOT_EXTENDED', 'NOT_FOUND', 'NOT_IMPLEMENTED',
+                        'NOT_MODIFIED', 'NO_CONTENT', 'NotConnected', 'OK',
+                        'PARTIAL_CONTENT', 'PAYMENT_REQUIRED',
+                        'PRECONDITION_FAILED', 'PROCESSING',
+                        'PROXY_AUTHENTICATION_REQUIRED',
+                        'REQUESTED_RANGE_NOT_SATISFIABLE',
+                        'REQUEST_ENTITY_TOO_LARGE', 'REQUEST_TIMEOUT',
+                        'REQUEST_URI_TOO_LONG', 'RESET_CONTENT',
+                        'ResponseNotReady', 'SEE_OTHER', 'SERVICE_UNAVAILABLE',
+                        'SSLFile', 'SWITCHING_PROTOCOLS', 'SharedSocket',
+                        'SharedSocketClient', 'StringIO', 'TEMPORARY_REDIRECT',
+                        'UNAUTHORIZED', 'UNPROCESSABLE_ENTITY',
+                        'UNSUPPORTED_MEDIA_TYPE', 'UPGRADE_REQUIRED',
+                        'USE_PROXY', 'UnimplementedFileMode', 'UnknownProtocol',
+                        'UnknownTransferEncoding', 'error', 'responses']),
+           'Cookie': ('http.cookies',
+                      ['BaseCookie', 'Cookie', 'CookieError', 'Morsel',
+                       'SerialCookie', 'SimpleCookie', 'SmartCookie']),
+           'cookielib': ('http.cookiejar',
+                         ['Absent', 'Cookie', 'CookieJar', 'CookiePolicy',
+                          'DAYS', 'DEFAULT_HTTP_PORT', 'DefaultCookiePolicy',
+                          'EPOCH_YEAR', 'ESCAPED_CHAR_RE', 'FileCookieJar',
+                          'HEADER_ESCAPE_RE', 'HEADER_JOIN_ESCAPE_RE',
+                          'HEADER_QUOTED_VALUE_RE', 'HEADER_TOKEN_RE',
+                          'HEADER_VALUE_RE', 'HTTP_PATH_SAFE', 'IPV4_RE',
+                          'ISO_DATE_RE', 'LOOSE_HTTP_DATE_RE', 'LWPCookieJar',
+                          'LoadError', 'MISSING_FILENAME_TEXT', 'MONTHS',
+                          'MONTHS_LOWER', 'MozillaCookieJar', 'STRICT_DATE_RE',
+                          'TIMEZONE_RE', 'UTC_ZONES', 'WEEKDAY_RE',
+                          'cut_port_re', 'deepvalues', 'domain_match',
+                          'eff_request_host', 'escape_path', 'http2time',
+                          'is_HDN', 'is_third_party', 'iso2time',
+                          'join_header_words', 'liberal_is_HDN', 'logger',
+                          'lwp_cookie_str', 'month', 'offset_from_tz_string',
+                          'parse_ns_headers', 'reach', 'request_host',
+                          'request_path', 'request_port', 'split_header_words',
+                          'time', 'time2isoz', 'time2netscape', 'unmatched',
+                          'uppercase_escaped_char', 'urllib',
+                          'user_domain_match', 'vals_sorted_by_key']),
+           'BaseHTTPServer': ('http.server',
+                              ['BaseHTTPRequestHandler',
+                               'DEFAULT_ERROR_MESSAGE', 'HTTPServer']),
+           'SimpleHTTPServer': ('http.server', ['SimpleHTTPRequestHandler']),
+           'CGIHTTPServer': ('http.server',
+                             ['CGIHTTPRequestHandler', 'executable',
+                              'nobody_uid', 'nobody']),
+           'test.test_support': ('test.support',
+                          ["Error", "TestFailed", "TestSkipped", "ResourceDenied",
+                          "import_module", "verbose", "use_resources",
+                          "max_memuse", "record_original_stdout",
+                          "get_original_stdout", "unload", "unlink", "rmtree",
+                          "forget", "is_resource_enabled", "requires",
+                          "find_unused_port", "bind_port",
+                          "fcmp", "is_jython", "TESTFN", "HOST",
+                          "FUZZ", "findfile", "verify", "vereq", "sortdict",
+                          "check_syntax_error", "open_urlresource", "WarningMessage",
+                          "catch_warning", "CleanImport", "EnvironmentVarGuard",
+                          "TransientResource", "captured_output", "captured_stdout",
+                          "TransientResource", "transient_internet", "run_with_locale",
+                          "set_memlimit", "bigmemtest", "bigaddrspacetest",
+                          "BasicTestRunner", "run_unittest", "run_doctest",
+                          "threading_setup", "threading_cleanup", "reap_children"]),
+           'commands': ('subprocess', ['getstatusoutput', 'getoutput']),
+           'UserString' : ('collections', ['UserString']),
+           'UserList' : ('collections', ['UserList']),
 }
 
 
@@ -180,7 +297,7 @@
     yield """bare_name=%s""" % alternates(bare)
 
 
-class FixImports(basefix.BaseFix):
+class FixImports(fixer_base.BaseFix):
     PATTERN = "|".join(build_pattern())
 
     order = "pre" # Pre-order tree traversal

Modified: python/branches/py3k/Lib/lib2to3/fixes/fix_input.py
==============================================================================
--- python/branches/py3k/Lib/lib2to3/fixes/fix_input.py	(original)
+++ python/branches/py3k/Lib/lib2to3/fixes/fix_input.py	Sun Jun 15 04:57:40 2008
@@ -2,15 +2,15 @@
 # Author: Andre Roberge
 
 # Local imports
-from . import basefix
-from .util import Call, Name
+from .. import fixer_base
+from ..fixer_util import Call, Name
 from .. import patcomp
 
 
 context = patcomp.compile_pattern("power< 'eval' trailer< '(' any ')' > >")
 
 
-class FixInput(basefix.BaseFix):
+class FixInput(fixer_base.BaseFix):
 
     PATTERN = """
               power< 'input' args=trailer< '(' [any] ')' > >

Modified: python/branches/py3k/Lib/lib2to3/fixes/fix_intern.py
==============================================================================
--- python/branches/py3k/Lib/lib2to3/fixes/fix_intern.py	(original)
+++ python/branches/py3k/Lib/lib2to3/fixes/fix_intern.py	Sun Jun 15 04:57:40 2008
@@ -7,11 +7,11 @@
 
 # Local imports
 from .. import pytree
-from . import basefix
-from .util import Name, Attr
+from .. import fixer_base
+from ..fixer_util import Name, Attr
 
 
-class FixIntern(basefix.BaseFix):
+class FixIntern(fixer_base.BaseFix):
 
     PATTERN = """
     power< 'intern'

Modified: python/branches/py3k/Lib/lib2to3/fixes/fix_itertools.py
==============================================================================
--- python/branches/py3k/Lib/lib2to3/fixes/fix_itertools.py	(original)
+++ python/branches/py3k/Lib/lib2to3/fixes/fix_itertools.py	Sun Jun 15 04:57:40 2008
@@ -8,10 +8,10 @@
     """
 
 # Local imports
-from . import basefix
-from .util import Name
+from .. import fixer_base
+from ..fixer_util import Name
 
-class FixItertools(basefix.BaseFix):
+class FixItertools(fixer_base.BaseFix):
     it_funcs = "('imap'|'ifilter'|'izip'|'ifilterfalse')"
     PATTERN = """
               power< it='itertools'

Modified: python/branches/py3k/Lib/lib2to3/fixes/fix_itertools_imports.py
==============================================================================
--- python/branches/py3k/Lib/lib2to3/fixes/fix_itertools_imports.py	(original)
+++ python/branches/py3k/Lib/lib2to3/fixes/fix_itertools_imports.py	Sun Jun 15 04:57:40 2008
@@ -1,10 +1,10 @@
 """ Fixer for imports of itertools.(imap|ifilter|izip|ifilterfalse) """
 
 # Local imports
-from . import basefix
-from .util import BlankLine
+from .. import fixer_base
+from ..fixer_util import BlankLine
 
-class FixItertoolsImports(basefix.BaseFix):
+class FixItertoolsImports(fixer_base.BaseFix):
     PATTERN = """
               import_from< 'from' 'itertools' 'import' imports=any >
               """ %(locals())

Modified: python/branches/py3k/Lib/lib2to3/fixes/fix_long.py
==============================================================================
--- python/branches/py3k/Lib/lib2to3/fixes/fix_long.py	(original)
+++ python/branches/py3k/Lib/lib2to3/fixes/fix_long.py	Sun Jun 15 04:57:40 2008
@@ -8,11 +8,11 @@
 
 # Local imports
 from .. import pytree
-from . import basefix
-from .util import Name, Number
+from .. import fixer_base
+from ..fixer_util import Name, Number
 
 
-class FixLong(basefix.BaseFix):
+class FixLong(fixer_base.BaseFix):
 
     PATTERN = """
     (long_type = 'long' | number = NUMBER)

Modified: python/branches/py3k/Lib/lib2to3/fixes/fix_map.py
==============================================================================
--- python/branches/py3k/Lib/lib2to3/fixes/fix_map.py	(original)
+++ python/branches/py3k/Lib/lib2to3/fixes/fix_map.py	Sun Jun 15 04:57:40 2008
@@ -21,11 +21,11 @@
 
 # Local imports
 from ..pgen2 import token
-from . import basefix
-from .util import Name, Call, ListComp, in_special_context
+from .. import fixer_base
+from ..fixer_util import Name, Call, ListComp, in_special_context
 from ..pygram import python_symbols as syms
 
-class FixMap(basefix.ConditionalFix):
+class FixMap(fixer_base.ConditionalFix):
 
     PATTERN = """
     map_none=power<

Modified: python/branches/py3k/Lib/lib2to3/fixes/fix_methodattrs.py
==============================================================================
--- python/branches/py3k/Lib/lib2to3/fixes/fix_methodattrs.py	(original)
+++ python/branches/py3k/Lib/lib2to3/fixes/fix_methodattrs.py	Sun Jun 15 04:57:40 2008
@@ -3,8 +3,8 @@
 # Author: Christian Heimes
 
 # Local imports
-from . import basefix
-from .util import Name
+from .. import fixer_base
+from ..fixer_util import Name
 
 MAP = {
     "im_func" : "__func__",
@@ -12,7 +12,7 @@
     "im_class" : "__self__.__class__"
     }
 
-class FixMethodattrs(basefix.BaseFix):
+class FixMethodattrs(fixer_base.BaseFix):
     PATTERN = """
     power< any+ trailer< '.' attr=('im_func' | 'im_self' | 'im_class') > any* >
     """

Modified: python/branches/py3k/Lib/lib2to3/fixes/fix_ne.py
==============================================================================
--- python/branches/py3k/Lib/lib2to3/fixes/fix_ne.py	(original)
+++ python/branches/py3k/Lib/lib2to3/fixes/fix_ne.py	Sun Jun 15 04:57:40 2008
@@ -6,10 +6,10 @@
 # Local imports
 from .. import pytree
 from ..pgen2 import token
-from . import basefix
+from .. import fixer_base
 
 
-class FixNe(basefix.BaseFix):
+class FixNe(fixer_base.BaseFix):
     # This is so simple that we don't need the pattern compiler.
 
     def match(self, node):

Modified: python/branches/py3k/Lib/lib2to3/fixes/fix_next.py
==============================================================================
--- python/branches/py3k/Lib/lib2to3/fixes/fix_next.py	(original)
+++ python/branches/py3k/Lib/lib2to3/fixes/fix_next.py	Sun Jun 15 04:57:40 2008
@@ -8,13 +8,13 @@
 # Local imports
 from ..pgen2 import token
 from ..pygram import python_symbols as syms
-from . import basefix
-from .util import Name, Call, find_binding, any
+from .. import fixer_base
+from ..fixer_util import Name, Call, find_binding, any
 
 bind_warning = "Calls to builtin next() possibly shadowed by global binding"
 
 
-class FixNext(basefix.BaseFix):
+class FixNext(fixer_base.BaseFix):
     PATTERN = """
     power< base=any+ trailer< '.' attr='next' > trailer< '(' ')' > >
     |

Modified: python/branches/py3k/Lib/lib2to3/fixes/fix_nonzero.py
==============================================================================
--- python/branches/py3k/Lib/lib2to3/fixes/fix_nonzero.py	(original)
+++ python/branches/py3k/Lib/lib2to3/fixes/fix_nonzero.py	Sun Jun 15 04:57:40 2008
@@ -2,10 +2,10 @@
 # Author: Collin Winter
 
 # Local imports
-from .import basefix
-from .util import Name, syms
+from .. import fixer_base
+from ..fixer_util import Name, syms
 
-class FixNonzero(basefix.BaseFix):
+class FixNonzero(fixer_base.BaseFix):
     PATTERN = """
     classdef< 'class' any+ ':'
               suite< any*

Modified: python/branches/py3k/Lib/lib2to3/fixes/fix_numliterals.py
==============================================================================
--- python/branches/py3k/Lib/lib2to3/fixes/fix_numliterals.py	(original)
+++ python/branches/py3k/Lib/lib2to3/fixes/fix_numliterals.py	Sun Jun 15 04:57:40 2008
@@ -5,11 +5,11 @@
 
 # Local imports
 from ..pgen2 import token
-from .import basefix
-from .util import Number, set
+from .. import fixer_base
+from ..fixer_util import Number, set
 
 
-class FixNumliterals(basefix.BaseFix):
+class FixNumliterals(fixer_base.BaseFix):
     # This is so simple that we don't need the pattern compiler.
 
     def match(self, node):

Modified: python/branches/py3k/Lib/lib2to3/fixes/fix_print.py
==============================================================================
--- python/branches/py3k/Lib/lib2to3/fixes/fix_print.py	(original)
+++ python/branches/py3k/Lib/lib2to3/fixes/fix_print.py	Sun Jun 15 04:57:40 2008
@@ -17,8 +17,8 @@
 from .. import patcomp
 from .. import pytree
 from ..pgen2 import token
-from .import basefix
-from .util import Name, Call, Comma, String, is_tuple
+from .. import fixer_base
+from ..fixer_util import Name, Call, Comma, String, is_tuple
 
 
 parend_expr = patcomp.compile_pattern(
@@ -26,7 +26,7 @@
               )
 
 
-class FixPrint(basefix.ConditionalFix):
+class FixPrint(fixer_base.ConditionalFix):
 
     PATTERN = """
               simple_stmt< bare='print' any > | print_stmt

Modified: python/branches/py3k/Lib/lib2to3/fixes/fix_raise.py
==============================================================================
--- python/branches/py3k/Lib/lib2to3/fixes/fix_raise.py	(original)
+++ python/branches/py3k/Lib/lib2to3/fixes/fix_raise.py	Sun Jun 15 04:57:40 2008
@@ -24,10 +24,10 @@
 # Local imports
 from .. import pytree
 from ..pgen2 import token
-from .import basefix
-from .util import Name, Call, Attr, ArgList, is_tuple
+from .. import fixer_base
+from ..fixer_util import Name, Call, Attr, ArgList, is_tuple
 
-class FixRaise(basefix.BaseFix):
+class FixRaise(fixer_base.BaseFix):
 
     PATTERN = """
     raise_stmt< 'raise' exc=any [',' val=any [',' tb=any]] >

Modified: python/branches/py3k/Lib/lib2to3/fixes/fix_raw_input.py
==============================================================================
--- python/branches/py3k/Lib/lib2to3/fixes/fix_raw_input.py	(original)
+++ python/branches/py3k/Lib/lib2to3/fixes/fix_raw_input.py	Sun Jun 15 04:57:40 2008
@@ -2,10 +2,10 @@
 # Author: Andre Roberge
 
 # Local imports
-from .import basefix
-from .util import Name
+from .. import fixer_base
+from ..fixer_util import Name
 
-class FixRawInput(basefix.BaseFix):
+class FixRawInput(fixer_base.BaseFix):
 
     PATTERN = """
               power< name='raw_input' trailer< '(' [any] ')' > >

Modified: python/branches/py3k/Lib/lib2to3/fixes/fix_renames.py
==============================================================================
--- python/branches/py3k/Lib/lib2to3/fixes/fix_renames.py	(original)
+++ python/branches/py3k/Lib/lib2to3/fixes/fix_renames.py	Sun Jun 15 04:57:40 2008
@@ -7,8 +7,8 @@
 # based on Collin Winter's fix_import
 
 # Local imports
-from .import basefix
-from .util import Name, attr_chain, any, set
+from .. import fixer_base
+from ..fixer_util import Name, attr_chain, any, set
 
 MAPPING = {"sys":  {"maxint" : "maxsize"},
           }
@@ -39,7 +39,7 @@
     #yield """bare_name=%s""" % alternates(bare)
 
 
-class FixRenames(basefix.BaseFix):
+class FixRenames(fixer_base.BaseFix):
     PATTERN = "|".join(build_pattern())
 
     order = "pre" # Pre-order tree traversal

Modified: python/branches/py3k/Lib/lib2to3/fixes/fix_repr.py
==============================================================================
--- python/branches/py3k/Lib/lib2to3/fixes/fix_repr.py	(original)
+++ python/branches/py3k/Lib/lib2to3/fixes/fix_repr.py	Sun Jun 15 04:57:40 2008
@@ -4,11 +4,11 @@
 """Fixer that transforms `xyzzy` into repr(xyzzy)."""
 
 # Local imports
-from .import basefix
-from .util import Call, Name
+from .. import fixer_base
+from ..fixer_util import Call, Name
 
 
-class FixRepr(basefix.BaseFix):
+class FixRepr(fixer_base.BaseFix):
 
     PATTERN = """
               atom < '`' expr=any '`' >

Modified: python/branches/py3k/Lib/lib2to3/fixes/fix_standarderror.py
==============================================================================
--- python/branches/py3k/Lib/lib2to3/fixes/fix_standarderror.py	(original)
+++ python/branches/py3k/Lib/lib2to3/fixes/fix_standarderror.py	Sun Jun 15 04:57:40 2008
@@ -4,11 +4,11 @@
 """Fixer for StandardError -> Exception."""
 
 # Local imports
-from .import basefix
-from .util import Name
+from .. import fixer_base
+from ..fixer_util import Name
 
 
-class FixStandarderror(basefix.BaseFix):
+class FixStandarderror(fixer_base.BaseFix):
 
     PATTERN = """
               'StandardError'

Modified: python/branches/py3k/Lib/lib2to3/fixes/fix_throw.py
==============================================================================
--- python/branches/py3k/Lib/lib2to3/fixes/fix_throw.py	(original)
+++ python/branches/py3k/Lib/lib2to3/fixes/fix_throw.py	Sun Jun 15 04:57:40 2008
@@ -10,10 +10,10 @@
 # Local imports
 from .. import pytree
 from ..pgen2 import token
-from .import basefix
-from .util import Name, Call, ArgList, Attr, is_tuple
+from .. import fixer_base
+from ..fixer_util import Name, Call, ArgList, Attr, is_tuple
 
-class FixThrow(basefix.BaseFix):
+class FixThrow(fixer_base.BaseFix):
 
     PATTERN = """
     power< any trailer< '.' 'throw' >

Modified: python/branches/py3k/Lib/lib2to3/fixes/fix_tuple_params.py
==============================================================================
--- python/branches/py3k/Lib/lib2to3/fixes/fix_tuple_params.py	(original)
+++ python/branches/py3k/Lib/lib2to3/fixes/fix_tuple_params.py	Sun Jun 15 04:57:40 2008
@@ -21,14 +21,14 @@
 # Local imports
 from .. import pytree
 from ..pgen2 import token
-from .import basefix
-from .util import Assign, Name, Newline, Number, Subscript, syms
+from .. import fixer_base
+from ..fixer_util import Assign, Name, Newline, Number, Subscript, syms
 
 def is_docstring(stmt):
     return isinstance(stmt, pytree.Node) and \
            stmt.children[0].type == token.STRING
 
-class FixTupleParams(basefix.BaseFix):
+class FixTupleParams(fixer_base.BaseFix):
     PATTERN = """
               funcdef< 'def' any parameters< '(' args=any ')' >
                        ['->' any] ':' suite=any+ >

Modified: python/branches/py3k/Lib/lib2to3/fixes/fix_types.py
==============================================================================
--- python/branches/py3k/Lib/lib2to3/fixes/fix_types.py	(original)
+++ python/branches/py3k/Lib/lib2to3/fixes/fix_types.py	Sun Jun 15 04:57:40 2008
@@ -21,8 +21,8 @@
 
 # Local imports
 from ..pgen2 import token
-from .import basefix
-from .util import Name
+from .. import fixer_base
+from ..fixer_util import Name
 
 _TYPE_MAPPING = {
         'BooleanType' : 'bool',
@@ -51,7 +51,7 @@
 
 _pats = ["power< 'types' trailer< '.' name='%s' > >" % t for t in _TYPE_MAPPING]
 
-class FixTypes(basefix.BaseFix):
+class FixTypes(fixer_base.BaseFix):
 
     PATTERN = '|'.join(_pats)
 

Modified: python/branches/py3k/Lib/lib2to3/fixes/fix_unicode.py
==============================================================================
--- python/branches/py3k/Lib/lib2to3/fixes/fix_unicode.py	(original)
+++ python/branches/py3k/Lib/lib2to3/fixes/fix_unicode.py	Sun Jun 15 04:57:40 2008
@@ -4,9 +4,9 @@
 
 import re
 from ..pgen2 import token
-from .import basefix
+from .. import fixer_base
 
-class FixUnicode(basefix.BaseFix):
+class FixUnicode(fixer_base.BaseFix):
 
     PATTERN = "STRING | NAME<'unicode' | 'unichr'>"
 

Modified: python/branches/py3k/Lib/lib2to3/fixes/fix_ws_comma.py
==============================================================================
--- python/branches/py3k/Lib/lib2to3/fixes/fix_ws_comma.py	(original)
+++ python/branches/py3k/Lib/lib2to3/fixes/fix_ws_comma.py	Sun Jun 15 04:57:40 2008
@@ -7,9 +7,9 @@
 
 from .. import pytree
 from ..pgen2 import token
-from .import basefix
+from .. import fixer_base
 
-class FixWsComma(basefix.BaseFix):
+class FixWsComma(fixer_base.BaseFix):
 
     explicit = True # The user must ask for this fixers
 

Modified: python/branches/py3k/Lib/lib2to3/fixes/fix_xrange.py
==============================================================================
--- python/branches/py3k/Lib/lib2to3/fixes/fix_xrange.py	(original)
+++ python/branches/py3k/Lib/lib2to3/fixes/fix_xrange.py	Sun Jun 15 04:57:40 2008
@@ -4,12 +4,12 @@
 """Fixer that changes xrange(...) into range(...)."""
 
 # Local imports
-from .import basefix
-from .util import Name, Call, consuming_calls
+from .. import fixer_base
+from ..fixer_util import Name, Call, consuming_calls
 from .. import patcomp
 
 
-class FixXrange(basefix.BaseFix):
+class FixXrange(fixer_base.BaseFix):
 
     PATTERN = """
               power< (name='range'|name='xrange') trailer< '(' [any] ')' > any* >

Modified: python/branches/py3k/Lib/lib2to3/fixes/fix_xreadlines.py
==============================================================================
--- python/branches/py3k/Lib/lib2to3/fixes/fix_xreadlines.py	(original)
+++ python/branches/py3k/Lib/lib2to3/fixes/fix_xreadlines.py	Sun Jun 15 04:57:40 2008
@@ -4,11 +4,11 @@
 # Author: Collin Winter
 
 # Local imports
-from .import basefix
-from .util import Name
+from .. import fixer_base
+from ..fixer_util import Name
 
 
-class FixXreadlines(basefix.BaseFix):
+class FixXreadlines(fixer_base.BaseFix):
     PATTERN = """
     power< call=any+ trailer< '.' 'xreadlines' > trailer< '(' ')' > >
     |

Modified: python/branches/py3k/Lib/lib2to3/fixes/fix_zip.py
==============================================================================
--- python/branches/py3k/Lib/lib2to3/fixes/fix_zip.py	(original)
+++ python/branches/py3k/Lib/lib2to3/fixes/fix_zip.py	Sun Jun 15 04:57:40 2008
@@ -8,10 +8,10 @@
 """
 
 # Local imports
-from . import basefix
-from .util import Name, Call, in_special_context
+from .. import fixer_base
+from ..fixer_util import Name, Call, in_special_context
 
-class FixZip(basefix.ConditionalFix):
+class FixZip(fixer_base.ConditionalFix):
 
     PATTERN = """
     power< 'zip' args=trailer< '(' [any] ')' >

Deleted: python/branches/py3k/Lib/lib2to3/fixes/util.py
==============================================================================
--- python/branches/py3k/Lib/lib2to3/fixes/util.py	Sun Jun 15 04:57:40 2008
+++ (empty file)
@@ -1,366 +0,0 @@
-"""Utility functions, node construction macros, etc."""
-# Author: Collin Winter
-
-# Local imports
-from ..pgen2 import token
-from ..pytree import Leaf, Node
-from ..pygram import python_symbols as syms
-from .. import patcomp
-
-
-###########################################################
-### Common node-construction "macros"
-###########################################################
-
-def KeywordArg(keyword, value):
-    return Node(syms.argument,
-                [keyword, Leaf(token.EQUAL, '='), value])
-
-def LParen():
-    return Leaf(token.LPAR, "(")
-
-def RParen():
-    return Leaf(token.RPAR, ")")
-
-def Assign(target, source):
-    """Build an assignment statement"""
-    if not isinstance(target, list):
-        target = [target]
-    if not isinstance(source, list):
-        source.set_prefix(" ")
-        source = [source]
-
-    return Node(syms.atom,
-                target + [Leaf(token.EQUAL, "=", prefix=" ")] + source)
-
-def Name(name, prefix=None):
-    """Return a NAME leaf"""
-    return Leaf(token.NAME, name, prefix=prefix)
-
-def Attr(obj, attr):
-    """A node tuple for obj.attr"""
-    return [obj, Node(syms.trailer, [Dot(), attr])]
-
-def Comma():
-    """A comma leaf"""
-    return Leaf(token.COMMA, ",")
-
-def Dot():
-    """A period (.) leaf"""
-    return Leaf(token.DOT, ".")
-
-def ArgList(args, lparen=LParen(), rparen=RParen()):
-    """A parenthesised argument list, used by Call()"""
-    return Node(syms.trailer,
-                [lparen.clone(),
-                 Node(syms.arglist, args),
-                 rparen.clone()])
-
-def Call(func_name, args, prefix=None):
-    """A function call"""
-    node = Node(syms.power, [func_name, ArgList(args)])
-    if prefix is not None:
-        node.set_prefix(prefix)
-    return node
-
-def Newline():
-    """A newline literal"""
-    return Leaf(token.NEWLINE, "\n")
-
-def BlankLine():
-    """A blank line"""
-    return Leaf(token.NEWLINE, "")
-
-def Number(n, prefix=None):
-    return Leaf(token.NUMBER, n, prefix=prefix)
-
-def Subscript(index_node):
-    """A numeric or string subscript"""
-    return Node(syms.trailer, [Leaf(token.LBRACE, '['),
-                               index_node,
-                               Leaf(token.RBRACE, ']')])
-
-def String(string, prefix=None):
-    """A string leaf"""
-    return Leaf(token.STRING, string, prefix=prefix)
-
-def ListComp(xp, fp, it, test=None):
-    """A list comprehension of the form [xp for fp in it if test].
-
-    If test is None, the "if test" part is omitted.
-    """
-    xp.set_prefix("")
-    fp.set_prefix(" ")
-    it.set_prefix(" ")
-    for_leaf = Leaf(token.NAME, "for")
-    for_leaf.set_prefix(" ")
-    in_leaf = Leaf(token.NAME, "in")
-    in_leaf.set_prefix(" ")
-    inner_args = [for_leaf, fp, in_leaf, it]
-    if test:
-        test.set_prefix(" ")
-        if_leaf = Leaf(token.NAME, "if")
-        if_leaf.set_prefix(" ")
-        inner_args.append(Node(syms.comp_if, [if_leaf, test]))
-    inner = Node(syms.listmaker, [xp, Node(syms.comp_for, inner_args)])
-    return Node(syms.atom,
-                       [Leaf(token.LBRACE, "["),
-                        inner,
-                        Leaf(token.RBRACE, "]")])
-
-def FromImport(package_name, name_leafs):
-    """ Return an import statement in the form:
-        from package import name_leafs"""
-    # XXX: May not handle dotted imports properly (eg, package_name='foo.bar')
-    assert package_name == '.' or '.' not in package.name, "FromImport has "\
-           "not been tested with dotted package names -- use at your own "\
-           "peril!"
-
-    for leaf in name_leafs:
-        # Pull the leaves out of their old tree
-        leaf.remove()
-
-    children = [Leaf(token.NAME, 'from'),
-                Leaf(token.NAME, package_name, prefix=" "),
-                Leaf(token.NAME, 'import', prefix=" "),
-                Node(syms.import_as_names, name_leafs)]
-    imp = Node(syms.import_from, children)
-    return imp
-
-
-###########################################################
-### Determine whether a node represents a given literal
-###########################################################
-
-def is_tuple(node):
-    """Does the node represent a tuple literal?"""
-    if isinstance(node, Node) and node.children == [LParen(), RParen()]:
-        return True
-    return (isinstance(node, Node)
-            and len(node.children) == 3
-            and isinstance(node.children[0], Leaf)
-            and isinstance(node.children[1], Node)
-            and isinstance(node.children[2], Leaf)
-            and node.children[0].value == "("
-            and node.children[2].value == ")")
-
-def is_list(node):
-    """Does the node represent a list literal?"""
-    return (isinstance(node, Node)
-            and len(node.children) > 1
-            and isinstance(node.children[0], Leaf)
-            and isinstance(node.children[-1], Leaf)
-            and node.children[0].value == "["
-            and node.children[-1].value == "]")
-
-###########################################################
-### Common portability code. This allows fixers to do, eg,
-###  "from .util import set" and forget about it.
-###########################################################
-
-try:
-    any = any
-except NameError:
-    def any(l):
-        for o in l:
-            if o:
-                return True
-        return False
-
-try:
-    set = set
-except NameError:
-    from sets import Set as set
-
-try:
-    reversed = reversed
-except NameError:
-    def reversed(l):
-        return l[::-1]
-
-###########################################################
-### Misc
-###########################################################
-
-
-consuming_calls = set(["sorted", "list", "set", "any", "all", "tuple", "sum",
-                       "min", "max"])
-
-def attr_chain(obj, attr):
-    """Follow an attribute chain.
-
-    If you have a chain of objects where a.foo -> b, b.foo-> c, etc,
-    use this to iterate over all objects in the chain. Iteration is
-    terminated by getattr(x, attr) is None.
-
-    Args:
-        obj: the starting object
-        attr: the name of the chaining attribute
-
-    Yields:
-        Each successive object in the chain.
-    """
-    next = getattr(obj, attr)
-    while next:
-        yield next
-        next = getattr(next, attr)
-
-p0 = """for_stmt< 'for' any 'in' node=any ':' any* >
-        | comp_for< 'for' any 'in' node=any any* >
-     """
-p1 = """
-power<
-    ( 'iter' | 'list' | 'tuple' | 'sorted' | 'set' | 'sum' |
-      'any' | 'all' | (any* trailer< '.' 'join' >) )
-    trailer< '(' node=any ')' >
-    any*
->
-"""
-p2 = """
-power<
-    'sorted'
-    trailer< '(' arglist<node=any any*> ')' >
-    any*
->
-"""
-pats_built = False
-def in_special_context(node):
-    """ Returns true if node is in an environment where all that is required
-        of it is being itterable (ie, it doesn't matter if it returns a list
-        or an itterator).
-        See test_map_nochange in test_fixers.py for some examples and tests.
-        """
-    global p0, p1, p2, pats_built
-    if not pats_built:
-        p1 = patcomp.compile_pattern(p1)
-        p0 = patcomp.compile_pattern(p0)
-        p2 = patcomp.compile_pattern(p2)
-        pats_built = True
-    patterns = [p0, p1, p2]
-    for pattern, parent in zip(patterns, attr_chain(node, "parent")):
-        results = {}
-        if pattern.match(parent, results) and results["node"] is node:
-            return True
-    return False
-
-###########################################################
-### The following functions are to find bindings in a suite
-###########################################################
-
-def make_suite(node):
-    if node.type == syms.suite:
-        return node
-    node = node.clone()
-    parent, node.parent = node.parent, None
-    suite = Node(syms.suite, [node])
-    suite.parent = parent
-    return suite
-
-def does_tree_import(package, name, node):
-    """ Returns true if name is imported from package at the
-        top level of the tree which node belongs to.
-        To cover the case of an import like 'import foo', use
-        Null for the package and 'foo' for the name. """
-    # Scamper up to the top level namespace
-    while node.type != syms.file_input:
-        assert node.parent, "Tree is insane! root found before "\
-                           "file_input node was found."
-        node = node.parent
-
-    binding = find_binding(name, node, package)
-    return bool(binding)
-
-_def_syms = set([syms.classdef, syms.funcdef])
-def find_binding(name, node, package=None):
-    """ Returns the node which binds variable name, otherwise None.
-        If optional argument package is supplied, only imports will
-        be returned.
-        See test cases for examples."""
-    for child in node.children:
-        ret = None
-        if child.type == syms.for_stmt:
-            if _find(name, child.children[1]):
-                return child
-            n = find_binding(name, make_suite(child.children[-1]), package)
-            if n: ret = n
-        elif child.type in (syms.if_stmt, syms.while_stmt):
-            n = find_binding(name, make_suite(child.children[-1]), package)
-            if n: ret = n
-        elif child.type == syms.try_stmt:
-            n = find_binding(name, make_suite(child.children[2]), package)
-            if n:
-                ret = n
-            else:
-                for i, kid in enumerate(child.children[3:]):
-                    if kid.type == token.COLON and kid.value == ":":
-                        # i+3 is the colon, i+4 is the suite
-                        n = find_binding(name, make_suite(child.children[i+4]), package)
-                        if n: ret = n
-        elif child.type in _def_syms and child.children[1].value == name:
-            ret = child
-        elif _is_import_binding(child, name, package):
-            ret = child
-        elif child.type == syms.simple_stmt:
-            ret = find_binding(name, child, package)
-        elif child.type == syms.expr_stmt:
-            if _find(name, child.children[0]):
-                ret = child
-
-        if ret:
-            if not package:
-                return ret
-            if ret.type in (syms.import_name, syms.import_from):
-                return ret
-    return None
-
-_block_syms = set([syms.funcdef, syms.classdef, syms.trailer])
-def _find(name, node):
-    nodes = [node]
-    while nodes:
-        node = nodes.pop()
-        if node.type > 256 and node.type not in _block_syms:
-            nodes.extend(node.children)
-        elif node.type == token.NAME and node.value == name:
-            return node
-    return None
-
-def _is_import_binding(node, name, package=None):
-    """ Will reuturn node if node will import name, or node
-        will import * from package.  None is returned otherwise.
-        See test cases for examples. """
-
-    if node.type == syms.import_name and not package:
-        imp = node.children[1]
-        if imp.type == syms.dotted_as_names:
-            for child in imp.children:
-                if child.type == syms.dotted_as_name:
-                    if child.children[2].value == name:
-                        return node
-                elif child.type == token.NAME and child.value == name:
-                    return node
-        elif imp.type == syms.dotted_as_name:
-            last = imp.children[-1]
-            if last.type == token.NAME and last.value == name:
-                return node
-        elif imp.type == token.NAME and imp.value == name:
-            return node
-    elif node.type == syms.import_from:
-        # unicode(...) is used to make life easier here, because
-        # from a.b import parses to ['import', ['a', '.', 'b'], ...]
-        if package and str(node.children[1]).strip() != package:
-            return None
-        n = node.children[3]
-        if package and _find('as', n):
-            # See test_from_import_as for explanation
-            return None
-        elif n.type == syms.import_as_names and _find(name, n):
-            return node
-        elif n.type == syms.import_as_name:
-            child = n.children[2]
-            if child.type == token.NAME and child.value == name:
-                return node
-        elif n.type == token.NAME and n.value == name:
-            return node
-        elif package and n.type == token.STAR:
-            return node
-    return None

Modified: python/branches/py3k/Lib/lib2to3/refactor.py
==============================================================================
--- python/branches/py3k/Lib/lib2to3/refactor.py	(original)
+++ python/branches/py3k/Lib/lib2to3/refactor.py	Sun Jun 15 04:57:40 2008
@@ -30,11 +30,13 @@
 from . import fixes
 from . import pygram
 
-def main(args=None):
+def main(fixer_dir, args=None):
     """Main program.
 
-    Call without arguments to use sys.argv[1:] as the arguments; or
-    call with a list of arguments (excluding sys.argv[0]).
+    Args:
+        fixer_dir: directory where fixer modules are located.
+        args: optional; a list of command line arguments. If omitted,
+              sys.argv[1:] is used.
 
     Returns a suggested exit status (0, 1, 2).
     """
@@ -57,7 +59,7 @@
     options, args = parser.parse_args(args)
     if options.list_fixes:
         print("Available transformations for the -f/--fix option:")
-        for fixname in get_all_fix_names():
+        for fixname in get_all_fix_names(fixer_dir):
             print(fixname)
         if not args:
             return 0
@@ -76,7 +78,7 @@
         logging.basicConfig(format='%(name)s: %(message)s', level=logging.INFO)
 
     # Initialize the refactoring tool
-    rt = RefactoringTool(options)
+    rt = RefactoringTool(fixer_dir, options)
 
     # Refactor all files and directories passed as arguments
     if not rt.errors:
@@ -87,10 +89,10 @@
     return int(bool(rt.errors))
 
 
-def get_all_fix_names():
+def get_all_fix_names(fixer_dir):
     """Return a sorted list of all available fix names."""
     fix_names = []
-    names = os.listdir(os.path.dirname(fixes.__file__))
+    names = os.listdir(fixer_dir)
     names.sort()
     for name in names:
         if name.startswith("fix_") and name.endswith(".py"):
@@ -138,11 +140,14 @@
 
 class RefactoringTool(object):
 
-    def __init__(self, options):
+    def __init__(self, fixer_dir, options):
         """Initializer.
 
-        The argument is an optparse.Values instance.
+        Args:
+            fixer_dir: directory in which to find fixer modules.
+            options: an optparse.Values instance.
         """
+        self.fixer_dir = fixer_dir
         self.options = options
         self.errors = []
         self.logger = logging.getLogger("RefactoringTool")
@@ -167,14 +172,15 @@
           want a pre-order AST traversal, and post_order is the list that want
           post-order traversal.
         """
+        fixer_pkg = ".".join(self.fixer_dir.split(os.path.sep))
         pre_order_fixers = []
         post_order_fixers = []
         fix_names = self.options.fix
         if not fix_names or "all" in fix_names:
-            fix_names = get_all_fix_names()
+            fix_names = get_all_fix_names(self.fixer_dir)
         for fix_name in fix_names:
             try:
-                mod = __import__("lib2to3.fixes.fix_" + fix_name, {}, {}, ["*"])
+                mod = __import__(fixer_pkg + ".fix_" + fix_name, {}, {}, ["*"])
             except ImportError:
                 self.log_error("Can't find transformation %s", fix_name)
                 continue

Modified: python/branches/py3k/Lib/lib2to3/tests/test_all_fixers.py
==============================================================================
--- python/branches/py3k/Lib/lib2to3/tests/test_all_fixers.py	(original)
+++ python/branches/py3k/Lib/lib2to3/tests/test_all_fixers.py	Sun Jun 15 04:57:40 2008
@@ -29,7 +29,7 @@
     def setUp(self):
         options = Options(fix=["all", "idioms", "ws_comma", "buffer"],
                           print_function=False)
-        self.refactor = refactor.RefactoringTool(options)
+        self.refactor = refactor.RefactoringTool("lib2to3/fixes", options)
 
     def test_all_project_files(self):
         for filepath in support.all_project_files():

Modified: python/branches/py3k/Lib/lib2to3/tests/test_fixers.py
==============================================================================
--- python/branches/py3k/Lib/lib2to3/tests/test_fixers.py	(original)
+++ python/branches/py3k/Lib/lib2to3/tests/test_fixers.py	Sun Jun 15 04:57:40 2008
@@ -10,13 +10,14 @@
 
 # Python imports
 import unittest
+from itertools import chain
 from os.path import dirname, pathsep
 
 # Local imports
 from .. import pygram
 from .. import pytree
 from .. import refactor
-from ..fixes import util
+from .. import fixer_util
 
 
 class Options:
@@ -29,11 +30,10 @@
 class FixerTestCase(support.TestCase):
     def setUp(self):
         options = Options(fix=[self.fixer], print_function=False)
-        self.refactor = refactor.RefactoringTool(options)
+        self.refactor = refactor.RefactoringTool("lib2to3/fixes", options)
         self.fixer_log = []
         self.filename = "<string>"
 
-        from itertools import chain
         for order in (self.refactor.pre_order.values(),\
                       self.refactor.post_order.values()):
             for fixer in chain(*order):
@@ -70,7 +70,7 @@
         fix = [self.fixer]
         fix.extend(names)
         options = Options(fix=fix, print_function=False)
-        r = refactor.RefactoringTool(options)
+        r = refactor.RefactoringTool("lib2to3/fixes", options)
         (pre, post) = r.get_fixers()
         n = "fix_" + self.fixer
         if post and post[-1].__class__.__module__.endswith(n):
@@ -1109,7 +1109,7 @@
         self.check(b, a)
 
     def test_unchanged(self):
-        for wrapper in util.consuming_calls:
+        for wrapper in fixer_util.consuming_calls:
             s = "s = %s(d.keys())" % wrapper
             self.unchanged(s)
 
@@ -1302,7 +1302,7 @@
         self.unchanged("x in range(10, 3, 9)")
 
     def test_in_consuming_context(self):
-        for call in util.consuming_calls:
+        for call in fixer_util.consuming_calls:
             self.unchanged("a = %s(range(10))" % call)
 
 class Test_raw_input(FixerTestCase):

Modified: python/branches/py3k/Lib/lib2to3/tests/test_util.py
==============================================================================
--- python/branches/py3k/Lib/lib2to3/tests/test_util.py	(original)
+++ python/branches/py3k/Lib/lib2to3/tests/test_util.py	Sun Jun 15 04:57:40 2008
@@ -10,7 +10,8 @@
 
 # Local imports
 from .. import pytree
-from ..fixes import util
+from .. import fixer_util
+from ..fixer_util import Attr, Name
 
 
 def parse(code, strip_levels=0):
@@ -25,13 +26,13 @@
 class MacroTestCase(support.TestCase):
     def assertStr(self, node, string):
         if isinstance(node, (tuple, list)):
-            node = pytree.Node(util.syms.simple_stmt, node)
+            node = pytree.Node(fixer_util.syms.simple_stmt, node)
         self.assertEqual(str(node), string)
 
 
 class Test_is_tuple(support.TestCase):
     def is_tuple(self, string):
-        return util.is_tuple(parse(string, strip_levels=2))
+        return fixer_util.is_tuple(parse(string, strip_levels=2))
 
     def test_valid(self):
         self.failUnless(self.is_tuple("(a, b)"))
@@ -47,7 +48,7 @@
 
 class Test_is_list(support.TestCase):
     def is_list(self, string):
-        return util.is_list(parse(string, strip_levels=2))
+        return fixer_util.is_list(parse(string, strip_levels=2))
 
     def test_valid(self):
         self.failUnless(self.is_list("[]"))
@@ -62,23 +63,18 @@
 
 class Test_Attr(MacroTestCase):
     def test(self):
-        from ..fixes.util import Attr, Name
         call = parse("foo()", strip_levels=2)
 
         self.assertStr(Attr(Name("a"), Name("b")), "a.b")
         self.assertStr(Attr(call, Name("b")), "foo().b")
 
     def test_returns(self):
-        from ..fixes.util import Attr, Name
-
         attr = Attr(Name("a"), Name("b"))
         self.assertEqual(type(attr), list)
 
 
 class Test_Name(MacroTestCase):
     def test(self):
-        from ..fixes.util import Name
-
         self.assertStr(Name("a"), "a")
         self.assertStr(Name("foo.foo().bar"), "foo.foo().bar")
         self.assertStr(Name("a", prefix="b"), "ba")
@@ -88,7 +84,7 @@
     def _find_bind_rec(self, name, node):
         # Search a tree for a binding -- used to find the starting
         # point for these tests.
-        c = util.find_binding(name, node)
+        c = fixer_util.find_binding(name, node)
         if c: return c
         for child in node.children:
             c = self._find_bind_rec(name, child)
@@ -98,7 +94,7 @@
         node = parse(string)
         # Find the binding of start -- that's what we'll go from
         node = self._find_bind_rec('start', node)
-        return util.does_tree_import(package, name, node)
+        return fixer_util.does_tree_import(package, name, node)
 
     def try_with(self, string):
         failing_tests = (("a", "a", "from a import b"),
@@ -130,7 +126,7 @@
 
 class Test_find_binding(support.TestCase):
     def find_binding(self, name, string, package=None):
-        return util.find_binding(name, parse(string), package)
+        return fixer_util.find_binding(name, parse(string), package)
 
     def test_simple_assignment(self):
         self.failUnless(self.find_binding("a", "a = b"))

From python-3000-checkins at python.org  Sun Jun 15 22:09:12 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Sun, 15 Jun 2008 22:09:12 +0200 (CEST)
Subject: [Python-3000-checkins] r64302 - in python/branches/py3k:
	Lib/test/test_exceptions.py Python/ceval.c
Message-ID: <20080615200912.A33451E400A@bag.python.org>

Author: benjamin.peterson
Date: Sun Jun 15 22:09:12 2008
New Revision: 64302

Log:
improvements to the fix for #3114

keep the tstate consistent and a better test


Modified:
   python/branches/py3k/Lib/test/test_exceptions.py
   python/branches/py3k/Python/ceval.c

Modified: python/branches/py3k/Lib/test/test_exceptions.py
==============================================================================
--- python/branches/py3k/Lib/test/test_exceptions.py	(original)
+++ python/branches/py3k/Lib/test/test_exceptions.py	Sun Jun 15 22:09:12 2008
@@ -5,8 +5,6 @@
 import unittest
 import pickle
 import weakref
-import gc
-import traceback
 
 from test.support import TESTFN, unlink, run_unittest
 
@@ -553,9 +551,9 @@
             del g
             self.assertEquals(sys.exc_info()[0], TypeError)
 
-    def test_crash_3114(self):
-        # Bug #3114: in its destructor, MyObject retrieves a pointer to a
-        # deallocated exception instance or traceback.
+    def test_3114(self):
+        # Bug #3114: in its destructor, MyObject retrieves a pointer to
+        # obsolete and/or deallocated objects.
         class MyObject:
             def __del__(self):
                 nonlocal e
@@ -565,10 +563,7 @@
             raise Exception(MyObject())
         except:
             pass
-        gc.collect()
-        [0]*10000
-        # Do something with the exception and its traceback
-        traceback.format_exception(*e)
+        self.assertEquals(e, (None, None, None))
 
 def test_main():
     run_unittest(ExceptionTests)

Modified: python/branches/py3k/Python/ceval.c
==============================================================================
--- python/branches/py3k/Python/ceval.c	(original)
+++ python/branches/py3k/Python/ceval.c	Sun Jun 15 22:09:12 2008
@@ -699,29 +699,39 @@
 	}
 
 #define UNWIND_EXCEPT_HANDLER(b) \
-	assert(STACK_LEVEL() >= (b)->b_level + 3); \
-	while (STACK_LEVEL() > (b)->b_level + 3) { \
-		PyObject *v = POP(); \
-		Py_XDECREF(v); \
-	} \
-	Py_CLEAR(tstate->exc_type); \
-	Py_CLEAR(tstate->exc_value); \
-	Py_CLEAR(tstate->exc_traceback); \
-	tstate->exc_type = POP(); \
-	tstate->exc_value = POP(); \
-	tstate->exc_traceback = POP();
+	{ \
+		PyObject *type, *value, *traceback; \
+		assert(STACK_LEVEL() >= (b)->b_level + 3); \
+		while (STACK_LEVEL() > (b)->b_level + 3) { \
+			value = POP(); \
+			Py_XDECREF(value); \
+		} \
+		type = tstate->exc_type; \
+		value = tstate->exc_value; \
+		traceback = tstate->exc_traceback; \
+		tstate->exc_type = POP(); \
+		tstate->exc_value = POP(); \
+		tstate->exc_traceback = POP(); \
+		Py_XDECREF(type); \
+		Py_XDECREF(value); \
+		Py_XDECREF(traceback); \
+	}
 
 #define SAVE_EXC_STATE() \
 	{ \
+		PyObject *type, *value, *traceback; \
 		Py_XINCREF(tstate->exc_type); \
 		Py_XINCREF(tstate->exc_value); \
 		Py_XINCREF(tstate->exc_traceback); \
-		Py_CLEAR(f->f_exc_type); \
-		Py_CLEAR(f->f_exc_value); \
-		Py_CLEAR(f->f_exc_traceback); \
+		type = f->f_exc_type; \
+		value = f->f_exc_value; \
+		traceback = f->f_exc_traceback; \
 		f->f_exc_type = tstate->exc_type; \
 		f->f_exc_value = tstate->exc_value; \
 		f->f_exc_traceback = tstate->exc_traceback; \
+		Py_XDECREF(type); \
+		Py_XDECREF(value); \
+		Py_XDECREF(traceback); \
 	}
 
 #define SWAP_EXC_STATE() \

From python-3000-checkins at python.org  Mon Jun 16 21:50:09 2008
From: python-3000-checkins at python.org (amaury.forgeotdarc)
Date: Mon, 16 Jun 2008 21:50:09 +0200 (CEST)
Subject: [Python-3000-checkins] r64311 - in python/branches/py3k:
	Lib/test/test_weakref.py Misc/NEWS Objects/weakrefobject.c
Message-ID: <20080616195010.07D201E400C@bag.python.org>

Author: amaury.forgeotdarc
Date: Mon Jun 16 21:50:09 2008
New Revision: 64311

Log:
Merged revisions 64309 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/trunk

........
  r64309 | amaury.forgeotdarc | 2008-06-16 21:12:42 +0200 (lun., 16 juin 2008) | 8 lines
  
  Issue 3110: Crash with weakref subclass, 
  seen after a "import multiprocessing.reduction"
  
  An instance of a weakref subclass can have attributes.
  If such a weakref holds the only strong reference to the object,
  deleting the weakref will delete the object. In this case,
  the callback must not be called, because the ref object is being deleted!
........


Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Lib/test/test_weakref.py
   python/branches/py3k/Misc/NEWS
   python/branches/py3k/Objects/weakrefobject.c

Modified: python/branches/py3k/Lib/test/test_weakref.py
==============================================================================
--- python/branches/py3k/Lib/test/test_weakref.py	(original)
+++ python/branches/py3k/Lib/test/test_weakref.py	Mon Jun 16 21:50:09 2008
@@ -661,7 +661,7 @@
         w = Target()
 
 
-class SubclassableWeakrefTestCase(unittest.TestCase):
+class SubclassableWeakrefTestCase(TestBase):
 
     def test_subclass_refs(self):
         class MyRef(weakref.ref):
@@ -725,6 +725,44 @@
         self.assertEqual(r.meth(), "abcdef")
         self.failIf(hasattr(r, "__dict__"))
 
+    def test_subclass_refs_with_cycle(self):
+        # Bug #3110
+        # An instance of a weakref subclass can have attributes.
+        # If such a weakref holds the only strong reference to the object,
+        # deleting the weakref will delete the object. In this case,
+        # the callback must not be called, because the ref object is
+        # being deleted.
+        class MyRef(weakref.ref):
+            pass
+
+        # Use a local callback, for "regrtest -R::"
+        # to detect refcounting problems
+        def callback(w):
+            self.cbcalled += 1
+
+        o = C()
+        r1 = MyRef(o, callback)
+        r1.o = o
+        del o
+
+        del r1 # Used to crash here
+
+        self.assertEqual(self.cbcalled, 0)
+
+        # Same test, with two weakrefs to the same object
+        # (since code paths are different)
+        o = C()
+        r1 = MyRef(o, callback)
+        r2 = MyRef(o, callback)
+        r1.r = r2
+        r2.o = o
+        del o
+        del r2
+
+        del r1 # Used to crash here
+
+        self.assertEqual(self.cbcalled, 0)
+
 
 class Object:
     def __init__(self, arg):
@@ -1171,6 +1209,7 @@
         MappingTestCase,
         WeakValueDictionaryTestCase,
         WeakKeyDictionaryTestCase,
+        SubclassableWeakrefTestCase,
         )
     support.run_doctest(sys.modules[__name__])
 

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Mon Jun 16 21:50:09 2008
@@ -12,6 +12,9 @@
 Core and Builtins
 -----------------
 
+- Issue #3100: Corrected a crash on deallocation of a subclassed weakref which
+  holds the last (strong) reference to its referent.
+
 - Issue #2630: implement PEP 3138. repr() now returns printable
   Unicode characters unescaped, to get an ASCII-only representation
   of an object use ascii().

Modified: python/branches/py3k/Objects/weakrefobject.c
==============================================================================
--- python/branches/py3k/Objects/weakrefobject.c	(original)
+++ python/branches/py3k/Objects/weakrefobject.c	Mon Jun 16 21:50:09 2008
@@ -884,7 +884,8 @@
             current->wr_callback = NULL;
             clear_weakref(current);
             if (callback != NULL) {
-                handle_callback(current, callback);
+                if (current->ob_refcnt > 0)
+                    handle_callback(current, callback);
                 Py_DECREF(callback);
             }
         }
@@ -902,9 +903,15 @@
             for (i = 0; i < count; ++i) {
                 PyWeakReference *next = current->wr_next;
 
-                Py_INCREF(current);
-                PyTuple_SET_ITEM(tuple, i * 2, (PyObject *) current);
-                PyTuple_SET_ITEM(tuple, i * 2 + 1, current->wr_callback);
+                if (current->ob_refcnt > 0)
+                {
+                    Py_INCREF(current);
+                    PyTuple_SET_ITEM(tuple, i * 2, (PyObject *) current);
+                    PyTuple_SET_ITEM(tuple, i * 2 + 1, current->wr_callback);
+                }
+                else {
+                    Py_DECREF(current->wr_callback);
+                }
                 current->wr_callback = NULL;
                 clear_weakref(current);
                 current = next;
@@ -912,6 +919,7 @@
             for (i = 0; i < count; ++i) {
                 PyObject *callback = PyTuple_GET_ITEM(tuple, i * 2 + 1);
 
+                /* The tuple may have slots left to NULL */
                 if (callback != NULL) {
                     PyObject *item = PyTuple_GET_ITEM(tuple, i * 2);
                     handle_callback((PyWeakReference *)item, callback);

From python-3000-checkins at python.org  Mon Jun 16 21:56:33 2008
From: python-3000-checkins at python.org (thomas.heller)
Date: Mon, 16 Jun 2008 21:56:33 +0200 (CEST)
Subject: [Python-3000-checkins] r64312 - in python/branches/py3k:
	Doc/library/ctypes.rst
Message-ID: <20080616195633.E68F31E4003@bag.python.org>

Author: thomas.heller
Date: Mon Jun 16 21:56:33 2008
New Revision: 64312

Log:
Merged revisions 64131,64134-64141,64143-64146 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/trunk

........
  r64131 | thomas.heller | 2008-06-11 19:58:19 +0200 (Wed, 11 Jun 2008) | 1 line
  
  Markup fixes, spelling corrections, and better wordings. Hopefully.
........
  r64135 | thomas.heller | 2008-06-11 20:10:43 +0200 (Wed, 11 Jun 2008) | 1 line
  
  More doc fixes.
........
  r64139 | thomas.heller | 2008-06-11 20:40:51 +0200 (Wed, 11 Jun 2008) | 1 line
  
  Smaller doc fixes.
........
  r64143 | thomas.heller | 2008-06-11 21:10:22 +0200 (Wed, 11 Jun 2008) | 1 line
  
  Add versionadded marker to ctypes.c_longdouble.
........
  r64146 | thomas.heller | 2008-06-11 21:58:22 +0200 (Wed, 11 Jun 2008) | 2 lines
  
  Markup fixes, thanks Georg for the help.
  Document ctypes.util.find_library() and ctypes.util.find_msvcrt().
........


Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Doc/library/ctypes.rst

Modified: python/branches/py3k/Doc/library/ctypes.rst
==============================================================================
--- python/branches/py3k/Doc/library/ctypes.rst	(original)
+++ python/branches/py3k/Doc/library/ctypes.rst	Mon Jun 16 21:56:33 2008
@@ -40,7 +40,7 @@
 convention, while *windll* libraries call functions using the ``stdcall``
 calling convention. *oledll* also uses the ``stdcall`` calling convention, and
 assumes the functions return a Windows :class:`HRESULT` error code. The error
-code is used to automatically raise :class:`WindowsError` Python exceptions when
+code is used to automatically raise a :class:`WindowsError` exception when
 the function call fails.
 
 Here are some examples for Windows. Note that ``msvcrt`` is the MS standard C
@@ -55,10 +55,10 @@
    >>> libc = cdll.msvcrt # doctest: +WINDOWS
    >>>
 
-Windows appends the usual '.dll' file suffix automatically.
+Windows appends the usual ``.dll`` file suffix automatically.
 
 On Linux, it is required to specify the filename *including* the extension to
-load a library, so attribute access does not work. Either the
+load a library, so attribute access can not be used to load libraries. Either the
 :meth:`LoadLibrary` method of the dll loaders should be used, or you should load
 the library by creating an instance of CDLL by calling the constructor::
 
@@ -107,7 +107,7 @@
 
 *windll* does not try to select one of them by magic, you must access the
 version you need by specifying ``GetModuleHandleA`` or ``GetModuleHandleW``
-explicitly, and then call it with normal strings or unicode strings
+explicitly, and then call it with strings or unicode strings
 respectively.
 
 Sometimes, dlls export functions with names which aren't valid Python
@@ -422,9 +422,9 @@
 in the :attr:`argtypes` sequence. The :meth:`from_param` class method receives
 the Python object passed to the function call, it should do a typecheck or
 whatever is needed to make sure this object is acceptable, and then return the
-object itself, it's :attr:`_as_parameter_` attribute, or whatever you want to
+object itself, its :attr:`_as_parameter_` attribute, or whatever you want to
 pass as the C function argument in this case. Again, the result should be an
-integer, string, unicode, a ``ctypes`` instance, or something having the
+integer, string, unicode, a ``ctypes`` instance, or an object with an
 :attr:`_as_parameter_` attribute.
 
 
@@ -719,6 +719,8 @@
    c_long(99)
    >>>
 
+.. XXX Document dereferencing pointers, and that it is preferred over the .contents attribute.
+
 Pointer instances can also be indexed with integers::
 
    >>> pi[0]
@@ -765,7 +767,7 @@
    >>>
 
 ``ctypes`` checks for ``NULL`` when dereferencing pointers (but dereferencing
-non-\ ``NULL`` pointers would crash Python)::
+invalid non-\ ``NULL`` pointers would crash Python)::
 
    >>> null_ptr[0]
    Traceback (most recent call last):
@@ -811,9 +813,9 @@
    >>> bar.values = None
    >>>
 
-XXX list other conversions...
+.. XXX list other conversions...
 
-Sometimes you have instances of incompatible types.  In ``C``, you can cast one
+Sometimes you have instances of incompatible types.  In C, you can cast one
 type into another type.  ``ctypes`` provides a ``cast`` function which can be
 used in the same way.  The ``Bar`` structure defined above accepts
 ``POINTER(c_int)`` pointers or :class:`c_int` arrays for its ``values`` field,
@@ -1070,7 +1072,7 @@
 Accessing values exported from dlls
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-Sometimes, a dll not only exports functions, it also exports variables. An
+Some shared libraries not only export functions, they also export variables. An
 example in the Python library itself is the ``Py_OptimizeFlag``, an integer set
 to 0, 1, or 2, depending on the :option:`-O` or :option:`-OO` flag given on
 startup.
@@ -1246,17 +1248,6 @@
 is already known, on a case by case basis.
 
 
-.. _ctypes-bugs-todo-non-implemented-things:
-
-Bugs, ToDo and non-implemented things
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Enumeration types are not implemented. You can do it easily yourself, using
-:class:`c_int` as the base class.
-
-``long double`` is not implemented.
-
-
 .. _ctypes-ctypes-reference:
 
 ctypes reference
@@ -1615,9 +1606,8 @@
    `use_last_error` does the same for the Windows error code.
 
    .. versionchanged:: 2.6
-
-   The optional `use_errno` and `use_last_error` parameters were added
-   in Python 2.6.
+      The optional `use_errno` and `use_last_error` parameters were
+      added.
 
 
 .. function:: WINFUNCTYPE(restype, *argtypes, use_errno=False, use_last_error=False)
@@ -1633,75 +1623,71 @@
    The returned function prototype creates functions that use the Python calling
    convention.  The function will *not* release the GIL during the call.
 
-Function prototypes created by the factory functions can be instantiated in
-different ways, depending on the type and number of the parameters in the call.
-
-
-.. function:: prototype(address)
-   :noindex:
+Function prototypes created by these factory functions can be instantiated in
+different ways, depending on the type and number of the parameters in the call:
 
-   Returns a foreign function at the specified address.
 
+   .. function:: prototype(address)
+      :noindex:
+      :module:
 
-.. function:: prototype(callable)
-   :noindex:
+      Returns a foreign function at the specified address which must be an integer.
 
-   Create a C callable function (a callback function) from a Python ``callable``.
 
+   .. function:: prototype(callable)
+      :noindex:
+      :module:
 
-.. function:: prototype(func_spec[, paramflags])
-   :noindex:
+      Create a C callable function (a callback function) from a Python ``callable``.
 
-   Returns a foreign function exported by a shared library. ``func_spec`` must be a
-   2-tuple ``(name_or_ordinal, library)``. The first item is the name of the
-   exported function as string, or the ordinal of the exported function as small
-   integer.  The second item is the shared library instance.
 
+   .. function:: prototype(func_spec[, paramflags])
+      :noindex:
+      :module:
 
-.. function:: prototype(vtbl_index, name[, paramflags[, iid]])
-   :noindex:
-
-   Returns a foreign function that will call a COM method. ``vtbl_index`` is the
-   index into the virtual function table, a small non-negative integer. *name* is
-   name of the COM method. *iid* is an optional pointer to the interface identifier
-   which is used in extended error reporting.
+      Returns a foreign function exported by a shared library. ``func_spec`` must be a
+      2-tuple ``(name_or_ordinal, library)``. The first item is the name of the
+      exported function as string, or the ordinal of the exported function as small
+      integer.  The second item is the shared library instance.
 
-   COM methods use a special calling convention: They require a pointer to the COM
-   interface as first argument, in addition to those parameters that are specified
-   in the :attr:`argtypes` tuple.
 
-The optional *paramflags* parameter creates foreign function wrappers with much
-more functionality than the features described above.
+   .. function:: prototype(vtbl_index, name[, paramflags[, iid]])
+      :noindex:
+      :module:
 
-*paramflags* must be a tuple of the same length as :attr:`argtypes`.
+      Returns a foreign function that will call a COM method. ``vtbl_index`` is the
+      index into the virtual function table, a small non-negative integer. *name* is
+      name of the COM method. *iid* is an optional pointer to the interface identifier
+      which is used in extended error reporting.
 
-Each item in this tuple contains further information about a parameter, it must
-be a tuple containing 1, 2, or 3 items.
-
-The first item is an integer containing flags for the parameter:
-
-
-.. data:: 1
-   :noindex:
+      COM methods use a special calling convention: They require a pointer to the COM
+      interface as first argument, in addition to those parameters that are specified
+      in the :attr:`argtypes` tuple.
 
-   Specifies an input parameter to the function.
+   The optional *paramflags* parameter creates foreign function wrappers with much
+   more functionality than the features described above.
 
+   *paramflags* must be a tuple of the same length as :attr:`argtypes`.
 
-.. data:: 2
-   :noindex:
+   Each item in this tuple contains further information about a parameter, it must
+   be a tuple containing one, two, or three items.
 
-   Output parameter.  The foreign function fills in a value.
+   The first item is an integer containing a combination of direction
+   flags for the parameter:
 
+      1
+         Specifies an input parameter to the function.
 
-.. data:: 4
-   :noindex:
+      2
+         Output parameter.  The foreign function fills in a value.
 
-   Input parameter which defaults to the integer zero.
+      4
+         Input parameter which defaults to the integer zero.
 
-The optional second item is the parameter name as string.  If this is specified,
-the foreign function can be called with named parameters.
+   The optional second item is the parameter name as string.  If this is specified,
+   the foreign function can be called with named parameters.
 
-The optional third item is the default value for this parameter.
+   The optional third item is the default value for this parameter.
 
 This example demonstrates how to wrap the Windows ``MessageBoxA`` function so
 that it supports default parameters and named arguments. The C declaration from
@@ -1714,16 +1700,14 @@
        LPCSTR lpCaption,
        UINT uType);
 
-Here is the wrapping with ``ctypes``:
-
-   ::
+Here is the wrapping with ``ctypes``::
 
-      >>> from ctypes import c_int, WINFUNCTYPE, windll
-      >>> from ctypes.wintypes import HWND, LPCSTR, UINT
-      >>> prototype = WINFUNCTYPE(c_int, HWND, LPCSTR, LPCSTR, UINT)
-      >>> paramflags = (1, "hwnd", 0), (1, "text", "Hi"), (1, "caption", None), (1, "flags", 0)
-      >>> MessageBox = prototype(("MessageBoxA", windll.user32), paramflags)
-      >>>
+   >>> from ctypes import c_int, WINFUNCTYPE, windll
+   >>> from ctypes.wintypes import HWND, LPCSTR, UINT
+   >>> prototype = WINFUNCTYPE(c_int, HWND, LPCSTR, LPCSTR, UINT)
+   >>> paramflags = (1, "hwnd", 0), (1, "text", "Hi"), (1, "caption", None), (1, "flags", 0)
+   >>> MessageBox = prototype(("MessageBoxA", windll.user32), paramflags)
+   >>>
 
 The MessageBox foreign function can now be called in these ways::
 
@@ -1741,16 +1725,14 @@
         HWND hWnd,
         LPRECT lpRect);
 
-Here is the wrapping with ``ctypes``:
-
-   ::
+Here is the wrapping with ``ctypes``::
 
-      >>> from ctypes import POINTER, WINFUNCTYPE, windll, WinError
-      >>> from ctypes.wintypes import BOOL, HWND, RECT
-      >>> prototype = WINFUNCTYPE(BOOL, HWND, POINTER(RECT))
-      >>> paramflags = (1, "hwnd"), (2, "lprect")
-      >>> GetWindowRect = prototype(("GetWindowRect", windll.user32), paramflags)
-      >>>
+   >>> from ctypes import POINTER, WINFUNCTYPE, windll, WinError
+   >>> from ctypes.wintypes import BOOL, HWND, RECT
+   >>> prototype = WINFUNCTYPE(BOOL, HWND, POINTER(RECT))
+   >>> paramflags = (1, "hwnd"), (2, "lprect")
+   >>> GetWindowRect = prototype(("GetWindowRect", windll.user32), paramflags)
+   >>>
 
 Functions with output parameters will automatically return the output parameter
 value if there is a single one, or a tuple containing the output parameter
@@ -1766,6 +1748,7 @@
    ...     if not result:
    ...         raise WinError()
    ...     return args
+   ...
    >>> GetWindowRect.errcheck = errcheck
    >>>
 
@@ -1780,7 +1763,7 @@
    ...         raise WinError()
    ...     rc = args[1]
    ...     return rc.left, rc.top, rc.bottom, rc.right
-   >>>
+   ...
    >>> GetWindowRect.errcheck = errcheck
    >>>
 
@@ -1866,6 +1849,33 @@
    servers with ctypes. It is called from the DllGetClassObject function that the
    ``_ctypes`` extension dll exports.
 
+.. function:: find_library(name)
+   :module: ctypes.util
+
+   Try to find a library and return a pathname.  `name` is the library name without
+   any prefix like `lib`, suffix like ``.so``, ``.dylib`` or version number (this
+   is the form used for the posix linker option :option:`-l`).  If no library can
+   be found, returns ``None``.
+
+   The exact functionality is system dependent.
+
+   .. versionchanged:: 2.6
+      Windows only: ``find_library("m")`` or
+      ``find_library("c")`` return the result of a call to
+      ``find_msvcrt()``.
+
+.. function:: find_msvcrt()
+   :module: ctypes.util
+
+   Windows only: return the filename of the VC runtype library used
+   by Python, and by the extension modules.  If the name of the
+   library cannot be determined, ``None`` is returned.
+
+   If you need to free memory, for example, allocated by an extension
+   module with a call to the ``free(void *)``, it is important that you
+   use the function in the same library that allocated the memory.
+
+   .. versionadded:: 2.6
 
 .. function:: FormatError([code])
 
@@ -2154,6 +2164,7 @@
    optional float initializer.  On platforms where ``sizeof(long
    double) == sizeof(double)`` it is an alias to :class:`c_double`.
 
+   .. versionadded:: 2.6
 
 .. class:: c_float
 

From python-3000-checkins at python.org  Mon Jun 16 22:23:03 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Mon, 16 Jun 2008 22:23:03 +0200 (CEST)
Subject: [Python-3000-checkins] r64314 - in python/branches/py3k:
	Tools/scripts/2to3
Message-ID: <20080616202303.A3A541E4003@bag.python.org>

Author: benjamin.peterson
Date: Mon Jun 16 22:23:03 2008
New Revision: 64314

Log:
Merged revisions 64313 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/trunk

........
  r64313 | benjamin.peterson | 2008-06-16 15:18:18 -0500 (Mon, 16 Jun 2008) | 1 line
  
  fix Tools/scripts/2to3 as the result of a merge error
........


Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Tools/scripts/2to3

Modified: python/branches/py3k/Tools/scripts/2to3
==============================================================================
--- python/branches/py3k/Tools/scripts/2to3	(original)
+++ python/branches/py3k/Tools/scripts/2to3	Mon Jun 16 22:23:03 2008
@@ -2,4 +2,4 @@
 from lib2to3 import refactor
 import sys
 
-sys.exit(refactor.main())
+sys.exit(refactor.main("lib2to3/fixes"))

From python-3000-checkins at python.org  Mon Jun 16 22:47:12 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Mon, 16 Jun 2008 22:47:12 +0200 (CEST)
Subject: [Python-3000-checkins] r64316 -
	python/branches/py3k/Objects/weakrefobject.c
Message-ID: <20080616204712.C54941E4003@bag.python.org>

Author: benjamin.peterson
Date: Mon Jun 16 22:47:12 2008
New Revision: 64316

Log:
add some casts and fix the build from 64311

Modified:
   python/branches/py3k/Objects/weakrefobject.c

Modified: python/branches/py3k/Objects/weakrefobject.c
==============================================================================
--- python/branches/py3k/Objects/weakrefobject.c	(original)
+++ python/branches/py3k/Objects/weakrefobject.c	Mon Jun 16 22:47:12 2008
@@ -884,7 +884,7 @@
             current->wr_callback = NULL;
             clear_weakref(current);
             if (callback != NULL) {
-                if (current->ob_refcnt > 0)
+                if (((PyObject *)current)->ob_refcnt > 0)
                     handle_callback(current, callback);
                 Py_DECREF(callback);
             }
@@ -903,7 +903,7 @@
             for (i = 0; i < count; ++i) {
                 PyWeakReference *next = current->wr_next;
 
-                if (current->ob_refcnt > 0)
+                if (((PyObject *)current)->ob_refcnt > 0)
                 {
                     Py_INCREF(current);
                     PyTuple_SET_ITEM(tuple, i * 2, (PyObject *) current);

From python-3000-checkins at python.org  Mon Jun 16 22:57:14 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Mon, 16 Jun 2008 22:57:14 +0200 (CEST)
Subject: [Python-3000-checkins] r64318 - in python/branches/py3k:
	Lib/test/test_multiprocessing.py
Message-ID: <20080616205714.B82631E4003@bag.python.org>

Author: benjamin.peterson
Date: Mon Jun 16 22:57:14 2008
New Revision: 64318

Log:
Merged revisions 64317 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/trunk

........
  r64317 | benjamin.peterson | 2008-06-16 15:52:48 -0500 (Mon, 16 Jun 2008) | 1 line
  
  reduce the test_multiprocessing load to ones that shouldn't hang. These will be reenabled gradually as we find the problems.
........


Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Lib/test/test_multiprocessing.py

Modified: python/branches/py3k/Lib/test/test_multiprocessing.py
==============================================================================
--- python/branches/py3k/Lib/test/test_multiprocessing.py	(original)
+++ python/branches/py3k/Lib/test/test_multiprocessing.py	Mon Jun 16 22:57:14 2008
@@ -390,7 +390,7 @@
 
     def _test_get(self, queue, child_can_start, parent_can_continue):
         child_can_start.wait()
-        queue.put(1)
+        #queue.put(1)
         queue.put(2)
         queue.put(3)
         queue.put(4)
@@ -417,7 +417,8 @@
         time.sleep(DELTA)
         self.assertEqual(queue_empty(queue), False)
 
-        self.assertEqual(queue.get(), 1)
+        # Hangs unexpectedly, remove for now
+        #self.assertEqual(queue.get(), 1)
         self.assertEqual(queue.get(True, None), 2)
         self.assertEqual(queue.get(True), 3)
         self.assertEqual(queue.get(timeout=1), 4)
@@ -959,7 +960,7 @@
 def sqr(x, wait=0.0):
     time.sleep(wait)
     return x*x
-
+"""
 class _TestPool(BaseTestCase):
 
     def test_apply(self):
@@ -1029,7 +1030,7 @@
         join = TimingWrapper(self.pool.join)
         join()
         self.assertTrue(join.elapsed < 0.2)
-
+"""
 #
 # Test that manager has expected number of shared objects left
 #
@@ -1356,7 +1357,7 @@
 #
 # Test of sending connection and socket objects between processes
 #
-
+"""
 class _TestPicklingConnections(BaseTestCase):
 
     ALLOWED_TYPES = ('processes',)
@@ -1438,7 +1439,7 @@
 
         lp.join()
         rp.join()
-
+"""
 #
 #
 #
@@ -1761,28 +1762,28 @@
 
     multiprocessing.get_logger().setLevel(LOG_LEVEL)
 
-    ProcessesMixin.pool = multiprocessing.Pool(4)
-    ThreadsMixin.pool = multiprocessing.dummy.Pool(4)
-    ManagerMixin.manager.__init__()
-    ManagerMixin.manager.start()
-    ManagerMixin.pool = ManagerMixin.manager.Pool(4)
+    #ProcessesMixin.pool = multiprocessing.Pool(4)
+    #ThreadsMixin.pool = multiprocessing.dummy.Pool(4)
+    #ManagerMixin.manager.__init__()
+    #ManagerMixin.manager.start()
+    #ManagerMixin.pool = ManagerMixin.manager.Pool(4)
 
     testcases = (
-        sorted(list(testcases_processes.values()), key=lambda tc:tc.__name__) +
-        sorted(list(testcases_threads.values()), key=lambda tc:tc.__name__) +
-        sorted(list(testcases_manager.values()), key=lambda tc:tc.__name__)
+        sorted(testcases_processes.values(), key=lambda tc:tc.__name__) #+
+        #sorted(testcases_threads.values(), key=lambda tc:tc.__name__) +
+        #sorted(testcases_manager.values(), key=lambda tc:tc.__name__)
         )
 
     loadTestsFromTestCase = unittest.defaultTestLoader.loadTestsFromTestCase
     suite = unittest.TestSuite(loadTestsFromTestCase(tc) for tc in testcases)
     run(suite)
 
-    ThreadsMixin.pool.terminate()
-    ProcessesMixin.pool.terminate()
-    ManagerMixin.pool.terminate()
-    ManagerMixin.manager.shutdown()
+    #ThreadsMixin.pool.terminate()
+    #ProcessesMixin.pool.terminate()
+    #ManagerMixin.pool.terminate()
+    #ManagerMixin.manager.shutdown()
 
-    del ProcessesMixin.pool, ThreadsMixin.pool, ManagerMixin.pool
+    #del ProcessesMixin.pool, ThreadsMixin.pool, ManagerMixin.pool
 
 def main():
     test_main(unittest.TextTestRunner(verbosity=2).run)

From python-3000-checkins at python.org  Mon Jun 16 22:58:19 2008
From: python-3000-checkins at python.org (amaury.forgeotdarc)
Date: Mon, 16 Jun 2008 22:58:19 +0200 (CEST)
Subject: [Python-3000-checkins] r64319 - python/branches/py3k
Message-ID: <20080616205819.E69F81E4003@bag.python.org>

Author: amaury.forgeotdarc
Date: Mon Jun 16 22:58:19 2008
New Revision: 64319

Log:
Blocked revisions 63685,64097,64129 via svnmerge

........
  r63685 | christian.heimes | 2008-05-26 15:51:41 +0200 (lun., 26 mai 2008) | 2 lines
  
  Used vs9to8.py to port all VS9.0 changes to 8.0
  Updated VS7.1 and VC6 project files
........
  r64097 | benjamin.peterson | 2008-06-11 00:39:25 +0200 (mer., 11 juin 2008) | 2 lines
  
  backport of 64096
........
  r64129 | georg.brandl | 2008-06-11 19:53:38 +0200 (mer., 11 juin 2008) | 2 lines
  
  Fix typos.
........


Modified:
   python/branches/py3k/   (props changed)

From python-3000-checkins at python.org  Tue Jun 17 14:44:04 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Tue, 17 Jun 2008 14:44:04 +0200 (CEST)
Subject: [Python-3000-checkins] r64340 - in python/branches/py3k:
	Lib/test/test_sys.py
Message-ID: <20080617124404.905021E4004@bag.python.org>

Author: benjamin.peterson
Date: Tue Jun 17 14:44:04 2008
New Revision: 64340

Log:
Merged revisions 64326 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/trunk

........
  r64326 | robert.schuppenies | 2008-06-17 03:42:15 -0500 (Tue, 17 Jun 2008) | 2 lines
  
  Issue 3048: Fixed sys.sizeof test fails with wide unicode.
........


Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Lib/test/test_sys.py

Modified: python/branches/py3k/Lib/test/test_sys.py
==============================================================================
--- python/branches/py3k/Lib/test/test_sys.py	(original)
+++ python/branches/py3k/Lib/test/test_sys.py	Tue Jun 17 14:44:04 2008
@@ -495,8 +495,7 @@
         self.check_sizeof([], h + l + p + l)
         self.check_sizeof([1, 2, 3], h + l + p + l + 3*l)
         # unicode
-        import math
-        usize = math.log(sys.maxunicode + 1, 2) / 8
+        usize = len('\0'.encode('unicode-internal'))
         samples = ['', '1'*100]
         # we need to test for both sizes, because we don't know if the string
         # has been cached

From python-3000-checkins at python.org  Tue Jun 17 14:53:52 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Tue, 17 Jun 2008 14:53:52 +0200 (CEST)
Subject: [Python-3000-checkins] r64341 - python/branches/py3k
Message-ID: <20080617125352.189121E4004@bag.python.org>

Author: benjamin.peterson
Date: Tue Jun 17 14:53:51 2008
New Revision: 64341

Log:
Blocked revisions 64142 via svnmerge

........
  r64142 | georg.brandl | 2008-06-11 13:55:38 -0500 (Wed, 11 Jun 2008) | 2 lines
  
  Add future_builtins.ascii().
........


Modified:
   python/branches/py3k/   (props changed)

From python-3000-checkins at python.org  Tue Jun 17 22:36:04 2008
From: python-3000-checkins at python.org (amaury.forgeotdarc)
Date: Tue, 17 Jun 2008 22:36:04 +0200 (CEST)
Subject: [Python-3000-checkins] r64343 - in python/branches/py3k:
	Doc/library/ast.rst Doc/library/ctypes.rst
	Doc/library/numbers.rst Doc/library/stdtypes.rst
	Include/Python.h Lib/test/test_heapq.py Lib/test/test_set.py
	Lib/test/test_struct.py Modules/_heapqmodule.c Objects/setobject.c
Message-ID: <20080617203604.335F11E4004@bag.python.org>

Author: amaury.forgeotdarc
Date: Tue Jun 17 22:36:03 2008
New Revision: 64343

Log:
Merged revisions 64089,64098,64100-64102,64113,64115-64116,64118,64120,64132,64342 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/trunk

........
  r64089 | armin.ronacher | 2008-06-10 22:37:02 +0200 (mar., 10 juin 2008) | 3 lines
  
  Fix a formatting error in the ast documentation.
........
  r64098 | raymond.hettinger | 2008-06-11 02:25:29 +0200 (mer., 11 juin 2008) | 6 lines
  
  Mini-PEP: Simplifying numbers.py
  * Convert binary methods in Integral to mixin methods
  * Remove three-arg __pow__ as a required method
  * Make __int__ the root method instead of __long__.
........
  r64100 | raymond.hettinger | 2008-06-11 02:28:51 +0200 (mer., 11 juin 2008) | 1 line
  
  Update numbers doc for the Integral simplification.
........
  r64101 | raymond.hettinger | 2008-06-11 02:44:47 +0200 (mer., 11 juin 2008) | 3 lines
  
  Handle the case with zero arguments.
........
  r64102 | benjamin.peterson | 2008-06-11 03:31:28 +0200 (mer., 11 juin 2008) | 4 lines
  
  convert test_struct to a unittest thanks to Giampaolo Rodola
  I had to disable one test because it was functioning incorrectly, see #1530559
  I also removed the debugging prints
........
  r64113 | thomas.heller | 2008-06-11 09:10:43 +0200 (mer., 11 juin 2008) | 2 lines
  
  Fix markup.
  Document the new 'offset' parameter for the 'ctypes.byref' function.
........
  r64115 | raymond.hettinger | 2008-06-11 12:30:54 +0200 (mer., 11 juin 2008) | 1 line
  
  Multi-arg form for set.difference() and set.difference_update().
........
  r64116 | raymond.hettinger | 2008-06-11 14:06:49 +0200 (mer., 11 juin 2008) | 1 line
  
  Issue 3051:  Let heapq work with either __lt__ or __le__.
........
  r64118 | raymond.hettinger | 2008-06-11 14:39:09 +0200 (mer., 11 juin 2008) | 1 line
  
  Optimize previous checkin for heapq.
........
  r64120 | raymond.hettinger | 2008-06-11 15:14:50 +0200 (mer., 11 juin 2008) | 1 line
  
  Add test for heapq using both __lt__ and __le__.
........
  r64132 | gregory.p.smith | 2008-06-11 20:00:52 +0200 (mer., 11 juin 2008) | 3 lines
  
  Correct an incorrect comment about our #include of stddef.h.
  (see Doug Evans' comment on python-dev 2008-06-10)
........
  r64342 | guido.van.rossum | 2008-06-17 19:38:02 +0200 (mar., 17 juin 2008) | 3 lines
  
  Roll back Raymond's -r64098 while we think of something better.
  (See issue 3056 -- we're close to a resolution but need unittests.)
........


Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Doc/library/ast.rst
   python/branches/py3k/Doc/library/ctypes.rst
   python/branches/py3k/Doc/library/numbers.rst
   python/branches/py3k/Doc/library/stdtypes.rst
   python/branches/py3k/Include/Python.h
   python/branches/py3k/Lib/test/test_heapq.py
   python/branches/py3k/Lib/test/test_set.py
   python/branches/py3k/Lib/test/test_struct.py
   python/branches/py3k/Modules/_heapqmodule.c
   python/branches/py3k/Objects/setobject.c

Modified: python/branches/py3k/Doc/library/ast.rst
==============================================================================
--- python/branches/py3k/Doc/library/ast.rst	(original)
+++ python/branches/py3k/Doc/library/ast.rst	Tue Jun 17 22:36:03 2008
@@ -135,7 +135,7 @@
    from untrusted sources without the need to parse the values oneself.
 
 
-.. function:: get_docstring(node, clean=True):
+.. function:: get_docstring(node, clean=True)
 
    Return the docstring of the given *node* (which must be a
    :class:`FunctionDef`, :class:`ClassDef` or :class:`Module` node), or ``None``

Modified: python/branches/py3k/Doc/library/ctypes.rst
==============================================================================
--- python/branches/py3k/Doc/library/ctypes.rst	(original)
+++ python/branches/py3k/Doc/library/ctypes.rst	Tue Jun 17 22:36:03 2008
@@ -1395,11 +1395,6 @@
 to request and change the ctypes private copy of the windows error
 code.
 
-.. versionchanged:: 2.6
-
-The `use_errno` and `use_last_error` parameters were added in Python
-2.6.
-
 .. data:: RTLD_GLOBAL
    :noindex:
 
@@ -1561,22 +1556,23 @@
       Assign a Python function or another callable to this attribute. The
       callable will be called with three or more arguments:
 
+      .. function:: callable(result, func, arguments)
+         :noindex:
 
-.. function:: callable(result, func, arguments)
-   :noindex:
-
-   ``result`` is what the foreign function returns, as specified by the
-   :attr:`restype` attribute.
-
-   ``func`` is the foreign function object itself, this allows to reuse the same
-   callable object to check or post process the results of several functions.
-
-   ``arguments`` is a tuple containing the parameters originally passed to the
-   function call, this allows to specialize the behavior on the arguments used.
+         ``result`` is what the foreign function returns, as specified
+         by the :attr:`restype` attribute.
 
-   The object that this function returns will be returned from the foreign
-   function call, but it can also check the result value and raise an exception
-   if the foreign function call failed.
+         ``func`` is the foreign function object itself, this allows
+         to reuse the same callable object to check or post process
+         the results of several functions.
+
+         ``arguments`` is a tuple containing the parameters originally
+         passed to the function call, this allows to specialize the
+         behavior on the arguments used.
+
+      The object that this function returns will be returned from the
+      foreign function call, but it can also check the result value
+      and raise an exception if the foreign function call failed.
 
 
 .. exception:: ArgumentError()
@@ -1605,10 +1601,6 @@
    variable is exchanged with the real `errno` value bafore and after the call;
    `use_last_error` does the same for the Windows error code.
 
-   .. versionchanged:: 2.6
-      The optional `use_errno` and `use_last_error` parameters were
-      added.
-
 
 .. function:: WINFUNCTYPE(restype, *argtypes, use_errno=False, use_last_error=False)
 
@@ -1786,11 +1778,19 @@
    ctypes type or instance.
 
 
-.. function:: byref(obj)
+.. function:: byref(obj[, offset])
+
+   Returns a light-weight pointer to ``obj``, which must be an
+   instance of a ctypes type.  ``offset`` defaults to zero, it must be
+   an integer which is added to the internal pointer value.
+
+   ``byref(obj, offset)`` corresponds to this C code::
+
+      (((char *)&obj) + offset)
 
-   Returns a light-weight pointer to ``obj``, which must be an instance of a ctypes
-   type. The returned object can only be used as a foreign function call parameter.
-   It behaves similar to ``pointer(obj)``, but the construction is a lot faster.
+   The returned object can only be used as a foreign function call
+   parameter.  It behaves similar to ``pointer(obj)``, but the
+   construction is a lot faster.
 
 
 .. function:: cast(obj, type)

Modified: python/branches/py3k/Doc/library/numbers.rst
==============================================================================
--- python/branches/py3k/Doc/library/numbers.rst	(original)
+++ python/branches/py3k/Doc/library/numbers.rst	Tue Jun 17 22:36:03 2008
@@ -71,10 +71,10 @@
 
 .. class:: Integral
 
-   Subtypes :class:`Rational` and adds a conversion to :class:`long`, the
-   3-argument form of :func:`pow`, and the bit-string operations: ``<<``,
-   ``>>``, ``&``, ``^``, ``|``, ``~``. Provides defaults for :func:`float`,
-   :attr:`Rational.numerator`, and :attr:`Rational.denominator`.
+   Subtypes :class:`Rational` and adds a conversion to :class:`int`.
+   Provides defaults for :func:`float`, :attr:`Rational.numerator`, and
+   :attr:`Rational.denominator`, and bit-string operations: ``<<``,
+   ``>>``, ``&``, ``^``, ``|``, ``~``.
 
 
 Notes for type implementors

Modified: python/branches/py3k/Doc/library/stdtypes.rst
==============================================================================
--- python/branches/py3k/Doc/library/stdtypes.rst	(original)
+++ python/branches/py3k/Doc/library/stdtypes.rst	Tue Jun 17 22:36:03 2008
@@ -1517,21 +1517,15 @@
 
       Return a new set with elements from both sets.
 
-      .. versionchanged:: 2.6
-         Accepts multiple input iterables.
-
    .. method:: intersection(other, ...)
                set & other & ...
 
       Return a new set with elements common to both sets.
 
-      .. versionchanged:: 2.6
-         Accepts multiple input iterables.
+   .. method:: difference(other, ...)
+               set - other - ...
 
-   .. method:: difference(other)
-               set - other
-
-      Return a new set with elements in the set that are not in *other*.
+      Return a new set with elements in the set that are not in the others.
 
    .. method:: symmetric_difference(other)
                set ^ other
@@ -1595,10 +1589,13 @@
       .. versionchanged:: 2.6
          Accepts multiple input iterables.
 
-   .. method:: difference_update(other)
-               set -= other
+   .. method:: difference_update(other, ...)
+               set -= other | ...
+
+      Update the set, removing elements found in others.
 
-      Update the set, removing elements found in *other*.
+      .. versionchanged:: 2.6
+         Accepts multiple input iterables.
 
    .. method:: symmetric_difference_update(other)
                set ^= other

Modified: python/branches/py3k/Include/Python.h
==============================================================================
--- python/branches/py3k/Include/Python.h	(original)
+++ python/branches/py3k/Include/Python.h	Tue Jun 17 22:36:03 2008
@@ -35,7 +35,7 @@
 #include <unistd.h>
 #endif
 
-/* For uintptr_t, intptr_t */
+/* For size_t? */
 #ifdef HAVE_STDDEF_H
 #include <stddef.h>
 #endif

Modified: python/branches/py3k/Lib/test/test_heapq.py
==============================================================================
--- python/branches/py3k/Lib/test/test_heapq.py	(original)
+++ python/branches/py3k/Lib/test/test_heapq.py	Tue Jun 17 22:36:03 2008
@@ -197,6 +197,27 @@
 class TestHeapC(TestHeap):
     module = c_heapq
 
+    def test_comparison_operator(self):
+        # Issue 3501: Make sure heapq works with both __lt__ and __le__
+        def hsort(data, comp):
+            data = [comp(x) for x in data]
+            self.module.heapify(data)
+            return [self.module.heappop(data).x for i in range(len(data))]
+        class LT:
+            def __init__(self, x):
+                self.x = x
+            def __lt__(self, other):
+                return self.x > other.x
+        class LE:
+            def __init__(self, x):
+                self.x = x
+            def __lt__(self, other):
+                return self.x >= other.x
+        data = [random.random() for i in range(100)]
+        target = sorted(data, reverse=True)
+        self.assertEqual(hsort(data, LT), target)
+        self.assertEqual(hsort(data, LE), target)
+
 
 #==============================================================================
 

Modified: python/branches/py3k/Lib/test/test_set.py
==============================================================================
--- python/branches/py3k/Lib/test/test_set.py	(original)
+++ python/branches/py3k/Lib/test/test_set.py	Tue Jun 17 22:36:03 2008
@@ -105,6 +105,12 @@
             self.assertEqual(self.thetype('abcba').intersection(C('ccb')), set('bc'))
             self.assertEqual(self.thetype('abcba').intersection(C('ef')), set(''))
             self.assertEqual(self.thetype('abcba').intersection(C('cbcf'), C('bag')), set('b'))
+        s = self.thetype('abcba')
+        z = s.intersection()
+        if self.thetype == frozenset():
+            self.assertEqual(id(s), id(z))
+        else:
+            self.assertNotEqual(id(s), id(z))
 
     def test_isdisjoint(self):
         def f(s1, s2):
@@ -144,6 +150,8 @@
             self.assertEqual(self.thetype('abcba').difference(C('efgfe')), set('abc'))
             self.assertEqual(self.thetype('abcba').difference(C('ccb')), set('a'))
             self.assertEqual(self.thetype('abcba').difference(C('ef')), set('abc'))
+            self.assertEqual(self.thetype('abcba').difference(), set('abc'))
+            self.assertEqual(self.thetype('abcba').difference(C('a'), C('b')), set('c'))
 
     def test_sub(self):
         i = self.s.difference(self.otherword)
@@ -470,6 +478,18 @@
                 self.assertEqual(s.difference_update(C(p)), None)
                 self.assertEqual(s, set(q))
 
+                s = self.thetype('abcdefghih')
+                s.difference_update()
+                self.assertEqual(s, self.thetype('abcdefghih'))
+
+                s = self.thetype('abcdefghih')
+                s.difference_update(C('aba'))
+                self.assertEqual(s, self.thetype('cdefghih'))
+
+                s = self.thetype('abcdefghih')
+                s.difference_update(C('cdc'), C('aba'))
+                self.assertEqual(s, self.thetype('efghih'))
+
     def test_isub(self):
         self.s -= set(self.otherword)
         for c in (self.word + self.otherword):

Modified: python/branches/py3k/Lib/test/test_struct.py
==============================================================================
--- python/branches/py3k/Lib/test/test_struct.py	(original)
+++ python/branches/py3k/Lib/test/test_struct.py	Tue Jun 17 22:36:03 2008
@@ -1,14 +1,14 @@
-from test.support import TestFailed, verbose, verify, vereq
-import test.support
-import struct
 import array
+import unittest
+import struct
 import warnings
 
+from functools import wraps
+from test.support import TestFailed, verbose, run_unittest, catch_warning
+
 import sys
 ISBIGENDIAN = sys.byteorder == "big"
 del sys
-verify((struct.pack('=i', 1)[0] == 0) == ISBIGENDIAN,
-       "bigendian determination appears wrong")
 
 try:
     import _struct
@@ -30,39 +30,21 @@
     else:
         return string_reverse(value)
 
-def simple_err(func, *args):
-    try:
-        func(*args)
-    except struct.error:
-        pass
-    else:
-        raise TestFailed("%s%s did not raise struct.error" % (
-            func.__name__, args))
-
-def any_err(func, *args):
-    try:
-        func(*args)
-    except (struct.error, TypeError):
-        pass
-    else:
-        raise TestFailed("%s%s did not raise error" % (
-            func.__name__, args))
-
 def with_warning_restore(func):
-    def _with_warning_restore(*args, **kw):
-        with test.support.catch_warning():
+    @wraps(func)
+    def decorator(*args, **kw):
+        with 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.
             globals = func.__globals__
             if '__warningregistry__' in globals:
                 del globals['__warningregistry__']
-            warnings.filterwarnings("error", r"""^struct.*""", DeprecationWarning)
-            warnings.filterwarnings("error", r""".*format requires.*""",
-                                    DeprecationWarning)
+            warnings.filterwarnings("error", category=DeprecationWarning)
             return func(*args, **kw)
-    return _with_warning_restore
+    return decorator
 
+ at with_warning_restore
 def deprecated_err(func, *args):
     try:
         func(*args)
@@ -75,615 +57,531 @@
     else:
         raise TestFailed("%s%s did not raise error" % (
             func.__name__, args))
-deprecated_err = with_warning_restore(deprecated_err)
 
 
-simple_err(struct.calcsize, 'Z')
-
-sz = struct.calcsize('i')
-if sz * 3 != struct.calcsize('iii'):
-    raise TestFailed('inconsistent sizes')
-
-fmt = 'cbxxxxxxhhhhiillffd?'
-fmt3 = '3c3b18x12h6i6l6f3d3?'
-sz = struct.calcsize(fmt)
-sz3 = struct.calcsize(fmt3)
-if sz * 3 != sz3:
-    raise TestFailed('inconsistent sizes (3*%r -> 3*%d = %d, %r -> %d)' % (
-        fmt, sz, 3*sz, fmt3, sz3))
-
-simple_err(struct.pack, 'iii', 3)
-simple_err(struct.pack, 'i', 3, 3, 3)
-simple_err(struct.pack, 'i', 'foo')
-simple_err(struct.pack, 'P', 'foo')
-simple_err(struct.unpack, 'd', b'flap')
-s = struct.pack('ii', 1, 2)
-simple_err(struct.unpack, 'iii', s)
-simple_err(struct.unpack, 'i', s)
-
-c = b'a'
-b = 1
-h = 255
-i = 65535
-l = 65536
-f = 3.1415
-d = 3.1415
-t = True
-
-for prefix in ('', '@', '<', '>', '=', '!'):
-    for format in ('xcbhilfd?', 'xcBHILfd?'):
-        format = prefix + format
-        if verbose:
-            print("trying:", format)
-        s = struct.pack(format, c, b, h, i, l, f, d, t)
-        cp, bp, hp, ip, lp, fp, dp, tp = struct.unpack(format, s)
-        if (cp != c or bp != b or hp != h or ip != i or lp != l or
-            int(100 * fp) != int(100 * f) or int(100 * dp) != int(100 * d) or
-                        tp != t):
-            # ^^^ calculate only to two decimal places
-            raise TestFailed("unpack/pack not transitive (%s, %s)" % (
-                str(format), str((cp, bp, hp, ip, lp, fp, dp, tp))))
-
-# Test some of the new features in detail
-
-# (format, argument, big-endian result, little-endian result, asymmetric)
-tests = [
-    ('c', 'a', 'a', 'a', 0),
-    ('xc', 'a', '\0a', '\0a', 0),
-    ('cx', 'a', 'a\0', 'a\0', 0),
-    ('s', 'a', 'a', 'a', 0),
-    ('0s', 'helloworld', '', '', 1),
-    ('1s', 'helloworld', 'h', 'h', 1),
-    ('9s', 'helloworld', 'helloworl', 'helloworl', 1),
-    ('10s', 'helloworld', 'helloworld', 'helloworld', 0),
-    ('11s', 'helloworld', 'helloworld\0', 'helloworld\0', 1),
-    ('20s', 'helloworld', 'helloworld'+10*'\0', 'helloworld'+10*'\0', 1),
-    ('b', 7, '\7', '\7', 0),
-    ('b', -7, '\371', '\371', 0),
-    ('B', 7, '\7', '\7', 0),
-    ('B', 249, '\371', '\371', 0),
-    ('h', 700, '\002\274', '\274\002', 0),
-    ('h', -700, '\375D', 'D\375', 0),
-    ('H', 700, '\002\274', '\274\002', 0),
-    ('H', 0x10000-700, '\375D', 'D\375', 0),
-    ('i', 70000000, '\004,\035\200', '\200\035,\004', 0),
-    ('i', -70000000, '\373\323\342\200', '\200\342\323\373', 0),
-    ('I', 70000000, '\004,\035\200', '\200\035,\004', 0),
-    ('I', 0x100000000-70000000, '\373\323\342\200', '\200\342\323\373', 0),
-    ('l', 70000000, '\004,\035\200', '\200\035,\004', 0),
-    ('l', -70000000, '\373\323\342\200', '\200\342\323\373', 0),
-    ('L', 70000000, '\004,\035\200', '\200\035,\004', 0),
-    ('L', 0x100000000-70000000, '\373\323\342\200', '\200\342\323\373', 0),
-    ('f', 2.0, '@\000\000\000', '\000\000\000@', 0),
-    ('d', 2.0, '@\000\000\000\000\000\000\000',
-               '\000\000\000\000\000\000\000@', 0),
-    ('f', -2.0, '\300\000\000\000', '\000\000\000\300', 0),
-    ('d', -2.0, '\300\000\000\000\000\000\000\000',
-               '\000\000\000\000\000\000\000\300', 0),
-        ('?', 0, '\0', '\0', 0),
-        ('?', 3, '\1', '\1', 1),
-        ('?', True, '\1', '\1', 0),
-        ('?', [], '\0', '\0', 1),
-        ('?', (1,), '\1', '\1', 1),
-]
-
-for fmt, arg, big, lil, asy in tests:
-    big = bytes(big, "latin-1")
-    lil = bytes(lil, "latin-1")
-    if verbose:
-        print("%r %r %r %r" % (fmt, arg, big, lil))
-    for (xfmt, exp) in [('>'+fmt, big), ('!'+fmt, big), ('<'+fmt, lil),
-                        ('='+fmt, ISBIGENDIAN and big or lil)]:
-        res = struct.pack(xfmt, arg)
-        if res != exp:
-            raise TestFailed("pack(%r, %r) -> %r # expected %r" % (
-                fmt, arg, res, exp))
-        n = struct.calcsize(xfmt)
-        if n != len(res):
-            raise TestFailed("calcsize(%r) -> %d # expected %d" % (
-                xfmt, n, len(res)))
-        rev = struct.unpack(xfmt, res)[0]
-        if isinstance(arg, str):
-            # Strings are returned as bytes since you can't know the encoding of
-            # the string when packed.
-            arg = bytes(arg, 'latin1')
-        if rev != arg and not asy:
-            raise TestFailed("unpack(%r, %r) -> (%r,) # expected (%r,)" % (
-                fmt, res, rev, arg))
-
-###########################################################################
-# Simple native q/Q tests.
-
-has_native_qQ = 1
-try:
-    struct.pack("q", 5)
-except struct.error:
-    has_native_qQ = 0
-
-if verbose:
-    print("Platform has native q/Q?", has_native_qQ and "Yes." or "No.")
-
-any_err(struct.pack, "Q", -1)   # can't pack -1 as unsigned regardless
-simple_err(struct.pack, "q", "a")  # can't pack string as 'q' regardless
-simple_err(struct.pack, "Q", "a")  # ditto, but 'Q'
-
-def test_native_qQ():
-    nbytes = struct.calcsize('q')
-    # The expected values here are in big-endian format, primarily because
-    # I'm on a little-endian machine and so this is the clearest way (for
-    # me) to force the code to get exercised.
-    for format, input, expected in (
-            ('q', -1, '\xff' * nbytes),
-            ('q', 0, '\x00' * nbytes),
-            ('Q', 0, '\x00' * nbytes),
-            ('q', 1, '\x00' * (nbytes-1) + '\x01'),
-            ('Q', (1 << (8*nbytes))-1, '\xff' * nbytes),
-            ('q', (1 << (8*nbytes-1))-1, '\x7f' + '\xff' * (nbytes - 1))):
-        expected = bytes(expected, "latin-1")
-        got = struct.pack(format, input)
-        native_expected = bigendian_to_native(expected)
-        verify(got == native_expected,
-               "%r-pack of %r gave %r, not %r" %
-                    (format, input, got, native_expected))
-        retrieved = struct.unpack(format, got)[0]
-        verify(retrieved == input,
-               "%r-unpack of %r gave %r, not %r" %
-                    (format, got, retrieved, input))
-
-if has_native_qQ:
-    test_native_qQ()
-
-###########################################################################
-# Standard integer tests (bBhHiIlLqQ).
-
-import binascii
-
-class IntTester:
-
-    # XXX Most std integer modes fail to test for out-of-range.
-    # The "i" and "l" codes appear to range-check OK on 32-bit boxes, but
-    # fail to check correctly on some 64-bit ones (Tru64 Unix + Compaq C
-    # reported by Mark Favas).
-    BUGGY_RANGE_CHECK = "bBhHiIlL"
-
-    def __init__(self, formatpair, bytesize):
-        assert len(formatpair) == 2
-        self.formatpair = formatpair
-        for direction in "<>!=":
-            for code in formatpair:
-                format = direction + code
-                verify(struct.calcsize(format) == bytesize)
-        self.bytesize = bytesize
-        self.bitsize = bytesize * 8
-        self.signed_code, self.unsigned_code = formatpair
-        self.unsigned_min = 0
-        self.unsigned_max = 2**self.bitsize - 1
-        self.signed_min = -(2**(self.bitsize-1))
-        self.signed_max = 2**(self.bitsize-1) - 1
-
-    def test_one(self, x, pack=struct.pack,
-                          unpack=struct.unpack,
-                          unhexlify=binascii.unhexlify):
-        if verbose:
-            print("trying std", self.formatpair, "on", x, "==", hex(x))
-
-        # Try signed.
-        code = self.signed_code
-        if self.signed_min <= x <= self.signed_max:
-            # Try big-endian.
-            expected = int(x)
-            if x < 0:
-                expected += 1 << self.bitsize
-                assert expected > 0
-            expected = hex(expected)[2:] # chop "0x"
-            if len(expected) & 1:
-                expected = "0" + expected
-            expected = unhexlify(expected)
-            expected = b"\x00" * (self.bytesize - len(expected)) + expected
-
-            # Pack work?
-            format = ">" + code
-            got = pack(format, x)
-            verify(got == expected,
-                   "'%s'-pack of %r gave %r, not %r" %
-                    (format, x, got, expected))
-
-            # Unpack work?
-            retrieved = unpack(format, got)[0]
-            verify(x == retrieved,
-                   "'%s'-unpack of %r gave %r, not %r" %
-                    (format, got, retrieved, x))
-
-            # Adding any byte should cause a "too big" error.
-            any_err(unpack, format, b'\x01' + got)
-
-            # Try little-endian.
-            format = "<" + code
-            expected = string_reverse(expected)
-
-            # Pack work?
-            got = pack(format, x)
-            verify(got == expected,
-                   "'%s'-pack of %r gave %r, not %r" %
-                    (format, x, got, expected))
-
-            # Unpack work?
-            retrieved = unpack(format, got)[0]
-            verify(x == retrieved,
-                   "'%s'-unpack of %r gave %r, not %r" %
-                    (format, got, retrieved, x))
-
-            # Adding any byte should cause a "too big" error.
-            any_err(unpack, format, b'\x01' + got)
+class StructTest(unittest.TestCase):
 
+    @with_warning_restore
+    def check_float_coerce(self, format, number):
+        # SF bug 1530559. struct.pack raises TypeError where it used to convert.
+        if PY_STRUCT_FLOAT_COERCE == 2:
+            # Test for pre-2.5 struct module
+            packed = struct.pack(format, number)
+            floored = struct.unpack(format, packed)[0]
+            self.assertEqual(floored, int(number),
+                             "did not correcly coerce float to int")
+            return
+        try:
+            struct.pack(format, number)
+        except (struct.error, TypeError):
+            if PY_STRUCT_FLOAT_COERCE:
+                self.fail("expected DeprecationWarning for float coerce")
+        except DeprecationWarning:
+            if not PY_STRUCT_FLOAT_COERCE:
+                self.fail("expected to raise struct.error for float coerce")
         else:
-            # x is out of range -- verify pack realizes that.
-            if not PY_STRUCT_RANGE_CHECKING and code in self.BUGGY_RANGE_CHECK:
-                if verbose:
-                    print("Skipping buggy range check for code", code)
-            else:
-                deprecated_err(pack, ">" + code, x)
-                deprecated_err(pack, "<" + code, x)
+            self.fail("did not raise error for float coerce")
 
-        # Much the same for unsigned.
-        code = self.unsigned_code
-        if self.unsigned_min <= x <= self.unsigned_max:
-            # Try big-endian.
-            format = ">" + code
-            expected = int(x)
-            expected = hex(expected)[2:] # chop "0x"
-            if len(expected) & 1:
-                expected = "0" + expected
-            expected = unhexlify(expected)
-            expected = b"\x00" * (self.bytesize - len(expected)) + expected
-
-            # Pack work?
-            got = pack(format, x)
-            verify(got == expected,
-                   "'%s'-pack of %r gave %r, not %r" %
-                    (format, x, got, expected))
-
-            # Unpack work?
-            retrieved = unpack(format, got)[0]
-            verify(x == retrieved,
-                   "'%s'-unpack of %r gave %r, not %r" %
-                    (format, got, retrieved, x))
-
-            # Adding any byte should cause a "too big" error.
-            any_err(unpack, format, b'\x01' + got)
-
-            # Try little-endian.
-            format = "<" + code
-            expected = string_reverse(expected)
-
-            # Pack work?
-            got = pack(format, x)
-            verify(got == expected,
-                   "'%s'-pack of %r gave %r, not %r" %
-                    (format, x, got, expected))
-
-            # Unpack work?
-            retrieved = unpack(format, got)[0]
-            verify(x == retrieved,
-                   "'%s'-unpack of %r gave %r, not %r" %
-                    (format, got, retrieved, x))
+    def test_isbigendian(self):
+        self.assertEqual((struct.pack('=i', 1)[0] == chr(0)), ISBIGENDIAN)
 
-            # Adding any byte should cause a "too big" error.
-            any_err(unpack, format, b'\x01' + got)
+    def test_consistence(self):
+        self.assertRaises(struct.error, struct.calcsize, 'Z')
 
+        sz = struct.calcsize('i')
+        self.assertEqual(sz * 3, struct.calcsize('iii'))
+
+        fmt = 'cbxxxxxxhhhhiillffd?'
+        fmt3 = '3c3b18x12h6i6l6f3d3?'
+        sz = struct.calcsize(fmt)
+        sz3 = struct.calcsize(fmt3)
+        self.assertEqual(sz * 3, sz3)
+
+        self.assertRaises(struct.error, struct.pack, 'iii', 3)
+        self.assertRaises(struct.error, struct.pack, 'i', 3, 3, 3)
+        self.assertRaises(struct.error, struct.pack, 'i', 'foo')
+        self.assertRaises(struct.error, struct.pack, 'P', 'foo')
+        self.assertRaises(struct.error, struct.unpack, 'd', b'flap')
+        s = struct.pack('ii', 1, 2)
+        self.assertRaises(struct.error, struct.unpack, 'iii', s)
+        self.assertRaises(struct.error, struct.unpack, 'i', s)
+
+    def test_transitiveness(self):
+        c = b'a'
+        b = 1
+        h = 255
+        i = 65535
+        l = 65536
+        f = 3.1415
+        d = 3.1415
+        t = True
+
+        for prefix in ('', '@', '<', '>', '=', '!'):
+            for format in ('xcbhilfd?', 'xcBHILfd?'):
+                format = prefix + format
+                s = struct.pack(format, c, b, h, i, l, f, d, t)
+                cp, bp, hp, ip, lp, fp, dp, tp = struct.unpack(format, s)
+                self.assertEqual(cp, c)
+                self.assertEqual(bp, b)
+                self.assertEqual(hp, h)
+                self.assertEqual(ip, i)
+                self.assertEqual(lp, l)
+                self.assertEqual(int(100 * fp), int(100 * f))
+                self.assertEqual(int(100 * dp), int(100 * d))
+                self.assertEqual(tp, t)
+
+    def test_new_features(self):
+        # Test some of the new features in detail
+        # (format, argument, big-endian result, little-endian result, asymmetric)
+        tests = [
+            ('c', 'a', 'a', 'a', 0),
+            ('xc', 'a', '\0a', '\0a', 0),
+            ('cx', 'a', 'a\0', 'a\0', 0),
+            ('s', 'a', 'a', 'a', 0),
+            ('0s', 'helloworld', '', '', 1),
+            ('1s', 'helloworld', 'h', 'h', 1),
+            ('9s', 'helloworld', 'helloworl', 'helloworl', 1),
+            ('10s', 'helloworld', 'helloworld', 'helloworld', 0),
+            ('11s', 'helloworld', 'helloworld\0', 'helloworld\0', 1),
+            ('20s', 'helloworld', 'helloworld'+10*'\0', 'helloworld'+10*'\0', 1),
+            ('b', 7, '\7', '\7', 0),
+            ('b', -7, '\371', '\371', 0),
+            ('B', 7, '\7', '\7', 0),
+            ('B', 249, '\371', '\371', 0),
+            ('h', 700, '\002\274', '\274\002', 0),
+            ('h', -700, '\375D', 'D\375', 0),
+            ('H', 700, '\002\274', '\274\002', 0),
+            ('H', 0x10000-700, '\375D', 'D\375', 0),
+            ('i', 70000000, '\004,\035\200', '\200\035,\004', 0),
+            ('i', -70000000, '\373\323\342\200', '\200\342\323\373', 0),
+            ('I', 70000000, '\004,\035\200', '\200\035,\004', 0),
+            ('I', 0x100000000-70000000, '\373\323\342\200', '\200\342\323\373', 0),
+            ('l', 70000000, '\004,\035\200', '\200\035,\004', 0),
+            ('l', -70000000, '\373\323\342\200', '\200\342\323\373', 0),
+            ('L', 70000000, '\004,\035\200', '\200\035,\004', 0),
+            ('L', 0x100000000-70000000, '\373\323\342\200', '\200\342\323\373', 0),
+            ('f', 2.0, '@\000\000\000', '\000\000\000@', 0),
+            ('d', 2.0, '@\000\000\000\000\000\000\000',
+                       '\000\000\000\000\000\000\000@', 0),
+            ('f', -2.0, '\300\000\000\000', '\000\000\000\300', 0),
+            ('d', -2.0, '\300\000\000\000\000\000\000\000',
+                       '\000\000\000\000\000\000\000\300', 0),
+                ('?', 0, '\0', '\0', 0),
+                ('?', 3, '\1', '\1', 1),
+                ('?', True, '\1', '\1', 0),
+                ('?', [], '\0', '\0', 1),
+                ('?', (1,), '\1', '\1', 1),
+        ]
+
+        for fmt, arg, big, lil, asy in tests:
+            big = bytes(big, "latin-1")
+            lil = bytes(lil, "latin-1")
+            for (xfmt, exp) in [('>'+fmt, big), ('!'+fmt, big), ('<'+fmt, lil),
+                                ('='+fmt, ISBIGENDIAN and big or lil)]:
+                res = struct.pack(xfmt, arg)
+                self.assertEqual(res, exp)
+                self.assertEqual(struct.calcsize(xfmt), len(res))
+                rev = struct.unpack(xfmt, res)[0]
+                if isinstance(arg, str):
+                    # Strings are returned as bytes since you can't know the
+                    # encoding of the string when packed.
+                    arg = bytes(arg, 'latin1')
+                if rev != arg:
+                    self.assert_(asy)
+
+    def test_native_qQ(self):
+        # can't pack -1 as unsigned regardless
+        self.assertRaises((struct.error, TypeError), struct.pack, "Q", -1)
+        # can't pack string as 'q' regardless
+        self.assertRaises(struct.error, struct.pack, "q", "a")
+        # ditto, but 'Q'
+        self.assertRaises(struct.error, struct.pack, "Q", "a")
+
+        try:
+            struct.pack("q", 5)
+        except struct.error:
+            # does not have native q/Q
+            pass
         else:
-            # x is out of range -- verify pack realizes that.
-            if not PY_STRUCT_RANGE_CHECKING and code in self.BUGGY_RANGE_CHECK:
-                if verbose:
-                    print("Skipping buggy range check for code", code)
-            else:
-                deprecated_err(pack, ">" + code, x)
-                deprecated_err(pack, "<" + code, x)
-
-    def run(self):
-        from random import randrange
-
-        # Create all interesting powers of 2.
-        values = []
-        for exp in range(self.bitsize + 3):
-            values.append(1 << exp)
-
-        # Add some random values.
-        for i in range(self.bitsize):
-            val = 0
-            for j in range(self.bytesize):
-                val = (val << 8) | randrange(256)
-            values.append(val)
-
-        # Try all those, and their negations, and +-1 from them.  Note
-        # that this tests all power-of-2 boundaries in range, and a few out
-        # of range, plus +-(2**n +- 1).
-        for base in values:
-            for val in -base, base:
-                for incr in -1, 0, 1:
-                    x = val + incr
-                    try:
-                        x = int(x)
-                    except OverflowError:
-                        pass
-                    self.test_one(x)
-
-        # Some error cases.
-        for direction in "<>":
-            for code in self.formatpair:
-                for badobject in "a string", 3+42j, randrange:
-                    any_err(struct.pack, direction + code, badobject)
-
-for args in [("bB", 1),
-             ("hH", 2),
-             ("iI", 4),
-             ("lL", 4),
-             ("qQ", 8)]:
-    t = IntTester(*args)
-    t.run()
-
-
-###########################################################################
-# The p ("Pascal string") code.
-
-def test_p_code():
-    for code, input, expected, expectedback in [
-            ('p','abc', '\x00', b''),
-            ('1p', 'abc', '\x00', b''),
-            ('2p', 'abc', '\x01a', b'a'),
-            ('3p', 'abc', '\x02ab', b'ab'),
-            ('4p', 'abc', '\x03abc', b'abc'),
-            ('5p', 'abc', '\x03abc\x00', b'abc'),
-            ('6p', 'abc', '\x03abc\x00\x00', b'abc'),
-            ('1000p', 'x'*1000, '\xff' + 'x'*999, b'x'*255)]:
-        expected = bytes(expected, "latin-1")
-        got = struct.pack(code, input)
-        if got != expected:
-            raise TestFailed("pack(%r, %r) == %r but expected %r" %
-                             (code, input, got, expected))
-        (got,) = struct.unpack(code, got)
-        if got != expectedback:
-            raise TestFailed("unpack(%r, %r) == %r but expected %r" %
-                             (code, input, got, expectedback))
-
-test_p_code()
-
-
-###########################################################################
-# SF bug 705836.  "<f" and ">f" had a severe rounding bug, where a carry
-# from the low-order discarded bits could propagate into the exponent
-# field, causing the result to be wrong by a factor of 2.
-
-def test_705836():
-    import math
-
-    for base in range(1, 33):
-        # smaller <- largest representable float less than base.
-        delta = 0.5
-        while base - delta / 2.0 != base:
-            delta /= 2.0
-        smaller = base - delta
-        # Packing this rounds away a solid string of trailing 1 bits.
-        packed = struct.pack("<f", smaller)
-        unpacked = struct.unpack("<f", packed)[0]
-        # This failed at base = 2, 4, and 32, with unpacked = 1, 2, and
-        # 16, respectively.
-        verify(base == unpacked)
-        bigpacked = struct.pack(">f", smaller)
-        verify(bigpacked == string_reverse(packed),
-               ">f pack should be byte-reversal of <f pack")
-        unpacked = struct.unpack(">f", bigpacked)[0]
-        verify(base == unpacked)
-
-    # Largest finite IEEE single.
-    big = (1 << 24) - 1
-    big = math.ldexp(big, 127 - 23)
-    packed = struct.pack(">f", big)
-    unpacked = struct.unpack(">f", packed)[0]
-    verify(big == unpacked)
-
-    # The same, but tack on a 1 bit so it rounds up to infinity.
-    big = (1 << 25) - 1
-    big = math.ldexp(big, 127 - 24)
-    try:
+            nbytes = struct.calcsize('q')
+            # The expected values here are in big-endian format, primarily
+            # because I'm on a little-endian machine and so this is the
+            # clearest way (for me) to force the code to get exercised.
+            for format, input, expected in (
+                    ('q', -1, '\xff' * nbytes),
+                    ('q', 0, '\x00' * nbytes),
+                    ('Q', 0, '\x00' * nbytes),
+                    ('q', 1, '\x00' * (nbytes-1) + '\x01'),
+                    ('Q', (1 << (8*nbytes))-1, '\xff' * nbytes),
+                    ('q', (1 << (8*nbytes-1))-1, '\x7f' + '\xff' * (nbytes - 1))):
+                expected = bytes(expected, "latin-1")
+                got = struct.pack(format, input)
+                native_expected = bigendian_to_native(expected)
+                self.assertEqual(got, native_expected)
+                retrieved = struct.unpack(format, got)[0]
+                self.assertEqual(retrieved, input)
+
+    def test_standard_integers(self):
+        # Standard integer tests (bBhHiIlLqQ).
+        import binascii
+
+        class IntTester(unittest.TestCase):
+
+            # XXX Most std integer modes fail to test for out-of-range.
+            # The "i" and "l" codes appear to range-check OK on 32-bit boxes, but
+            # fail to check correctly on some 64-bit ones (Tru64 Unix + Compaq C
+            # reported by Mark Favas).
+            BUGGY_RANGE_CHECK = "bBhHiIlL"
+
+            def __init__(self, formatpair, bytesize):
+                self.assertEqual(len(formatpair), 2)
+                self.formatpair = formatpair
+                for direction in "<>!=":
+                    for code in formatpair:
+                        format = direction + code
+                        self.assertEqual(struct.calcsize(format), bytesize)
+                self.bytesize = bytesize
+                self.bitsize = bytesize * 8
+                self.signed_code, self.unsigned_code = formatpair
+                self.unsigned_min = 0
+                self.unsigned_max = 2**self.bitsize - 1
+                self.signed_min = -(2**(self.bitsize-1))
+                self.signed_max = 2**(self.bitsize-1) - 1
+
+            def test_one(self, x, pack=struct.pack,
+                                  unpack=struct.unpack,
+                                  unhexlify=binascii.unhexlify):
+                # Try signed.
+                code = self.signed_code
+                if self.signed_min <= x <= self.signed_max:
+                    # Try big-endian.
+                    expected = x
+                    if x < 0:
+                        expected += 1 << self.bitsize
+                        self.assert_(expected > 0)
+                    expected = hex(expected)[2:] # chop "0x"
+                    if len(expected) & 1:
+                        expected = "0" + expected
+                    expected = unhexlify(expected)
+                    expected = b"\x00" * (self.bytesize - len(expected)) + expected
+
+                    # Pack work?
+                    format = ">" + code
+                    got = pack(format, x)
+                    self.assertEqual(got, expected)
+
+                    # Unpack work?
+                    retrieved = unpack(format, got)[0]
+                    self.assertEqual(x, retrieved)
+
+                    # Adding any byte should cause a "too big" error.
+                    self.assertRaises((struct.error, TypeError),
+                                      unpack, format, b'\x01' + got)
+
+                    # Try little-endian.
+                    format = "<" + code
+                    expected = string_reverse(expected)
+
+                    # Pack work?
+                    got = pack(format, x)
+                    self.assertEqual(got, expected)
+
+                    # Unpack work?
+                    retrieved = unpack(format, got)[0]
+                    self.assertEqual(x, retrieved)
+
+                    # Adding any byte should cause a "too big" error.
+                    self.assertRaises((struct.error, TypeError),
+                                      unpack, format, b'\x01' + got)
+
+                else:
+                    # x is out of range -- verify pack realizes that.
+                    if not PY_STRUCT_RANGE_CHECKING and code in self.BUGGY_RANGE_CHECK:
+                        if verbose:
+                            print("Skipping buggy range check for code", code)
+                    else:
+                        deprecated_err(pack, ">" + code, x)
+                        deprecated_err(pack, "<" + code, x)
+
+                # Much the same for unsigned.
+                code = self.unsigned_code
+                if self.unsigned_min <= x <= self.unsigned_max:
+                    # Try big-endian.
+                    format = ">" + code
+                    expected = x
+                    expected = hex(expected)[2:] # chop "0x"
+                    if len(expected) & 1:
+                        expected = "0" + expected
+                    expected = unhexlify(expected)
+                    expected = b"\x00" * (self.bytesize - len(expected)) + expected
+
+                    # Pack work?
+                    got = pack(format, x)
+                    self.assertEqual(got, expected)
+
+                    # Unpack work?
+                    retrieved = unpack(format, got)[0]
+                    self.assertEqual(x, retrieved)
+
+                    # Adding any byte should cause a "too big" error.
+                    self.assertRaises((struct.error, TypeError),
+                                      unpack, format, b'\x01' + got)
+
+                    # Try little-endian.
+                    format = "<" + code
+                    expected = string_reverse(expected)
+
+                    # Pack work?
+                    got = pack(format, x)
+                    self.assertEqual(got, expected)
+
+                    # Unpack work?
+                    retrieved = unpack(format, got)[0]
+                    self.assertEqual(x, retrieved)
+
+                    # Adding any byte should cause a "too big" error.
+                    self.assertRaises((struct.error, TypeError),
+                                      unpack, format, b'\x01' + got)
+
+                else:
+                    # x is out of range -- verify pack realizes that.
+                    if not PY_STRUCT_RANGE_CHECKING and code in self.BUGGY_RANGE_CHECK:
+                        if verbose:
+                            print("Skipping buggy range check for code", code)
+                    else:
+                        deprecated_err(pack, ">" + code, x)
+                        deprecated_err(pack, "<" + code, x)
+
+            def run(self):
+                from random import randrange
+
+                # Create all interesting powers of 2.
+                values = []
+                for exp in range(self.bitsize + 3):
+                    values.append(1 << exp)
+
+                # Add some random values.
+                for i in range(self.bitsize):
+                    val = 0
+                    for j in range(self.bytesize):
+                        val = (val << 8) | randrange(256)
+                    values.append(val)
+
+                # Try all those, and their negations, and +-1 from them.  Note
+                # that this tests all power-of-2 boundaries in range, and a few out
+                # of range, plus +-(2**n +- 1).
+                for base in values:
+                    for val in -base, base:
+                        for incr in -1, 0, 1:
+                            x = val + incr
+                            try:
+                                x = int(x)
+                            except OverflowError:
+                                pass
+                            self.test_one(x)
+
+                # Some error cases.
+                for direction in "<>":
+                    for code in self.formatpair:
+                        for badobject in "a string", 3+42j, randrange:
+                            self.assertRaises((struct.error, TypeError),
+                                               struct.pack, direction + code,
+                                               badobject)
+
+        for args in [("bB", 1),
+                     ("hH", 2),
+                     ("iI", 4),
+                     ("lL", 4),
+                     ("qQ", 8)]:
+            t = IntTester(*args)
+            t.run()
+
+    def test_p_code(self):
+        # Test p ("Pascal string") code.
+        for code, input, expected, expectedback in [
+                ('p','abc', '\x00', b''),
+                ('1p', 'abc', '\x00', b''),
+                ('2p', 'abc', '\x01a', b'a'),
+                ('3p', 'abc', '\x02ab', b'ab'),
+                ('4p', 'abc', '\x03abc', b'abc'),
+                ('5p', 'abc', '\x03abc\x00', b'abc'),
+                ('6p', 'abc', '\x03abc\x00\x00', b'abc'),
+                ('1000p', 'x'*1000, '\xff' + 'x'*999, b'x'*255)]:
+            expected = bytes(expected, "latin-1")
+            got = struct.pack(code, input)
+            self.assertEqual(got, expected)
+            (got,) = struct.unpack(code, got)
+            self.assertEqual(got, expectedback)
+
+    def test_705836(self):
+        # SF bug 705836.  "<f" and ">f" had a severe rounding bug, where a carry
+        # from the low-order discarded bits could propagate into the exponent
+        # field, causing the result to be wrong by a factor of 2.
+        import math
+
+        for base in range(1, 33):
+            # smaller <- largest representable float less than base.
+            delta = 0.5
+            while base - delta / 2.0 != base:
+                delta /= 2.0
+            smaller = base - delta
+            # Packing this rounds away a solid string of trailing 1 bits.
+            packed = struct.pack("<f", smaller)
+            unpacked = struct.unpack("<f", packed)[0]
+            # This failed at base = 2, 4, and 32, with unpacked = 1, 2, and
+            # 16, respectively.
+            self.assertEqual(base, unpacked)
+            bigpacked = struct.pack(">f", smaller)
+            self.assertEqual(bigpacked, string_reverse(packed))
+            unpacked = struct.unpack(">f", bigpacked)[0]
+            self.assertEqual(base, unpacked)
+
+        # Largest finite IEEE single.
+        big = (1 << 24) - 1
+        big = math.ldexp(big, 127 - 23)
         packed = struct.pack(">f", big)
-    except OverflowError:
-        pass
-    else:
-        raise TestFailed("expected OverflowError")
-
-test_705836()
-
-###########################################################################
-# SF bug 1229380. No struct.pack exception for some out of range integers
-
-def test_1229380():
-    import sys
-    for endian in ('', '>', '<'):
-        for fmt in ('B', 'H', 'I', 'L'):
-            deprecated_err(struct.pack, endian + fmt, -1)
-
-        deprecated_err(struct.pack, endian + 'B', 300)
-        deprecated_err(struct.pack, endian + 'H', 70000)
-
-        deprecated_err(struct.pack, endian + 'I', sys.maxsize * 4)
-        deprecated_err(struct.pack, endian + 'L', sys.maxsize * 4)
-
-if PY_STRUCT_RANGE_CHECKING:
-    test_1229380()
-
-###########################################################################
-# SF bug 1530559. struct.pack raises TypeError where it used to convert.
-
-def check_float_coerce(format, number):
-    if PY_STRUCT_FLOAT_COERCE == 2:
-        # Test for pre-2.5 struct module
-        packed = struct.pack(format, number)
-        floored = struct.unpack(format, packed)[0]
-        if floored != int(number):
-            raise TestFailed("did not correcly coerce float to int")
-        return
-    try:
-        func(*args)
-    except (struct.error, TypeError):
-        if PY_STRUCT_FLOAT_COERCE:
-            raise TestFailed("expected DeprecationWarning for float coerce")
-    except DeprecationWarning:
-        if not PY_STRUCT_FLOAT_COERCE:
-            raise TestFailed("expected to raise struct.error for float coerce")
-    else:
-        raise TestFailed("did not raise error for float coerce")
-
-check_float_coerce = with_warning_restore(deprecated_err)
-
-def test_1530559():
-    for endian in ('', '>', '<'):
-        for fmt in ('B', 'H', 'I', 'L', 'b', 'h', 'i', 'l'):
-            check_float_coerce(endian + fmt, 1.0)
-            check_float_coerce(endian + fmt, 1.5)
+        unpacked = struct.unpack(">f", packed)[0]
+        self.assertEqual(big, unpacked)
 
-test_1530559()
+        # The same, but tack on a 1 bit so it rounds up to infinity.
+        big = (1 << 25) - 1
+        big = math.ldexp(big, 127 - 24)
+        self.assertRaises(OverflowError, struct.pack, ">f", big)
+
+    if PY_STRUCT_RANGE_CHECKING:
+        def test_1229380(self):
+            # SF bug 1229380. No struct.pack exception for some out of
+            # range integers
+            import sys
+            for endian in ('', '>', '<'):
+                for fmt in ('B', 'H', 'I', 'L'):
+                    deprecated_err(struct.pack, endian + fmt, -1)
+
+                deprecated_err(struct.pack, endian + 'B', 300)
+                deprecated_err(struct.pack, endian + 'H', 70000)
+
+                deprecated_err(struct.pack, endian + 'I', sys.maxsize * 4)
+                deprecated_err(struct.pack, endian + 'L', sys.maxsize * 4)
+
+    def XXXtest_1530559(self):
+        # XXX This is broken: see the bug report
+        # SF bug 1530559. struct.pack raises TypeError where it used to convert.
+        for endian in ('', '>', '<'):
+            for fmt in ('B', 'H', 'I', 'L', 'b', 'h', 'i', 'l'):
+                self.check_float_coerce(endian + fmt, 1.0)
+                self.check_float_coerce(endian + fmt, 1.5)
+
+    def test_unpack_from(self):
+        test_string = b'abcd01234'
+        fmt = '4s'
+        s = struct.Struct(fmt)
+        for cls in (bytes, bytearray):
+            data = cls(test_string)
+            if not isinstance(data, (bytes, bytearray)):
+                bytes_data = bytes(data, 'latin1')
+            else:
+                bytes_data = data
+            self.assertEqual(s.unpack_from(data), (b'abcd',))
+            self.assertEqual(s.unpack_from(data, 2), (b'cd01',))
+            self.assertEqual(s.unpack_from(data, 4), (b'0123',))
+            for i in range(6):
+                self.assertEqual(s.unpack_from(data, i), (bytes_data[i:i+4],))
+            for i in range(6, len(test_string) + 1):
+                self.assertRaises(struct.error, s.unpack_from, data, i)
+        for cls in (bytes, bytearray):
+            data = cls(test_string)
+            self.assertEqual(struct.unpack_from(fmt, data), (b'abcd',))
+            self.assertEqual(struct.unpack_from(fmt, data, 2), (b'cd01',))
+            self.assertEqual(struct.unpack_from(fmt, data, 4), (b'0123',))
+            for i in range(6):
+                self.assertEqual(struct.unpack_from(fmt, data, i), (data[i:i+4],))
+            for i in range(6, len(test_string) + 1):
+                self.assertRaises(struct.error, struct.unpack_from, fmt, data, i)
+
+    def test_pack_into(self):
+        test_string = b'Reykjavik rocks, eow!'
+        writable_buf = array.array('b', b' '*100)
+        fmt = '21s'
+        s = struct.Struct(fmt)
+
+        # Test without offset
+        s.pack_into(writable_buf, 0, test_string)
+        from_buf = writable_buf.tostring()[:len(test_string)]
+        self.assertEqual(from_buf, test_string)
+
+        # Test with offset.
+        s.pack_into(writable_buf, 10, test_string)
+        from_buf = writable_buf.tostring()[:len(test_string)+10]
+        self.assertEqual(from_buf, test_string[:10] + test_string)
+
+        # Go beyond boundaries.
+        small_buf = array.array('b', b' '*10)
+        self.assertRaises(struct.error, s.pack_into, small_buf, 0, test_string)
+        self.assertRaises(struct.error, s.pack_into, small_buf, 2, test_string)
+
+    def test_pack_into_fn(self):
+        test_string = b'Reykjavik rocks, eow!'
+        writable_buf = array.array('b', b' '*100)
+        fmt = '21s'
+        pack_into = lambda *args: struct.pack_into(fmt, *args)
+
+        # Test without offset.
+        pack_into(writable_buf, 0, test_string)
+        from_buf = writable_buf.tostring()[:len(test_string)]
+        self.assertEqual(from_buf, test_string)
+
+        # Test with offset.
+        pack_into(writable_buf, 10, test_string)
+        from_buf = writable_buf.tostring()[:len(test_string)+10]
+        self.assertEqual(from_buf, test_string[:10] + test_string)
+
+        # Go beyond boundaries.
+        small_buf = array.array('b', b' '*10)
+        self.assertRaises(struct.error, pack_into, small_buf, 0, test_string)
+        self.assertRaises(struct.error, pack_into, small_buf, 2, test_string)
+
+    def test_unpack_with_buffer(self):
+        # SF bug 1563759: struct.unpack doens't support buffer protocol objects
+        data1 = array.array('B', b'\x12\x34\x56\x78')
+        data2 = memoryview(b'\x12\x34\x56\x78') # XXX b'......XXXX......', 6, 4
+        for data in [data1, data2]:
+            value, = struct.unpack('>I', data)
+            self.assertEqual(value, 0x12345678)
+
+    def test_bool(self):
+        for prefix in tuple("<>!=")+('',):
+            false = (), [], [], '', 0
+            true = [1], 'test', 5, -1, 0xffffffff+1, 0xffffffff/2
+
+            falseFormat = prefix + '?' * len(false)
+            packedFalse = struct.pack(falseFormat, *false)
+            unpackedFalse = struct.unpack(falseFormat, packedFalse)
+
+            trueFormat = prefix + '?' * len(true)
+            packedTrue = struct.pack(trueFormat, *true)
+            unpackedTrue = struct.unpack(trueFormat, packedTrue)
+
+            self.assertEqual(len(true), len(unpackedTrue))
+            self.assertEqual(len(false), len(unpackedFalse))
+
+            for t in unpackedFalse:
+                self.assertFalse(t)
+            for t in unpackedTrue:
+                self.assertTrue(t)
+
+            packed = struct.pack(prefix+'?', 1)
+
+            self.assertEqual(len(packed), struct.calcsize(prefix+'?'))
+
+            if len(packed) != 1:
+                self.assertFalse(prefix, msg='encoded bool is not one byte: %r'
+                                             %packed)
 
-###########################################################################
-# Packing and unpacking to/from memory views.
+            for c in [b'\x01', b'\x7f', b'\xff', b'\x0f', b'\xf0']:
+                self.assertTrue(struct.unpack('>?', c)[0])
 
-# Copied and modified from unittest.
-def assertRaises(excClass, callableObj, *args, **kwargs):
-    try:
-        callableObj(*args, **kwargs)
-    except excClass:
-        return
-    else:
-        raise TestFailed("%s not raised." % excClass)
-
-def test_unpack_from():
-    test_string = b'abcd01234'
-    fmt = '4s'
-    s = struct.Struct(fmt)
-    for cls in (bytes, bytearray):
-        if verbose:
-            print("test_unpack_from using", cls.__name__)
-        data = cls(test_string)
-        if not isinstance(data, (bytes, bytearray)):
-            bytes_data = bytes(data, 'latin1')
-        else:
-            bytes_data = data
-        vereq(s.unpack_from(data), (b'abcd',))
-        vereq(s.unpack_from(data, 2), (b'cd01',))
-        vereq(s.unpack_from(data, 4), (b'0123',))
-        for i in range(6):
-            vereq(s.unpack_from(data, i), (bytes_data[i:i+4],))
-        for i in range(6, len(test_string) + 1):
-            simple_err(s.unpack_from, data, i)
-    for cls in (bytes, bytearray):
-        data = cls(test_string)
-        vereq(struct.unpack_from(fmt, data), (b'abcd',))
-        vereq(struct.unpack_from(fmt, data, 2), (b'cd01',))
-        vereq(struct.unpack_from(fmt, data, 4), (b'0123',))
-        for i in range(6):
-            vereq(struct.unpack_from(fmt, data, i), (bytes_data[i:i+4],))
-        for i in range(6, len(test_string) + 1):
-            simple_err(struct.unpack_from, fmt, data, i)
-
-def test_pack_into():
-    test_string = b'Reykjavik rocks, eow!'
-    writable_buf = array.array('b', b' '*100)
-    fmt = '21s'
-    s = struct.Struct(fmt)
-
-    # Test without offset
-    s.pack_into(writable_buf, 0, test_string)
-    from_buf = writable_buf.tostring()[:len(test_string)]
-    vereq(from_buf, test_string)
-
-    # Test with offset.
-    s.pack_into(writable_buf, 10, test_string)
-    from_buf = writable_buf.tostring()[:len(test_string)+10]
-    vereq(from_buf, test_string[:10] + test_string)
-
-    # Go beyond boundaries.
-    small_buf = array.array('b', b' '*10)
-    assertRaises(struct.error, s.pack_into, small_buf, 0, test_string)
-    assertRaises(struct.error, s.pack_into, small_buf, 2, test_string)
-
-def test_pack_into_fn():
-    test_string = b'Reykjavik rocks, eow!'
-    writable_buf = array.array('b', b' '*100)
-    fmt = '21s'
-    pack_into = lambda *args: struct.pack_into(fmt, *args)
-
-    # Test without offset.
-    pack_into(writable_buf, 0, test_string)
-    from_buf = writable_buf.tostring()[:len(test_string)]
-    vereq(from_buf, test_string)
-
-    # Test with offset.
-    pack_into(writable_buf, 10, test_string)
-    from_buf = writable_buf.tostring()[:len(test_string)+10]
-    vereq(from_buf, test_string[:10] + test_string)
-
-    # Go beyond boundaries.
-    small_buf = array.array('b', b' '*10)
-    assertRaises(struct.error, pack_into, small_buf, 0, test_string)
-    assertRaises(struct.error, pack_into, small_buf, 2, test_string)
-
-def test_unpack_with_memoryview():
-    # SF bug 1563759: struct.unpack doens't support buffer protocol objects
-    data1 = array.array('B', b'\x12\x34\x56\x78')
-    data2 = memoryview(b'\x12\x34\x56\x78') # XXX b'......XXXX......', 6, 4
-    for data in [data1, data2]:
-        value, = struct.unpack('>I', data)
-        vereq(value, 0x12345678)
-
-# Test methods to pack and unpack from memoryviews rather than strings.
-test_unpack_from()
-test_pack_into()
-test_pack_into_fn()
-test_unpack_with_memoryview()
-
-def test_bool():
-    for prefix in tuple("<>!=")+('',):
-        false = (), [], [], '', 0
-        true = [1], 'test', 5, -1, 0xffffffff+1, 0xffffffff/2
-
-        falseFormat = prefix + '?' * len(false)
-        if verbose:
-            print('trying bool pack/unpack on', false, 'using format', falseFormat)
-        packedFalse = struct.pack(falseFormat, *false)
-        unpackedFalse = struct.unpack(falseFormat, packedFalse)
-
-        trueFormat = prefix + '?' * len(true)
-        if verbose:
-            print('trying bool pack/unpack on', true, 'using format', trueFormat)
-        packedTrue = struct.pack(trueFormat, *true)
-        unpackedTrue = struct.unpack(trueFormat, packedTrue)
-
-        if len(true) != len(unpackedTrue):
-            raise TestFailed('unpacked true array is not of same size as input')
-        if len(false) != len(unpackedFalse):
-            raise TestFailed('unpacked false array is not of same size as input')
-
-        for t in unpackedFalse:
-            if t is not False:
-                raise TestFailed('%r did not unpack as False' % t)
-        for t in unpackedTrue:
-            if t is not True:
-                raise TestFailed('%r did not unpack as false' % t)
-
-        if prefix and verbose:
-            print('trying size of bool with format %r' % (prefix+'?'))
-        packed = struct.pack(prefix+'?', 1)
-
-        if len(packed) != struct.calcsize(prefix+'?'):
-            raise TestFailed('packed length is not equal to calculated size')
-
-        if len(packed) != 1 and prefix:
-            raise TestFailed('encoded bool is not one byte: %r' % packed)
-        elif not prefix and verbose:
-            print('size of bool in native format is %i' % (len(packed)))
-
-        for c in [b'\x01', b'\x7f', b'\xff', b'\x0f', b'\xf0']:
-            if struct.unpack('>?', c)[0] is not True:
-                raise TestFailed('%c did not unpack as True' % c)
+def test_main():
+    run_unittest(StructTest)
 
-test_bool()
+if __name__ == '__main__':
+    test_main()

Modified: python/branches/py3k/Modules/_heapqmodule.c
==============================================================================
--- python/branches/py3k/Modules/_heapqmodule.c	(original)
+++ python/branches/py3k/Modules/_heapqmodule.c	Tue Jun 17 22:36:03 2008
@@ -17,13 +17,18 @@
 cmp_lt(PyObject *x, PyObject *y)
 {
 	int cmp;
-	cmp = PyObject_RichCompareBool(x, y, Py_LT);
-	if (cmp == -1 && PyErr_ExceptionMatches(PyExc_AttributeError)) {
-		PyErr_Clear();
-		cmp = PyObject_RichCompareBool(y, x, Py_LE);
-		if (cmp != -1)
-			cmp = 1 - cmp;
+	static PyObject *lt = NULL;
+
+	if (lt == NULL) {
+		lt = PyUnicode_FromString("__lt__");
+		if (lt == NULL)
+			return -1;
 	}
+	if (PyObject_HasAttr(x, lt))
+		return PyObject_RichCompareBool(x, y, Py_LT);
+	cmp = PyObject_RichCompareBool(y, x, Py_LE);
+	if (cmp != -1)
+		cmp = 1 - cmp;
 	return cmp;
 }
 

Modified: python/branches/py3k/Objects/setobject.c
==============================================================================
--- python/branches/py3k/Objects/setobject.c	(original)
+++ python/branches/py3k/Objects/setobject.c	Tue Jun 17 22:36:03 2008
@@ -1304,6 +1304,9 @@
 	Py_ssize_t i;
 	PyObject *result = (PyObject *)so;
 
+	if (PyTuple_GET_SIZE(args) == 0)
+		return set_copy(so);
+
 	Py_INCREF(so);
 	for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
 		PyObject *other = PyTuple_GET_ITEM(args, i);
@@ -1484,11 +1487,16 @@
 }
 
 static PyObject *
-set_difference_update(PySetObject *so, PyObject *other)
+set_difference_update(PySetObject *so, PyObject *args)
 {
-	if (set_difference_update_internal(so, other) != -1)
-		Py_RETURN_NONE;
-	return NULL;
+	Py_ssize_t i;
+
+	for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
+		PyObject *other = PyTuple_GET_ITEM(args, i);
+		if (set_difference_update_internal(so, other) == -1)
+			return NULL;
+	}
+	Py_RETURN_NONE;
 }
 
 PyDoc_STRVAR(difference_update_doc,
@@ -1546,10 +1554,34 @@
 	return result;
 }
 
+static PyObject *
+set_difference_multi(PySetObject *so, PyObject *args)
+{
+	Py_ssize_t i;
+	PyObject *result, *other;
+
+	if (PyTuple_GET_SIZE(args) == 0)
+		return set_copy(so);
+
+	other = PyTuple_GET_ITEM(args, 0);
+	result = set_difference(so, other);
+	if (result == NULL)
+		return NULL;
+
+	for (i=1 ; i<PyTuple_GET_SIZE(args) ; i++) {
+		other = PyTuple_GET_ITEM(args, i);
+		if (set_difference_update_internal((PySetObject *)result, other) == -1) {
+			Py_DECREF(result);
+			return NULL;
+		}
+	}
+	return result;
+}
+
 PyDoc_STRVAR(difference_doc,
-"Return the difference of two sets as a new set.\n\
+"Return the difference of two or more sets as a new set.\n\
 \n\
-(i.e. all elements that are in this set but not the other.)");
+(i.e. all elements that are in this set but not the others.)");
 static PyObject *
 set_sub(PySetObject *so, PyObject *other)
 {
@@ -1563,16 +1595,12 @@
 static PyObject *
 set_isub(PySetObject *so, PyObject *other)
 {
-	PyObject *result;
-
 	if (!PyAnySet_Check(other)) {
 		Py_INCREF(Py_NotImplemented);
 		return Py_NotImplemented;
 	}
-	result = set_difference_update(so, other);
-	if (result == NULL)
+	if (set_difference_update_internal(so, other) == -1)
 		return NULL;
-	Py_DECREF(result);
 	Py_INCREF(so);
 	return (PyObject *)so;
 }
@@ -1963,9 +1991,9 @@
 	 copy_doc},
 	{"discard",	(PyCFunction)set_discard,	METH_O,
 	 discard_doc},
-	{"difference",	(PyCFunction)set_difference,	METH_O,
+	{"difference",	(PyCFunction)set_difference_multi,	METH_VARARGS,
 	 difference_doc},
-	{"difference_update",	(PyCFunction)set_difference_update,	METH_O,
+	{"difference_update",	(PyCFunction)set_difference_update,	METH_VARARGS,
 	 difference_update_doc},
 	{"intersection",(PyCFunction)set_intersection_multi,	METH_VARARGS,
 	 intersection_doc},
@@ -2087,7 +2115,7 @@
 	 contains_doc},
 	{"copy",	(PyCFunction)frozenset_copy,	METH_NOARGS,
 	 copy_doc},
-	{"difference",	(PyCFunction)set_difference,	METH_O,
+	{"difference",	(PyCFunction)set_difference_multi,	METH_VARARGS,
 	 difference_doc},
 	{"intersection",(PyCFunction)set_intersection_multi,	METH_VARARGS,
 	 intersection_doc},

From python-3000-checkins at python.org  Tue Jun 17 22:38:00 2008
From: python-3000-checkins at python.org (amaury.forgeotdarc)
Date: Tue, 17 Jun 2008 22:38:00 +0200 (CEST)
Subject: [Python-3000-checkins] r64344 - in
	python/branches/py3k/Doc/library: ctypes.rst numbers.rst
Message-ID: <20080617203800.F03331E4004@bag.python.org>

Author: amaury.forgeotdarc
Date: Tue Jun 17 22:38:00 2008
New Revision: 64344

Log:
Removed some versionadded tags, and a reference to "long" in a sample


Modified:
   python/branches/py3k/Doc/library/ctypes.rst
   python/branches/py3k/Doc/library/numbers.rst

Modified: python/branches/py3k/Doc/library/ctypes.rst
==============================================================================
--- python/branches/py3k/Doc/library/ctypes.rst	(original)
+++ python/branches/py3k/Doc/library/ctypes.rst	Tue Jun 17 22:38:00 2008
@@ -1875,8 +1875,6 @@
    module with a call to the ``free(void *)``, it is important that you
    use the function in the same library that allocated the memory.
 
-   .. versionadded:: 2.6
-
 .. function:: FormatError([code])
 
    Windows only: Returns a textual description of the error code. If no error code
@@ -1895,15 +1893,11 @@
    Returns the current value of the ctypes-private copy of the system
    `errno` variable in the calling thread.
 
-   .. versionadded:: 2.6
-
 .. function:: get_last_error()
 
    Windows only: returns the current value of the ctypes-private copy of the system
    `LastError` variable in the calling thread.
 
-   .. versionadded:: 2.6
-
 .. function:: memmove(dst, src, count)
 
    Same as the standard C memmove library function: copies *count* bytes from
@@ -1961,16 +1955,12 @@
    `errno` variable in the calling thread to `value` and return the
    previous value.
 
-   .. versionadded:: 2.6
-
 .. function:: set_last_error(value)
 
    Windows only: set the current value of the ctypes-private copy of
    the system `LastError` variable in the calling thread to `value`
    and return the previous value.
 
-   .. versionadded:: 2.6
-
 .. function:: sizeof(obj_or_type)
 
    Returns the size in bytes of a ctypes type or instance memory buffer. Does the
@@ -2164,8 +2154,6 @@
    optional float initializer.  On platforms where ``sizeof(long
    double) == sizeof(double)`` it is an alias to :class:`c_double`.
 
-   .. versionadded:: 2.6
-
 .. class:: c_float
 
    Represents the C float datatype. The constructor accepts an optional float

Modified: python/branches/py3k/Doc/library/numbers.rst
==============================================================================
--- python/branches/py3k/Doc/library/numbers.rst	(original)
+++ python/branches/py3k/Doc/library/numbers.rst	Tue Jun 17 22:38:00 2008
@@ -181,7 +181,7 @@
 
     def _operator_fallbacks(monomorphic_operator, fallback_operator):
         def forward(a, b):
-            if isinstance(b, (int, long, Fraction)):
+            if isinstance(b, (int, Fraction)):
                 return monomorphic_operator(a, b)
             elif isinstance(b, float):
                 return fallback_operator(float(a), b)

From python-3000-checkins at python.org  Tue Jun 17 22:44:58 2008
From: python-3000-checkins at python.org (jeremy.hylton)
Date: Tue, 17 Jun 2008 22:44:58 +0200 (CEST)
Subject: [Python-3000-checkins] r64345 - python/branches/py3k-urllib
Message-ID: <20080617204458.1C9AB1E4004@bag.python.org>

Author: jeremy.hylton
Date: Tue Jun 17 22:44:57 2008
New Revision: 64345

Log:


Added:
   python/branches/py3k-urllib/
      - copied from r64344, /python/branches/py3k/

From python-3000-checkins at python.org  Tue Jun 17 23:01:38 2008
From: python-3000-checkins at python.org (jeremy.hylton)
Date: Tue, 17 Jun 2008 23:01:38 +0200 (CEST)
Subject: [Python-3000-checkins] r64346 - in python/branches/py3k-urllib:
	Lib/cgi.py Lib/distutils/command/register.py
	Lib/distutils/command/upload.py Lib/email/utils.py
	Lib/http/client.py Lib/http/cookiejar.py Lib/http/server.py
	Lib/macurl2path.py Lib/mimetypes.py Lib/robotparser.py
	Lib/test/regrtest.py Lib/test/test___all__.py
	Lib/test/test_http_cookiejar.py Lib/test/test_httpservers.py
	Lib/test/test_importhooks.py Lib/test/test_pyclbr.py
	Lib/test/test_robotparser.py Lib/test/test_ssl.py
	Lib/test/test_urllib.py Lib/test/test_urllib2.py
	Lib/test/test_urllib2_localnet.py Lib/test/test_urllib2net.py
	Lib/test/test_urllibnet.py Lib/test/test_urlparse.py
	Lib/test/test_xmlrpc.py Lib/urllib Lib/urllib.py
	Lib/urllib/__init__.py Lib/urllib/error.py
	Lib/urllib/parse.py Lib/urllib/request.py
	Lib/urllib/response.py Lib/urllib/robotparser.py
	Lib/urllib2.py Lib/urlparse.py Lib/wsgiref/simple_server.py
	Lib/wsgiref/util.py Lib/xmlrpc/client.py Makefile.pre.in
Message-ID: <20080617210138.BF1B81E4010@bag.python.org>

Author: jeremy.hylton
Date: Tue Jun 17 23:01:35 2008
New Revision: 64346

Log:
Mostly working version of urllib+urllib2 modules to urllib package conversion.


Added:
   python/branches/py3k-urllib/Lib/urllib/
   python/branches/py3k-urllib/Lib/urllib/__init__.py
   python/branches/py3k-urllib/Lib/urllib/error.py
   python/branches/py3k-urllib/Lib/urllib/parse.py
      - copied, changed from r64345, /python/branches/py3k-urllib/Lib/urllib.py
   python/branches/py3k-urllib/Lib/urllib/request.py
      - copied, changed from r64345, /python/branches/py3k-urllib/Lib/urllib2.py
   python/branches/py3k-urllib/Lib/urllib/response.py
   python/branches/py3k-urllib/Lib/urllib/robotparser.py
      - copied, changed from r64345, /python/branches/py3k-urllib/Lib/robotparser.py
Removed:
   python/branches/py3k-urllib/Lib/robotparser.py
   python/branches/py3k-urllib/Lib/urllib.py
   python/branches/py3k-urllib/Lib/urllib2.py
   python/branches/py3k-urllib/Lib/urlparse.py
Modified:
   python/branches/py3k-urllib/Lib/cgi.py
   python/branches/py3k-urllib/Lib/distutils/command/register.py
   python/branches/py3k-urllib/Lib/distutils/command/upload.py
   python/branches/py3k-urllib/Lib/email/utils.py
   python/branches/py3k-urllib/Lib/http/client.py
   python/branches/py3k-urllib/Lib/http/cookiejar.py
   python/branches/py3k-urllib/Lib/http/server.py
   python/branches/py3k-urllib/Lib/macurl2path.py
   python/branches/py3k-urllib/Lib/mimetypes.py
   python/branches/py3k-urllib/Lib/test/regrtest.py
   python/branches/py3k-urllib/Lib/test/test___all__.py
   python/branches/py3k-urllib/Lib/test/test_http_cookiejar.py
   python/branches/py3k-urllib/Lib/test/test_httpservers.py
   python/branches/py3k-urllib/Lib/test/test_importhooks.py
   python/branches/py3k-urllib/Lib/test/test_pyclbr.py
   python/branches/py3k-urllib/Lib/test/test_robotparser.py
   python/branches/py3k-urllib/Lib/test/test_ssl.py
   python/branches/py3k-urllib/Lib/test/test_urllib.py
   python/branches/py3k-urllib/Lib/test/test_urllib2.py
   python/branches/py3k-urllib/Lib/test/test_urllib2_localnet.py
   python/branches/py3k-urllib/Lib/test/test_urllib2net.py
   python/branches/py3k-urllib/Lib/test/test_urllibnet.py
   python/branches/py3k-urllib/Lib/test/test_urlparse.py
   python/branches/py3k-urllib/Lib/test/test_xmlrpc.py
   python/branches/py3k-urllib/Lib/wsgiref/simple_server.py
   python/branches/py3k-urllib/Lib/wsgiref/util.py
   python/branches/py3k-urllib/Lib/xmlrpc/client.py
   python/branches/py3k-urllib/Makefile.pre.in

Modified: python/branches/py3k-urllib/Lib/cgi.py
==============================================================================
--- python/branches/py3k-urllib/Lib/cgi.py	(original)
+++ python/branches/py3k-urllib/Lib/cgi.py	Tue Jun 17 23:01:35 2008
@@ -35,7 +35,7 @@
 from io import StringIO
 import sys
 import os
-import urllib
+import urllib.parse
 import email.parser
 
 __all__ = ["MiniFieldStorage", "FieldStorage",
@@ -216,8 +216,8 @@
             else:
                 continue
         if len(nv[1]) or keep_blank_values:
-            name = urllib.unquote(nv[0].replace('+', ' '))
-            value = urllib.unquote(nv[1].replace('+', ' '))
+            name = urllib.parse.unquote(nv[0].replace('+', ' '))
+            value = urllib.parse.unquote(nv[1].replace('+', ' '))
             r.append((name, value))
 
     return r

Modified: python/branches/py3k-urllib/Lib/distutils/command/register.py
==============================================================================
--- python/branches/py3k-urllib/Lib/distutils/command/register.py	(original)
+++ python/branches/py3k-urllib/Lib/distutils/command/register.py	Tue Jun 17 23:01:35 2008
@@ -7,8 +7,9 @@
 
 __revision__ = "$Id$"
 
-import os, string, urllib2, getpass, urlparse
+import os, string, getpass
 import io
+import urllib.parse, urllib.request
 
 from distutils.core import PyPIRCCommand
 from distutils.errors import *
@@ -94,7 +95,8 @@
     def classifiers(self):
         ''' Fetch the list of classifiers from the server.
         '''
-        response = urllib2.urlopen(self.repository+'?:action=list_classifiers')
+        url = self.repository+'?:action=list_classifiers'
+        response = urllib.request.urlopen(url)
         print(response.read())
 
     def verify_metadata(self):
@@ -166,8 +168,8 @@
                 password = getpass.getpass('Password: ')
 
             # set up the authentication
-            auth = urllib2.HTTPPasswordMgr()
-            host = urlparse.urlparse(self.repository)[1]
+            auth = urllib.request.HTTPPasswordMgr()
+            host = urllib.parse.urlparse(self.repository)[1]
             auth.add_password(self.realm, host, username, password)
             # send the info to the server and report the result
             code, result = self.post_to_server(self.build_post_data('submit'),
@@ -276,20 +278,20 @@
             'Content-type': 'multipart/form-data; boundary=%s; charset=utf-8'%boundary,
             'Content-length': str(len(body))
         }
-        req = urllib2.Request(self.repository, body, headers)
+        req = urllib.request.Request(self.repository, body, headers)
 
         # handle HTTP and include the Basic Auth handler
-        opener = urllib2.build_opener(
-            urllib2.HTTPBasicAuthHandler(password_mgr=auth)
+        opener = urllib.request.build_opener(
+            urllib.request.HTTPBasicAuthHandler(password_mgr=auth)
         )
         data = ''
         try:
             result = opener.open(req)
-        except urllib2.HTTPError as e:
+        except urllib.error.HTTPError as e:
             if self.show_response:
                 data = e.fp.read()
             result = e.code, e.msg
-        except urllib2.URLError as e:
+        except urllib.error.URLError as e:
             result = 500, str(e)
         else:
             if self.show_response:

Modified: python/branches/py3k-urllib/Lib/distutils/command/upload.py
==============================================================================
--- python/branches/py3k-urllib/Lib/distutils/command/upload.py	(original)
+++ python/branches/py3k-urllib/Lib/distutils/command/upload.py	Tue Jun 17 23:01:35 2008
@@ -13,7 +13,7 @@
 import configparser
 import http.client
 import base64
-import urlparse
+import urllib.parse
 
 class upload(PyPIRCCommand):
 
@@ -145,10 +145,11 @@
         self.announce("Submitting %s to %s" % (filename, self.repository), log.INFO)
 
         # build the Request
-        # We can't use urllib2 since we need to send the Basic
+        # We can't use urllib since we need to send the Basic
         # auth right with the first request
+        # TODO(jhylton): Can we fix urllib?
         schema, netloc, url, params, query, fragments = \
-            urlparse.urlparse(self.repository)
+            urllib.parse.urlparse(self.repository)
         assert not params and not query and not fragments
         if schema == 'http':
             http = http.client.HTTPConnection(netloc)

Modified: python/branches/py3k-urllib/Lib/email/utils.py
==============================================================================
--- python/branches/py3k-urllib/Lib/email/utils.py	(original)
+++ python/branches/py3k-urllib/Lib/email/utils.py	Tue Jun 17 23:01:35 2008
@@ -25,6 +25,7 @@
 import base64
 import random
 import socket
+import urllib.parse
 import warnings
 from io import StringIO
 
@@ -218,8 +219,7 @@
     charset is given but not language, the string is encoded using the empty
     string for language.
     """
-    import urllib
-    s = urllib.quote(s, safe='')
+    s = urllib.parse.quote(s, safe='')
     if charset is None and language is None:
         return s
     if language is None:
@@ -234,7 +234,6 @@
 
     params is a sequence of 2-tuples containing (param name, string value).
     """
-    import urllib
     # Copy params so we don't mess with the original
     params = params[:]
     new_params = []
@@ -272,7 +271,7 @@
             # language specifiers at the beginning of the string.
             for num, s, encoded in continuations:
                 if encoded:
-                    s = urllib.unquote(s)
+                    s = urllib.parse.unquote(s)
                     extended = True
                 value.append(s)
             value = quote(EMPTYSTRING.join(value))

Modified: python/branches/py3k-urllib/Lib/http/client.py
==============================================================================
--- python/branches/py3k-urllib/Lib/http/client.py	(original)
+++ python/branches/py3k-urllib/Lib/http/client.py	Tue Jun 17 23:01:35 2008
@@ -70,7 +70,7 @@
 import socket
 import email.parser
 import email.message
-from urlparse import urlsplit
+from urllib.parse import urlsplit
 import warnings
 
 __all__ = ["HTTPResponse", "HTTPConnection",

Modified: python/branches/py3k-urllib/Lib/http/cookiejar.py
==============================================================================
--- python/branches/py3k-urllib/Lib/http/cookiejar.py	(original)
+++ python/branches/py3k-urllib/Lib/http/cookiejar.py	Tue Jun 17 23:01:35 2008
@@ -28,7 +28,10 @@
 __all__ = ['Cookie', 'CookieJar', 'CookiePolicy', 'DefaultCookiePolicy',
            'FileCookieJar', 'LWPCookieJar', 'LoadError', 'MozillaCookieJar']
 
-import re, urlparse, copy, time, urllib
+import copy
+import re
+import time
+import urllib.parse, urllib.request
 try:
     import threading as _threading
 except ImportError:
@@ -580,7 +583,7 @@
 
     """
     url = request.get_full_url()
-    host = urlparse.urlparse(url)[1]
+    host = urllib.parse.urlparse(url)[1]
     if host == "":
         host = request.get_header("Host", "")
 
@@ -602,13 +605,11 @@
 def request_path(request):
     """request-URI, as defined by RFC 2965."""
     url = request.get_full_url()
-    #scheme, netloc, path, parameters, query, frag = urlparse.urlparse(url)
-    #req_path = escape_path("".join(urlparse.urlparse(url)[2:]))
-    path, parameters, query, frag = urlparse.urlparse(url)[2:]
+    path, parameters, query, frag = urllib.parse.urlparse(url)[2:]
     if parameters:
         path = "%s;%s" % (path, parameters)
     path = escape_path(path)
-    req_path = urlparse.urlunparse(("", "", path, "", query, frag))
+    req_path = urllib.parse.urlunparse(("", "", path, "", query, frag))
     if not req_path.startswith("/"):
         # fix bad RFC 2396 absoluteURI
         req_path = "/"+req_path
@@ -644,7 +645,7 @@
     # And here, kind of: draft-fielding-uri-rfc2396bis-03
     # (And in draft IRI specification: draft-duerst-iri-05)
     # (And here, for new URI schemes: RFC 2718)
-    path = urllib.quote(path, HTTP_PATH_SAFE)
+    path = urllib.parse.quote(path, HTTP_PATH_SAFE)
     path = ESCAPED_CHAR_RE.sub(uppercase_escaped_char, path)
     return path
 
@@ -1197,8 +1198,7 @@
     """Collection of HTTP cookies.
 
     You may not need to know about this class: try
-    urllib2.build_opener(HTTPCookieProcessor).open(url).
-
+    urllib.request.build_opener(HTTPCookieProcessor).open(url).
     """
 
     non_word_re = re.compile(r"\W")

Modified: python/branches/py3k-urllib/Lib/http/server.py
==============================================================================
--- python/branches/py3k-urllib/Lib/http/server.py	(original)
+++ python/branches/py3k-urllib/Lib/http/server.py	Tue Jun 17 23:01:35 2008
@@ -93,7 +93,7 @@
 import time
 import socket # For gethostbyaddr()
 import shutil
-import urllib
+import urllib.parse
 import select
 import mimetypes
 import posixpath
@@ -683,7 +683,7 @@
             return None
         list.sort(key=lambda a: a.lower())
         r = []
-        displaypath = cgi.escape(urllib.unquote(self.path))
+        displaypath = cgi.escape(urllib.parse.unquote(self.path))
         r.append('<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">')
         r.append("<html>\n<title>Directory listing for %s</title>\n" % displaypath)
         r.append("<body>\n<h2>Directory listing for %s</h2>\n" % displaypath)
@@ -699,7 +699,7 @@
                 displayname = name + "@"
                 # Note: a link to a directory displays with @ and links with /
             r.append('<li><a href="%s">%s</a>\n'
-                    % (urllib.quote(linkname), cgi.escape(displayname)))
+                    % (urllib.parse.quote(linkname), cgi.escape(displayname)))
         r.append("</ul>\n<hr>\n</body>\n</html>\n")
         enc = sys.getfilesystemencoding()
         encoded = ''.join(r).encode(enc)
@@ -723,7 +723,7 @@
         # abandon query parameters
         path = path.split('?',1)[0]
         path = path.split('#',1)[0]
-        path = posixpath.normpath(urllib.unquote(path))
+        path = posixpath.normpath(urllib.parse.unquote(path))
         words = path.split('/')
         words = filter(None, words)
         path = os.getcwd()
@@ -947,7 +947,7 @@
         env['SERVER_PROTOCOL'] = self.protocol_version
         env['SERVER_PORT'] = str(self.server.server_port)
         env['REQUEST_METHOD'] = self.command
-        uqrest = urllib.unquote(rest)
+        uqrest = urllib.parse.unquote(rest)
         env['PATH_INFO'] = uqrest
         env['PATH_TRANSLATED'] = self.translate_path(uqrest)
         env['SCRIPT_NAME'] = scriptname

Modified: python/branches/py3k-urllib/Lib/macurl2path.py
==============================================================================
--- python/branches/py3k-urllib/Lib/macurl2path.py	(original)
+++ python/branches/py3k-urllib/Lib/macurl2path.py	Tue Jun 17 23:01:35 2008
@@ -2,7 +2,7 @@
 
 Do not import directly; use urllib instead."""
 
-import urllib
+import urllib.parse
 import os
 
 __all__ = ["url2pathname","pathname2url"]
@@ -13,7 +13,7 @@
     #
     # XXXX The .. handling should be fixed...
     #
-    tp = urllib.splittype(pathname)[0]
+    tp = urllib.parsesplittype(pathname)[0]
     if tp and tp != 'file':
         raise RuntimeError('Cannot convert non-local URL to pathname')
     # Turn starting /// into /, an empty hostname means current host
@@ -47,7 +47,7 @@
             i = i + 1
         rv = ':' + ':'.join(components)
     # and finally unquote slashes and other funny characters
-    return urllib.unquote(rv)
+    return urllib.parseunquote(rv)
 
 def pathname2url(pathname):
     """OS-specific conversion from a file system path to a relative URL
@@ -73,8 +73,8 @@
         return '/'.join(components)
 
 def _pncomp2url(component):
-    component = urllib.quote(component[:31], safe='')  # We want to quote slashes
-    return component
+    # We want to quote slashes
+    return urllib.parsequote(component[:31], safe='')
 
 def test():
     for url in ["index.html",

Modified: python/branches/py3k-urllib/Lib/mimetypes.py
==============================================================================
--- python/branches/py3k-urllib/Lib/mimetypes.py	(original)
+++ python/branches/py3k-urllib/Lib/mimetypes.py	Tue Jun 17 23:01:35 2008
@@ -24,7 +24,7 @@
 
 import os
 import posixpath
-import urllib
+import urllib.parse
 
 __all__ = [
     "guess_type","guess_extension","guess_all_extensions",
@@ -104,7 +104,7 @@
         Optional `strict' argument when False adds a bunch of commonly found,
         but non-standard types.
         """
-        scheme, url = urllib.splittype(url)
+        scheme, url = urllib.parse.splittype(url)
         if scheme == 'data':
             # syntax of data URLs:
             # dataurl   := "data:" [ mediatype ] [ ";base64" ] "," data

Deleted: python/branches/py3k-urllib/Lib/robotparser.py
==============================================================================
--- python/branches/py3k-urllib/Lib/robotparser.py	Tue Jun 17 23:01:35 2008
+++ (empty file)
@@ -1,212 +0,0 @@
-""" robotparser.py
-
-    Copyright (C) 2000  Bastian Kleineidam
-
-    You can choose between two licenses when using this package:
-    1) GNU GPLv2
-    2) PSF license for Python 2.2
-
-    The robots.txt Exclusion Protocol is implemented as specified in
-    http://info.webcrawler.com/mak/projects/robots/norobots-rfc.html
-"""
-import urlparse
-import urllib
-
-__all__ = ["RobotFileParser"]
-
-class RobotFileParser:
-    """ This class provides a set of methods to read, parse and answer
-    questions about a single robots.txt file.
-
-    """
-
-    def __init__(self, url=''):
-        self.entries = []
-        self.default_entry = None
-        self.disallow_all = False
-        self.allow_all = False
-        self.set_url(url)
-        self.last_checked = 0
-
-    def mtime(self):
-        """Returns the time the robots.txt file was last fetched.
-
-        This is useful for long-running web spiders that need to
-        check for new robots.txt files periodically.
-
-        """
-        return self.last_checked
-
-    def modified(self):
-        """Sets the time the robots.txt file was last fetched to the
-        current time.
-
-        """
-        import time
-        self.last_checked = time.time()
-
-    def set_url(self, url):
-        """Sets the URL referring to a robots.txt file."""
-        self.url = url
-        self.host, self.path = urlparse.urlparse(url)[1:3]
-
-    def read(self):
-        """Reads the robots.txt URL and feeds it to the parser."""
-        opener = URLopener()
-        f = opener.open(self.url)
-        lines = []
-        line = f.readline()
-        while line:
-            lines.append(line.strip())
-            line = f.readline()
-        self.errcode = opener.errcode
-        if self.errcode in (401, 403):
-            self.disallow_all = True
-        elif self.errcode >= 400:
-            self.allow_all = True
-        elif self.errcode == 200 and lines:
-            self.parse(lines)
-
-    def _add_entry(self, entry):
-        if "*" in entry.useragents:
-            # the default entry is considered last
-            self.default_entry = entry
-        else:
-            self.entries.append(entry)
-
-    def parse(self, lines):
-        """parse the input lines from a robots.txt file.
-           We allow that a user-agent: line is not preceded by
-           one or more blank lines."""
-        state = 0
-        linenumber = 0
-        entry = Entry()
-
-        for line in lines:
-            linenumber = linenumber + 1
-            if not line:
-                if state == 1:
-                    entry = Entry()
-                    state = 0
-                elif state == 2:
-                    self._add_entry(entry)
-                    entry = Entry()
-                    state = 0
-            # remove optional comment and strip line
-            i = line.find('#')
-            if i >= 0:
-                line = line[:i]
-            line = line.strip()
-            if not line:
-                continue
-            line = line.split(':', 1)
-            if len(line) == 2:
-                line[0] = line[0].strip().lower()
-                line[1] = urllib.unquote(line[1].strip())
-                if line[0] == "user-agent":
-                    if state == 2:
-                        self._add_entry(entry)
-                        entry = Entry()
-                    entry.useragents.append(line[1])
-                    state = 1
-                elif line[0] == "disallow":
-                    if state != 0:
-                        entry.rulelines.append(RuleLine(line[1], False))
-                        state = 2
-                elif line[0] == "allow":
-                    if state != 0:
-                        entry.rulelines.append(RuleLine(line[1], True))
-        if state == 2:
-            self.entries.append(entry)
-
-
-    def can_fetch(self, useragent, url):
-        """using the parsed robots.txt decide if useragent can fetch url"""
-        if self.disallow_all:
-            return False
-        if self.allow_all:
-            return True
-        # search for given user agent matches
-        # the first match counts
-        url = urllib.quote(urlparse.urlparse(urllib.unquote(url))[2]) or "/"
-        for entry in self.entries:
-            if entry.applies_to(useragent):
-                return entry.allowance(url)
-        # try the default entry last
-        if self.default_entry:
-            return self.default_entry.allowance(url)
-        # agent not found ==> access granted
-        return True
-
-
-    def __str__(self):
-        return ''.join([str(entry) + "\n" for entry in self.entries])
-
-
-class RuleLine:
-    """A rule line is a single "Allow:" (allowance==True) or "Disallow:"
-       (allowance==False) followed by a path."""
-    def __init__(self, path, allowance):
-        if path == '' and not allowance:
-            # an empty value means allow all
-            allowance = True
-        self.path = urllib.quote(path)
-        self.allowance = allowance
-
-    def applies_to(self, filename):
-        return self.path == "*" or filename.startswith(self.path)
-
-    def __str__(self):
-        return (self.allowance and "Allow" or "Disallow") + ": " + self.path
-
-
-class Entry:
-    """An entry has one or more user-agents and zero or more rulelines"""
-    def __init__(self):
-        self.useragents = []
-        self.rulelines = []
-
-    def __str__(self):
-        ret = []
-        for agent in self.useragents:
-            ret.extend(["User-agent: ", agent, "\n"])
-        for line in self.rulelines:
-            ret.extend([str(line), "\n"])
-        return ''.join(ret)
-
-    def applies_to(self, useragent):
-        """check if this entry applies to the specified agent"""
-        # split the name token and make it lower case
-        useragent = useragent.split("/")[0].lower()
-        for agent in self.useragents:
-            if agent == '*':
-                # we have the catch-all agent
-                return True
-            agent = agent.lower()
-            if agent in useragent:
-                return True
-        return False
-
-    def allowance(self, filename):
-        """Preconditions:
-        - our agent applies to this entry
-        - filename is URL decoded"""
-        for line in self.rulelines:
-            if line.applies_to(filename):
-                return line.allowance
-        return True
-
-class URLopener(urllib.FancyURLopener):
-    def __init__(self, *args):
-        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,
-                                                        errmsg, headers)

Modified: python/branches/py3k-urllib/Lib/test/regrtest.py
==============================================================================
--- python/branches/py3k-urllib/Lib/test/regrtest.py	(original)
+++ python/branches/py3k-urllib/Lib/test/regrtest.py	Tue Jun 17 23:01:35 2008
@@ -725,7 +725,7 @@
 def dash_R_cleanup(fs, ps, pic, abcs):
     import gc, copyreg
     import _strptime, linecache
-    import urlparse, urllib, urllib2, mimetypes, doctest
+    import urllib.parse, urllib.request, mimetypes, doctest
     import struct, filecmp, _abcoll
     from distutils.dir_util import _path_created
     from weakref import WeakSet
@@ -758,9 +758,8 @@
     _path_created.clear()
     re.purge()
     _strptime._regex_cache.clear()
-    urlparse.clear_cache()
-    urllib.urlcleanup()
-    urllib2.install_opener(None)
+    urllib.parse.clear_cache()
+    urllib.request.urlcleanup()
     linecache.clearcache()
     mimetypes._default_mime_types()
     filecmp._cache.clear()

Modified: python/branches/py3k-urllib/Lib/test/test___all__.py
==============================================================================
--- python/branches/py3k-urllib/Lib/test/test___all__.py	(original)
+++ python/branches/py3k-urllib/Lib/test/test___all__.py	Tue Jun 17 23:01:35 2008
@@ -111,7 +111,7 @@
         self.check_all("re")
         self.check_all("reprlib")
         self.check_all("rlcompleter")
-        self.check_all("robotparser")
+        self.check_all("urllib.robotparser")
         self.check_all("sched")
         self.check_all("shelve")
         self.check_all("shlex")
@@ -134,8 +134,6 @@
         self.check_all("traceback")
         self.check_all("tty")
         self.check_all("unittest")
-        self.check_all("urllib")
-        self.check_all("urlparse")
         self.check_all("uu")
         self.check_all("warnings")
         self.check_all("wave")

Modified: python/branches/py3k-urllib/Lib/test/test_http_cookiejar.py
==============================================================================
--- python/branches/py3k-urllib/Lib/test/test_http_cookiejar.py	(original)
+++ python/branches/py3k-urllib/Lib/test/test_http_cookiejar.py	Tue Jun 17 23:01:35 2008
@@ -1,6 +1,6 @@
 """Tests for http/cookiejar.py."""
 
-import re, os, time, urllib2
+import re, os, time, urllib.request
 from unittest import TestCase
 
 from test import support
@@ -206,7 +206,7 @@
 
 def _interact(cookiejar, url, set_cookie_hdrs, hdr_name):
     """Perform a single request / response cycle, returning Cookie: header."""
-    req = urllib2.Request(url)
+    req = urllib.request.Request(url)
     cookiejar.add_cookie_header(req)
     cookie_hdr = req.get_header("Cookie", "")
     headers = []
@@ -330,7 +330,7 @@
             ("http://foo/", "foo.local", True),
             ("http://foo/", ".local", True),
             ]:
-            request = urllib2.Request(url)
+            request = urllib.request.Request(url)
             r = pol.domain_return_ok(domain, request)
             if ok: self.assert_(r)
             else: self.assert_(not r)
@@ -547,46 +547,48 @@
 
     def test_request_path(self):
         # with parameters
-        req = urllib2.Request("http://www.example.com/rheum/rhaponicum;"
-                              "foo=bar;sing=song?apples=pears&spam=eggs#ni")
+        req = urllib.request.Request(
+            "http://www.example.com/rheum/rhaponicum;"
+            "foo=bar;sing=song?apples=pears&spam=eggs#ni")
         self.assertEquals(request_path(req), "/rheum/rhaponicum;"
                      "foo=bar;sing=song?apples=pears&spam=eggs#ni")
         # without parameters
-        req = urllib2.Request("http://www.example.com/rheum/rhaponicum?"
-                              "apples=pears&spam=eggs#ni")
+        req = urllib.request.Request(
+            "http://www.example.com/rheum/rhaponicum?"
+            "apples=pears&spam=eggs#ni")
         self.assertEquals(request_path(req), "/rheum/rhaponicum?"
                      "apples=pears&spam=eggs#ni")
         # missing final slash
-        req = urllib2.Request("http://www.example.com")
+        req = urllib.request.Request("http://www.example.com")
         self.assertEquals(request_path(req), "/")
 
     def test_request_port(self):
-        req = urllib2.Request("http://www.acme.com:1234/",
-                              headers={"Host": "www.acme.com:4321"})
+        req = urllib.request.Request("http://www.acme.com:1234/",
+                                     headers={"Host": "www.acme.com:4321"})
         self.assertEquals(request_port(req), "1234")
-        req = urllib2.Request("http://www.acme.com/",
-                              headers={"Host": "www.acme.com:4321"})
+        req = urllib.request.Request("http://www.acme.com/",
+                                     headers={"Host": "www.acme.com:4321"})
         self.assertEquals(request_port(req), DEFAULT_HTTP_PORT)
 
     def test_request_host(self):
         # this request is illegal (RFC2616, 14.2.3)
-        req = urllib2.Request("http://1.1.1.1/",
-                              headers={"Host": "www.acme.com:80"})
+        req = urllib.request.Request("http://1.1.1.1/",
+                                     headers={"Host": "www.acme.com:80"})
         # libwww-perl wants this response, but that seems wrong (RFC 2616,
         # section 5.2, point 1., and RFC 2965 section 1, paragraph 3)
         #self.assertEquals(request_host(req), "www.acme.com")
         self.assertEquals(request_host(req), "1.1.1.1")
-        req = urllib2.Request("http://www.acme.com/",
-                              headers={"Host": "irrelevant.com"})
+        req = urllib.request.Request("http://www.acme.com/",
+                                     headers={"Host": "irrelevant.com"})
         self.assertEquals(request_host(req), "www.acme.com")
         # not actually sure this one is valid Request object, so maybe should
         # remove test for no host in url in request_host function?
-        req = urllib2.Request("/resource.html",
-                              headers={"Host": "www.acme.com"})
+        req = urllib.request.Request("/resource.html",
+                                     headers={"Host": "www.acme.com"})
         self.assertEquals(request_host(req), "www.acme.com")
         # port shouldn't be in request-host
-        req = urllib2.Request("http://www.acme.com:2345/resource.html",
-                              headers={"Host": "www.acme.com:5432"})
+        req = urllib.request.Request("http://www.acme.com:2345/resource.html",
+                                     headers={"Host": "www.acme.com:5432"})
         self.assertEquals(request_host(req), "www.acme.com")
 
     def test_is_HDN(self):
@@ -766,24 +768,24 @@
             blocked_domains=["acme.com"],
             allowed_domains=["www.acme.com"]))
 
-        req = urllib2.Request("http://acme.com/")
+        req = urllib.request.Request("http://acme.com/")
         headers = ["Set-Cookie: CUSTOMER=WILE_E_COYOTE; path=/"]
         res = FakeResponse(headers, "http://acme.com/")
         c.extract_cookies(res, req)
         self.assertEquals(len(c), 0)
 
-        req = urllib2.Request("http://www.acme.com/")
+        req = urllib.request.Request("http://www.acme.com/")
         res = FakeResponse(headers, "http://www.acme.com/")
         c.extract_cookies(res, req)
         self.assertEquals(len(c), 1)
 
-        req = urllib2.Request("http://www.coyote.com/")
+        req = urllib.request.Request("http://www.coyote.com/")
         res = FakeResponse(headers, "http://www.coyote.com/")
         c.extract_cookies(res, req)
         self.assertEquals(len(c), 1)
 
         # set a cookie with non-allowed domain...
-        req = urllib2.Request("http://www.coyote.com/")
+        req = urllib.request.Request("http://www.coyote.com/")
         res = FakeResponse(headers, "http://www.coyote.com/")
         cookies = c.make_cookies(res, req)
         c.set_cookie(cookies[0])
@@ -798,7 +800,7 @@
         c = CookieJar(policy=pol)
         headers = ["Set-Cookie: CUSTOMER=WILE_E_COYOTE; path=/"]
 
-        req = urllib2.Request("http://www.acme.com/")
+        req = urllib.request.Request("http://www.acme.com/")
         res = FakeResponse(headers, "http://www.acme.com/")
         c.extract_cookies(res, req)
         self.assertEquals(len(c), 0)
@@ -808,11 +810,11 @@
         self.assertEquals(len(c), 1)
 
         c.clear()
-        req = urllib2.Request("http://www.roadrunner.net/")
+        req = urllib.request.Request("http://www.roadrunner.net/")
         res = FakeResponse(headers, "http://www.roadrunner.net/")
         c.extract_cookies(res, req)
         self.assertEquals(len(c), 1)
-        req = urllib2.Request("http://www.roadrunner.net/")
+        req = urllib.request.Request("http://www.roadrunner.net/")
         c.add_cookie_header(req)
         self.assert_((req.has_header("Cookie") and
                       req.has_header("Cookie2")))
@@ -823,7 +825,7 @@
         self.assertEquals(len(c), 1)
 
         # set a cookie with blocked domain...
-        req = urllib2.Request("http://www.acme.com/")
+        req = urllib.request.Request("http://www.acme.com/")
         res = FakeResponse(headers, "http://www.acme.com/")
         cookies = c.make_cookies(res, req)
         c.set_cookie(cookies[0])
@@ -866,7 +868,7 @@
         url = "http://www.acme.com"
         c = CookieJar(DefaultCookiePolicy(rfc2965=True))
         interact_2965(c, url, "foo=bar; Version=1")
-        req = urllib2.Request(url)
+        req = urllib.request.Request(url)
         self.assertEquals(len(c), 1)
         c.add_cookie_header(req)
         self.assert_(req.has_header("Cookie"))
@@ -1009,7 +1011,7 @@
 
         def cookiejar_from_cookie_headers(headers):
             c = CookieJar()
-            req = urllib2.Request("http://www.example.com/")
+            req = urllib.request.Request("http://www.example.com/")
             r = FakeResponse(headers, "http://www.example.com/")
             c.extract_cookies(r, req)
             return c
@@ -1080,9 +1082,9 @@
 
         c = CookieJar(DefaultCookiePolicy(rfc2965 = True))
 
-        #req = urllib2.Request("http://1.1.1.1/",
+        #req = urllib.request.Request("http://1.1.1.1/",
         #              headers={"Host": "www.acme.com:80"})
-        req = urllib2.Request("http://www.acme.com:80/",
+        req = urllib.request.Request("http://www.acme.com:80/",
                       headers={"Host": "www.acme.com:80"})
 
         headers.append(
@@ -1091,7 +1093,7 @@
         res = FakeResponse(headers, "http://www.acme.com/")
         c.extract_cookies(res, req)
 
-        req = urllib2.Request("http://www.acme.com/")
+        req = urllib.request.Request("http://www.acme.com/")
         c.add_cookie_header(req)
 
         self.assertEqual(req.get_header("Cookie"), "CUSTOMER=WILE_E_COYOTE")
@@ -1101,7 +1103,7 @@
         res = FakeResponse(headers, "http://www.acme.com/")
         c.extract_cookies(res, req)
 
-        req = urllib2.Request("http://www.acme.com/foo/bar")
+        req = urllib.request.Request("http://www.acme.com/foo/bar")
         c.add_cookie_header(req)
 
         h = req.get_header("Cookie")
@@ -1112,7 +1114,7 @@
         res = FakeResponse(headers, "http://www.acme.com")
         c.extract_cookies(res, req)
 
-        req = urllib2.Request("http://www.acme.com/")
+        req = urllib.request.Request("http://www.acme.com/")
         c.add_cookie_header(req)
 
         h = req.get_header("Cookie")
@@ -1120,7 +1122,7 @@
                      "CUSTOMER=WILE_E_COYOTE" in h and
                      "SHIPPING=FEDEX" not in h)
 
-        req = urllib2.Request("http://www.acme.com/foo/")
+        req = urllib.request.Request("http://www.acme.com/foo/")
         c.add_cookie_header(req)
 
         h = req.get_header("Cookie")
@@ -1155,13 +1157,13 @@
         c = CookieJar()
         headers = []
 
-        req = urllib2.Request("http://www.acme.com/")
+        req = urllib.request.Request("http://www.acme.com/")
         headers.append("Set-Cookie: PART_NUMBER=ROCKET_LAUNCHER_0001; path=/")
         res = FakeResponse(headers, "http://www.acme.com/")
 
         c.extract_cookies(res, req)
 
-        req = urllib2.Request("http://www.acme.com/")
+        req = urllib.request.Request("http://www.acme.com/")
         c.add_cookie_header(req)
 
         self.assertEquals(req.get_header("Cookie"),
@@ -1172,7 +1174,7 @@
         res = FakeResponse(headers, "http://www.acme.com/")
         c.extract_cookies(res, req)
 
-        req = urllib2.Request("http://www.acme.com/ammo")
+        req = urllib.request.Request("http://www.acme.com/ammo")
         c.add_cookie_header(req)
 
         self.assert_(re.search(r"PART_NUMBER=RIDING_ROCKET_0023;\s*"
@@ -1503,7 +1505,7 @@
         # Some additional Netscape cookies tests.
         c = CookieJar()
         headers = []
-        req = urllib2.Request("http://foo.bar.acme.com/foo")
+        req = urllib.request.Request("http://foo.bar.acme.com/foo")
 
         # Netscape allows a host part that contains dots
         headers.append("Set-Cookie: Customer=WILE_E_COYOTE; domain=.acme.com")
@@ -1517,7 +1519,7 @@
         res = FakeResponse(headers, "http://www.acme.com/foo")
         c.extract_cookies(res, req)
 
-        req = urllib2.Request("http://foo.bar.acme.com/foo")
+        req = urllib.request.Request("http://foo.bar.acme.com/foo")
         c.add_cookie_header(req)
         self.assert_(
             "PART_NUMBER=3,4" in req.get_header("Cookie") and
@@ -1559,12 +1561,12 @@
         c = CookieJar(DefaultCookiePolicy(rfc2965 = True))
         headers = []
 
-        req = urllib2.Request("http://www.ants.com/")
+        req = urllib.request.Request("http://www.ants.com/")
         headers.append("Set-Cookie: JSESSIONID=ABCDERANDOM123; Path=")
         res = FakeResponse(headers, "http://www.ants.com/")
         c.extract_cookies(res, req)
 
-        req = urllib2.Request("http://www.ants.com/")
+        req = urllib.request.Request("http://www.ants.com/")
         c.add_cookie_header(req)
 
         self.assertEquals(req.get_header("Cookie"),
@@ -1572,7 +1574,7 @@
         self.assertEquals(req.get_header("Cookie2"), '$Version="1"')
 
         # missing path in the request URI
-        req = urllib2.Request("http://www.ants.com:8080")
+        req = urllib.request.Request("http://www.ants.com:8080")
         c.add_cookie_header(req)
 
         self.assertEquals(req.get_header("Cookie"),
@@ -1585,7 +1587,7 @@
         # Check session cookies are deleted properly by
         # CookieJar.clear_session_cookies method
 
-        req = urllib2.Request('http://www.perlmeister.com/scripts')
+        req = urllib.request.Request('http://www.perlmeister.com/scripts')
         headers = []
         headers.append("Set-Cookie: s1=session;Path=/scripts")
         headers.append("Set-Cookie: p1=perm; Domain=.perlmeister.com;"

Modified: python/branches/py3k-urllib/Lib/test/test_httpservers.py
==============================================================================
--- python/branches/py3k-urllib/Lib/test/test_httpservers.py	(original)
+++ python/branches/py3k-urllib/Lib/test/test_httpservers.py	Tue Jun 17 23:01:35 2008
@@ -11,7 +11,7 @@
 import sys
 import base64
 import shutil
-import urllib
+import urllib.parse
 import http.client
 import tempfile
 import threading
@@ -322,7 +322,8 @@
              (res.read(), res.getheader('Content-type'), res.status))
 
     def test_post(self):
-        params = urllib.urlencode({'spam' : 1, 'eggs' : 'python', 'bacon' : 123456})
+        params = urllib.parse.urlencode(
+            {'spam' : 1, 'eggs' : 'python', 'bacon' : 123456})
         headers = {'Content-type' : 'application/x-www-form-urlencoded'}
         res = self.request('/cgi-bin/file2.py', 'POST', params, headers)
 

Modified: python/branches/py3k-urllib/Lib/test/test_importhooks.py
==============================================================================
--- python/branches/py3k-urllib/Lib/test/test_importhooks.py	(original)
+++ python/branches/py3k-urllib/Lib/test/test_importhooks.py	Tue Jun 17 23:01:35 2008
@@ -247,22 +247,22 @@
         i = ImpWrapper()
         sys.meta_path.append(i)
         sys.path_hooks.append(ImpWrapper)
-        mnames = ("colorsys", "urlparse", "distutils.core")
+        mnames = ("colorsys", "urllib.parse", "distutils.core")
         for mname in mnames:
             parent = mname.split(".")[0]
-            for n in list(sys.modules.keys()):
+            for n in list(sys.modules):
                 if n.startswith(parent):
                     del sys.modules[n]
         for mname in mnames:
             m = __import__(mname, globals(), locals(), ["__dummy__"])
             m.__loader__  # to make sure we actually handled the import
-        # Delete urllib from modules because urlparse was imported above.
-        # Without this hack, test_socket_ssl fails if run in this order:
-        # regrtest.py test_codecmaps_tw test_importhooks test_socket_ssl
-        try:
-            del sys.modules['urllib']
-        except KeyError:
-            pass
+##        # Delete urllib from modules because urlparse was imported above.
+##        # Without this hack, test_socket_ssl fails if run in this order:
+##        # regrtest.py test_codecmaps_tw test_importhooks test_socket_ssl
+##        try:
+##            del sys.modules['urllib']
+##        except KeyError:
+##            pass
 
 def test_main():
     support.run_unittest(ImportHooksTestCase)

Modified: python/branches/py3k-urllib/Lib/test/test_pyclbr.py
==============================================================================
--- python/branches/py3k-urllib/Lib/test/test_pyclbr.py	(original)
+++ python/branches/py3k-urllib/Lib/test/test_pyclbr.py	Tue Jun 17 23:01:35 2008
@@ -156,16 +156,6 @@
         # These were once about the 10 longest modules
         cm('random', ignore=('Random',))  # from _random import Random as CoreGenerator
         cm('cgi', ignore=('log',))      # set with = in module
-        cm('urllib', ignore=('_CFNumberToInt32',
-                             '_CStringFromCFString',
-                             '_CFSetup',
-                             'getproxies_registry',
-                             'proxy_bypass_registry',
-                             'proxy_bypass_macosx_sysconf',
-                             'open_https',
-                             '_https_connection',
-                             'getproxies_macosx_sysconf',
-                             'getproxies_internetconfig',)) # not on all platforms
         cm('pickle')
         cm('aifc', ignore=('openfp',))  # set with = in module
         cm('sre_parse', ignore=('dump',)) # from sre_constants import *

Modified: python/branches/py3k-urllib/Lib/test/test_robotparser.py
==============================================================================
--- python/branches/py3k-urllib/Lib/test/test_robotparser.py	(original)
+++ python/branches/py3k-urllib/Lib/test/test_robotparser.py	Tue Jun 17 23:01:35 2008
@@ -1,5 +1,6 @@
-import unittest, robotparser
 import io
+import unittest
+import urllib.robotparser
 from test import support
 
 class RobotTestCase(unittest.TestCase):
@@ -34,7 +35,7 @@
               agent="test_robotparser"):
 
     lines = io.StringIO(robots_txt).readlines()
-    parser = robotparser.RobotFileParser()
+    parser = urllib.robotparser.RobotFileParser()
     parser.parse(lines)
     for url in good_urls:
         tests.addTest(RobotTestCase(index, parser, url, 1, agent))
@@ -140,7 +141,7 @@
         support.requires('network')
         # whole site is password-protected.
         url = 'http://mueblesmoraleda.com'
-        parser = robotparser.RobotFileParser()
+        parser = urllib.robotparser.RobotFileParser()
         parser.set_url(url)
         parser.read()
         self.assertEqual(parser.can_fetch("*", url+"/robots.txt"), False)

Modified: python/branches/py3k-urllib/Lib/test/test_ssl.py
==============================================================================
--- python/branches/py3k-urllib/Lib/test/test_ssl.py	(original)
+++ python/branches/py3k-urllib/Lib/test/test_ssl.py	Tue Jun 17 23:01:35 2008
@@ -10,7 +10,7 @@
 import time
 import os
 import pprint
-import urllib, urlparse
+import urllib.parse, urllib.request
 import shutil
 import traceback
 import asyncore
@@ -440,8 +440,8 @@
 
                 """
                 # abandon query parameters
-                path = urlparse.urlparse(path)[2]
-                path = os.path.normpath(urllib.unquote(path))
+                path = urllib.parse.urlparse(path)[2]
+                path = os.path.normpath(urllib.parse.unquote(path))
                 words = path.split('/')
                 words = filter(None, words)
                 path = self.root
@@ -943,7 +943,7 @@
                 # now fetch the same data from the HTTPS server
                 url = 'https://%s:%d/%s' % (
                     HOST, server.port, os.path.split(CERTFILE)[1])
-                f = urllib.urlopen(url)
+                f = urllib.request.urlopen(url)
                 dlen = f.info().get("content-length")
                 if dlen and (int(dlen) > 0):
                     d2 = f.read(int(dlen))

Modified: python/branches/py3k-urllib/Lib/test/test_urllib.py
==============================================================================
--- python/branches/py3k-urllib/Lib/test/test_urllib.py	(original)
+++ python/branches/py3k-urllib/Lib/test/test_urllib.py	Tue Jun 17 23:01:35 2008
@@ -1,6 +1,7 @@
 """Regresssion tests for urllib"""
 
-import urllib
+import urllib.parse
+import urllib.request
 import http.client
 import email.message
 import io
@@ -16,6 +17,23 @@
         hex_repr = "0%s" % hex_repr
     return "%" + hex_repr
 
+# Shortcut for testing FancyURLopener
+_urlopener = None
+def urlopen(url, data=None, proxies=None):
+    """urlopen(url [, data]) -> open file-like object"""
+    global _urlopener
+    if proxies is not None:
+        opener = urllib.request.FancyURLopener(proxies=proxies)
+    elif not _urlopener:
+        opener = urllib.request.FancyURLopener()
+        _urlopener = opener
+    else:
+        opener = _urlopener
+    if data is None:
+        return opener.open(url)
+    else:
+        return opener.open(url, data)
+
 class urlopen_FileTests(unittest.TestCase):
     """Test urlopen() opening a temporary file.
 
@@ -25,15 +43,16 @@
     """
 
     def setUp(self):
-        """Setup of a temp file to use for testing"""
-        self.text = bytes("test_urllib: %s\n" % self.__class__.__name__, "ascii")
-        FILE = open(support.TESTFN, 'wb')
+        # Create a temp file to use for testing
+        self.text = bytes("test_urllib: %s\n" % self.__class__.__name__,
+                          "ascii")
+        f = open(support.TESTFN, 'wb')
         try:
-            FILE.write(self.text)
+            f.write(self.text)
         finally:
-            FILE.close()
+            f.close()
         self.pathname = support.TESTFN
-        self.returned_obj = urllib.urlopen("file:%s" % self.pathname)
+        self.returned_obj = urlopen("file:%s" % self.pathname)
 
     def tearDown(self):
         """Shut down the open object"""
@@ -119,7 +138,7 @@
     def test_read(self):
         self.fakehttp(b"Hello!")
         try:
-            fp = urllib.urlopen("http://python.org/")
+            fp = urlopen("http://python.org/")
             self.assertEqual(fp.readline(), b"Hello!")
             self.assertEqual(fp.readline(), b"")
             self.assertEqual(fp.geturl(), 'http://python.org/')
@@ -136,7 +155,7 @@
 Content-Type: text/html; charset=iso-8859-1
 ''')
         try:
-            self.assertRaises(IOError, urllib.urlopen, "http://python.org/")
+            self.assertRaises(IOError, urlopen, "http://python.org/")
         finally:
             self.unfakehttp()
 
@@ -145,7 +164,7 @@
         # data. (#1680230)
         self.fakehttp(b'')
         try:
-            self.assertRaises(IOError, urllib.urlopen, "http://something")
+            self.assertRaises(IOError, urlopen, "http://something")
         finally:
             self.unfakehttp()
 
@@ -180,7 +199,8 @@
             except: pass
 
     def constructLocalFileUrl(self, filePath):
-        return "file://%s" % urllib.pathname2url(os.path.abspath(filePath))
+        return "file://%s" % urllib.request.pathname2url(
+            os.path.abspath(filePath))
 
     def createNewTempFile(self, data=b""):
         """Creates a new temporary file containing the specified data,
@@ -204,7 +224,7 @@
     def test_basic(self):
         # Make sure that a local file just gets its own location returned and
         # a headers value is returned.
-        result = urllib.urlretrieve("file:%s" % support.TESTFN)
+        result = urllib.request.urlretrieve("file:%s" % support.TESTFN)
         self.assertEqual(result[0], support.TESTFN)
         self.assert_(isinstance(result[1], email.message.Message),
                      "did not get a email.message.Message instance as second "
@@ -214,7 +234,7 @@
         # Test that setting the filename argument works.
         second_temp = "%s.2" % support.TESTFN
         self.registerFileForCleanUp(second_temp)
-        result = urllib.urlretrieve(self.constructLocalFileUrl(
+        result = urllib.request.urlretrieve(self.constructLocalFileUrl(
             support.TESTFN), second_temp)
         self.assertEqual(second_temp, result[0])
         self.assert_(os.path.exists(second_temp), "copy of the file was not "
@@ -238,7 +258,8 @@
             count_holder[0] = count_holder[0] + 1
         second_temp = "%s.2" % support.TESTFN
         self.registerFileForCleanUp(second_temp)
-        urllib.urlretrieve(self.constructLocalFileUrl(support.TESTFN),
+        urllib.request.urlretrieve(
+            self.constructLocalFileUrl(support.TESTFN),
             second_temp, hooktester)
 
     def test_reporthook_0_bytes(self):
@@ -247,7 +268,7 @@
         def hooktester(count, block_size, total_size, _report=report):
             _report.append((count, block_size, total_size))
         srcFileName = self.createNewTempFile()
-        urllib.urlretrieve(self.constructLocalFileUrl(srcFileName),
+        urllib.request.urlretrieve(self.constructLocalFileUrl(srcFileName),
             support.TESTFN, hooktester)
         self.assertEqual(len(report), 1)
         self.assertEqual(report[0][2], 0)
@@ -261,7 +282,7 @@
         def hooktester(count, block_size, total_size, _report=report):
             _report.append((count, block_size, total_size))
         srcFileName = self.createNewTempFile(b"x" * 5)
-        urllib.urlretrieve(self.constructLocalFileUrl(srcFileName),
+        urllib.request.urlretrieve(self.constructLocalFileUrl(srcFileName),
             support.TESTFN, hooktester)
         self.assertEqual(len(report), 2)
         self.assertEqual(report[0][1], 8192)
@@ -275,7 +296,7 @@
         def hooktester(count, block_size, total_size, _report=report):
             _report.append((count, block_size, total_size))
         srcFileName = self.createNewTempFile(b"x" * 8193)
-        urllib.urlretrieve(self.constructLocalFileUrl(srcFileName),
+        urllib.request.urlretrieve(self.constructLocalFileUrl(srcFileName),
             support.TESTFN, hooktester)
         self.assertEqual(len(report), 3)
         self.assertEqual(report[0][1], 8192)
@@ -284,10 +305,10 @@
 class QuotingTests(unittest.TestCase):
     """Tests for urllib.quote() and urllib.quote_plus()
 
-    According to RFC 2396 ("Uniform Resource Identifiers), to escape a
-    character you write it as '%' + <2 character US-ASCII hex value>.  The Python
-    code of ``'%' + hex(ord(<character>))[2:]`` escapes a character properly.
-    Case does not matter on the hex letters.
+    According to RFC 2396 (Uniform Resource Identifiers), to escape a
+    character you write it as '%' + <2 character US-ASCII hex value>.
+    The Python code of ``'%' + hex(ord(<character>))[2:]`` escapes a
+    character properly. Case does not matter on the hex letters.
 
     The various character sets specified are:
 
@@ -313,24 +334,24 @@
                                  "abcdefghijklmnopqrstuvwxyz",
                                  "0123456789",
                                  "_.-"])
-        result = urllib.quote(do_not_quote)
+        result = urllib.parse.quote(do_not_quote)
         self.assertEqual(do_not_quote, result,
                          "using quote(): %s != %s" % (do_not_quote, result))
-        result = urllib.quote_plus(do_not_quote)
+        result = urllib.parse.quote_plus(do_not_quote)
         self.assertEqual(do_not_quote, result,
                         "using quote_plus(): %s != %s" % (do_not_quote, result))
 
     def test_default_safe(self):
         # Test '/' is default value for 'safe' parameter
-        self.assertEqual(urllib.quote.__defaults__[0], '/')
+        self.assertEqual(urllib.parse.quote.__defaults__[0], '/')
 
     def test_safe(self):
         # Test setting 'safe' parameter does what it should do
         quote_by_default = "<>"
-        result = urllib.quote(quote_by_default, safe=quote_by_default)
+        result = urllib.parse.quote(quote_by_default, safe=quote_by_default)
         self.assertEqual(quote_by_default, result,
                          "using quote(): %s != %s" % (quote_by_default, result))
-        result = urllib.quote_plus(quote_by_default, safe=quote_by_default)
+        result = urllib.parse.quote_plus(quote_by_default, safe=quote_by_default)
         self.assertEqual(quote_by_default, result,
                          "using quote_plus(): %s != %s" %
                          (quote_by_default, result))
@@ -343,11 +364,11 @@
         should_quote.append(chr(127)) # For 0x7F
         should_quote = ''.join(should_quote)
         for char in should_quote:
-            result = urllib.quote(char)
+            result = urllib.parse.quote(char)
             self.assertEqual(hexescape(char), result,
                              "using quote(): %s should be escaped to %s, not %s" %
                              (char, hexescape(char), result))
-            result = urllib.quote_plus(char)
+            result = urllib.parse.quote_plus(char)
             self.assertEqual(hexescape(char), result,
                              "using quote_plus(): "
                              "%s should be escapes to %s, not %s" %
@@ -355,7 +376,7 @@
         del should_quote
         partial_quote = "ab[]cd"
         expected = "ab%5B%5Dcd"
-        result = urllib.quote(partial_quote)
+        result = urllib.parse.quote(partial_quote)
         self.assertEqual(expected, result,
                          "using quote(): %s != %s" % (expected, result))
         self.assertEqual(expected, result,
@@ -364,26 +385,26 @@
     def test_quoting_space(self):
         # Make sure quote() and quote_plus() handle spaces as specified in
         # their unique way
-        result = urllib.quote(' ')
+        result = urllib.parse.quote(' ')
         self.assertEqual(result, hexescape(' '),
                          "using quote(): %s != %s" % (result, hexescape(' ')))
-        result = urllib.quote_plus(' ')
+        result = urllib.parse.quote_plus(' ')
         self.assertEqual(result, '+',
                          "using quote_plus(): %s != +" % result)
         given = "a b cd e f"
         expect = given.replace(' ', hexescape(' '))
-        result = urllib.quote(given)
+        result = urllib.parse.quote(given)
         self.assertEqual(expect, result,
                          "using quote(): %s != %s" % (expect, result))
         expect = given.replace(' ', '+')
-        result = urllib.quote_plus(given)
+        result = urllib.parse.quote_plus(given)
         self.assertEqual(expect, result,
                          "using quote_plus(): %s != %s" % (expect, result))
 
     def test_quoting_plus(self):
-        self.assertEqual(urllib.quote_plus('alpha+beta gamma'),
+        self.assertEqual(urllib.parse.quote_plus('alpha+beta gamma'),
                          'alpha%2Bbeta+gamma')
-        self.assertEqual(urllib.quote_plus('alpha+beta gamma', '+'),
+        self.assertEqual(urllib.parse.quote_plus('alpha+beta gamma', '+'),
                          'alpha+beta+gamma')
 
 class UnquotingTests(unittest.TestCase):
@@ -399,21 +420,21 @@
         for num in range(128):
             given = hexescape(chr(num))
             expect = chr(num)
-            result = urllib.unquote(given)
+            result = urllib.parse.unquote(given)
             self.assertEqual(expect, result,
                              "using unquote(): %s != %s" % (expect, result))
-            result = urllib.unquote_plus(given)
+            result = urllib.parse.unquote_plus(given)
             self.assertEqual(expect, result,
                              "using unquote_plus(): %s != %s" %
                              (expect, result))
             escape_list.append(given)
         escape_string = ''.join(escape_list)
         del escape_list
-        result = urllib.unquote(escape_string)
+        result = urllib.parse.unquote(escape_string)
         self.assertEqual(result.count('%'), 1,
                          "using quote(): not all characters escaped; %s" %
                          result)
-        result = urllib.unquote(escape_string)
+        result = urllib.parse.unquote(escape_string)
         self.assertEqual(result.count('%'), 1,
                          "using unquote(): not all characters escaped: "
                          "%s" % result)
@@ -423,10 +444,10 @@
         # interspersed
         given = 'ab%sd' % hexescape('c')
         expect = "abcd"
-        result = urllib.unquote(given)
+        result = urllib.parse.unquote(given)
         self.assertEqual(expect, result,
                          "using quote(): %s != %s" % (expect, result))
-        result = urllib.unquote_plus(given)
+        result = urllib.parse.unquote_plus(given)
         self.assertEqual(expect, result,
                          "using unquote_plus(): %s != %s" % (expect, result))
 
@@ -434,16 +455,16 @@
         # Test difference between unquote() and unquote_plus()
         given = "are+there+spaces..."
         expect = given
-        result = urllib.unquote(given)
+        result = urllib.parse.unquote(given)
         self.assertEqual(expect, result,
                          "using unquote(): %s != %s" % (expect, result))
         expect = given.replace('+', ' ')
-        result = urllib.unquote_plus(given)
+        result = urllib.parse.unquote_plus(given)
         self.assertEqual(expect, result,
                          "using unquote_plus(): %s != %s" % (expect, result))
 
     def test_unquote_with_unicode(self):
-        r = urllib.unquote('br%C3%BCckner_sapporo_20050930.doc')
+        r = urllib.parse.unquote('br%C3%BCckner_sapporo_20050930.doc')
         self.assertEqual(r, 'br\xc3\xbcckner_sapporo_20050930.doc')
 
 class urlencode_Tests(unittest.TestCase):
@@ -462,7 +483,7 @@
 
         """
         expect_somewhere = ["1st=1", "2nd=2", "3rd=3"]
-        result = urllib.urlencode(given)
+        result = urllib.parse.urlencode(given)
         for expected in expect_somewhere:
             self.assert_(expected in result,
                          "testing %s: %s not found in %s" %
@@ -495,20 +516,20 @@
         # Make sure keys and values are quoted using quote_plus()
         given = {"&":"="}
         expect = "%s=%s" % (hexescape('&'), hexescape('='))
-        result = urllib.urlencode(given)
+        result = urllib.parse.urlencode(given)
         self.assertEqual(expect, result)
         given = {"key name":"A bunch of pluses"}
         expect = "key+name=A+bunch+of+pluses"
-        result = urllib.urlencode(given)
+        result = urllib.parse.urlencode(given)
         self.assertEqual(expect, result)
 
     def test_doseq(self):
         # Test that passing True for 'doseq' parameter works correctly
         given = {'sequence':['1', '2', '3']}
-        expect = "sequence=%s" % urllib.quote_plus(str(['1', '2', '3']))
-        result = urllib.urlencode(given)
+        expect = "sequence=%s" % urllib.parse.quote_plus(str(['1', '2', '3']))
+        result = urllib.parse.urlencode(given)
         self.assertEqual(expect, result)
-        result = urllib.urlencode(given, True)
+        result = urllib.parse.urlencode(given, True)
         for value in given["sequence"]:
             expect = "sequence=%s" % value
             self.assert_(expect in result,
@@ -523,11 +544,11 @@
         # Make sure simple tests pass
         expected_path = os.path.join("parts", "of", "a", "path")
         expected_url = "parts/of/a/path"
-        result = urllib.pathname2url(expected_path)
+        result = urllib.request.pathname2url(expected_path)
         self.assertEqual(expected_url, result,
                          "pathname2url() failed; %s != %s" %
                          (result, expected_url))
-        result = urllib.url2pathname(expected_url)
+        result = urllib.request.url2pathname(expected_url)
         self.assertEqual(expected_path, result,
                          "url2pathame() failed; %s != %s" %
                          (result, expected_path))
@@ -536,25 +557,25 @@
         # Test automatic quoting and unquoting works for pathnam2url() and
         # url2pathname() respectively
         given = os.path.join("needs", "quot=ing", "here")
-        expect = "needs/%s/here" % urllib.quote("quot=ing")
-        result = urllib.pathname2url(given)
+        expect = "needs/%s/here" % urllib.parse.quote("quot=ing")
+        result = urllib.request.pathname2url(given)
         self.assertEqual(expect, result,
                          "pathname2url() failed; %s != %s" %
                          (expect, result))
         expect = given
-        result = urllib.url2pathname(result)
+        result = urllib.request.url2pathname(result)
         self.assertEqual(expect, result,
                          "url2pathname() failed; %s != %s" %
                          (expect, result))
         given = os.path.join("make sure", "using_quote")
-        expect = "%s/using_quote" % urllib.quote("make sure")
-        result = urllib.pathname2url(given)
+        expect = "%s/using_quote" % urllib.parse.quote("make sure")
+        result = urllib.request.pathname2url(given)
         self.assertEqual(expect, result,
                          "pathname2url() failed; %s != %s" %
                          (expect, result))
         given = "make+sure/using_unquote"
         expect = os.path.join("make+sure", "using_unquote")
-        result = urllib.url2pathname(given)
+        result = urllib.request.url2pathname(given)
         self.assertEqual(expect, result,
                          "url2pathname() failed; %s != %s" %
                          (expect, result))

Modified: python/branches/py3k-urllib/Lib/test/test_urllib2.py
==============================================================================
--- python/branches/py3k-urllib/Lib/test/test_urllib2.py	(original)
+++ python/branches/py3k-urllib/Lib/test/test_urllib2.py	Tue Jun 17 23:01:35 2008
@@ -5,8 +5,8 @@
 import io
 import socket
 
-import urllib2
-from urllib2 import Request, OpenerDirector
+import urllib.request
+from urllib.request import Request, OpenerDirector
 
 # XXX
 # Request
@@ -17,10 +17,10 @@
     def test_trivial(self):
         # A couple trivial tests
 
-        self.assertRaises(ValueError, urllib2.urlopen, 'bogus url')
+        self.assertRaises(ValueError, urllib.request.urlopen, 'bogus url')
 
         # XXX Name hacking to get this to work on Windows.
-        fname = os.path.abspath(urllib2.__file__).replace('\\', '/')
+        fname = os.path.abspath(urllib.request.__file__).replace('\\', '/')
         if fname[1:2] == ":":
             fname = fname[2:]
         # And more hacking to get it to work on MacOS. This assumes
@@ -29,18 +29,21 @@
             fname = '/' + fname.replace(':', '/')
 
         file_url = "file://%s" % fname
-        f = urllib2.urlopen(file_url)
+        f = urllib.request.urlopen(file_url)
 
         buf = f.read()
         f.close()
 
     def test_parse_http_list(self):
-        tests = [('a,b,c', ['a', 'b', 'c']),
-                 ('path"o,l"og"i"cal, example', ['path"o,l"og"i"cal', 'example']),
-                 ('a, b, "c", "d", "e,f", g, h', ['a', 'b', '"c"', '"d"', '"e,f"', 'g', 'h']),
-                 ('a="b\\"c", d="e\\,f", g="h\\\\i"', ['a="b"c"', 'd="e,f"', 'g="h\\i"'])]
+        tests = [
+            ('a,b,c', ['a', 'b', 'c']),
+            ('path"o,l"og"i"cal, example', ['path"o,l"og"i"cal', 'example']),
+            ('a, b, "c", "d", "e,f", g, h',
+             ['a', 'b', '"c"', '"d"', '"e,f"', 'g', 'h']),
+            ('a="b\\"c", d="e\\,f", g="h\\\\i"',
+             ['a="b"c"', 'd="e,f"', 'g="h\\i"'])]
         for string, list in tests:
-            self.assertEquals(urllib2.parse_http_list(string), list)
+            self.assertEquals(urllib.request.parse_http_list(string), list)
 
 
 def test_request_headers_dict():
@@ -107,7 +110,7 @@
 
 def test_password_manager(self):
     """
-    >>> mgr = urllib2.HTTPPasswordMgr()
+    >>> mgr = urllib.request.HTTPPasswordMgr()
     >>> add = mgr.add_password
     >>> add("Some Realm", "http://example.com/", "joe", "password")
     >>> add("Some Realm", "http://example.com/ni", "ni", "ni")
@@ -172,7 +175,7 @@
 
 def test_password_manager_default_port(self):
     """
-    >>> mgr = urllib2.HTTPPasswordMgr()
+    >>> mgr = urllib.request.HTTPPasswordMgr()
     >>> add = mgr.add_password
 
     The point to note here is that we can't guess the default port if there's
@@ -288,7 +291,7 @@
             res = MockResponse(200, "OK", {}, "")
             return self.parent.error("http", args[0], res, code, "", {})
         elif action == "raise":
-            raise urllib2.URLError("blah")
+            raise urllib.error.URLError("blah")
         assert False
     def close(self): pass
     def add_parent(self, parent):
@@ -337,7 +340,7 @@
         opener.add_handler(h)
     return opener
 
-class MockHTTPHandler(urllib2.BaseHandler):
+class MockHTTPHandler(urllib.request.BaseHandler):
     # useful for testing redirections and auth
     # sends supplied headers and code as first response
     # sends 200 OK as second response
@@ -392,7 +395,7 @@
         # TypeError in real code; here, returning self from these mock
         # methods would either cause no exception, or AttributeError.
 
-        from urllib2 import URLError
+        from urllib.error import URLError
 
         o = OpenerDirector()
         meth_spec = [
@@ -400,7 +403,7 @@
             [("redirect_request", "return self")],
             ]
         handlers = add_ordered_mock_handlers(o, meth_spec)
-        o.add_handler(urllib2.UnknownHandler())
+        o.add_handler(urllib.request.UnknownHandler())
         for scheme in "do", "proxy", "redirect":
             self.assertRaises(URLError, o.open, scheme+"://example.com/")
 
@@ -458,7 +461,7 @@
         handlers = add_ordered_mock_handlers(o, meth_spec)
 
         req = Request("http://example.com/")
-        self.assertRaises(urllib2.URLError, o.open, req)
+        self.assertRaises(urllib.error.URLError, o.open, req)
         self.assertEqual(o.calls, [(handlers[0], "http_open", (req,), {})])
 
 ##     def test_error(self):
@@ -529,8 +532,7 @@
 
 
 def sanepathname2url(path):
-    import urllib
-    urlpath = urllib.pathname2url(path)
+    urlpath = urllib.request.pathname2url(path)
     if os.name == "nt" and urlpath.startswith("///"):
         urlpath = urlpath[2:]
     # XXX don't ask me about the mac...
@@ -545,7 +547,7 @@
                 self.filename, self.filetype = filename, filetype
                 return io.StringIO(self.data), len(self.data)
 
-        class NullFTPHandler(urllib2.FTPHandler):
+        class NullFTPHandler(urllib.request.FTPHandler):
             def __init__(self, data): self.data = data
             def connect_ftp(self, user, passwd, host, port, dirs,
                             timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
@@ -587,7 +589,7 @@
 
     def test_file(self):
         import email.utils, socket
-        h = urllib2.FileHandler()
+        h = urllib.request.FileHandler()
         o = h.parent = MockOpener()
 
         TESTFN = support.TESTFN
@@ -644,12 +646,12 @@
                 finally:
                     f.close()
 
-                self.assertRaises(urllib2.URLError,
+                self.assertRaises(urllib.error.URLError,
                                   h.file_open, Request(url))
             finally:
                 os.remove(TESTFN)
 
-        h = urllib2.FileHandler()
+        h = urllib.request.FileHandler()
         o = h.parent = MockOpener()
         # XXXX why does // mean ftp (and /// mean not ftp!), and where
         #  is file: scheme specified?  I think this is really a bug, and
@@ -668,7 +670,7 @@
             try:
                 h.file_open(req)
             # XXXX remove OSError when bug fixed
-            except (urllib2.URLError, OSError):
+            except (urllib.error.URLError, OSError):
                 self.assert_(not ftp)
             else:
                 self.assert_(o.req is req)
@@ -685,6 +687,7 @@
                 return ''
         class MockHTTPClass:
             def __init__(self):
+                self.level = 0
                 self.req_headers = []
                 self.data = None
                 self.raise_on_endheaders = False
@@ -707,7 +710,7 @@
             def getresponse(self):
                 return MockHTTPResponse(MockFile(), {}, 200, "OK")
 
-        h = urllib2.AbstractHTTPHandler()
+        h = urllib.request.AbstractHTTPHandler()
         o = h.parent = MockOpener()
 
         url = "http://example.com/"
@@ -737,7 +740,7 @@
 
         # check socket.error converted to URLError
         http.raise_on_endheaders = True
-        self.assertRaises(urllib2.URLError, h.do_open, http, req)
+        self.assertRaises(urllib.error.URLError, h.do_open, http, req)
 
         # check adding of standard headers
         o.addheaders = [("Spam", "eggs")]
@@ -768,7 +771,7 @@
             self.assertEqual(req.unredirected_hdrs["Spam"], "foo")
 
     def test_errors(self):
-        h = urllib2.HTTPErrorProcessor()
+        h = urllib.request.HTTPErrorProcessor()
         o = h.parent = MockOpener()
 
         url = "http://example.com/"
@@ -794,7 +797,7 @@
 
     def test_cookies(self):
         cj = MockCookieJar()
-        h = urllib2.HTTPCookieProcessor(cj)
+        h = urllib.request.HTTPCookieProcessor(cj)
         o = h.parent = MockOpener()
 
         req = Request("http://example.com/")
@@ -810,7 +813,7 @@
     def test_redirect(self):
         from_url = "http://example.com/a.html"
         to_url = "http://example.com/b.html"
-        h = urllib2.HTTPRedirectHandler()
+        h = urllib.request.HTTPRedirectHandler()
         o = h.parent = MockOpener()
 
         # ordinary redirect behaviour
@@ -825,7 +828,7 @@
                 try:
                     method(req, MockFile(), code, "Blah",
                            MockHeaders({"location": to_url}))
-                except urllib2.HTTPError:
+                except urllib.error.HTTPError:
                     # 307 in response to POST requires user OK
                     self.assert_(code == 307 and data is not None)
                 self.assertEqual(o.req.get_full_url(), to_url)
@@ -860,9 +863,9 @@
             while 1:
                 redirect(h, req, "http://example.com/")
                 count = count + 1
-        except urllib2.HTTPError:
+        except urllib.error.HTTPError:
             # don't stop until max_repeats, because cookies may introduce state
-            self.assertEqual(count, urllib2.HTTPRedirectHandler.max_repeats)
+            self.assertEqual(count, urllib.request.HTTPRedirectHandler.max_repeats)
 
         # detect endless non-repeating chain of redirects
         req = Request(from_url, origin_req_host="example.com")
@@ -871,9 +874,9 @@
             while 1:
                 redirect(h, req, "http://example.com/%d" % count)
                 count = count + 1
-        except urllib2.HTTPError:
+        except urllib.error.HTTPError:
             self.assertEqual(count,
-                             urllib2.HTTPRedirectHandler.max_redirections)
+                             urllib.request.HTTPRedirectHandler.max_redirections)
 
     def test_cookie_redirect(self):
         # cookies shouldn't leak into redirected requests
@@ -883,16 +886,16 @@
         cj = CookieJar()
         interact_netscape(cj, "http://www.example.com/", "spam=eggs")
         hh = MockHTTPHandler(302, "Location: http://www.cracker.com/\r\n\r\n")
-        hdeh = urllib2.HTTPDefaultErrorHandler()
-        hrh = urllib2.HTTPRedirectHandler()
-        cp = urllib2.HTTPCookieProcessor(cj)
+        hdeh = urllib.request.HTTPDefaultErrorHandler()
+        hrh = urllib.request.HTTPRedirectHandler()
+        cp = urllib.request.HTTPCookieProcessor(cj)
         o = build_test_opener(hh, hdeh, hrh, cp)
         o.open("http://www.example.com/")
         self.assert_(not hh.req.has_header("Cookie"))
 
     def test_proxy(self):
         o = OpenerDirector()
-        ph = urllib2.ProxyHandler(dict(http="proxy.example.com:3128"))
+        ph = urllib.request.ProxyHandler(dict(http="proxy.example.com:3128"))
         o.add_handler(ph)
         meth_spec = [
             [("http_open", "return response")]
@@ -910,7 +913,7 @@
     def test_basic_auth(self, quote_char='"'):
         opener = OpenerDirector()
         password_manager = MockPasswordManager()
-        auth_handler = urllib2.HTTPBasicAuthHandler(password_manager)
+        auth_handler = urllib.request.HTTPBasicAuthHandler(password_manager)
         realm = "ACME Widget Store"
         http_handler = MockHTTPHandler(
             401, 'WWW-Authenticate: Basic realm=%s%s%s\r\n\r\n' %
@@ -928,10 +931,10 @@
 
     def test_proxy_basic_auth(self):
         opener = OpenerDirector()
-        ph = urllib2.ProxyHandler(dict(http="proxy.example.com:3128"))
+        ph = urllib.request.ProxyHandler(dict(http="proxy.example.com:3128"))
         opener.add_handler(ph)
         password_manager = MockPasswordManager()
-        auth_handler = urllib2.ProxyBasicAuthHandler(password_manager)
+        auth_handler = urllib.request.ProxyBasicAuthHandler(password_manager)
         realm = "ACME Networks"
         http_handler = MockHTTPHandler(
             407, 'Proxy-Authenticate: Basic realm="%s"\r\n\r\n' % realm)
@@ -958,15 +961,15 @@
                 self.recorded = []
             def record(self, info):
                 self.recorded.append(info)
-        class TestDigestAuthHandler(urllib2.HTTPDigestAuthHandler):
+        class TestDigestAuthHandler(urllib.request.HTTPDigestAuthHandler):
             def http_error_401(self, *args, **kwds):
                 self.parent.record("digest")
-                urllib2.HTTPDigestAuthHandler.http_error_401(self,
+                urllib.request.HTTPDigestAuthHandler.http_error_401(self,
                                                              *args, **kwds)
-        class TestBasicAuthHandler(urllib2.HTTPBasicAuthHandler):
+        class TestBasicAuthHandler(urllib.request.HTTPBasicAuthHandler):
             def http_error_401(self, *args, **kwds):
                 self.parent.record("basic")
-                urllib2.HTTPBasicAuthHandler.http_error_401(self,
+                urllib.request.HTTPBasicAuthHandler.http_error_401(self,
                                                             *args, **kwds)
 
         opener = RecordingOpenerDirector()
@@ -1030,13 +1033,13 @@
 class MiscTests(unittest.TestCase):
 
     def test_build_opener(self):
-        class MyHTTPHandler(urllib2.HTTPHandler): pass
-        class FooHandler(urllib2.BaseHandler):
+        class MyHTTPHandler(urllib.request.HTTPHandler): pass
+        class FooHandler(urllib.request.BaseHandler):
             def foo_open(self): pass
-        class BarHandler(urllib2.BaseHandler):
+        class BarHandler(urllib.request.BaseHandler):
             def bar_open(self): pass
 
-        build_opener = urllib2.build_opener
+        build_opener = urllib.request.build_opener
 
         o = build_opener(FooHandler, BarHandler)
         self.opener_has_handler(o, FooHandler)
@@ -1054,14 +1057,14 @@
         # a particular case of overriding: default handlers can be passed
         # in explicitly
         o = build_opener()
-        self.opener_has_handler(o, urllib2.HTTPHandler)
-        o = build_opener(urllib2.HTTPHandler)
-        self.opener_has_handler(o, urllib2.HTTPHandler)
-        o = build_opener(urllib2.HTTPHandler())
-        self.opener_has_handler(o, urllib2.HTTPHandler)
+        self.opener_has_handler(o, urllib.request.HTTPHandler)
+        o = build_opener(urllib.request.HTTPHandler)
+        self.opener_has_handler(o, urllib.request.HTTPHandler)
+        o = build_opener(urllib.request.HTTPHandler())
+        self.opener_has_handler(o, urllib.request.HTTPHandler)
 
         # Issue2670: multiple handlers sharing the same base class
-        class MyOtherHTTPHandler(urllib2.HTTPHandler): pass
+        class MyOtherHTTPHandler(urllib.request.HTTPHandler): pass
         o = build_opener(MyHTTPHandler, MyOtherHTTPHandler)
         self.opener_has_handler(o, MyHTTPHandler)
         self.opener_has_handler(o, MyOtherHTTPHandler)
@@ -1077,7 +1080,7 @@
 def test_main(verbose=None):
     from test import test_urllib2
     support.run_doctest(test_urllib2, verbose)
-    support.run_doctest(urllib2, verbose)
+    support.run_doctest(urllib.request, verbose)
     tests = (TrivialTests,
              OpenerDirectorTests,
              HandlerTests,

Modified: python/branches/py3k-urllib/Lib/test/test_urllib2_localnet.py
==============================================================================
--- python/branches/py3k-urllib/Lib/test/test_urllib2_localnet.py	(original)
+++ python/branches/py3k-urllib/Lib/test/test_urllib2_localnet.py	Tue Jun 17 23:01:35 2008
@@ -2,8 +2,8 @@
 
 import email
 import threading
-import urlparse
-import urllib2
+import urllib.parse
+import urllib.request
 import http.server
 import unittest
 import hashlib
@@ -45,7 +45,7 @@
         self._stop_server = False
         self.ready = threading.Event()
         request_handler.protocol_version = "HTTP/1.0"
-        self.httpd = LoopbackHttpServer(('127.0.0.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)
@@ -154,11 +154,11 @@
         if len(self._users) == 0:
             return True
 
-        if 'Proxy-Authorization' not in request_handler.headers:
+        if "Proxy-Authorization" not in request_handler.headers:
             return self._return_auth_challenge(request_handler)
         else:
             auth_dict = self._create_auth_dict(
-                request_handler.headers['Proxy-Authorization']
+                request_handler.headers["Proxy-Authorization"]
                 )
             if auth_dict["username"] in self._users:
                 password = self._users[ auth_dict["username"] ]
@@ -199,12 +199,12 @@
 
     def log_message(self, format, *args):
         # Uncomment the next line for debugging.
-        #sys.stderr.write(format % args)
+        # sys.stderr.write(format % args)
         pass
 
     def do_GET(self):
-        (scm, netloc, path, params, query, fragment) = urlparse.urlparse(
-            self.path, 'http')
+        (scm, netloc, path, params, query, fragment) = urllib.parse.urlparse(
+            self.path, "http")
         self.short_path = path
         if self.digest_auth_handler.handle_request(self):
             self.send_response(200, "OK")
@@ -234,9 +234,10 @@
         self.server.start()
         self.server.ready.wait()
         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)
+        handler = urllib.request.ProxyHandler({"http" : proxy_url})
+        self._digest_auth_handler = urllib.request.ProxyDigestAuthHandler()
+        self.opener = urllib.request.build_opener(
+            handler, self._digest_auth_handler)
 
     def tearDown(self):
         self.server.stop()
@@ -245,13 +246,13 @@
         self._digest_auth_handler.add_password(self.REALM, self.URL,
                                                self.USER, self.PASSWD+"bad")
         FakeProxyHandler.digest_auth_handler.set_qop("auth")
-        self.assertRaises(urllib2.HTTPError,
+        self.assertRaises(urllib.error.HTTPError,
                           self.opener.open,
                           self.URL)
 
     def test_proxy_with_no_password_raises_httperror(self):
         FakeProxyHandler.digest_auth_handler.set_qop("auth")
-        self.assertRaises(urllib2.HTTPError,
+        self.assertRaises(urllib.error.HTTPError,
                           self.opener.open,
                           self.URL)
 
@@ -270,7 +271,7 @@
         FakeProxyHandler.digest_auth_handler.set_qop("auth-int")
         try:
             result = self.opener.open(self.URL)
-        except urllib2.URLError:
+        except urllib.error.URLError:
             # It's okay if we don't support auth-int, but we certainly
             # shouldn't receive any kind of exception here other than
             # a URLError.
@@ -296,7 +297,7 @@
                 self.wfile.write(body)
 
         def do_POST(self):
-            content_length = self.headers['Content-Length']
+            content_length = self.headers["Content-Length"]
             post_data = self.rfile.read(int(content_length))
             self.do_GET()
             self.requests.append(post_data)
@@ -311,7 +312,7 @@
             for (header, value) in headers:
                 self.send_header(header, value % self.port)
             if body:
-                self.send_header('Content-type', 'text/plain')
+                self.send_header("Content-type", "text/plain")
                 self.end_headers()
                 return body
             self.end_headers()
@@ -332,7 +333,22 @@
     for transparent redirection have been written.
     """
 
-    def start_server(self, responses):
+    def setUp(self):
+        self.server = None
+
+    def tearDown(self):
+        if self.server is not None:
+            self.server.stop()
+
+    def urlopen(self, url, data=None):
+        f = urllib.request.urlopen(url, data)
+        result = f.read()
+        f.close()
+        return result
+
+    def start_server(self, responses=None):
+        if responses is None:
+            responses = [(200, [], b"we don't care")]
         handler = GetRequestHandler(responses)
 
         self.server = LoopbackHttpServerThread(handler)
@@ -342,103 +358,71 @@
         handler.port = port
         return handler
 
-
     def test_redirection(self):
-        expected_response = b'We got here...'
+        expected_response = b"We got here..."
         responses = [
-            (302, [('Location', 'http://localhost:%s/somewhere_else')], ''),
+            (302, [("Location", "http://localhost:%s/somewhere_else")], ""),
             (200, [], expected_response)
         ]
 
         handler = self.start_server(responses)
-
-        try:
-            f = urllib2.urlopen('http://localhost:%s/' % handler.port)
-            data = f.read()
-            f.close()
-
-            self.assertEquals(data, expected_response)
-            self.assertEquals(handler.requests, ['/', '/somewhere_else'])
-        finally:
-            self.server.stop()
-
+        data = self.urlopen("http://localhost:%s/" % handler.port)
+        self.assertEquals(data, expected_response)
+        self.assertEquals(handler.requests, ["/", "/somewhere_else"])
 
     def test_404(self):
-        expected_response = b'Bad bad bad...'
+        expected_response = b"Bad bad bad..."
         handler = self.start_server([(404, [], expected_response)])
 
         try:
-            try:
-                urllib2.urlopen('http://localhost:%s/weeble' % handler.port)
-            except urllib2.URLError as f:
-                data = f.read()
-                f.close()
-            else:
-                self.fail('404 should raise URLError')
-
-            self.assertEquals(data, expected_response)
-            self.assertEquals(handler.requests, ['/weeble'])
-        finally:
-            self.server.stop()
+            self.urlopen("http://localhost:%s/weeble" % handler.port)
+        except urllib.error.URLError as f:
+            data = f.read()
+            f.close()
+        else:
+            self.fail("404 should raise URLError")
 
+        self.assertEquals(data, expected_response)
+        self.assertEquals(handler.requests, ["/weeble"])
 
     def test_200(self):
-        expected_response = b'pycon 2008...'
+        expected_response = b"pycon 2008..."
         handler = self.start_server([(200, [], expected_response)])
-
-        try:
-            f = urllib2.urlopen('http://localhost:%s/bizarre' % handler.port)
-            data = f.read()
-            f.close()
-
-            self.assertEquals(data, expected_response)
-            self.assertEquals(handler.requests, ['/bizarre'])
-        finally:
-            self.server.stop()
+        data = self.urlopen("http://localhost:%s/bizarre" % handler.port)
+        self.assertEquals(data, expected_response)
+        self.assertEquals(handler.requests, ["/bizarre"])
 
     def test_200_with_parameters(self):
-        expected_response = b'pycon 2008...'
+        expected_response = b"pycon 2008..."
         handler = self.start_server([(200, [], expected_response)])
-
-        try:
-            f = urllib2.urlopen('http://localhost:%s/bizarre' % handler.port, b'get=with_feeling')
-            data = f.read()
-            f.close()
-
-            self.assertEquals(data, expected_response)
-            self.assertEquals(handler.requests, ['/bizarre', b'get=with_feeling'])
-        finally:
-            self.server.stop()
-
+        data = self.urlopen("http://localhost:%s/bizarre" % handler.port,
+                             b"get=with_feeling")
+        self.assertEquals(data, expected_response)
+        self.assertEquals(handler.requests, ["/bizarre", b"get=with_feeling"])
 
     def test_sending_headers(self):
-        handler = self.start_server([(200, [], b"we don't care")])
-
-        try:
-            req = urllib2.Request("http://localhost:%s/" % handler.port,
-                                  headers={'Range': 'bytes=20-39'})
-            urllib2.urlopen(req)
-            self.assertEqual(handler.headers_received['Range'], 'bytes=20-39')
-        finally:
-            self.server.stop()
+        handler = self.start_server()
+        req = urllib.request.Request("http://localhost:%s/" % handler.port,
+                                     headers={"Range": "bytes=20-39"})
+        urllib.request.urlopen(req)
+        self.assertEqual(handler.headers_received["Range"], "bytes=20-39")
 
     def test_basic(self):
-        handler = self.start_server([(200, [], b"we don't care")])
-
+        handler = self.start_server()
+        open_url = urllib.request.urlopen("http://localhost:%s" % handler.port)
+        for attr in ("read", "close", "info", "geturl"):
+            self.assert_(hasattr(open_url, attr), "object returned from "
+                         "urlopen lacks the %s attribute" % attr)
         try:
-            open_url = urllib2.urlopen("http://localhost:%s" % handler.port)
-            for attr in ("read", "close", "info", "geturl"):
-                self.assert_(hasattr(open_url, attr), "object returned from "
-                             "urlopen lacks the %s attribute" % attr)
-            try:
-                self.assert_(open_url.read(), "calling 'read' failed")
-            finally:
-                open_url.close()
+            self.assert_(open_url.read(), "calling 'read' failed")
         finally:
-            self.server.stop()
+            open_url.close()
 
     def test_info(self):
-        handler = self.start_server([(200, [], b"we don't care")])
+        handler = self.start_server()
+        open_url = urllib.request.urlopen("http://localhost:%s" % handler.port)
+        info_obj = open_url.info()
+        self.assertEqual(info_obj.getsubtype(), "plain")
 
         try:
             open_url = urllib2.urlopen("http://localhost:%s" % handler.port)
@@ -452,15 +436,10 @@
 
     def test_geturl(self):
         # Make sure same URL as opened is returned by geturl.
-        handler = self.start_server([(200, [], b"we don't care")])
-
-        try:
-            open_url = urllib2.urlopen("http://localhost:%s" % handler.port)
-            url = open_url.geturl()
-            self.assertEqual(url, "http://localhost:%s" % handler.port)
-        finally:
-            self.server.stop()
-
+        handler = self.start_server()
+        open_url = urllib.request.urlopen("http://localhost:%s" % handler.port)
+        url = open_url.geturl()
+        self.assertEqual(url, "http://localhost:%s" % handler.port)
 
     def test_bad_address(self):
         # Make sure proper exception is raised when connecting to a bogus
@@ -472,17 +451,10 @@
                           # started failing then.  One hopes the .invalid
                           # domain will be spared to serve its defined
                           # purpose.
-                          # urllib2.urlopen, "http://www.sadflkjsasadf.com/")
-                          urllib2.urlopen, "http://www.python.invalid./")
-
+                          urllib.request.urlopen,
+                          "http://www.python.invalid./")
 
 def test_main():
-    # We will NOT depend on the network resource flag
-    # (Lib/test/regrtest.py -u network) since all tests here are only
-    # localhost.  However, if this is a bad rationale, then uncomment
-    # the next line.
-    #support.requires("network")
-
     support.run_unittest(ProxyAuthTests)
     support.run_unittest(TestUrlopen)
 

Modified: python/branches/py3k-urllib/Lib/test/test_urllib2net.py
==============================================================================
--- python/branches/py3k-urllib/Lib/test/test_urllib2net.py	(original)
+++ python/branches/py3k-urllib/Lib/test/test_urllib2net.py	Tue Jun 17 23:01:35 2008
@@ -4,10 +4,11 @@
 from test import support
 from test.test_urllib2 import sanepathname2url
 
+import os
 import socket
-import urllib2
 import sys
-import os
+import urllib.error
+import urllib.request
 
 
 def _retry_thrice(func, exc, *args, **kwargs):
@@ -28,7 +29,8 @@
 
 # Connecting to remote hosts is flaky.  Make it more robust by retrying
 # the connection several times.
-_urlopen_with_retry = _wrap_with_retry_thrice(urllib2.urlopen, urllib2.URLError)
+_urlopen_with_retry = _wrap_with_retry_thrice(urllib.request.urlopen,
+                                              urllib.error.URLError)
 
 
 class AuthTests(unittest.TestCase):
@@ -82,7 +84,8 @@
         response = _urlopen_with_retry("http://www.python.org/")
         abused_fileobject = response.fp
         httpresponse = abused_fileobject.raw
-        self.assert_(httpresponse.__class__ is http.client.HTTPResponse)
+        self.assert_(httpresponse.__class__ is http.client.HTTPResponse,
+                     httpresponse.__class__)
         fileobject = httpresponse.fp
 
         self.assert_(not fileobject.closed)
@@ -116,8 +119,9 @@
             f.write('hi there\n')
             f.close()
             urls = [
-                'file:'+sanepathname2url(os.path.abspath(TESTFN)),
-                ('file:///nonsensename/etc/passwd', None, urllib2.URLError),
+                'file:' + sanepathname2url(os.path.abspath(TESTFN)),
+                ('file:///nonsensename/etc/passwd', None,
+                 urllib.error.URLError),
                 ]
             self._test_urls(urls, self._extra_handlers(), retry=True)
         finally:
@@ -157,9 +161,9 @@
         import logging
         debug = logging.getLogger("test_urllib2").debug
 
-        urlopen = urllib2.build_opener(*handlers).open
+        urlopen = urllib.request.build_opener(*handlers).open
         if retry:
-            urlopen = _wrap_with_retry_thrice(urlopen, urllib2.URLError)
+            urlopen = _wrap_with_retry_thrice(urlopen, urllib.error.URLError)
 
         for url in urls:
             if isinstance(url, tuple):
@@ -186,7 +190,7 @@
     def _extra_handlers(self):
         handlers = []
 
-        cfh = urllib2.CacheFTPHandler()
+        cfh = urllib.request.CacheFTPHandler()
         cfh.setTimeout(1)
         handlers.append(cfh)
 

Modified: python/branches/py3k-urllib/Lib/test/test_urllibnet.py
==============================================================================
--- python/branches/py3k-urllib/Lib/test/test_urllibnet.py	(original)
+++ python/branches/py3k-urllib/Lib/test/test_urllibnet.py	Tue Jun 17 23:01:35 2008
@@ -4,7 +4,7 @@
 from test import support
 
 import socket
-import urllib
+import urllib.request
 import sys
 import os
 import email.message
@@ -36,11 +36,11 @@
         socket.setdefaulttimeout(None)
 
     def testURLread(self):
-        f = _open_with_retry(urllib.urlopen, "http://www.python.org/")
+        f = _open_with_retry(urllib.request.urlopen, "http://www.python.org/")
         x = f.read()
 
 class urlopenNetworkTests(unittest.TestCase):
-    """Tests urllib.urlopen using the network.
+    """Tests urllib.reqest.urlopen using the network.
 
     These tests are not exhaustive.  Assuming that testing using files does a
     good job overall of some of the basic interface features.  There are no
@@ -55,7 +55,7 @@
     """
 
     def urlopen(self, *args):
-        return _open_with_retry(urllib.urlopen, *args)
+        return _open_with_retry(urllib.request.urlopen, *args)
 
     def test_basic(self):
         # Simple test expected to pass.
@@ -105,7 +105,7 @@
     def test_getcode(self):
         # test getcode() with the fancy opener to get 404 error codes
         URL = "http://www.python.org/XXXinvalidXXX"
-        open_url = urllib.FancyURLopener().open(URL)
+        open_url = urllib.request.FancyURLopener().open(URL)
         try:
             code = open_url.getcode()
         finally:
@@ -114,7 +114,7 @@
 
     def test_fileno(self):
         if (sys.platform in ('win32',) or
-                not hasattr(os, 'fdopen')):
+            not hasattr(os, 'fdopen')):
             # On Windows, socket handles are not file descriptors; this
             # test can't pass on Windows.
             return
@@ -142,13 +142,14 @@
                           # domain will be spared to serve its defined
                           # purpose.
                           # urllib.urlopen, "http://www.sadflkjsasadf.com/")
-                          urllib.urlopen, "http://www.python.invalid./")
+                          urllib.request.urlopen,
+                          "http://www.python.invalid./")
 
 class urlretrieveNetworkTests(unittest.TestCase):
-    """Tests urllib.urlretrieve using the network."""
+    """Tests urllib.request.urlretrieve using the network."""
 
     def urlretrieve(self, *args):
-        return _open_with_retry(urllib.urlretrieve, *args)
+        return _open_with_retry(urllib.request.urlretrieve, *args)
 
     def test_basic(self):
         # Test basic functionality.

Modified: python/branches/py3k-urllib/Lib/test/test_urlparse.py
==============================================================================
--- python/branches/py3k-urllib/Lib/test/test_urlparse.py	(original)
+++ python/branches/py3k-urllib/Lib/test/test_urlparse.py	Tue Jun 17 23:01:35 2008
@@ -2,7 +2,7 @@
 
 from test import support
 import unittest
-import urlparse
+import urllib.parse
 
 RFC1808_BASE = "http://a/b/c/d;p?q#f"
 RFC2396_BASE = "http://a/b/c/d;p?q"
@@ -10,19 +10,19 @@
 class UrlParseTestCase(unittest.TestCase):
 
     def checkRoundtrips(self, url, parsed, split):
-        result = urlparse.urlparse(url)
+        result = urllib.parse.urlparse(url)
         self.assertEqual(result, parsed)
         t = (result.scheme, result.netloc, result.path,
              result.params, result.query, result.fragment)
         self.assertEqual(t, parsed)
         # put it back together and it should be the same
-        result2 = urlparse.urlunparse(result)
+        result2 = urllib.parse.urlunparse(result)
         self.assertEqual(result2, url)
         self.assertEqual(result2, result.geturl())
 
         # the result of geturl() is a fixpoint; we can always parse it
         # again to get the same result:
-        result3 = urlparse.urlparse(result.geturl())
+        result3 = urllib.parse.urlparse(result.geturl())
         self.assertEqual(result3.geturl(), result.geturl())
         self.assertEqual(result3,          result)
         self.assertEqual(result3.scheme,   result.scheme)
@@ -37,17 +37,17 @@
         self.assertEqual(result3.port,     result.port)
 
         # check the roundtrip using urlsplit() as well
-        result = urlparse.urlsplit(url)
+        result = urllib.parse.urlsplit(url)
         self.assertEqual(result, split)
         t = (result.scheme, result.netloc, result.path,
              result.query, result.fragment)
         self.assertEqual(t, split)
-        result2 = urlparse.urlunsplit(result)
+        result2 = urllib.parse.urlunsplit(result)
         self.assertEqual(result2, url)
         self.assertEqual(result2, result.geturl())
 
         # check the fixpoint property of re-parsing the result of geturl()
-        result3 = urlparse.urlsplit(result.geturl())
+        result3 = urllib.parse.urlsplit(result.geturl())
         self.assertEqual(result3.geturl(), result.geturl())
         self.assertEqual(result3,          result)
         self.assertEqual(result3.scheme,   result.scheme)
@@ -83,7 +83,7 @@
             self.checkRoundtrips(url, parsed, split)
 
     def test_http_roundtrips(self):
-        # urlparse.urlsplit treats 'http:' as an optimized special case,
+        # urllib.parse.urlsplit treats 'http:' as an optimized special case,
         # so we test both 'http:' and 'https:' in all the following.
         # Three cheers for white box knowledge!
         testcases = [
@@ -111,13 +111,13 @@
                 self.checkRoundtrips(url, parsed, split)
 
     def checkJoin(self, base, relurl, expected):
-        self.assertEqual(urlparse.urljoin(base, relurl), expected,
+        self.assertEqual(urllib.parse.urljoin(base, relurl), expected,
                          (base, relurl, expected))
 
     def test_unparse_parse(self):
         for u in ['Python', './Python']:
-            self.assertEqual(urlparse.urlunsplit(urlparse.urlsplit(u)), u)
-            self.assertEqual(urlparse.urlunparse(urlparse.urlparse(u)), u)
+            self.assertEqual(urllib.parse.urlunsplit(urllib.parse.urlsplit(u)), u)
+            self.assertEqual(urllib.parse.urlunparse(urllib.parse.urlparse(u)), u)
 
     def test_RFC1808(self):
         # "normal" cases from RFC 1808:
@@ -223,11 +223,11 @@
             (RFC1808_BASE, 'http://a/b/c/d;p?q', 'f'),
             (RFC2396_BASE, 'http://a/b/c/d;p?q', ''),
             ]:
-            self.assertEqual(urlparse.urldefrag(url), (defrag, frag))
+            self.assertEqual(urllib.parse.urldefrag(url), (defrag, frag))
 
     def test_urlsplit_attributes(self):
         url = "HTTP://WWW.PYTHON.ORG/doc/#frag"
-        p = urlparse.urlsplit(url)
+        p = urllib.parse.urlsplit(url)
         self.assertEqual(p.scheme, "http")
         self.assertEqual(p.netloc, "WWW.PYTHON.ORG")
         self.assertEqual(p.path, "/doc/")
@@ -242,7 +242,7 @@
         #self.assertEqual(p.geturl(), url)
 
         url = "http://User:Pass at www.python.org:080/doc/?query=yes#frag"
-        p = urlparse.urlsplit(url)
+        p = urllib.parse.urlsplit(url)
         self.assertEqual(p.scheme, "http")
         self.assertEqual(p.netloc, "User:Pass at www.python.org:080")
         self.assertEqual(p.path, "/doc/")
@@ -259,7 +259,7 @@
         # and request email addresses as usernames.
 
         url = "http://User at example.com:Pass at www.python.org:080/doc/?query=yes#frag"
-        p = urlparse.urlsplit(url)
+        p = urllib.parse.urlsplit(url)
         self.assertEqual(p.scheme, "http")
         self.assertEqual(p.netloc, "User at example.com:Pass at www.python.org:080")
         self.assertEqual(p.path, "/doc/")
@@ -274,11 +274,11 @@
 
     def test_attributes_bad_port(self):
         """Check handling of non-integer ports."""
-        p = urlparse.urlsplit("http://www.example.net:foo")
+        p = urllib.parse.urlsplit("http://www.example.net:foo")
         self.assertEqual(p.netloc, "www.example.net:foo")
         self.assertRaises(ValueError, lambda: p.port)
 
-        p = urlparse.urlparse("http://www.example.net:foo")
+        p = urllib.parse.urlparse("http://www.example.net:foo")
         self.assertEqual(p.netloc, "www.example.net:foo")
         self.assertRaises(ValueError, lambda: p.port)
 
@@ -289,7 +289,7 @@
         # scheme://netloc syntax, the netloc and related attributes
         # should be left empty.
         uri = "sip:alice at atlanta.com;maddr=239.255.255.1;ttl=15"
-        p = urlparse.urlsplit(uri)
+        p = urllib.parse.urlsplit(uri)
         self.assertEqual(p.netloc, "")
         self.assertEqual(p.username, None)
         self.assertEqual(p.password, None)
@@ -297,7 +297,7 @@
         self.assertEqual(p.port, None)
         self.assertEqual(p.geturl(), uri)
 
-        p = urlparse.urlparse(uri)
+        p = urllib.parse.urlparse(uri)
         self.assertEqual(p.netloc, "")
         self.assertEqual(p.username, None)
         self.assertEqual(p.password, None)
@@ -307,7 +307,7 @@
 
     def test_noslash(self):
         # Issue 1637: http://foo.com?query is legal
-        self.assertEqual(urlparse.urlparse("http://example.com?blahblah=/foo"),
+        self.assertEqual(urllib.parse.urlparse("http://example.com?blahblah=/foo"),
                          ('http', 'example.com', '', '', 'blahblah=/foo', ''))
 
 def test_main():

Modified: python/branches/py3k-urllib/Lib/test/test_xmlrpc.py
==============================================================================
--- python/branches/py3k-urllib/Lib/test/test_xmlrpc.py	(original)
+++ python/branches/py3k-urllib/Lib/test/test_xmlrpc.py	Tue Jun 17 23:01:35 2008
@@ -111,8 +111,10 @@
                               (int(2**34),))
 
         xmlrpclib.dumps((xmlrpclib.MAXINT, xmlrpclib.MININT))
-        self.assertRaises(OverflowError, xmlrpclib.dumps, (xmlrpclib.MAXINT+1,))
-        self.assertRaises(OverflowError, xmlrpclib.dumps, (xmlrpclib.MININT-1,))
+        self.assertRaises(OverflowError, xmlrpclib.dumps,
+                          (xmlrpclib.MAXINT+1,))
+        self.assertRaises(OverflowError, xmlrpclib.dumps,
+                          (xmlrpclib.MININT-1,))
 
         def dummy_write(s):
             pass
@@ -120,9 +122,10 @@
         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)
-
+        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]
@@ -132,7 +135,6 @@
                           xmlrpclib.loads(strg)[0][0])
         self.assertRaises(TypeError, xmlrpclib.dumps, (arg1,))
 
-
 class HelperTestCase(unittest.TestCase):
     def test_escape(self):
         self.assertEqual(xmlrpclib.escape("a&b"), "a&amp;b")
@@ -160,7 +162,6 @@
         # private methods
         self.assertRaises(AttributeError,
                           xmlrpc.server.resolve_dotted_attribute, str, '__add')
-
         self.assert_(xmlrpc.server.resolve_dotted_attribute(str, 'title'))
 
 class DateTimeTestCase(unittest.TestCase):
@@ -170,7 +171,8 @@
     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)))
+        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)
@@ -180,7 +182,7 @@
     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))
+        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)
@@ -350,12 +352,12 @@
         self.assertEqual(response.reason, 'Not Found')
 
     def test_introspection1(self):
+        expected_methods = set(['pow', 'div', 'my_function', 'add',
+                                'system.listMethods', 'system.methodHelp',
+                                'system.methodSignature', 'system.multicall'])
         try:
             p = xmlrpclib.ServerProxy('http://localhost:%d' % PORT)
             meth = p.system.listMethods()
-            expected_methods = set(['pow', 'div', 'my_function', 'add',
-                                    'system.listMethods', 'system.methodHelp',
-                                    'system.methodSignature', 'system.multicall'])
             self.assertEqual(set(meth), expected_methods)
         except (xmlrpclib.ProtocolError, socket.error) as e:
             # ignore failures due to non-blocking socket 'unavailable' errors
@@ -593,7 +595,8 @@
         # will respond exception, if so, our goal is achieved ;)
         handle = open(support.TESTFN, "r").read()
 
-        # start with 44th char so as not to get http header, we just need only xml
+        # start with 44th char so as not to get http header, we just
+        # need only xml
         self.assertRaises(xmlrpclib.Fault, xmlrpclib.loads, handle[44:])
 
         os.remove("xmldata.txt")

Deleted: python/branches/py3k-urllib/Lib/urllib.py
==============================================================================
--- python/branches/py3k-urllib/Lib/urllib.py	Tue Jun 17 23:01:35 2008
+++ (empty file)
@@ -1,1714 +0,0 @@
-"""Open an arbitrary URL.
-
-See the following document for more info on URLs:
-"Names and Addresses, URIs, URLs, URNs, URCs", at
-http://www.w3.org/pub/WWW/Addressing/Overview.html
-
-See also the HTTP spec (from which the error codes are derived):
-"HTTP - Hypertext Transfer Protocol", at
-http://www.w3.org/pub/WWW/Protocols/
-
-Related standards and specs:
-- RFC1808: the "relative URL" spec. (authoritative status)
-- RFC1738 - the "URL standard". (authoritative status)
-- RFC1630 - the "URI spec". (informational status)
-
-The object returned by URLopener().open(file) will differ per
-protocol.  All you know is that is has methods read(), readline(),
-readlines(), fileno(), close() and info().  The read*(), fileno()
-and close() methods work like those of open files.
-The info() method returns a email.message.Message object which can be
-used to query various info about the object, if available.
-(email.message.Message objects provide a dict-like interface.)
-"""
-
-import http.client
-import email.message
-import email
-import os
-import socket
-import sys
-import time
-from urlparse import urljoin as basejoin
-
-__all__ = ["urlopen", "URLopener", "FancyURLopener", "urlretrieve",
-           "urlcleanup", "quote", "quote_plus", "unquote", "unquote_plus",
-           "urlencode", "url2pathname", "pathname2url", "splittag",
-           "localhost", "thishost", "ftperrors", "basejoin", "unwrap",
-           "splittype", "splithost", "splituser", "splitpasswd", "splitport",
-           "splitnport", "splitquery", "splitattr", "splitvalue",
-           "getproxies"]
-
-__version__ = '1.17'    # XXX This version is not always updated :-(
-
-MAXFTPCACHE = 10        # Trim the ftp cache beyond this size
-
-# Helper for non-unix systems
-if os.name == 'mac':
-    from macurl2path import url2pathname, pathname2url
-elif os.name == 'nt':
-    from nturl2path import url2pathname, pathname2url
-else:
-    def url2pathname(pathname):
-        """OS-specific conversion from a relative URL of the 'file' scheme
-        to a file system path; not recommended for general use."""
-        return unquote(pathname)
-
-    def pathname2url(pathname):
-        """OS-specific conversion from a file system path to a relative URL
-        of the 'file' scheme; not recommended for general use."""
-        return quote(pathname)
-
-# This really consists of two pieces:
-# (1) a class which handles opening of all sorts of URLs
-#     (plus assorted utilities etc.)
-# (2) a set of functions for parsing URLs
-# XXX Should these be separated out into different modules?
-
-
-# Shortcut for basic usage
-_urlopener = None
-def urlopen(url, data=None, proxies=None):
-    """urlopen(url [, data]) -> open file-like object"""
-    global _urlopener
-    if proxies is not None:
-        opener = FancyURLopener(proxies=proxies)
-    elif not _urlopener:
-        opener = FancyURLopener()
-        _urlopener = opener
-    else:
-        opener = _urlopener
-    if data is None:
-        return opener.open(url)
-    else:
-        return opener.open(url, data)
-
-def urlretrieve(url, filename=None, reporthook=None, data=None):
-    global _urlopener
-    if not _urlopener:
-        _urlopener = FancyURLopener()
-    return _urlopener.retrieve(url, filename, reporthook, data)
-
-def urlcleanup():
-    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):
-        IOError.__init__(self, message)
-        self.content = content
-
-ftpcache = {}
-class URLopener:
-    """Class to open URLs.
-    This is a class rather than just a subroutine because we may need
-    more than one set of global protocol-specific options.
-    Note -- this is a base class for those who don't want the
-    automatic handling of errors type 302 (relocated) and 401
-    (authorization needed)."""
-
-    __tempfiles = None
-
-    version = "Python-urllib/%s" % __version__
-
-    # Constructor
-    def __init__(self, proxies=None, **x509):
-        if proxies is None:
-            proxies = getproxies()
-        assert hasattr(proxies, 'keys'), "proxies must be a mapping"
-        self.proxies = proxies
-        self.key_file = x509.get('key_file')
-        self.cert_file = x509.get('cert_file')
-        self.addheaders = [('User-Agent', self.version)]
-        self.__tempfiles = []
-        self.__unlink = os.unlink # See cleanup()
-        self.tempcache = None
-        # Undocumented feature: if you assign {} to tempcache,
-        # it is used to cache files retrieved with
-        # self.retrieve().  This is not enabled by default
-        # since it does not work for changing documents (and I
-        # haven't got the logic to check expiration headers
-        # yet).
-        self.ftpcache = ftpcache
-        # Undocumented feature: you can use a different
-        # ftp cache by assigning to the .ftpcache member;
-        # in case you want logically independent URL openers
-        # XXX This is not threadsafe.  Bah.
-
-    def __del__(self):
-        self.close()
-
-    def close(self):
-        self.cleanup()
-
-    def cleanup(self):
-        # This code sometimes runs when the rest of this module
-        # has already been deleted, so it can't use any globals
-        # or import anything.
-        if self.__tempfiles:
-            for file in self.__tempfiles:
-                try:
-                    self.__unlink(file)
-                except OSError:
-                    pass
-            del self.__tempfiles[:]
-        if self.tempcache:
-            self.tempcache.clear()
-
-    def addheader(self, *args):
-        """Add a header to be used by the HTTP interface only
-        e.g. u.addheader('Accept', 'sound/basic')"""
-        self.addheaders.append(args)
-
-    # External interface
-    def open(self, fullurl, data=None):
-        """Use URLopener().open(file) instead of open(file, 'r')."""
-        fullurl = unwrap(toBytes(fullurl))
-        if self.tempcache and fullurl in self.tempcache:
-            filename, headers = self.tempcache[fullurl]
-            fp = open(filename, 'rb')
-            return addinfourl(fp, headers, fullurl)
-        urltype, url = splittype(fullurl)
-        if not urltype:
-            urltype = 'file'
-        if urltype in self.proxies:
-            proxy = self.proxies[urltype]
-            urltype, proxyhost = splittype(proxy)
-            host, selector = splithost(proxyhost)
-            url = (host, fullurl) # Signal special case to open_*()
-        else:
-            proxy = None
-        name = 'open_' + urltype
-        self.type = urltype
-        name = name.replace('-', '_')
-        if not hasattr(self, name):
-            if proxy:
-                return self.open_unknown_proxy(proxy, fullurl, data)
-            else:
-                return self.open_unknown(fullurl, data)
-        try:
-            if data is None:
-                return getattr(self, name)(url)
-            else:
-                return getattr(self, name)(url, data)
-        except socket.error as msg:
-            raise IOError('socket error', msg).with_traceback(sys.exc_info()[2])
-
-    def open_unknown(self, fullurl, data=None):
-        """Overridable interface to open unknown URL type."""
-        type, url = splittype(fullurl)
-        raise IOError('url error', 'unknown url type', type)
-
-    def open_unknown_proxy(self, proxy, fullurl, data=None):
-        """Overridable interface to open unknown URL type."""
-        type, url = splittype(fullurl)
-        raise IOError('url error', 'invalid proxy for %s' % type, proxy)
-
-    # External interface
-    def retrieve(self, url, filename=None, reporthook=None, data=None):
-        """retrieve(url) returns (filename, headers) for a local object
-        or (tempfilename, headers) for a remote object."""
-        url = unwrap(toBytes(url))
-        if self.tempcache and url in self.tempcache:
-            return self.tempcache[url]
-        type, url1 = splittype(url)
-        if filename is None and (not type or type == 'file'):
-            try:
-                fp = self.open_local_file(url1)
-                hdrs = fp.info()
-                del fp
-                return url2pathname(splithost(url1)[1]), hdrs
-            except IOError as msg:
-                pass
-        fp = self.open(url, data)
-        headers = fp.info()
-        if filename:
-            tfp = open(filename, 'wb')
-        else:
-            import tempfile
-            garbage, path = splittype(url)
-            garbage, path = splithost(path or "")
-            path, garbage = splitquery(path or "")
-            path, garbage = splitattr(path or "")
-            suffix = os.path.splitext(path)[1]
-            (fd, filename) = tempfile.mkstemp(suffix)
-            self.__tempfiles.append(filename)
-            tfp = os.fdopen(fd, 'wb')
-        result = filename, headers
-        if self.tempcache is not None:
-            self.tempcache[url] = result
-        bs = 1024*8
-        size = -1
-        read = 0
-        blocknum = 0
-        if reporthook:
-            if "content-length" in headers:
-                size = int(headers["Content-Length"])
-            reporthook(blocknum, bs, size)
-        while 1:
-            block = fp.read(bs)
-            if not block:
-                break
-            read += len(block)
-            tfp.write(block)
-            blocknum += 1
-            if reporthook:
-                reporthook(blocknum, bs, size)
-        fp.close()
-        tfp.close()
-        del fp
-        del tfp
-
-        # raise exception if actual size does not match content-length header
-        if size >= 0 and read < size:
-            raise ContentTooShortError("retrieval incomplete: got only %i out "
-                                       "of %i bytes" % (read, size), result)
-
-        return result
-
-    # Each method named open_<type> knows how to open that type of URL
-
-    def _open_generic_http(self, connection_factory, url, data):
-        """Make an HTTP connection using connection_class.
-
-        This is an internal method that should be called from
-        open_http() or open_https().
-
-        Arguments:
-        - connection_factory should take a host name and return an
-          HTTPConnection instance.
-        - url is the url to retrieval or a host, relative-path pair.
-        - data is payload for a POST request or None.
-        """
-
-        user_passwd = None
-        proxy_passwd= None
-        if isinstance(url, str):
-            host, selector = splithost(url)
-            if host:
-                user_passwd, host = splituser(host)
-                host = unquote(host)
-            realhost = host
-        else:
-            host, selector = url
-            # check whether the proxy contains authorization information
-            proxy_passwd, host = splituser(host)
-            # now we proceed with the url we want to obtain
-            urltype, rest = splittype(selector)
-            url = rest
-            user_passwd = None
-            if urltype.lower() != 'http':
-                realhost = None
-            else:
-                realhost, rest = splithost(rest)
-                if realhost:
-                    user_passwd, realhost = splituser(realhost)
-                if user_passwd:
-                    selector = "%s://%s%s" % (urltype, realhost, rest)
-                if proxy_bypass(realhost):
-                    host = realhost
-
-            #print "proxy via http:", host, selector
-        if not host: raise IOError('http error', 'no host given')
-
-        if proxy_passwd:
-            import base64
-            proxy_auth = base64.b64encode(proxy_passwd).strip()
-        else:
-            proxy_auth = None
-
-        if user_passwd:
-            import base64
-            auth = base64.b64encode(user_passwd).strip()
-        else:
-            auth = None
-        http_conn = connection_factory(host)
-        # XXX We should fix urllib so that it works with HTTP/1.1.
-        http_conn._http_vsn = 10
-        http_conn._http_vsn_str = "HTTP/1.0"
-
-        headers = {}
-        if proxy_auth:
-            headers["Proxy-Authorization"] = "Basic %s" % proxy_auth
-        if auth:
-            headers["Authorization"] =  "Basic %s" % auth
-        if realhost:
-            headers["Host"] = realhost
-        for header, value in self.addheaders:
-            headers[header] = value
-
-        if data is not None:
-            headers["Content-Type"] = "application/x-www-form-urlencoded"
-            http_conn.request("POST", selector, data, headers)
-        else:
-            http_conn.request("GET", selector, headers=headers)
-
-        try:
-            response = http_conn.getresponse()
-        except http.client.BadStatusLine:
-            # something went wrong with the HTTP status line
-            raise IOError('http protocol error', 0,
-                          'got a bad status line', None)
-
-        # According to RFC 2616, "2xx" code indicates that the client's
-        # request was successfully received, understood, and accepted.
-        if (200 <= response.status < 300):
-            return addinfourl(response.fp, response.msg, "http:" + url,
-                              response.status)
-        else:
-            return self.http_error(
-                url, response.fp,
-                response.status, response.reason, response.msg, data)
-
-    def open_http(self, url, data=None):
-        """Use HTTP protocol."""
-        return self._open_generic_http(http.client.HTTPConnection, url, data)
-
-    def http_error(self, url, fp, errcode, errmsg, headers, data=None):
-        """Handle http errors.
-
-        Derived class can override this, or provide specific handlers
-        named http_error_DDD where DDD is the 3-digit error code."""
-        # First check if there's a specific handler for this error
-        name = 'http_error_%d' % errcode
-        if hasattr(self, name):
-            method = getattr(self, name)
-            if data is None:
-                result = method(url, fp, errcode, errmsg, headers)
-            else:
-                result = method(url, fp, errcode, errmsg, headers, data)
-            if result: return result
-        return self.http_error_default(url, fp, errcode, errmsg, headers)
-
-    def http_error_default(self, url, fp, errcode, errmsg, headers):
-        """Default error handler: close the connection and raise IOError."""
-        void = fp.read()
-        fp.close()
-        raise IOError('http error', errcode, errmsg, headers)
-
-    if _have_ssl:
-        def _https_connection(self, host):
-            return http.client.HTTPSConnection(host,
-                                               key_file=self.key_file,
-                                               cert_file=self.cert_file)
-
-        def open_https(self, url, data=None):
-            """Use HTTPS protocol."""
-            return self._open_generic_http(self._https_connection, url, data)
-
-    def open_file(self, url):
-        """Use local file or FTP depending on form of URL."""
-        if not isinstance(url, str):
-            raise IOError('file error', 'proxy support for file protocol currently not implemented')
-        if url[:2] == '//' and url[2:3] != '/' and url[2:12].lower() != 'localhost/':
-            return self.open_ftp(url)
-        else:
-            return self.open_local_file(url)
-
-    def open_local_file(self, url):
-        """Use local file."""
-        import mimetypes, email.utils
-        host, file = splithost(url)
-        localname = url2pathname(file)
-        try:
-            stats = os.stat(localname)
-        except OSError as e:
-            raise IOError(e.errno, e.strerror, e.filename)
-        size = stats.st_size
-        modified = email.utils.formatdate(stats.st_mtime, usegmt=True)
-        mtype = mimetypes.guess_type(url)[0]
-        headers = email.message_from_string(
-            'Content-Type: %s\nContent-Length: %d\nLast-modified: %s\n' %
-            (mtype or 'text/plain', size, modified))
-        if not host:
-            urlfile = file
-            if file[:1] == '/':
-                urlfile = 'file://' + file
-            return addinfourl(open(localname, 'rb'),
-                              headers, urlfile)
-        host, port = splitport(host)
-        if not port \
-           and socket.gethostbyname(host) in (localhost(), thishost()):
-            urlfile = file
-            if file[:1] == '/':
-                urlfile = 'file://' + file
-            return addinfourl(open(localname, 'rb'),
-                              headers, urlfile)
-        raise IOError('local file error', 'not on local host')
-
-    def open_ftp(self, url):
-        """Use FTP protocol."""
-        if not isinstance(url, str):
-            raise IOError('ftp error', 'proxy support for ftp protocol currently not implemented')
-        import mimetypes
-        host, path = splithost(url)
-        if not host: raise IOError('ftp error', 'no host given')
-        host, port = splitport(host)
-        user, host = splituser(host)
-        if user: user, passwd = splitpasswd(user)
-        else: passwd = None
-        host = unquote(host)
-        user = unquote(user or '')
-        passwd = unquote(passwd or '')
-        host = socket.gethostbyname(host)
-        if not port:
-            import ftplib
-            port = ftplib.FTP_PORT
-        else:
-            port = int(port)
-        path, attrs = splitattr(path)
-        path = unquote(path)
-        dirs = path.split('/')
-        dirs, file = dirs[:-1], dirs[-1]
-        if dirs and not dirs[0]: dirs = dirs[1:]
-        if dirs and not dirs[0]: dirs[0] = '/'
-        key = user, host, port, '/'.join(dirs)
-        # XXX thread unsafe!
-        if len(self.ftpcache) > MAXFTPCACHE:
-            # Prune the cache, rather arbitrarily
-            for k in self.ftpcache.keys():
-                if k != key:
-                    v = self.ftpcache[k]
-                    del self.ftpcache[k]
-                    v.close()
-        try:
-            if not key in self.ftpcache:
-                self.ftpcache[key] = \
-                    ftpwrapper(user, passwd, host, port, dirs)
-            if not file: type = 'D'
-            else: type = 'I'
-            for attr in attrs:
-                attr, value = splitvalue(attr)
-                if attr.lower() == 'type' and \
-                   value in ('a', 'A', 'i', 'I', 'd', 'D'):
-                    type = value.upper()
-            (fp, retrlen) = self.ftpcache[key].retrfile(file, type)
-            mtype = mimetypes.guess_type("ftp:" + url)[0]
-            headers = ""
-            if mtype:
-                headers += "Content-Type: %s\n" % mtype
-            if retrlen is not None and retrlen >= 0:
-                headers += "Content-Length: %d\n" % retrlen
-            headers = email.message_from_string(headers)
-            return addinfourl(fp, headers, "ftp:" + url)
-        except ftperrors() as msg:
-            raise IOError('ftp error', msg).with_traceback(sys.exc_info()[2])
-
-    def open_data(self, url, data=None):
-        """Use "data" URL."""
-        if not isinstance(url, str):
-            raise IOError('data error', 'proxy support for data protocol currently not implemented')
-        # ignore POSTed data
-        #
-        # syntax of data URLs:
-        # dataurl   := "data:" [ mediatype ] [ ";base64" ] "," data
-        # mediatype := [ type "/" subtype ] *( ";" parameter )
-        # data      := *urlchar
-        # parameter := attribute "=" value
-        from io import StringIO
-        try:
-            [type, data] = url.split(',', 1)
-        except ValueError:
-            raise IOError('data error', 'bad data URL')
-        if not type:
-            type = 'text/plain;charset=US-ASCII'
-        semi = type.rfind(';')
-        if semi >= 0 and '=' not in type[semi:]:
-            encoding = type[semi+1:]
-            type = type[:semi]
-        else:
-            encoding = ''
-        msg = []
-        msg.append('Date: %s'%time.strftime('%a, %d %b %Y %T GMT',
-                                            time.gmtime(time.time())))
-        msg.append('Content-type: %s' % type)
-        if encoding == 'base64':
-            import base64
-            data = base64.decodestring(data)
-        else:
-            data = unquote(data)
-        msg.append('Content-Length: %d' % len(data))
-        msg.append('')
-        msg.append(data)
-        msg = '\n'.join(msg)
-        headers = email.message_from_string(msg)
-        f = StringIO(msg)
-        #f.fileno = None     # needed for addinfourl
-        return addinfourl(f, headers, url)
-
-
-class FancyURLopener(URLopener):
-    """Derived class with handlers for errors we can handle (perhaps)."""
-
-    def __init__(self, *args, **kwargs):
-        URLopener.__init__(self, *args, **kwargs)
-        self.auth_cache = {}
-        self.tries = 0
-        self.maxtries = 10
-
-    def http_error_default(self, url, fp, errcode, errmsg, headers):
-        """Default error handling -- don't raise an exception."""
-        return addinfourl(fp, headers, "http:" + url, errcode)
-
-    def http_error_302(self, url, fp, errcode, errmsg, headers, data=None):
-        """Error 302 -- relocated (temporarily)."""
-        self.tries += 1
-        if self.maxtries and self.tries >= self.maxtries:
-            if hasattr(self, "http_error_500"):
-                meth = self.http_error_500
-            else:
-                meth = self.http_error_default
-            self.tries = 0
-            return meth(url, fp, 500,
-                        "Internal Server Error: Redirect Recursion", headers)
-        result = self.redirect_internal(url, fp, errcode, errmsg, headers,
-                                        data)
-        self.tries = 0
-        return result
-
-    def redirect_internal(self, url, fp, errcode, errmsg, headers, data):
-        if 'location' in headers:
-            newurl = headers['location']
-        elif 'uri' in headers:
-            newurl = headers['uri']
-        else:
-            return
-        void = fp.read()
-        fp.close()
-        # In case the server sent a relative URL, join with original:
-        newurl = basejoin(self.type + ":" + url, newurl)
-        return self.open(newurl)
-
-    def http_error_301(self, url, fp, errcode, errmsg, headers, data=None):
-        """Error 301 -- also relocated (permanently)."""
-        return self.http_error_302(url, fp, errcode, errmsg, headers, data)
-
-    def http_error_303(self, url, fp, errcode, errmsg, headers, data=None):
-        """Error 303 -- also relocated (essentially identical to 302)."""
-        return self.http_error_302(url, fp, errcode, errmsg, headers, data)
-
-    def http_error_307(self, url, fp, errcode, errmsg, headers, data=None):
-        """Error 307 -- relocated, but turn POST into error."""
-        if data is None:
-            return self.http_error_302(url, fp, errcode, errmsg, headers, data)
-        else:
-            return self.http_error_default(url, fp, errcode, errmsg, headers)
-
-    def http_error_401(self, url, fp, errcode, errmsg, headers, data=None):
-        """Error 401 -- authentication required.
-        This function supports Basic authentication only."""
-        if not 'www-authenticate' in headers:
-            URLopener.http_error_default(self, url, fp,
-                                         errcode, errmsg, headers)
-        stuff = headers['www-authenticate']
-        import re
-        match = re.match('[ \t]*([^ \t]+)[ \t]+realm="([^"]*)"', stuff)
-        if not match:
-            URLopener.http_error_default(self, url, fp,
-                                         errcode, errmsg, headers)
-        scheme, realm = match.groups()
-        if scheme.lower() != 'basic':
-            URLopener.http_error_default(self, url, fp,
-                                         errcode, errmsg, headers)
-        name = 'retry_' + self.type + '_basic_auth'
-        if data is None:
-            return getattr(self,name)(url, realm)
-        else:
-            return getattr(self,name)(url, realm, data)
-
-    def http_error_407(self, url, fp, errcode, errmsg, headers, data=None):
-        """Error 407 -- proxy authentication required.
-        This function supports Basic authentication only."""
-        if not 'proxy-authenticate' in headers:
-            URLopener.http_error_default(self, url, fp,
-                                         errcode, errmsg, headers)
-        stuff = headers['proxy-authenticate']
-        import re
-        match = re.match('[ \t]*([^ \t]+)[ \t]+realm="([^"]*)"', stuff)
-        if not match:
-            URLopener.http_error_default(self, url, fp,
-                                         errcode, errmsg, headers)
-        scheme, realm = match.groups()
-        if scheme.lower() != 'basic':
-            URLopener.http_error_default(self, url, fp,
-                                         errcode, errmsg, headers)
-        name = 'retry_proxy_' + self.type + '_basic_auth'
-        if data is None:
-            return getattr(self,name)(url, realm)
-        else:
-            return getattr(self,name)(url, realm, data)
-
-    def retry_proxy_http_basic_auth(self, url, realm, data=None):
-        host, selector = splithost(url)
-        newurl = 'http://' + host + selector
-        proxy = self.proxies['http']
-        urltype, proxyhost = splittype(proxy)
-        proxyhost, proxyselector = splithost(proxyhost)
-        i = proxyhost.find('@') + 1
-        proxyhost = proxyhost[i:]
-        user, passwd = self.get_user_passwd(proxyhost, realm, i)
-        if not (user or passwd): return None
-        proxyhost = quote(user, safe='') + ':' + quote(passwd, safe='') + '@' + proxyhost
-        self.proxies['http'] = 'http://' + proxyhost + proxyselector
-        if data is None:
-            return self.open(newurl)
-        else:
-            return self.open(newurl, data)
-
-    def retry_proxy_https_basic_auth(self, url, realm, data=None):
-        host, selector = splithost(url)
-        newurl = 'https://' + host + selector
-        proxy = self.proxies['https']
-        urltype, proxyhost = splittype(proxy)
-        proxyhost, proxyselector = splithost(proxyhost)
-        i = proxyhost.find('@') + 1
-        proxyhost = proxyhost[i:]
-        user, passwd = self.get_user_passwd(proxyhost, realm, i)
-        if not (user or passwd): return None
-        proxyhost = quote(user, safe='') + ':' + quote(passwd, safe='') + '@' + proxyhost
-        self.proxies['https'] = 'https://' + proxyhost + proxyselector
-        if data is None:
-            return self.open(newurl)
-        else:
-            return self.open(newurl, data)
-
-    def retry_http_basic_auth(self, url, realm, data=None):
-        host, selector = splithost(url)
-        i = host.find('@') + 1
-        host = host[i:]
-        user, passwd = self.get_user_passwd(host, realm, i)
-        if not (user or passwd): return None
-        host = quote(user, safe='') + ':' + quote(passwd, safe='') + '@' + host
-        newurl = 'http://' + host + selector
-        if data is None:
-            return self.open(newurl)
-        else:
-            return self.open(newurl, data)
-
-    def retry_https_basic_auth(self, url, realm, data=None):
-        host, selector = splithost(url)
-        i = host.find('@') + 1
-        host = host[i:]
-        user, passwd = self.get_user_passwd(host, realm, i)
-        if not (user or passwd): return None
-        host = quote(user, safe='') + ':' + quote(passwd, safe='') + '@' + host
-        newurl = 'https://' + host + selector
-        if data is None:
-            return self.open(newurl)
-        else:
-            return self.open(newurl, data)
-
-    def get_user_passwd(self, host, realm, clear_cache = 0):
-        key = realm + '@' + host.lower()
-        if key in self.auth_cache:
-            if clear_cache:
-                del self.auth_cache[key]
-            else:
-                return self.auth_cache[key]
-        user, passwd = self.prompt_user_passwd(host, realm)
-        if user or passwd: self.auth_cache[key] = (user, passwd)
-        return user, passwd
-
-    def prompt_user_passwd(self, host, realm):
-        """Override this in a GUI environment!"""
-        import getpass
-        try:
-            user = input("Enter username for %s at %s: " % (realm, host))
-            passwd = getpass.getpass("Enter password for %s in %s at %s: " %
-                (user, realm, host))
-            return user, passwd
-        except KeyboardInterrupt:
-            print()
-            return None, None
-
-
-# Utility functions
-
-_localhost = None
-def localhost():
-    """Return the IP address of the magic hostname 'localhost'."""
-    global _localhost
-    if _localhost is None:
-        _localhost = socket.gethostbyname('localhost')
-    return _localhost
-
-_thishost = None
-def thishost():
-    """Return the IP address of the current host."""
-    global _thishost
-    if _thishost is None:
-        _thishost = socket.gethostbyname(socket.gethostname())
-    return _thishost
-
-_ftperrors = None
-def ftperrors():
-    """Return the set of errors raised by the FTP class."""
-    global _ftperrors
-    if _ftperrors is None:
-        import ftplib
-        _ftperrors = ftplib.all_errors
-    return _ftperrors
-
-_noheaders = None
-def noheaders():
-    """Return an empty email.message.Message object."""
-    global _noheaders
-    if _noheaders is None:
-        _noheaders = email.message.Message()
-    return _noheaders
-
-
-# Utility classes
-
-class ftpwrapper:
-    """Class used by open_ftp() for cache of open FTP connections."""
-
-    def __init__(self, user, passwd, host, port, dirs,
-                 timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
-        self.user = user
-        self.passwd = passwd
-        self.host = host
-        self.port = port
-        self.dirs = dirs
-        self.timeout = timeout
-        self.init()
-
-    def init(self):
-        import ftplib
-        self.busy = 0
-        self.ftp = ftplib.FTP()
-        self.ftp.connect(self.host, self.port, self.timeout)
-        self.ftp.login(self.user, self.passwd)
-        for dir in self.dirs:
-            self.ftp.cwd(dir)
-
-    def retrfile(self, file, type):
-        import ftplib
-        self.endtransfer()
-        if type in ('d', 'D'): cmd = 'TYPE A'; isdir = 1
-        else: cmd = 'TYPE ' + type; isdir = 0
-        try:
-            self.ftp.voidcmd(cmd)
-        except ftplib.all_errors:
-            self.init()
-            self.ftp.voidcmd(cmd)
-        conn = None
-        if file and not isdir:
-            # Try to retrieve as a file
-            try:
-                cmd = 'RETR ' + file
-                conn = self.ftp.ntransfercmd(cmd)
-            except ftplib.error_perm as reason:
-                if str(reason)[:3] != '550':
-                    raise IOError('ftp error', reason).with_traceback(sys.exc_info()[2])
-        if not conn:
-            # Set transfer mode to ASCII!
-            self.ftp.voidcmd('TYPE A')
-            # Try a directory listing. Verify that directory exists.
-            if file:
-                pwd = self.ftp.pwd()
-                try:
-                    try:
-                        self.ftp.cwd(file)
-                    except ftplib.error_perm as reason:
-                        raise IOError('ftp error', reason) from reason
-                finally:
-                    self.ftp.cwd(pwd)
-                cmd = 'LIST ' + file
-            else:
-                cmd = 'LIST'
-            conn = self.ftp.ntransfercmd(cmd)
-        self.busy = 1
-        # Pass back both a suitably decorated object and a retrieval length
-        return (addclosehook(conn[0].makefile('rb'),
-                             self.endtransfer), conn[1])
-    def endtransfer(self):
-        if not self.busy:
-            return
-        self.busy = 0
-        try:
-            self.ftp.voidresp()
-        except ftperrors():
-            pass
-
-    def close(self):
-        self.endtransfer()
-        try:
-            self.ftp.close()
-        except ftperrors():
-            pass
-
-class addbase:
-    """Base class for addinfo and addclosehook."""
-
-    # XXX Add a method to expose the timeout on the underlying socket?
-
-    def __init__(self, fp):
-        self.fp = fp
-        self.read = self.fp.read
-        self.readline = self.fp.readline
-        if hasattr(self.fp, "readlines"): self.readlines = self.fp.readlines
-        if hasattr(self.fp, "fileno"):
-            self.fileno = self.fp.fileno
-        else:
-            self.fileno = lambda: None
-        if hasattr(self.fp, "__iter__"):
-            self.__iter__ = self.fp.__iter__
-            if hasattr(self.fp, "__next__"):
-                self.__next__ = self.fp.__next__
-
-    def __repr__(self):
-        return '<%s at %r whose fp = %r>' % (self.__class__.__name__,
-                                             id(self), self.fp)
-
-    def close(self):
-        self.read = None
-        self.readline = None
-        self.readlines = None
-        self.fileno = None
-        if self.fp: self.fp.close()
-        self.fp = None
-
-class addclosehook(addbase):
-    """Class to add a close hook to an open file."""
-
-    def __init__(self, fp, closehook, *hookargs):
-        addbase.__init__(self, fp)
-        self.closehook = closehook
-        self.hookargs = hookargs
-
-    def close(self):
-        addbase.close(self)
-        if self.closehook:
-            self.closehook(*self.hookargs)
-            self.closehook = None
-            self.hookargs = None
-
-class addinfo(addbase):
-    """class to add an info() method to an open file."""
-
-    def __init__(self, fp, headers):
-        addbase.__init__(self, fp)
-        self.headers = headers
-
-    def info(self):
-        return self.headers
-
-class addinfourl(addbase):
-    """class to add info() and geturl() methods to an open file."""
-
-    def __init__(self, fp, headers, url, code=None):
-        addbase.__init__(self, fp)
-        self.headers = headers
-        self.url = url
-        self.code = code
-
-    def info(self):
-        return self.headers
-
-    def getcode(self):
-        return self.code
-
-    def geturl(self):
-        return self.url
-
-
-# Utilities to parse URLs (most of these return None for missing parts):
-# unwrap('<URL:type://host/path>') --> 'type://host/path'
-# splittype('type:opaquestring') --> 'type', 'opaquestring'
-# splithost('//host[:port]/path') --> 'host[:port]', '/path'
-# splituser('user[:passwd]@host[:port]') --> 'user[:passwd]', 'host[:port]'
-# splitpasswd('user:passwd') -> 'user', 'passwd'
-# splitport('host:port') --> 'host', 'port'
-# splitquery('/path?query') --> '/path', 'query'
-# splittag('/path#tag') --> '/path', 'tag'
-# splitattr('/path;attr1=value1;attr2=value2;...') ->
-#   '/path', ['attr1=value1', 'attr2=value2', ...]
-# splitvalue('attr=value') --> 'attr', 'value'
-# unquote('abc%20def') -> 'abc def'
-# quote('abc def') -> 'abc%20def')
-
-def toBytes(url):
-    """toBytes(u"URL") --> 'URL'."""
-    # Most URL schemes require ASCII. If that changes, the conversion
-    # can be relaxed.
-    # XXX get rid of toBytes()
-    if isinstance(url, str):
-        try:
-            url = url.encode("ASCII").decode()
-        except UnicodeError:
-            raise UnicodeError("URL " + repr(url) +
-                               " contains non-ASCII characters")
-    return url
-
-def unwrap(url):
-    """unwrap('<URL:type://host/path>') --> 'type://host/path'."""
-    url = str(url).strip()
-    if url[:1] == '<' and url[-1:] == '>':
-        url = url[1:-1].strip()
-    if url[:4] == 'URL:': url = url[4:].strip()
-    return url
-
-_typeprog = None
-def splittype(url):
-    """splittype('type:opaquestring') --> 'type', 'opaquestring'."""
-    global _typeprog
-    if _typeprog is None:
-        import re
-        _typeprog = re.compile('^([^/:]+):')
-
-    match = _typeprog.match(url)
-    if match:
-        scheme = match.group(1)
-        return scheme.lower(), url[len(scheme) + 1:]
-    return None, url
-
-_hostprog = None
-def splithost(url):
-    """splithost('//host[:port]/path') --> 'host[:port]', '/path'."""
-    global _hostprog
-    if _hostprog is None:
-        import re
-        _hostprog = re.compile('^//([^/?]*)(.*)$')
-
-    match = _hostprog.match(url)
-    if match: return match.group(1, 2)
-    return None, url
-
-_userprog = None
-def splituser(host):
-    """splituser('user[:passwd]@host[:port]') --> 'user[:passwd]', 'host[:port]'."""
-    global _userprog
-    if _userprog is None:
-        import re
-        _userprog = re.compile('^(.*)@(.*)$')
-
-    match = _userprog.match(host)
-    if match: return map(unquote, match.group(1, 2))
-    return None, host
-
-_passwdprog = None
-def splitpasswd(user):
-    """splitpasswd('user:passwd') -> 'user', 'passwd'."""
-    global _passwdprog
-    if _passwdprog is None:
-        import re
-        _passwdprog = re.compile('^([^:]*):(.*)$')
-
-    match = _passwdprog.match(user)
-    if match: return match.group(1, 2)
-    return user, None
-
-# splittag('/path#tag') --> '/path', 'tag'
-_portprog = None
-def splitport(host):
-    """splitport('host:port') --> 'host', 'port'."""
-    global _portprog
-    if _portprog is None:
-        import re
-        _portprog = re.compile('^(.*):([0-9]+)$')
-
-    match = _portprog.match(host)
-    if match: return match.group(1, 2)
-    return host, None
-
-_nportprog = None
-def splitnport(host, defport=-1):
-    """Split host and port, returning numeric port.
-    Return given default port if no ':' found; defaults to -1.
-    Return numerical port if a valid number are found after ':'.
-    Return None if ':' but not a valid number."""
-    global _nportprog
-    if _nportprog is None:
-        import re
-        _nportprog = re.compile('^(.*):(.*)$')
-
-    match = _nportprog.match(host)
-    if match:
-        host, port = match.group(1, 2)
-        try:
-            if not port: raise ValueError("no digits")
-            nport = int(port)
-        except ValueError:
-            nport = None
-        return host, nport
-    return host, defport
-
-_queryprog = None
-def splitquery(url):
-    """splitquery('/path?query') --> '/path', 'query'."""
-    global _queryprog
-    if _queryprog is None:
-        import re
-        _queryprog = re.compile('^(.*)\?([^?]*)$')
-
-    match = _queryprog.match(url)
-    if match: return match.group(1, 2)
-    return url, None
-
-_tagprog = None
-def splittag(url):
-    """splittag('/path#tag') --> '/path', 'tag'."""
-    global _tagprog
-    if _tagprog is None:
-        import re
-        _tagprog = re.compile('^(.*)#([^#]*)$')
-
-    match = _tagprog.match(url)
-    if match: return match.group(1, 2)
-    return url, None
-
-def splitattr(url):
-    """splitattr('/path;attr1=value1;attr2=value2;...') ->
-        '/path', ['attr1=value1', 'attr2=value2', ...]."""
-    words = url.split(';')
-    return words[0], words[1:]
-
-_valueprog = None
-def splitvalue(attr):
-    """splitvalue('attr=value') --> 'attr', 'value'."""
-    global _valueprog
-    if _valueprog is None:
-        import re
-        _valueprog = re.compile('^([^=]*)=(.*)$')
-
-    match = _valueprog.match(attr)
-    if match: return match.group(1, 2)
-    return attr, None
-
-_hextochr = dict(('%02x' % i, chr(i)) for i in range(256))
-_hextochr.update(('%02X' % i, chr(i)) for i in range(256))
-
-def unquote(s):
-    """unquote('abc%20def') -> 'abc def'."""
-    res = s.split('%')
-    for i in range(1, len(res)):
-        item = res[i]
-        try:
-            res[i] = _hextochr[item[:2]] + item[2:]
-        except KeyError:
-            res[i] = '%' + item
-        except UnicodeDecodeError:
-            res[i] = chr(int(item[:2], 16)) + item[2:]
-    return "".join(res)
-
-def unquote_plus(s):
-    """unquote('%7e/abc+def') -> '~/abc def'"""
-    s = s.replace('+', ' ')
-    return unquote(s)
-
-always_safe = ('ABCDEFGHIJKLMNOPQRSTUVWXYZ'
-               'abcdefghijklmnopqrstuvwxyz'
-               '0123456789' '_.-')
-_safe_quoters= {}
-
-class Quoter:
-    def __init__(self, safe):
-        self.cache = {}
-        self.safe = safe + always_safe
-
-    def __call__(self, c):
-        try:
-            return self.cache[c]
-        except KeyError:
-            if ord(c) < 256:
-                res = (c in self.safe) and c or ('%%%02X' % ord(c))
-                self.cache[c] = res
-                return res
-            else:
-                return "".join(['%%%02X' % i for i in c.encode("utf-8")])
-
-def quote(s, safe = '/'):
-    """quote('abc def') -> 'abc%20def'
-
-    Each part of a URL, e.g. the path info, the query, etc., has a
-    different set of reserved characters that must be quoted.
-
-    RFC 2396 Uniform Resource Identifiers (URI): Generic Syntax lists
-    the following reserved characters.
-
-    reserved    = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" |
-                  "$" | ","
-
-    Each of these characters is reserved in some component of a URL,
-    but not necessarily in all of them.
-
-    By default, the quote function is intended for quoting the path
-    section of a URL.  Thus, it will not encode '/'.  This character
-    is reserved, but in typical usage the quote function is being
-    called on a path where the existing slash characters are used as
-    reserved characters.
-    """
-    cachekey = (safe, always_safe)
-    try:
-        quoter = _safe_quoters[cachekey]
-    except KeyError:
-        quoter = Quoter(safe)
-        _safe_quoters[cachekey] = quoter
-    res = map(quoter, s)
-    return ''.join(res)
-
-def quote_plus(s, safe = ''):
-    """Quote the query fragment of a URL; replacing ' ' with '+'"""
-    if ' ' in s:
-        s = quote(s, safe + ' ')
-        return s.replace(' ', '+')
-    return quote(s, safe)
-
-def urlencode(query,doseq=0):
-    """Encode a sequence of two-element tuples or dictionary into a URL query string.
-
-    If any values in the query arg are sequences and doseq is true, each
-    sequence element is converted to a separate parameter.
-
-    If the query arg is a sequence of two-element tuples, the order of the
-    parameters in the output will match the order of parameters in the
-    input.
-    """
-
-    if hasattr(query,"items"):
-        # mapping objects
-        query = query.items()
-    else:
-        # it's a bother at times that strings and string-like objects are
-        # sequences...
-        try:
-            # non-sequence items should not work with len()
-            # non-empty strings will fail this
-            if len(query) and not isinstance(query[0], tuple):
-                raise TypeError
-            # zero-length sequences of all types will get here and succeed,
-            # but that's a minor nit - since the original implementation
-            # allowed empty dicts that type of behavior probably should be
-            # preserved for consistency
-        except TypeError:
-            ty,va,tb = sys.exc_info()
-            raise TypeError("not a valid non-string sequence or mapping object").with_traceback(tb)
-
-    l = []
-    if not doseq:
-        # preserve old behavior
-        for k, v in query:
-            k = quote_plus(str(k))
-            v = quote_plus(str(v))
-            l.append(k + '=' + v)
-    else:
-        for k, v in query:
-            k = quote_plus(str(k))
-            if isinstance(v, str):
-                v = quote_plus(v)
-                l.append(k + '=' + v)
-            elif isinstance(v, str):
-                # is there a reasonable way to convert to ASCII?
-                # encode generates a string, but "replace" or "ignore"
-                # lose information and "strict" can raise UnicodeError
-                v = quote_plus(v.encode("ASCII","replace"))
-                l.append(k + '=' + v)
-            else:
-                try:
-                    # is this a sufficient test for sequence-ness?
-                    x = len(v)
-                except TypeError:
-                    # not a sequence
-                    v = quote_plus(str(v))
-                    l.append(k + '=' + v)
-                else:
-                    # loop over the sequence
-                    for elt in v:
-                        l.append(k + '=' + quote_plus(str(elt)))
-    return '&'.join(l)
-
-# Proxy handling
-def getproxies_environment():
-    """Return a dictionary of scheme -> proxy server URL mappings.
-
-    Scan the environment for variables named <scheme>_proxy;
-    this seems to be the standard convention.  If you need a
-    different way, you can pass a proxies dictionary to the
-    [Fancy]URLopener constructor.
-
-    """
-    proxies = {}
-    for name, value in os.environ.items():
-        name = name.lower()
-        if name == 'no_proxy':
-            # handled in proxy_bypass_environment
-            continue
-        if value and name[-6:] == '_proxy':
-            proxies[name[:-6]] = value
-    return proxies
-
-def proxy_bypass_environment(host):
-    """Test if proxies should not be used for a particular host.
-
-    Checks the environment for a variable named no_proxy, which should
-    be a list of DNS suffixes separated by commas, or '*' for all hosts.
-    """
-    no_proxy = os.environ.get('no_proxy', '') or os.environ.get('NO_PROXY', '')
-    # '*' is special case for always bypass
-    if no_proxy == '*':
-        return 1
-    # strip port off host
-    hostonly, port = splitport(host)
-    # check if the host ends with any of the DNS suffixes
-    for name in no_proxy.split(','):
-        if name and (hostonly.endswith(name) or host.endswith(name)):
-            return 1
-    # otherwise, don't bypass
-    return 0
-
-
-if sys.platform == 'darwin':
-
-    def _CFSetup(sc):
-        from ctypes import c_int32, c_void_p, c_char_p, c_int
-        sc.CFStringCreateWithCString.argtypes = [ c_void_p, c_char_p, c_int32 ]
-        sc.CFStringCreateWithCString.restype = c_void_p
-        sc.SCDynamicStoreCopyProxies.argtypes = [ c_void_p ]
-        sc.SCDynamicStoreCopyProxies.restype = c_void_p
-        sc.CFDictionaryGetValue.argtypes = [ c_void_p, c_void_p ]
-        sc.CFDictionaryGetValue.restype = c_void_p
-        sc.CFStringGetLength.argtypes = [ c_void_p ]
-        sc.CFStringGetLength.restype = c_int32
-        sc.CFStringGetCString.argtypes = [ c_void_p, c_char_p, c_int32, c_int32 ]
-        sc.CFStringGetCString.restype = c_int32
-        sc.CFNumberGetValue.argtypes = [ c_void_p, c_int, c_void_p ]
-        sc.CFNumberGetValue.restype = c_int32
-        sc.CFRelease.argtypes = [ c_void_p ]
-        sc.CFRelease.restype = None
-
-    def _CStringFromCFString(sc, value):
-        from ctypes import create_string_buffer
-        length = sc.CFStringGetLength(value) + 1
-        buff = create_string_buffer(length)
-        sc.CFStringGetCString(value, buff, length, 0)
-        return buff.value
-
-    def _CFNumberToInt32(sc, cfnum):
-        from ctypes import byref, c_int
-        val = c_int()
-        kCFNumberSInt32Type = 3
-        sc.CFNumberGetValue(cfnum, kCFNumberSInt32Type, byref(val))
-        return val.value
-
-
-    def proxy_bypass_macosx_sysconf(host):
-        """
-        Return True iff this host shouldn't be accessed using a proxy
-
-        This function uses the MacOSX framework SystemConfiguration
-        to fetch the proxy information.
-        """
-        from ctypes import cdll
-        from ctypes.util import find_library
-        import re
-        import socket
-        from fnmatch import fnmatch
-
-        def ip2num(ipAddr):
-            parts = ipAddr.split('.')
-            parts = map(int, parts)
-            if len(parts) != 4:
-                parts = (parts + [0, 0, 0, 0])[:4]
-            return (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8) | parts[3]
-
-        sc = cdll.LoadLibrary(find_library("SystemConfiguration"))
-        _CFSetup(sc)
-
-        hostIP = None
-
-        if not sc:
-            return False
-
-        kSCPropNetProxiesExceptionsList = sc.CFStringCreateWithCString(0, "ExceptionsList", 0)
-        kSCPropNetProxiesExcludeSimpleHostnames = sc.CFStringCreateWithCString(0,
-                "ExcludeSimpleHostnames", 0)
-
-
-        proxyDict = sc.SCDynamicStoreCopyProxies(None)
-        if proxyDict is None:
-            return False
-
-        try:
-            # Check for simple host names:
-            if '.' not in host:
-                exclude_simple = sc.CFDictionaryGetValue(proxyDict,
-                        kSCPropNetProxiesExcludeSimpleHostnames)
-                if exclude_simple and _CFNumberToInt32(sc, exclude_simple):
-                    return True
-
-
-            # Check the exceptions list:
-            exceptions = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesExceptionsList)
-            if exceptions:
-                # Items in the list are strings like these: *.local, 169.254/16
-                for index in xrange(sc.CFArrayGetCount(exceptions)):
-                    value = sc.CFArrayGetValueAtIndex(exceptions, index)
-                    if not value: continue
-                    value = _CStringFromCFString(sc, value)
-
-                    m = re.match(r"(\d+(?:\.\d+)*)(/\d+)?", value)
-                    if m is not None:
-                        if hostIP is None:
-                            hostIP = socket.gethostbyname(host)
-                            hostIP = ip2num(hostIP)
-
-                        base = ip2num(m.group(1))
-                        mask = int(m.group(2)[1:])
-                        mask = 32 - mask
-
-                        if (hostIP >> mask) == (base >> mask):
-                            return True
-
-                    elif fnmatch(host, value):
-                        return True
-
-            return False
-
-        finally:
-            sc.CFRelease(kSCPropNetProxiesExceptionsList)
-            sc.CFRelease(kSCPropNetProxiesExcludeSimpleHostnames)
-
-
-
-    def getproxies_macosx_sysconf():
-        """Return a dictionary of scheme -> proxy server URL mappings.
-
-        This function uses the MacOSX framework SystemConfiguration
-        to fetch the proxy information.
-        """
-        from ctypes import cdll
-        from ctypes.util import find_library
-
-        sc = cdll.LoadLibrary(find_library("SystemConfiguration"))
-        _CFSetup(sc)
-
-        if not sc:
-            return {}
-
-        kSCPropNetProxiesHTTPEnable = sc.CFStringCreateWithCString(0, b"HTTPEnable", 0)
-        kSCPropNetProxiesHTTPProxy = sc.CFStringCreateWithCString(0, b"HTTPProxy", 0)
-        kSCPropNetProxiesHTTPPort = sc.CFStringCreateWithCString(0, b"HTTPPort", 0)
-
-        kSCPropNetProxiesHTTPSEnable = sc.CFStringCreateWithCString(0, b"HTTPSEnable", 0)
-        kSCPropNetProxiesHTTPSProxy = sc.CFStringCreateWithCString(0, b"HTTPSProxy", 0)
-        kSCPropNetProxiesHTTPSPort = sc.CFStringCreateWithCString(0, b"HTTPSPort", 0)
-
-        kSCPropNetProxiesFTPEnable = sc.CFStringCreateWithCString(0, b"FTPEnable", 0)
-        kSCPropNetProxiesFTPPassive = sc.CFStringCreateWithCString(0, b"FTPPassive", 0)
-        kSCPropNetProxiesFTPPort = sc.CFStringCreateWithCString(0, b"FTPPort", 0)
-        kSCPropNetProxiesFTPProxy = sc.CFStringCreateWithCString(0, b"FTPProxy", 0)
-
-        kSCPropNetProxiesGopherEnable = sc.CFStringCreateWithCString(0, b"GopherEnable", 0)
-        kSCPropNetProxiesGopherPort = sc.CFStringCreateWithCString(0, b"GopherPort", 0)
-        kSCPropNetProxiesGopherProxy = sc.CFStringCreateWithCString(0, b"GopherProxy", 0)
-
-        proxies = {}
-        proxyDict = sc.SCDynamicStoreCopyProxies(None)
-
-        try:
-            # HTTP:
-            enabled = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesHTTPEnable)
-            if enabled and _CFNumberToInt32(sc, enabled):
-                proxy = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesHTTPProxy)
-                port = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesHTTPPort)
-
-                if proxy:
-                    proxy = _CStringFromCFString(sc, proxy)
-                    if port:
-                        port = _CFNumberToInt32(sc, port)
-                        proxies["http"] = "http://%s:%i" % (proxy, port)
-                    else:
-                        proxies["http"] = "http://%s" % (proxy, )
-
-            # HTTPS:
-            enabled = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesHTTPSEnable)
-            if enabled and _CFNumberToInt32(sc, enabled):
-                proxy = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesHTTPSProxy)
-                port = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesHTTPSPort)
-
-                if proxy:
-                    proxy = _CStringFromCFString(sc, proxy)
-                    if port:
-                        port = _CFNumberToInt32(sc, port)
-                        proxies["https"] = "http://%s:%i" % (proxy, port)
-                    else:
-                        proxies["https"] = "http://%s" % (proxy, )
-
-            # FTP:
-            enabled = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesFTPEnable)
-            if enabled and _CFNumberToInt32(sc, enabled):
-                proxy = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesFTPProxy)
-                port = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesFTPPort)
-
-                if proxy:
-                    proxy = _CStringFromCFString(sc, proxy)
-                    if port:
-                        port = _CFNumberToInt32(sc, port)
-                        proxies["ftp"] = "http://%s:%i" % (proxy, port)
-                    else:
-                        proxies["ftp"] = "http://%s" % (proxy, )
-
-            # Gopher:
-            enabled = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesGopherEnable)
-            if enabled and _CFNumberToInt32(sc, enabled):
-                proxy = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesGopherProxy)
-                port = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesGopherPort)
-
-                if proxy:
-                    proxy = _CStringFromCFString(sc, proxy)
-                    if port:
-                        port = _CFNumberToInt32(sc, port)
-                        proxies["gopher"] = "http://%s:%i" % (proxy, port)
-                    else:
-                        proxies["gopher"] = "http://%s" % (proxy, )
-        finally:
-            sc.CFRelease(proxyDict)
-
-        sc.CFRelease(kSCPropNetProxiesHTTPEnable)
-        sc.CFRelease(kSCPropNetProxiesHTTPProxy)
-        sc.CFRelease(kSCPropNetProxiesHTTPPort)
-        sc.CFRelease(kSCPropNetProxiesFTPEnable)
-        sc.CFRelease(kSCPropNetProxiesFTPPassive)
-        sc.CFRelease(kSCPropNetProxiesFTPPort)
-        sc.CFRelease(kSCPropNetProxiesFTPProxy)
-        sc.CFRelease(kSCPropNetProxiesGopherEnable)
-        sc.CFRelease(kSCPropNetProxiesGopherPort)
-        sc.CFRelease(kSCPropNetProxiesGopherProxy)
-
-        return proxies
-
-
-
-    def proxy_bypass(host):
-        if getproxies_environment():
-            return proxy_bypass_environment(host)
-        else:
-            return proxy_bypass_macosx_sysconf(host)
-
-    def getproxies():
-        return getproxies_environment() or getproxies_macosx_sysconf()
-
-elif os.name == 'nt':
-    def getproxies_registry():
-        """Return a dictionary of scheme -> proxy server URL mappings.
-
-        Win32 uses the registry to store proxies.
-
-        """
-        proxies = {}
-        try:
-            import winreg
-        except ImportError:
-            # Std module, so should be around - but you never know!
-            return proxies
-        try:
-            internetSettings = winreg.OpenKey(winreg.HKEY_CURRENT_USER,
-                r'Software\Microsoft\Windows\CurrentVersion\Internet Settings')
-            proxyEnable = winreg.QueryValueEx(internetSettings,
-                                              'ProxyEnable')[0]
-            if proxyEnable:
-                # Returned as Unicode but problems if not converted to ASCII
-                proxyServer = str(winreg.QueryValueEx(internetSettings,
-                                                      'ProxyServer')[0])
-                if '=' in proxyServer:
-                    # Per-protocol settings
-                    for p in proxyServer.split(';'):
-                        protocol, address = p.split('=', 1)
-                        # See if address has a type:// prefix
-                        import re
-                        if not re.match('^([^/:]+)://', address):
-                            address = '%s://%s' % (protocol, address)
-                        proxies[protocol] = address
-                else:
-                    # Use one setting for all protocols
-                    if proxyServer[:5] == 'http:':
-                        proxies['http'] = proxyServer
-                    else:
-                        proxies['http'] = 'http://%s' % proxyServer
-                        proxies['ftp'] = 'ftp://%s' % proxyServer
-            internetSettings.Close()
-        except (WindowsError, ValueError, TypeError):
-            # Either registry key not found etc, or the value in an
-            # unexpected format.
-            # proxies already set up to be empty so nothing to do
-            pass
-        return proxies
-
-    def getproxies():
-        """Return a dictionary of scheme -> proxy server URL mappings.
-
-        Returns settings gathered from the environment, if specified,
-        or the registry.
-
-        """
-        return getproxies_environment() or getproxies_registry()
-
-    def proxy_bypass_registry(host):
-        try:
-            import winreg
-            import re
-        except ImportError:
-            # Std modules, so should be around - but you never know!
-            return 0
-        try:
-            internetSettings = winreg.OpenKey(winreg.HKEY_CURRENT_USER,
-                r'Software\Microsoft\Windows\CurrentVersion\Internet Settings')
-            proxyEnable = winreg.QueryValueEx(internetSettings,
-                                              'ProxyEnable')[0]
-            proxyOverride = str(winreg.QueryValueEx(internetSettings,
-                                                    'ProxyOverride')[0])
-            # ^^^^ Returned as Unicode but problems if not converted to ASCII
-        except WindowsError:
-            return 0
-        if not proxyEnable or not proxyOverride:
-            return 0
-        # try to make a host list from name and IP address.
-        rawHost, port = splitport(host)
-        host = [rawHost]
-        try:
-            addr = socket.gethostbyname(rawHost)
-            if addr != rawHost:
-                host.append(addr)
-        except socket.error:
-            pass
-        try:
-            fqdn = socket.getfqdn(rawHost)
-            if fqdn != rawHost:
-                host.append(fqdn)
-        except socket.error:
-            pass
-        # make a check value list from the registry entry: replace the
-        # '<local>' string by the localhost entry and the corresponding
-        # canonical entry.
-        proxyOverride = proxyOverride.split(';')
-        i = 0
-        while i < len(proxyOverride):
-            if proxyOverride[i] == '<local>':
-                proxyOverride[i:i+1] = ['localhost',
-                                        '127.0.0.1',
-                                        socket.gethostname(),
-                                        socket.gethostbyname(
-                                            socket.gethostname())]
-            i += 1
-        # print proxyOverride
-        # now check if we match one of the registry values.
-        for test in proxyOverride:
-            test = test.replace(".", r"\.")     # mask dots
-            test = test.replace("*", r".*")     # change glob sequence
-            test = test.replace("?", r".")      # change glob char
-            for val in host:
-                # print "%s <--> %s" %( test, val )
-                if re.match(test, val, re.I):
-                    return 1
-        return 0
-
-    def proxy_bypass(host):
-        """Return a dictionary of scheme -> proxy server URL mappings.
-
-        Returns settings gathered from the environment, if specified,
-        or the registry.
-
-        """
-        if getproxies_environment():
-            return proxy_bypass_environment(host)
-        else:
-            return proxy_bypass_registry(host)
-
-else:
-    # By default use environment variables
-    getproxies = getproxies_environment
-    proxy_bypass = proxy_bypass_environment
-
-# Test and time quote() and unquote()
-def test1():
-    s = ''
-    for i in range(256): s = s + chr(i)
-    s = s*4
-    t0 = time.time()
-    qs = quote(s)
-    uqs = unquote(qs)
-    t1 = time.time()
-    if uqs != s:
-        print('Wrong!')
-    print(repr(s))
-    print(repr(qs))
-    print(repr(uqs))
-    print(round(t1 - t0, 3), 'sec')
-
-
-def reporthook(blocknum, blocksize, totalsize):
-    # Report during remote transfers
-    print("Block number: %d, Block size: %d, Total size: %d" % (
-        blocknum, blocksize, totalsize))
-
-# Test program
-def test(args=[]):
-    if not args:
-        args = [
-            '/etc/passwd',
-            'file:/etc/passwd',
-            'file://localhost/etc/passwd',
-            'ftp://ftp.gnu.org/pub/README',
-            'http://www.python.org/index.html',
-            ]
-        if hasattr(URLopener, "open_https"):
-            args.append('https://synergy.as.cmu.edu/~geek/')
-    try:
-        for url in args:
-            print('-'*10, url, '-'*10)
-            fn, h = urlretrieve(url, None, reporthook)
-            print(fn)
-            if h:
-                print('======')
-                for k in h.keys(): print(k + ':', h[k])
-                print('======')
-            fp = open(fn, 'rb')
-            data = fp.read()
-            del fp
-            data = data.replace("\r", "")
-            print(data)
-            fn, h = None, None
-        print('-'*40)
-    finally:
-        urlcleanup()
-
-def main():
-    import getopt, sys
-    try:
-        opts, args = getopt.getopt(sys.argv[1:], "th")
-    except getopt.error as msg:
-        print(msg)
-        print("Use -h for help")
-        return
-    t = 0
-    for o, a in opts:
-        if o == '-t':
-            t = t + 1
-        if o == '-h':
-            print("Usage: python urllib.py [-t] [url ...]")
-            print("-t runs self-test;", end=' ')
-            print("otherwise, contents of urls are printed")
-            return
-    if t:
-        if t > 1:
-            test1()
-        test(args)
-    else:
-        if not args:
-            print("Use -h for help")
-        for url in args:
-            print(urlopen(url).read(), end=' ')
-
-# Run test program when run as a script
-if __name__ == '__main__':
-    main()

Added: python/branches/py3k-urllib/Lib/urllib/__init__.py
==============================================================================

Added: python/branches/py3k-urllib/Lib/urllib/error.py
==============================================================================
--- (empty file)
+++ python/branches/py3k-urllib/Lib/urllib/error.py	Tue Jun 17 23:01:35 2008
@@ -0,0 +1,59 @@
+"""Exception classes raised by urllib.
+
+The base exception class is URLError, which inherits from IOError.  It
+doesn't define any behavior of its own, but is the base class for all
+exceptions defined in this package.
+
+HTTPError is an exception class that is also a valid HTTP response
+instance.  It behaves this way because HTTP protocol errors are valid
+responses, with a status code, headers, and a body.  In some contexts,
+an application may want to handle an exception like a regular
+response.
+"""
+
+import urllib.response
+
+# do these error classes make sense?
+# make sure all of the IOError stuff is overridden.  we just want to be
+# subtypes.
+
+class URLError(IOError):
+    # URLError is a sub-type of IOError, but it doesn't share any of
+    # the implementation.  need to override __init__ and __str__.
+    # It sets self.args for compatibility with other EnvironmentError
+    # subclasses, but args doesn't have the typical format with errno in
+    # slot 0 and strerror in slot 1.  This may be better than nothing.
+    def __init__(self, reason, filename=None):
+        self.args = reason,
+        self.reason = reason
+        if filename is not None:
+            self.filename = filename
+
+    def __str__(self):
+        return '<urlopen error %s>' % self.reason
+
+class HTTPError(URLError, urllib.response.addinfourl):
+    """Raised when HTTP error occurs, but also acts like non-error return"""
+    __super_init = urllib.response.addinfourl.__init__
+
+    def __init__(self, url, code, msg, hdrs, fp):
+        self.code = code
+        self.msg = msg
+        self.hdrs = hdrs
+        self.fp = fp
+        self.filename = url
+        # The addinfourl classes depend on fp being a valid file
+        # object.  In some cases, the HTTPError may not have a valid
+        # file object.  If this happens, the simplest workaround is to
+        # not initialize the base classes.
+        if fp is not None:
+            self.__super_init(fp, hdrs, url, code)
+
+    def __str__(self):
+        return 'HTTP Error %s: %s' % (self.code, self.msg)
+
+# exception raised when downloaded size does not match content-length
+class ContentTooShortError(URLError):
+    def __init__(self, message, content):
+        URLError.__init__(self, message)
+        self.content = content

Copied: python/branches/py3k-urllib/Lib/urllib/parse.py (from r64345, /python/branches/py3k-urllib/Lib/urllib.py)
==============================================================================
--- /python/branches/py3k-urllib/Lib/urllib.py	(original)
+++ python/branches/py3k-urllib/Lib/urllib/parse.py	Tue Jun 17 23:01:35 2008
@@ -1,926 +1,405 @@
-"""Open an arbitrary URL.
+"""Parse (absolute and relative) URLs.
 
-See the following document for more info on URLs:
-"Names and Addresses, URIs, URLs, URNs, URCs", at
-http://www.w3.org/pub/WWW/Addressing/Overview.html
-
-See also the HTTP spec (from which the error codes are derived):
-"HTTP - Hypertext Transfer Protocol", at
-http://www.w3.org/pub/WWW/Protocols/
-
-Related standards and specs:
-- RFC1808: the "relative URL" spec. (authoritative status)
-- RFC1738 - the "URL standard". (authoritative status)
-- RFC1630 - the "URI spec". (informational status)
-
-The object returned by URLopener().open(file) will differ per
-protocol.  All you know is that is has methods read(), readline(),
-readlines(), fileno(), close() and info().  The read*(), fileno()
-and close() methods work like those of open files.
-The info() method returns a email.message.Message object which can be
-used to query various info about the object, if available.
-(email.message.Message objects provide a dict-like interface.)
+See RFC 1808: "Relative Uniform Resource Locators", by R. Fielding,
+UC Irvine, June 1995.
 """
 
-import http.client
-import email.message
-import email
-import os
-import socket
-import sys
-import time
-from urlparse import urljoin as basejoin
-
-__all__ = ["urlopen", "URLopener", "FancyURLopener", "urlretrieve",
-           "urlcleanup", "quote", "quote_plus", "unquote", "unquote_plus",
-           "urlencode", "url2pathname", "pathname2url", "splittag",
-           "localhost", "thishost", "ftperrors", "basejoin", "unwrap",
-           "splittype", "splithost", "splituser", "splitpasswd", "splitport",
-           "splitnport", "splitquery", "splitattr", "splitvalue",
-           "getproxies"]
-
-__version__ = '1.17'    # XXX This version is not always updated :-(
-
-MAXFTPCACHE = 10        # Trim the ftp cache beyond this size
-
-# Helper for non-unix systems
-if os.name == 'mac':
-    from macurl2path import url2pathname, pathname2url
-elif os.name == 'nt':
-    from nturl2path import url2pathname, pathname2url
-else:
-    def url2pathname(pathname):
-        """OS-specific conversion from a relative URL of the 'file' scheme
-        to a file system path; not recommended for general use."""
-        return unquote(pathname)
-
-    def pathname2url(pathname):
-        """OS-specific conversion from a file system path to a relative URL
-        of the 'file' scheme; not recommended for general use."""
-        return quote(pathname)
-
-# This really consists of two pieces:
-# (1) a class which handles opening of all sorts of URLs
-#     (plus assorted utilities etc.)
-# (2) a set of functions for parsing URLs
-# XXX Should these be separated out into different modules?
-
-
-# Shortcut for basic usage
-_urlopener = None
-def urlopen(url, data=None, proxies=None):
-    """urlopen(url [, data]) -> open file-like object"""
-    global _urlopener
-    if proxies is not None:
-        opener = FancyURLopener(proxies=proxies)
-    elif not _urlopener:
-        opener = FancyURLopener()
-        _urlopener = opener
+__all__ = ["urlparse", "urlunparse", "urljoin", "urldefrag",
+           "urlsplit", "urlunsplit"]
+
+# A classification of schemes ('' means apply by default)
+uses_relative = ['ftp', 'http', 'gopher', 'nntp', 'imap',
+                 'wais', 'file', 'https', 'shttp', 'mms',
+                 'prospero', 'rtsp', 'rtspu', '', 'sftp']
+uses_netloc = ['ftp', 'http', 'gopher', 'nntp', 'telnet',
+               'imap', 'wais', 'file', 'mms', 'https', 'shttp',
+               'snews', 'prospero', 'rtsp', 'rtspu', 'rsync', '',
+               'svn', 'svn+ssh', 'sftp']
+non_hierarchical = ['gopher', 'hdl', 'mailto', 'news',
+                    'telnet', 'wais', 'imap', 'snews', 'sip', 'sips']
+uses_params = ['ftp', 'hdl', 'prospero', 'http', 'imap',
+               'https', 'shttp', 'rtsp', 'rtspu', 'sip', 'sips',
+               'mms', '', 'sftp']
+uses_query = ['http', 'wais', 'imap', 'https', 'shttp', 'mms',
+              'gopher', 'rtsp', 'rtspu', 'sip', 'sips', '']
+uses_fragment = ['ftp', 'hdl', 'http', 'gopher', 'news',
+                 'nntp', 'wais', 'https', 'shttp', 'snews',
+                 'file', 'prospero', '']
+
+# Characters valid in scheme names
+scheme_chars = ('abcdefghijklmnopqrstuvwxyz'
+                'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+                '0123456789'
+                '+-.')
+
+MAX_CACHE_SIZE = 20
+_parse_cache = {}
+
+def clear_cache():
+    """Clear the parse cache."""
+    _parse_cache.clear()
+
+
+class ResultMixin(object):
+    """Shared methods for the parsed result objects."""
+
+    @property
+    def username(self):
+        netloc = self.netloc
+        if "@" in netloc:
+            userinfo = netloc.rsplit("@", 1)[0]
+            if ":" in userinfo:
+                userinfo = userinfo.split(":", 1)[0]
+            return userinfo
+        return None
+
+    @property
+    def password(self):
+        netloc = self.netloc
+        if "@" in netloc:
+            userinfo = netloc.rsplit("@", 1)[0]
+            if ":" in userinfo:
+                return userinfo.split(":", 1)[1]
+        return None
+
+    @property
+    def hostname(self):
+        netloc = self.netloc
+        if "@" in netloc:
+            netloc = netloc.rsplit("@", 1)[1]
+        if ":" in netloc:
+            netloc = netloc.split(":", 1)[0]
+        return netloc.lower() or None
+
+    @property
+    def port(self):
+        netloc = self.netloc
+        if "@" in netloc:
+            netloc = netloc.rsplit("@", 1)[1]
+        if ":" in netloc:
+            port = netloc.split(":", 1)[1]
+            return int(port, 10)
+        return None
+
+from collections import namedtuple
+
+class SplitResult(namedtuple('SplitResult', 'scheme netloc path query fragment'), ResultMixin):
+
+    __slots__ = ()
+
+    def geturl(self):
+        return urlunsplit(self)
+
+
+class ParseResult(namedtuple('ParseResult', 'scheme netloc path params query fragment'), ResultMixin):
+
+    __slots__ = ()
+
+    def geturl(self):
+        return urlunparse(self)
+
+
+def urlparse(url, scheme='', allow_fragments=True):
+    """Parse a URL into 6 components:
+    <scheme>://<netloc>/<path>;<params>?<query>#<fragment>
+    Return a 6-tuple: (scheme, netloc, path, params, query, fragment).
+    Note that we don't break the components up in smaller bits
+    (e.g. netloc is a single string) and we don't expand % escapes."""
+    tuple = urlsplit(url, scheme, allow_fragments)
+    scheme, netloc, url, query, fragment = tuple
+    if scheme in uses_params and ';' in url:
+        url, params = _splitparams(url)
     else:
-        opener = _urlopener
-    if data is None:
-        return opener.open(url)
+        params = ''
+    return ParseResult(scheme, netloc, url, params, query, fragment)
+
+def _splitparams(url):
+    if '/'  in url:
+        i = url.find(';', url.rfind('/'))
+        if i < 0:
+            return url, ''
     else:
-        return opener.open(url, data)
+        i = url.find(';')
+    return url[:i], url[i+1:]
 
-def urlretrieve(url, filename=None, reporthook=None, data=None):
-    global _urlopener
-    if not _urlopener:
-        _urlopener = FancyURLopener()
-    return _urlopener.retrieve(url, filename, reporthook, data)
-
-def urlcleanup():
-    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):
-        IOError.__init__(self, message)
-        self.content = content
-
-ftpcache = {}
-class URLopener:
-    """Class to open URLs.
-    This is a class rather than just a subroutine because we may need
-    more than one set of global protocol-specific options.
-    Note -- this is a base class for those who don't want the
-    automatic handling of errors type 302 (relocated) and 401
-    (authorization needed)."""
-
-    __tempfiles = None
-
-    version = "Python-urllib/%s" % __version__
-
-    # Constructor
-    def __init__(self, proxies=None, **x509):
-        if proxies is None:
-            proxies = getproxies()
-        assert hasattr(proxies, 'keys'), "proxies must be a mapping"
-        self.proxies = proxies
-        self.key_file = x509.get('key_file')
-        self.cert_file = x509.get('cert_file')
-        self.addheaders = [('User-Agent', self.version)]
-        self.__tempfiles = []
-        self.__unlink = os.unlink # See cleanup()
-        self.tempcache = None
-        # Undocumented feature: if you assign {} to tempcache,
-        # it is used to cache files retrieved with
-        # self.retrieve().  This is not enabled by default
-        # since it does not work for changing documents (and I
-        # haven't got the logic to check expiration headers
-        # yet).
-        self.ftpcache = ftpcache
-        # Undocumented feature: you can use a different
-        # ftp cache by assigning to the .ftpcache member;
-        # in case you want logically independent URL openers
-        # XXX This is not threadsafe.  Bah.
-
-    def __del__(self):
-        self.close()
-
-    def close(self):
-        self.cleanup()
-
-    def cleanup(self):
-        # This code sometimes runs when the rest of this module
-        # has already been deleted, so it can't use any globals
-        # or import anything.
-        if self.__tempfiles:
-            for file in self.__tempfiles:
-                try:
-                    self.__unlink(file)
-                except OSError:
-                    pass
-            del self.__tempfiles[:]
-        if self.tempcache:
-            self.tempcache.clear()
-
-    def addheader(self, *args):
-        """Add a header to be used by the HTTP interface only
-        e.g. u.addheader('Accept', 'sound/basic')"""
-        self.addheaders.append(args)
-
-    # External interface
-    def open(self, fullurl, data=None):
-        """Use URLopener().open(file) instead of open(file, 'r')."""
-        fullurl = unwrap(toBytes(fullurl))
-        if self.tempcache and fullurl in self.tempcache:
-            filename, headers = self.tempcache[fullurl]
-            fp = open(filename, 'rb')
-            return addinfourl(fp, headers, fullurl)
-        urltype, url = splittype(fullurl)
-        if not urltype:
-            urltype = 'file'
-        if urltype in self.proxies:
-            proxy = self.proxies[urltype]
-            urltype, proxyhost = splittype(proxy)
-            host, selector = splithost(proxyhost)
-            url = (host, fullurl) # Signal special case to open_*()
-        else:
-            proxy = None
-        name = 'open_' + urltype
-        self.type = urltype
-        name = name.replace('-', '_')
-        if not hasattr(self, name):
-            if proxy:
-                return self.open_unknown_proxy(proxy, fullurl, data)
-            else:
-                return self.open_unknown(fullurl, data)
-        try:
-            if data is None:
-                return getattr(self, name)(url)
-            else:
-                return getattr(self, name)(url, data)
-        except socket.error as msg:
-            raise IOError('socket error', msg).with_traceback(sys.exc_info()[2])
-
-    def open_unknown(self, fullurl, data=None):
-        """Overridable interface to open unknown URL type."""
-        type, url = splittype(fullurl)
-        raise IOError('url error', 'unknown url type', type)
-
-    def open_unknown_proxy(self, proxy, fullurl, data=None):
-        """Overridable interface to open unknown URL type."""
-        type, url = splittype(fullurl)
-        raise IOError('url error', 'invalid proxy for %s' % type, proxy)
-
-    # External interface
-    def retrieve(self, url, filename=None, reporthook=None, data=None):
-        """retrieve(url) returns (filename, headers) for a local object
-        or (tempfilename, headers) for a remote object."""
-        url = unwrap(toBytes(url))
-        if self.tempcache and url in self.tempcache:
-            return self.tempcache[url]
-        type, url1 = splittype(url)
-        if filename is None and (not type or type == 'file'):
-            try:
-                fp = self.open_local_file(url1)
-                hdrs = fp.info()
-                del fp
-                return url2pathname(splithost(url1)[1]), hdrs
-            except IOError as msg:
-                pass
-        fp = self.open(url, data)
-        headers = fp.info()
-        if filename:
-            tfp = open(filename, 'wb')
-        else:
-            import tempfile
-            garbage, path = splittype(url)
-            garbage, path = splithost(path or "")
-            path, garbage = splitquery(path or "")
-            path, garbage = splitattr(path or "")
-            suffix = os.path.splitext(path)[1]
-            (fd, filename) = tempfile.mkstemp(suffix)
-            self.__tempfiles.append(filename)
-            tfp = os.fdopen(fd, 'wb')
-        result = filename, headers
-        if self.tempcache is not None:
-            self.tempcache[url] = result
-        bs = 1024*8
-        size = -1
-        read = 0
-        blocknum = 0
-        if reporthook:
-            if "content-length" in headers:
-                size = int(headers["Content-Length"])
-            reporthook(blocknum, bs, size)
-        while 1:
-            block = fp.read(bs)
-            if not block:
+def _splitnetloc(url, start=0):
+    delim = len(url)   # position of end of domain part of url, default is end
+    for c in '/?#':    # look for delimiters; the order is NOT important
+        wdelim = url.find(c, start)        # find first of this delim
+        if wdelim >= 0:                    # if found
+            delim = min(delim, wdelim)     # use earliest delim position
+    return url[start:delim], url[delim:]   # return (domain, rest)
+
+def urlsplit(url, scheme='', allow_fragments=True):
+    """Parse a URL into 5 components:
+    <scheme>://<netloc>/<path>?<query>#<fragment>
+    Return a 5-tuple: (scheme, netloc, path, query, fragment).
+    Note that we don't break the components up in smaller bits
+    (e.g. netloc is a single string) and we don't expand % escapes."""
+    allow_fragments = bool(allow_fragments)
+    key = url, scheme, allow_fragments, type(url), type(scheme)
+    cached = _parse_cache.get(key, None)
+    if cached:
+        return cached
+    if len(_parse_cache) >= MAX_CACHE_SIZE: # avoid runaway growth
+        clear_cache()
+    netloc = query = fragment = ''
+    i = url.find(':')
+    if i > 0:
+        if url[:i] == 'http': # optimize the common case
+            scheme = url[:i].lower()
+            url = url[i+1:]
+            if url[:2] == '//':
+                netloc, url = _splitnetloc(url, 2)
+            if allow_fragments and '#' in url:
+                url, fragment = url.split('#', 1)
+            if '?' in url:
+                url, query = url.split('?', 1)
+            v = SplitResult(scheme, netloc, url, query, fragment)
+            _parse_cache[key] = v
+            return v
+        for c in url[:i]:
+            if c not in scheme_chars:
                 break
-            read += len(block)
-            tfp.write(block)
-            blocknum += 1
-            if reporthook:
-                reporthook(blocknum, bs, size)
-        fp.close()
-        tfp.close()
-        del fp
-        del tfp
-
-        # raise exception if actual size does not match content-length header
-        if size >= 0 and read < size:
-            raise ContentTooShortError("retrieval incomplete: got only %i out "
-                                       "of %i bytes" % (read, size), result)
-
-        return result
-
-    # Each method named open_<type> knows how to open that type of URL
-
-    def _open_generic_http(self, connection_factory, url, data):
-        """Make an HTTP connection using connection_class.
-
-        This is an internal method that should be called from
-        open_http() or open_https().
-
-        Arguments:
-        - connection_factory should take a host name and return an
-          HTTPConnection instance.
-        - url is the url to retrieval or a host, relative-path pair.
-        - data is payload for a POST request or None.
-        """
-
-        user_passwd = None
-        proxy_passwd= None
-        if isinstance(url, str):
-            host, selector = splithost(url)
-            if host:
-                user_passwd, host = splituser(host)
-                host = unquote(host)
-            realhost = host
-        else:
-            host, selector = url
-            # check whether the proxy contains authorization information
-            proxy_passwd, host = splituser(host)
-            # now we proceed with the url we want to obtain
-            urltype, rest = splittype(selector)
-            url = rest
-            user_passwd = None
-            if urltype.lower() != 'http':
-                realhost = None
-            else:
-                realhost, rest = splithost(rest)
-                if realhost:
-                    user_passwd, realhost = splituser(realhost)
-                if user_passwd:
-                    selector = "%s://%s%s" % (urltype, realhost, rest)
-                if proxy_bypass(realhost):
-                    host = realhost
-
-            #print "proxy via http:", host, selector
-        if not host: raise IOError('http error', 'no host given')
-
-        if proxy_passwd:
-            import base64
-            proxy_auth = base64.b64encode(proxy_passwd).strip()
         else:
-            proxy_auth = None
+            scheme, url = url[:i].lower(), url[i+1:]
+    if scheme in uses_netloc and url[:2] == '//':
+        netloc, url = _splitnetloc(url, 2)
+    if allow_fragments and scheme in uses_fragment and '#' in url:
+        url, fragment = url.split('#', 1)
+    if scheme in uses_query and '?' in url:
+        url, query = url.split('?', 1)
+    v = SplitResult(scheme, netloc, url, query, fragment)
+    _parse_cache[key] = v
+    return v
+
+def urlunparse(components):
+    """Put a parsed URL back together again.  This may result in a
+    slightly different, but equivalent URL, if the URL that was parsed
+    originally had redundant delimiters, e.g. a ? with an empty query
+    (the draft states that these are equivalent)."""
+    scheme, netloc, url, params, query, fragment = components
+    if params:
+        url = "%s;%s" % (url, params)
+    return urlunsplit((scheme, netloc, url, query, fragment))
+
+def urlunsplit(components):
+    scheme, netloc, url, query, fragment = components
+    if netloc or (scheme and scheme in uses_netloc and url[:2] != '//'):
+        if url and url[:1] != '/': url = '/' + url
+        url = '//' + (netloc or '') + url
+    if scheme:
+        url = scheme + ':' + url
+    if query:
+        url = url + '?' + query
+    if fragment:
+        url = url + '#' + fragment
+    return url
 
-        if user_passwd:
-            import base64
-            auth = base64.b64encode(user_passwd).strip()
-        else:
-            auth = None
-        http_conn = connection_factory(host)
-        # XXX We should fix urllib so that it works with HTTP/1.1.
-        http_conn._http_vsn = 10
-        http_conn._http_vsn_str = "HTTP/1.0"
-
-        headers = {}
-        if proxy_auth:
-            headers["Proxy-Authorization"] = "Basic %s" % proxy_auth
-        if auth:
-            headers["Authorization"] =  "Basic %s" % auth
-        if realhost:
-            headers["Host"] = realhost
-        for header, value in self.addheaders:
-            headers[header] = value
-
-        if data is not None:
-            headers["Content-Type"] = "application/x-www-form-urlencoded"
-            http_conn.request("POST", selector, data, headers)
+def urljoin(base, url, allow_fragments=True):
+    """Join a base URL and a possibly relative URL to form an absolute
+    interpretation of the latter."""
+    if not base:
+        return url
+    if not url:
+        return base
+    bscheme, bnetloc, bpath, bparams, bquery, bfragment = \
+            urlparse(base, '', allow_fragments)
+    scheme, netloc, path, params, query, fragment = \
+            urlparse(url, bscheme, allow_fragments)
+    if scheme != bscheme or scheme not in uses_relative:
+        return url
+    if scheme in uses_netloc:
+        if netloc:
+            return urlunparse((scheme, netloc, path,
+                               params, query, fragment))
+        netloc = bnetloc
+    if path[:1] == '/':
+        return urlunparse((scheme, netloc, path,
+                           params, query, fragment))
+    if not (path or params or query):
+        return urlunparse((scheme, netloc, bpath,
+                           bparams, bquery, fragment))
+    segments = bpath.split('/')[:-1] + path.split('/')
+    # XXX The stuff below is bogus in various ways...
+    if segments[-1] == '.':
+        segments[-1] = ''
+    while '.' in segments:
+        segments.remove('.')
+    while 1:
+        i = 1
+        n = len(segments) - 1
+        while i < n:
+            if (segments[i] == '..'
+                and segments[i-1] not in ('', '..')):
+                del segments[i-1:i+1]
+                break
+            i = i+1
         else:
-            http_conn.request("GET", selector, headers=headers)
+            break
+    if segments == ['', '..']:
+        segments[-1] = ''
+    elif len(segments) >= 2 and segments[-1] == '..':
+        segments[-2:] = ['']
+    return urlunparse((scheme, netloc, '/'.join(segments),
+                       params, query, fragment))
+
+def urldefrag(url):
+    """Removes any existing fragment from URL.
+
+    Returns a tuple of the defragmented URL and the fragment.  If
+    the URL contained no fragments, the second element is the
+    empty string.
+    """
+    if '#' in url:
+        s, n, p, a, q, frag = urlparse(url)
+        defrag = urlunparse((s, n, p, a, q, ''))
+        return defrag, frag
+    else:
+        return url, ''
 
-        try:
-            response = http_conn.getresponse()
-        except http.client.BadStatusLine:
-            # something went wrong with the HTTP status line
-            raise IOError('http protocol error', 0,
-                          'got a bad status line', None)
-
-        # According to RFC 2616, "2xx" code indicates that the client's
-        # request was successfully received, understood, and accepted.
-        if (200 <= response.status < 300):
-            return addinfourl(response.fp, response.msg, "http:" + url,
-                              response.status)
-        else:
-            return self.http_error(
-                url, response.fp,
-                response.status, response.reason, response.msg, data)
-
-    def open_http(self, url, data=None):
-        """Use HTTP protocol."""
-        return self._open_generic_http(http.client.HTTPConnection, url, data)
-
-    def http_error(self, url, fp, errcode, errmsg, headers, data=None):
-        """Handle http errors.
-
-        Derived class can override this, or provide specific handlers
-        named http_error_DDD where DDD is the 3-digit error code."""
-        # First check if there's a specific handler for this error
-        name = 'http_error_%d' % errcode
-        if hasattr(self, name):
-            method = getattr(self, name)
-            if data is None:
-                result = method(url, fp, errcode, errmsg, headers)
-            else:
-                result = method(url, fp, errcode, errmsg, headers, data)
-            if result: return result
-        return self.http_error_default(url, fp, errcode, errmsg, headers)
-
-    def http_error_default(self, url, fp, errcode, errmsg, headers):
-        """Default error handler: close the connection and raise IOError."""
-        void = fp.read()
-        fp.close()
-        raise IOError('http error', errcode, errmsg, headers)
-
-    if _have_ssl:
-        def _https_connection(self, host):
-            return http.client.HTTPSConnection(host,
-                                               key_file=self.key_file,
-                                               cert_file=self.cert_file)
-
-        def open_https(self, url, data=None):
-            """Use HTTPS protocol."""
-            return self._open_generic_http(self._https_connection, url, data)
-
-    def open_file(self, url):
-        """Use local file or FTP depending on form of URL."""
-        if not isinstance(url, str):
-            raise IOError('file error', 'proxy support for file protocol currently not implemented')
-        if url[:2] == '//' and url[2:3] != '/' and url[2:12].lower() != 'localhost/':
-            return self.open_ftp(url)
-        else:
-            return self.open_local_file(url)
 
-    def open_local_file(self, url):
-        """Use local file."""
-        import mimetypes, email.utils
-        host, file = splithost(url)
-        localname = url2pathname(file)
-        try:
-            stats = os.stat(localname)
-        except OSError as e:
-            raise IOError(e.errno, e.strerror, e.filename)
-        size = stats.st_size
-        modified = email.utils.formatdate(stats.st_mtime, usegmt=True)
-        mtype = mimetypes.guess_type(url)[0]
-        headers = email.message_from_string(
-            'Content-Type: %s\nContent-Length: %d\nLast-modified: %s\n' %
-            (mtype or 'text/plain', size, modified))
-        if not host:
-            urlfile = file
-            if file[:1] == '/':
-                urlfile = 'file://' + file
-            return addinfourl(open(localname, 'rb'),
-                              headers, urlfile)
-        host, port = splitport(host)
-        if not port \
-           and socket.gethostbyname(host) in (localhost(), thishost()):
-            urlfile = file
-            if file[:1] == '/':
-                urlfile = 'file://' + file
-            return addinfourl(open(localname, 'rb'),
-                              headers, urlfile)
-        raise IOError('local file error', 'not on local host')
-
-    def open_ftp(self, url):
-        """Use FTP protocol."""
-        if not isinstance(url, str):
-            raise IOError('ftp error', 'proxy support for ftp protocol currently not implemented')
-        import mimetypes
-        host, path = splithost(url)
-        if not host: raise IOError('ftp error', 'no host given')
-        host, port = splitport(host)
-        user, host = splituser(host)
-        if user: user, passwd = splitpasswd(user)
-        else: passwd = None
-        host = unquote(host)
-        user = unquote(user or '')
-        passwd = unquote(passwd or '')
-        host = socket.gethostbyname(host)
-        if not port:
-            import ftplib
-            port = ftplib.FTP_PORT
-        else:
-            port = int(port)
-        path, attrs = splitattr(path)
-        path = unquote(path)
-        dirs = path.split('/')
-        dirs, file = dirs[:-1], dirs[-1]
-        if dirs and not dirs[0]: dirs = dirs[1:]
-        if dirs and not dirs[0]: dirs[0] = '/'
-        key = user, host, port, '/'.join(dirs)
-        # XXX thread unsafe!
-        if len(self.ftpcache) > MAXFTPCACHE:
-            # Prune the cache, rather arbitrarily
-            for k in self.ftpcache.keys():
-                if k != key:
-                    v = self.ftpcache[k]
-                    del self.ftpcache[k]
-                    v.close()
+_hextochr = dict(('%02x' % i, chr(i)) for i in range(256))
+_hextochr.update(('%02X' % i, chr(i)) for i in range(256))
+
+def unquote(s):
+    """unquote('abc%20def') -> 'abc def'."""
+    res = s.split('%')
+    for i in range(1, len(res)):
+        item = res[i]
         try:
-            if not key in self.ftpcache:
-                self.ftpcache[key] = \
-                    ftpwrapper(user, passwd, host, port, dirs)
-            if not file: type = 'D'
-            else: type = 'I'
-            for attr in attrs:
-                attr, value = splitvalue(attr)
-                if attr.lower() == 'type' and \
-                   value in ('a', 'A', 'i', 'I', 'd', 'D'):
-                    type = value.upper()
-            (fp, retrlen) = self.ftpcache[key].retrfile(file, type)
-            mtype = mimetypes.guess_type("ftp:" + url)[0]
-            headers = ""
-            if mtype:
-                headers += "Content-Type: %s\n" % mtype
-            if retrlen is not None and retrlen >= 0:
-                headers += "Content-Length: %d\n" % retrlen
-            headers = email.message_from_string(headers)
-            return addinfourl(fp, headers, "ftp:" + url)
-        except ftperrors() as msg:
-            raise IOError('ftp error', msg).with_traceback(sys.exc_info()[2])
-
-    def open_data(self, url, data=None):
-        """Use "data" URL."""
-        if not isinstance(url, str):
-            raise IOError('data error', 'proxy support for data protocol currently not implemented')
-        # ignore POSTed data
-        #
-        # syntax of data URLs:
-        # dataurl   := "data:" [ mediatype ] [ ";base64" ] "," data
-        # mediatype := [ type "/" subtype ] *( ";" parameter )
-        # data      := *urlchar
-        # parameter := attribute "=" value
-        from io import StringIO
+            res[i] = _hextochr[item[:2]] + item[2:]
+        except KeyError:
+            res[i] = '%' + item
+        except UnicodeDecodeError:
+            res[i] = chr(int(item[:2], 16)) + item[2:]
+    return "".join(res)
+
+def unquote_plus(s):
+    """unquote('%7e/abc+def') -> '~/abc def'"""
+    s = s.replace('+', ' ')
+    return unquote(s)
+
+always_safe = ('ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+               'abcdefghijklmnopqrstuvwxyz'
+               '0123456789' '_.-')
+_safe_quoters= {}
+
+class Quoter:
+    def __init__(self, safe):
+        self.cache = {}
+        self.safe = safe + always_safe
+
+    def __call__(self, c):
         try:
-            [type, data] = url.split(',', 1)
-        except ValueError:
-            raise IOError('data error', 'bad data URL')
-        if not type:
-            type = 'text/plain;charset=US-ASCII'
-        semi = type.rfind(';')
-        if semi >= 0 and '=' not in type[semi:]:
-            encoding = type[semi+1:]
-            type = type[:semi]
-        else:
-            encoding = ''
-        msg = []
-        msg.append('Date: %s'%time.strftime('%a, %d %b %Y %T GMT',
-                                            time.gmtime(time.time())))
-        msg.append('Content-type: %s' % type)
-        if encoding == 'base64':
-            import base64
-            data = base64.decodestring(data)
-        else:
-            data = unquote(data)
-        msg.append('Content-Length: %d' % len(data))
-        msg.append('')
-        msg.append(data)
-        msg = '\n'.join(msg)
-        headers = email.message_from_string(msg)
-        f = StringIO(msg)
-        #f.fileno = None     # needed for addinfourl
-        return addinfourl(f, headers, url)
-
-
-class FancyURLopener(URLopener):
-    """Derived class with handlers for errors we can handle (perhaps)."""
-
-    def __init__(self, *args, **kwargs):
-        URLopener.__init__(self, *args, **kwargs)
-        self.auth_cache = {}
-        self.tries = 0
-        self.maxtries = 10
-
-    def http_error_default(self, url, fp, errcode, errmsg, headers):
-        """Default error handling -- don't raise an exception."""
-        return addinfourl(fp, headers, "http:" + url, errcode)
-
-    def http_error_302(self, url, fp, errcode, errmsg, headers, data=None):
-        """Error 302 -- relocated (temporarily)."""
-        self.tries += 1
-        if self.maxtries and self.tries >= self.maxtries:
-            if hasattr(self, "http_error_500"):
-                meth = self.http_error_500
+            return self.cache[c]
+        except KeyError:
+            if ord(c) < 256:
+                res = (c in self.safe) and c or ('%%%02X' % ord(c))
+                self.cache[c] = res
+                return res
             else:
-                meth = self.http_error_default
-            self.tries = 0
-            return meth(url, fp, 500,
-                        "Internal Server Error: Redirect Recursion", headers)
-        result = self.redirect_internal(url, fp, errcode, errmsg, headers,
-                                        data)
-        self.tries = 0
-        return result
-
-    def redirect_internal(self, url, fp, errcode, errmsg, headers, data):
-        if 'location' in headers:
-            newurl = headers['location']
-        elif 'uri' in headers:
-            newurl = headers['uri']
-        else:
-            return
-        void = fp.read()
-        fp.close()
-        # In case the server sent a relative URL, join with original:
-        newurl = basejoin(self.type + ":" + url, newurl)
-        return self.open(newurl)
-
-    def http_error_301(self, url, fp, errcode, errmsg, headers, data=None):
-        """Error 301 -- also relocated (permanently)."""
-        return self.http_error_302(url, fp, errcode, errmsg, headers, data)
-
-    def http_error_303(self, url, fp, errcode, errmsg, headers, data=None):
-        """Error 303 -- also relocated (essentially identical to 302)."""
-        return self.http_error_302(url, fp, errcode, errmsg, headers, data)
-
-    def http_error_307(self, url, fp, errcode, errmsg, headers, data=None):
-        """Error 307 -- relocated, but turn POST into error."""
-        if data is None:
-            return self.http_error_302(url, fp, errcode, errmsg, headers, data)
-        else:
-            return self.http_error_default(url, fp, errcode, errmsg, headers)
+                return "".join(['%%%02X' % i for i in c.encode("utf-8")])
 
-    def http_error_401(self, url, fp, errcode, errmsg, headers, data=None):
-        """Error 401 -- authentication required.
-        This function supports Basic authentication only."""
-        if not 'www-authenticate' in headers:
-            URLopener.http_error_default(self, url, fp,
-                                         errcode, errmsg, headers)
-        stuff = headers['www-authenticate']
-        import re
-        match = re.match('[ \t]*([^ \t]+)[ \t]+realm="([^"]*)"', stuff)
-        if not match:
-            URLopener.http_error_default(self, url, fp,
-                                         errcode, errmsg, headers)
-        scheme, realm = match.groups()
-        if scheme.lower() != 'basic':
-            URLopener.http_error_default(self, url, fp,
-                                         errcode, errmsg, headers)
-        name = 'retry_' + self.type + '_basic_auth'
-        if data is None:
-            return getattr(self,name)(url, realm)
-        else:
-            return getattr(self,name)(url, realm, data)
+def quote(s, safe = '/'):
+    """quote('abc def') -> 'abc%20def'
 
-    def http_error_407(self, url, fp, errcode, errmsg, headers, data=None):
-        """Error 407 -- proxy authentication required.
-        This function supports Basic authentication only."""
-        if not 'proxy-authenticate' in headers:
-            URLopener.http_error_default(self, url, fp,
-                                         errcode, errmsg, headers)
-        stuff = headers['proxy-authenticate']
-        import re
-        match = re.match('[ \t]*([^ \t]+)[ \t]+realm="([^"]*)"', stuff)
-        if not match:
-            URLopener.http_error_default(self, url, fp,
-                                         errcode, errmsg, headers)
-        scheme, realm = match.groups()
-        if scheme.lower() != 'basic':
-            URLopener.http_error_default(self, url, fp,
-                                         errcode, errmsg, headers)
-        name = 'retry_proxy_' + self.type + '_basic_auth'
-        if data is None:
-            return getattr(self,name)(url, realm)
-        else:
-            return getattr(self,name)(url, realm, data)
+    Each part of a URL, e.g. the path info, the query, etc., has a
+    different set of reserved characters that must be quoted.
 
-    def retry_proxy_http_basic_auth(self, url, realm, data=None):
-        host, selector = splithost(url)
-        newurl = 'http://' + host + selector
-        proxy = self.proxies['http']
-        urltype, proxyhost = splittype(proxy)
-        proxyhost, proxyselector = splithost(proxyhost)
-        i = proxyhost.find('@') + 1
-        proxyhost = proxyhost[i:]
-        user, passwd = self.get_user_passwd(proxyhost, realm, i)
-        if not (user or passwd): return None
-        proxyhost = quote(user, safe='') + ':' + quote(passwd, safe='') + '@' + proxyhost
-        self.proxies['http'] = 'http://' + proxyhost + proxyselector
-        if data is None:
-            return self.open(newurl)
-        else:
-            return self.open(newurl, data)
+    RFC 2396 Uniform Resource Identifiers (URI): Generic Syntax lists
+    the following reserved characters.
 
-    def retry_proxy_https_basic_auth(self, url, realm, data=None):
-        host, selector = splithost(url)
-        newurl = 'https://' + host + selector
-        proxy = self.proxies['https']
-        urltype, proxyhost = splittype(proxy)
-        proxyhost, proxyselector = splithost(proxyhost)
-        i = proxyhost.find('@') + 1
-        proxyhost = proxyhost[i:]
-        user, passwd = self.get_user_passwd(proxyhost, realm, i)
-        if not (user or passwd): return None
-        proxyhost = quote(user, safe='') + ':' + quote(passwd, safe='') + '@' + proxyhost
-        self.proxies['https'] = 'https://' + proxyhost + proxyselector
-        if data is None:
-            return self.open(newurl)
-        else:
-            return self.open(newurl, data)
+    reserved    = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" |
+                  "$" | ","
 
-    def retry_http_basic_auth(self, url, realm, data=None):
-        host, selector = splithost(url)
-        i = host.find('@') + 1
-        host = host[i:]
-        user, passwd = self.get_user_passwd(host, realm, i)
-        if not (user or passwd): return None
-        host = quote(user, safe='') + ':' + quote(passwd, safe='') + '@' + host
-        newurl = 'http://' + host + selector
-        if data is None:
-            return self.open(newurl)
-        else:
-            return self.open(newurl, data)
+    Each of these characters is reserved in some component of a URL,
+    but not necessarily in all of them.
 
-    def retry_https_basic_auth(self, url, realm, data=None):
-        host, selector = splithost(url)
-        i = host.find('@') + 1
-        host = host[i:]
-        user, passwd = self.get_user_passwd(host, realm, i)
-        if not (user or passwd): return None
-        host = quote(user, safe='') + ':' + quote(passwd, safe='') + '@' + host
-        newurl = 'https://' + host + selector
-        if data is None:
-            return self.open(newurl)
-        else:
-            return self.open(newurl, data)
+    By default, the quote function is intended for quoting the path
+    section of a URL.  Thus, it will not encode '/'.  This character
+    is reserved, but in typical usage the quote function is being
+    called on a path where the existing slash characters are used as
+    reserved characters.
+    """
+    cachekey = (safe, always_safe)
+    try:
+        quoter = _safe_quoters[cachekey]
+    except KeyError:
+        quoter = Quoter(safe)
+        _safe_quoters[cachekey] = quoter
+    res = map(quoter, s)
+    return ''.join(res)
 
-    def get_user_passwd(self, host, realm, clear_cache = 0):
-        key = realm + '@' + host.lower()
-        if key in self.auth_cache:
-            if clear_cache:
-                del self.auth_cache[key]
-            else:
-                return self.auth_cache[key]
-        user, passwd = self.prompt_user_passwd(host, realm)
-        if user or passwd: self.auth_cache[key] = (user, passwd)
-        return user, passwd
-
-    def prompt_user_passwd(self, host, realm):
-        """Override this in a GUI environment!"""
-        import getpass
-        try:
-            user = input("Enter username for %s at %s: " % (realm, host))
-            passwd = getpass.getpass("Enter password for %s in %s at %s: " %
-                (user, realm, host))
-            return user, passwd
-        except KeyboardInterrupt:
-            print()
-            return None, None
-
-
-# Utility functions
-
-_localhost = None
-def localhost():
-    """Return the IP address of the magic hostname 'localhost'."""
-    global _localhost
-    if _localhost is None:
-        _localhost = socket.gethostbyname('localhost')
-    return _localhost
-
-_thishost = None
-def thishost():
-    """Return the IP address of the current host."""
-    global _thishost
-    if _thishost is None:
-        _thishost = socket.gethostbyname(socket.gethostname())
-    return _thishost
-
-_ftperrors = None
-def ftperrors():
-    """Return the set of errors raised by the FTP class."""
-    global _ftperrors
-    if _ftperrors is None:
-        import ftplib
-        _ftperrors = ftplib.all_errors
-    return _ftperrors
-
-_noheaders = None
-def noheaders():
-    """Return an empty email.message.Message object."""
-    global _noheaders
-    if _noheaders is None:
-        _noheaders = email.message.Message()
-    return _noheaders
-
-
-# Utility classes
-
-class ftpwrapper:
-    """Class used by open_ftp() for cache of open FTP connections."""
-
-    def __init__(self, user, passwd, host, port, dirs,
-                 timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
-        self.user = user
-        self.passwd = passwd
-        self.host = host
-        self.port = port
-        self.dirs = dirs
-        self.timeout = timeout
-        self.init()
-
-    def init(self):
-        import ftplib
-        self.busy = 0
-        self.ftp = ftplib.FTP()
-        self.ftp.connect(self.host, self.port, self.timeout)
-        self.ftp.login(self.user, self.passwd)
-        for dir in self.dirs:
-            self.ftp.cwd(dir)
-
-    def retrfile(self, file, type):
-        import ftplib
-        self.endtransfer()
-        if type in ('d', 'D'): cmd = 'TYPE A'; isdir = 1
-        else: cmd = 'TYPE ' + type; isdir = 0
-        try:
-            self.ftp.voidcmd(cmd)
-        except ftplib.all_errors:
-            self.init()
-            self.ftp.voidcmd(cmd)
-        conn = None
-        if file and not isdir:
-            # Try to retrieve as a file
-            try:
-                cmd = 'RETR ' + file
-                conn = self.ftp.ntransfercmd(cmd)
-            except ftplib.error_perm as reason:
-                if str(reason)[:3] != '550':
-                    raise IOError('ftp error', reason).with_traceback(sys.exc_info()[2])
-        if not conn:
-            # Set transfer mode to ASCII!
-            self.ftp.voidcmd('TYPE A')
-            # Try a directory listing. Verify that directory exists.
-            if file:
-                pwd = self.ftp.pwd()
-                try:
-                    try:
-                        self.ftp.cwd(file)
-                    except ftplib.error_perm as reason:
-                        raise IOError('ftp error', reason) from reason
-                finally:
-                    self.ftp.cwd(pwd)
-                cmd = 'LIST ' + file
-            else:
-                cmd = 'LIST'
-            conn = self.ftp.ntransfercmd(cmd)
-        self.busy = 1
-        # Pass back both a suitably decorated object and a retrieval length
-        return (addclosehook(conn[0].makefile('rb'),
-                             self.endtransfer), conn[1])
-    def endtransfer(self):
-        if not self.busy:
-            return
-        self.busy = 0
-        try:
-            self.ftp.voidresp()
-        except ftperrors():
-            pass
+def quote_plus(s, safe = ''):
+    """Quote the query fragment of a URL; replacing ' ' with '+'"""
+    if ' ' in s:
+        s = quote(s, safe + ' ')
+        return s.replace(' ', '+')
+    return quote(s, safe)
 
-    def close(self):
-        self.endtransfer()
-        try:
-            self.ftp.close()
-        except ftperrors():
-            pass
-
-class addbase:
-    """Base class for addinfo and addclosehook."""
-
-    # XXX Add a method to expose the timeout on the underlying socket?
-
-    def __init__(self, fp):
-        self.fp = fp
-        self.read = self.fp.read
-        self.readline = self.fp.readline
-        if hasattr(self.fp, "readlines"): self.readlines = self.fp.readlines
-        if hasattr(self.fp, "fileno"):
-            self.fileno = self.fp.fileno
-        else:
-            self.fileno = lambda: None
-        if hasattr(self.fp, "__iter__"):
-            self.__iter__ = self.fp.__iter__
-            if hasattr(self.fp, "__next__"):
-                self.__next__ = self.fp.__next__
-
-    def __repr__(self):
-        return '<%s at %r whose fp = %r>' % (self.__class__.__name__,
-                                             id(self), self.fp)
-
-    def close(self):
-        self.read = None
-        self.readline = None
-        self.readlines = None
-        self.fileno = None
-        if self.fp: self.fp.close()
-        self.fp = None
-
-class addclosehook(addbase):
-    """Class to add a close hook to an open file."""
-
-    def __init__(self, fp, closehook, *hookargs):
-        addbase.__init__(self, fp)
-        self.closehook = closehook
-        self.hookargs = hookargs
-
-    def close(self):
-        addbase.close(self)
-        if self.closehook:
-            self.closehook(*self.hookargs)
-            self.closehook = None
-            self.hookargs = None
-
-class addinfo(addbase):
-    """class to add an info() method to an open file."""
-
-    def __init__(self, fp, headers):
-        addbase.__init__(self, fp)
-        self.headers = headers
-
-    def info(self):
-        return self.headers
-
-class addinfourl(addbase):
-    """class to add info() and geturl() methods to an open file."""
-
-    def __init__(self, fp, headers, url, code=None):
-        addbase.__init__(self, fp)
-        self.headers = headers
-        self.url = url
-        self.code = code
+def urlencode(query,doseq=0):
+    """Encode a sequence of two-element tuples or dictionary into a URL query string.
 
-    def info(self):
-        return self.headers
+    If any values in the query arg are sequences and doseq is true, each
+    sequence element is converted to a separate parameter.
 
-    def getcode(self):
-        return self.code
+    If the query arg is a sequence of two-element tuples, the order of the
+    parameters in the output will match the order of parameters in the
+    input.
+    """
 
-    def geturl(self):
-        return self.url
+    if hasattr(query,"items"):
+        # mapping objects
+        query = query.items()
+    else:
+        # it's a bother at times that strings and string-like objects are
+        # sequences...
+        try:
+            # non-sequence items should not work with len()
+            # non-empty strings will fail this
+            if len(query) and not isinstance(query[0], tuple):
+                raise TypeError
+            # zero-length sequences of all types will get here and succeed,
+            # but that's a minor nit - since the original implementation
+            # allowed empty dicts that type of behavior probably should be
+            # preserved for consistency
+        except TypeError:
+            ty,va,tb = sys.exc_info()
+            raise TypeError("not a valid non-string sequence or mapping object").with_traceback(tb)
 
+    l = []
+    if not doseq:
+        # preserve old behavior
+        for k, v in query:
+            k = quote_plus(str(k))
+            v = quote_plus(str(v))
+            l.append(k + '=' + v)
+    else:
+        for k, v in query:
+            k = quote_plus(str(k))
+            if isinstance(v, str):
+                v = quote_plus(v)
+                l.append(k + '=' + v)
+            elif isinstance(v, str):
+                # is there a reasonable way to convert to ASCII?
+                # encode generates a string, but "replace" or "ignore"
+                # lose information and "strict" can raise UnicodeError
+                v = quote_plus(v.encode("ASCII","replace"))
+                l.append(k + '=' + v)
+            else:
+                try:
+                    # is this a sufficient test for sequence-ness?
+                    x = len(v)
+                except TypeError:
+                    # not a sequence
+                    v = quote_plus(str(v))
+                    l.append(k + '=' + v)
+                else:
+                    # loop over the sequence
+                    for elt in v:
+                        l.append(k + '=' + quote_plus(str(elt)))
+    return '&'.join(l)
 
 # Utilities to parse URLs (most of these return None for missing parts):
 # unwrap('<URL:type://host/path>') --> 'type://host/path'
@@ -934,7 +413,7 @@
 # splitattr('/path;attr1=value1;attr2=value2;...') ->
 #   '/path', ['attr1=value1', 'attr2=value2', ...]
 # splitvalue('attr=value') --> 'attr', 'value'
-# unquote('abc%20def') -> 'abc def'
+# urllib.parse.unquote('abc%20def') -> 'abc def'
 # quote('abc def') -> 'abc%20def')
 
 def toBytes(url):
@@ -1085,630 +564,67 @@
     if match: return match.group(1, 2)
     return attr, None
 
-_hextochr = dict(('%02x' % i, chr(i)) for i in range(256))
-_hextochr.update(('%02X' % i, chr(i)) for i in range(256))
+test_input = """
+      http://a/b/c/d
 
-def unquote(s):
-    """unquote('abc%20def') -> 'abc def'."""
-    res = s.split('%')
-    for i in range(1, len(res)):
-        item = res[i]
-        try:
-            res[i] = _hextochr[item[:2]] + item[2:]
-        except KeyError:
-            res[i] = '%' + item
-        except UnicodeDecodeError:
-            res[i] = chr(int(item[:2], 16)) + item[2:]
-    return "".join(res)
-
-def unquote_plus(s):
-    """unquote('%7e/abc+def') -> '~/abc def'"""
-    s = s.replace('+', ' ')
-    return unquote(s)
-
-always_safe = ('ABCDEFGHIJKLMNOPQRSTUVWXYZ'
-               'abcdefghijklmnopqrstuvwxyz'
-               '0123456789' '_.-')
-_safe_quoters= {}
-
-class Quoter:
-    def __init__(self, safe):
-        self.cache = {}
-        self.safe = safe + always_safe
-
-    def __call__(self, c):
-        try:
-            return self.cache[c]
-        except KeyError:
-            if ord(c) < 256:
-                res = (c in self.safe) and c or ('%%%02X' % ord(c))
-                self.cache[c] = res
-                return res
-            else:
-                return "".join(['%%%02X' % i for i in c.encode("utf-8")])
-
-def quote(s, safe = '/'):
-    """quote('abc def') -> 'abc%20def'
-
-    Each part of a URL, e.g. the path info, the query, etc., has a
-    different set of reserved characters that must be quoted.
-
-    RFC 2396 Uniform Resource Identifiers (URI): Generic Syntax lists
-    the following reserved characters.
-
-    reserved    = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" |
-                  "$" | ","
-
-    Each of these characters is reserved in some component of a URL,
-    but not necessarily in all of them.
-
-    By default, the quote function is intended for quoting the path
-    section of a URL.  Thus, it will not encode '/'.  This character
-    is reserved, but in typical usage the quote function is being
-    called on a path where the existing slash characters are used as
-    reserved characters.
-    """
-    cachekey = (safe, always_safe)
-    try:
-        quoter = _safe_quoters[cachekey]
-    except KeyError:
-        quoter = Quoter(safe)
-        _safe_quoters[cachekey] = quoter
-    res = map(quoter, s)
-    return ''.join(res)
-
-def quote_plus(s, safe = ''):
-    """Quote the query fragment of a URL; replacing ' ' with '+'"""
-    if ' ' in s:
-        s = quote(s, safe + ' ')
-        return s.replace(' ', '+')
-    return quote(s, safe)
-
-def urlencode(query,doseq=0):
-    """Encode a sequence of two-element tuples or dictionary into a URL query string.
-
-    If any values in the query arg are sequences and doseq is true, each
-    sequence element is converted to a separate parameter.
-
-    If the query arg is a sequence of two-element tuples, the order of the
-    parameters in the output will match the order of parameters in the
-    input.
-    """
-
-    if hasattr(query,"items"):
-        # mapping objects
-        query = query.items()
-    else:
-        # it's a bother at times that strings and string-like objects are
-        # sequences...
-        try:
-            # non-sequence items should not work with len()
-            # non-empty strings will fail this
-            if len(query) and not isinstance(query[0], tuple):
-                raise TypeError
-            # zero-length sequences of all types will get here and succeed,
-            # but that's a minor nit - since the original implementation
-            # allowed empty dicts that type of behavior probably should be
-            # preserved for consistency
-        except TypeError:
-            ty,va,tb = sys.exc_info()
-            raise TypeError("not a valid non-string sequence or mapping object").with_traceback(tb)
-
-    l = []
-    if not doseq:
-        # preserve old behavior
-        for k, v in query:
-            k = quote_plus(str(k))
-            v = quote_plus(str(v))
-            l.append(k + '=' + v)
-    else:
-        for k, v in query:
-            k = quote_plus(str(k))
-            if isinstance(v, str):
-                v = quote_plus(v)
-                l.append(k + '=' + v)
-            elif isinstance(v, str):
-                # is there a reasonable way to convert to ASCII?
-                # encode generates a string, but "replace" or "ignore"
-                # lose information and "strict" can raise UnicodeError
-                v = quote_plus(v.encode("ASCII","replace"))
-                l.append(k + '=' + v)
-            else:
-                try:
-                    # is this a sufficient test for sequence-ness?
-                    x = len(v)
-                except TypeError:
-                    # not a sequence
-                    v = quote_plus(str(v))
-                    l.append(k + '=' + v)
-                else:
-                    # loop over the sequence
-                    for elt in v:
-                        l.append(k + '=' + quote_plus(str(elt)))
-    return '&'.join(l)
-
-# Proxy handling
-def getproxies_environment():
-    """Return a dictionary of scheme -> proxy server URL mappings.
-
-    Scan the environment for variables named <scheme>_proxy;
-    this seems to be the standard convention.  If you need a
-    different way, you can pass a proxies dictionary to the
-    [Fancy]URLopener constructor.
-
-    """
-    proxies = {}
-    for name, value in os.environ.items():
-        name = name.lower()
-        if name == 'no_proxy':
-            # handled in proxy_bypass_environment
-            continue
-        if value and name[-6:] == '_proxy':
-            proxies[name[:-6]] = value
-    return proxies
-
-def proxy_bypass_environment(host):
-    """Test if proxies should not be used for a particular host.
-
-    Checks the environment for a variable named no_proxy, which should
-    be a list of DNS suffixes separated by commas, or '*' for all hosts.
-    """
-    no_proxy = os.environ.get('no_proxy', '') or os.environ.get('NO_PROXY', '')
-    # '*' is special case for always bypass
-    if no_proxy == '*':
-        return 1
-    # strip port off host
-    hostonly, port = splitport(host)
-    # check if the host ends with any of the DNS suffixes
-    for name in no_proxy.split(','):
-        if name and (hostonly.endswith(name) or host.endswith(name)):
-            return 1
-    # otherwise, don't bypass
-    return 0
-
-
-if sys.platform == 'darwin':
-
-    def _CFSetup(sc):
-        from ctypes import c_int32, c_void_p, c_char_p, c_int
-        sc.CFStringCreateWithCString.argtypes = [ c_void_p, c_char_p, c_int32 ]
-        sc.CFStringCreateWithCString.restype = c_void_p
-        sc.SCDynamicStoreCopyProxies.argtypes = [ c_void_p ]
-        sc.SCDynamicStoreCopyProxies.restype = c_void_p
-        sc.CFDictionaryGetValue.argtypes = [ c_void_p, c_void_p ]
-        sc.CFDictionaryGetValue.restype = c_void_p
-        sc.CFStringGetLength.argtypes = [ c_void_p ]
-        sc.CFStringGetLength.restype = c_int32
-        sc.CFStringGetCString.argtypes = [ c_void_p, c_char_p, c_int32, c_int32 ]
-        sc.CFStringGetCString.restype = c_int32
-        sc.CFNumberGetValue.argtypes = [ c_void_p, c_int, c_void_p ]
-        sc.CFNumberGetValue.restype = c_int32
-        sc.CFRelease.argtypes = [ c_void_p ]
-        sc.CFRelease.restype = None
-
-    def _CStringFromCFString(sc, value):
-        from ctypes import create_string_buffer
-        length = sc.CFStringGetLength(value) + 1
-        buff = create_string_buffer(length)
-        sc.CFStringGetCString(value, buff, length, 0)
-        return buff.value
-
-    def _CFNumberToInt32(sc, cfnum):
-        from ctypes import byref, c_int
-        val = c_int()
-        kCFNumberSInt32Type = 3
-        sc.CFNumberGetValue(cfnum, kCFNumberSInt32Type, byref(val))
-        return val.value
-
-
-    def proxy_bypass_macosx_sysconf(host):
-        """
-        Return True iff this host shouldn't be accessed using a proxy
-
-        This function uses the MacOSX framework SystemConfiguration
-        to fetch the proxy information.
-        """
-        from ctypes import cdll
-        from ctypes.util import find_library
-        import re
-        import socket
-        from fnmatch import fnmatch
-
-        def ip2num(ipAddr):
-            parts = ipAddr.split('.')
-            parts = map(int, parts)
-            if len(parts) != 4:
-                parts = (parts + [0, 0, 0, 0])[:4]
-            return (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8) | parts[3]
-
-        sc = cdll.LoadLibrary(find_library("SystemConfiguration"))
-        _CFSetup(sc)
-
-        hostIP = None
-
-        if not sc:
-            return False
-
-        kSCPropNetProxiesExceptionsList = sc.CFStringCreateWithCString(0, "ExceptionsList", 0)
-        kSCPropNetProxiesExcludeSimpleHostnames = sc.CFStringCreateWithCString(0,
-                "ExcludeSimpleHostnames", 0)
-
-
-        proxyDict = sc.SCDynamicStoreCopyProxies(None)
-        if proxyDict is None:
-            return False
-
-        try:
-            # Check for simple host names:
-            if '.' not in host:
-                exclude_simple = sc.CFDictionaryGetValue(proxyDict,
-                        kSCPropNetProxiesExcludeSimpleHostnames)
-                if exclude_simple and _CFNumberToInt32(sc, exclude_simple):
-                    return True
-
-
-            # Check the exceptions list:
-            exceptions = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesExceptionsList)
-            if exceptions:
-                # Items in the list are strings like these: *.local, 169.254/16
-                for index in xrange(sc.CFArrayGetCount(exceptions)):
-                    value = sc.CFArrayGetValueAtIndex(exceptions, index)
-                    if not value: continue
-                    value = _CStringFromCFString(sc, value)
-
-                    m = re.match(r"(\d+(?:\.\d+)*)(/\d+)?", value)
-                    if m is not None:
-                        if hostIP is None:
-                            hostIP = socket.gethostbyname(host)
-                            hostIP = ip2num(hostIP)
-
-                        base = ip2num(m.group(1))
-                        mask = int(m.group(2)[1:])
-                        mask = 32 - mask
-
-                        if (hostIP >> mask) == (base >> mask):
-                            return True
-
-                    elif fnmatch(host, value):
-                        return True
-
-            return False
-
-        finally:
-            sc.CFRelease(kSCPropNetProxiesExceptionsList)
-            sc.CFRelease(kSCPropNetProxiesExcludeSimpleHostnames)
-
-
-
-    def getproxies_macosx_sysconf():
-        """Return a dictionary of scheme -> proxy server URL mappings.
-
-        This function uses the MacOSX framework SystemConfiguration
-        to fetch the proxy information.
-        """
-        from ctypes import cdll
-        from ctypes.util import find_library
-
-        sc = cdll.LoadLibrary(find_library("SystemConfiguration"))
-        _CFSetup(sc)
-
-        if not sc:
-            return {}
-
-        kSCPropNetProxiesHTTPEnable = sc.CFStringCreateWithCString(0, b"HTTPEnable", 0)
-        kSCPropNetProxiesHTTPProxy = sc.CFStringCreateWithCString(0, b"HTTPProxy", 0)
-        kSCPropNetProxiesHTTPPort = sc.CFStringCreateWithCString(0, b"HTTPPort", 0)
-
-        kSCPropNetProxiesHTTPSEnable = sc.CFStringCreateWithCString(0, b"HTTPSEnable", 0)
-        kSCPropNetProxiesHTTPSProxy = sc.CFStringCreateWithCString(0, b"HTTPSProxy", 0)
-        kSCPropNetProxiesHTTPSPort = sc.CFStringCreateWithCString(0, b"HTTPSPort", 0)
-
-        kSCPropNetProxiesFTPEnable = sc.CFStringCreateWithCString(0, b"FTPEnable", 0)
-        kSCPropNetProxiesFTPPassive = sc.CFStringCreateWithCString(0, b"FTPPassive", 0)
-        kSCPropNetProxiesFTPPort = sc.CFStringCreateWithCString(0, b"FTPPort", 0)
-        kSCPropNetProxiesFTPProxy = sc.CFStringCreateWithCString(0, b"FTPProxy", 0)
-
-        kSCPropNetProxiesGopherEnable = sc.CFStringCreateWithCString(0, b"GopherEnable", 0)
-        kSCPropNetProxiesGopherPort = sc.CFStringCreateWithCString(0, b"GopherPort", 0)
-        kSCPropNetProxiesGopherProxy = sc.CFStringCreateWithCString(0, b"GopherProxy", 0)
-
-        proxies = {}
-        proxyDict = sc.SCDynamicStoreCopyProxies(None)
-
-        try:
-            # HTTP:
-            enabled = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesHTTPEnable)
-            if enabled and _CFNumberToInt32(sc, enabled):
-                proxy = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesHTTPProxy)
-                port = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesHTTPPort)
-
-                if proxy:
-                    proxy = _CStringFromCFString(sc, proxy)
-                    if port:
-                        port = _CFNumberToInt32(sc, port)
-                        proxies["http"] = "http://%s:%i" % (proxy, port)
-                    else:
-                        proxies["http"] = "http://%s" % (proxy, )
-
-            # HTTPS:
-            enabled = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesHTTPSEnable)
-            if enabled and _CFNumberToInt32(sc, enabled):
-                proxy = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesHTTPSProxy)
-                port = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesHTTPSPort)
-
-                if proxy:
-                    proxy = _CStringFromCFString(sc, proxy)
-                    if port:
-                        port = _CFNumberToInt32(sc, port)
-                        proxies["https"] = "http://%s:%i" % (proxy, port)
-                    else:
-                        proxies["https"] = "http://%s" % (proxy, )
-
-            # FTP:
-            enabled = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesFTPEnable)
-            if enabled and _CFNumberToInt32(sc, enabled):
-                proxy = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesFTPProxy)
-                port = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesFTPPort)
-
-                if proxy:
-                    proxy = _CStringFromCFString(sc, proxy)
-                    if port:
-                        port = _CFNumberToInt32(sc, port)
-                        proxies["ftp"] = "http://%s:%i" % (proxy, port)
-                    else:
-                        proxies["ftp"] = "http://%s" % (proxy, )
-
-            # Gopher:
-            enabled = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesGopherEnable)
-            if enabled and _CFNumberToInt32(sc, enabled):
-                proxy = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesGopherProxy)
-                port = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesGopherPort)
-
-                if proxy:
-                    proxy = _CStringFromCFString(sc, proxy)
-                    if port:
-                        port = _CFNumberToInt32(sc, port)
-                        proxies["gopher"] = "http://%s:%i" % (proxy, port)
-                    else:
-                        proxies["gopher"] = "http://%s" % (proxy, )
-        finally:
-            sc.CFRelease(proxyDict)
-
-        sc.CFRelease(kSCPropNetProxiesHTTPEnable)
-        sc.CFRelease(kSCPropNetProxiesHTTPProxy)
-        sc.CFRelease(kSCPropNetProxiesHTTPPort)
-        sc.CFRelease(kSCPropNetProxiesFTPEnable)
-        sc.CFRelease(kSCPropNetProxiesFTPPassive)
-        sc.CFRelease(kSCPropNetProxiesFTPPort)
-        sc.CFRelease(kSCPropNetProxiesFTPProxy)
-        sc.CFRelease(kSCPropNetProxiesGopherEnable)
-        sc.CFRelease(kSCPropNetProxiesGopherPort)
-        sc.CFRelease(kSCPropNetProxiesGopherProxy)
-
-        return proxies
-
-
-
-    def proxy_bypass(host):
-        if getproxies_environment():
-            return proxy_bypass_environment(host)
-        else:
-            return proxy_bypass_macosx_sysconf(host)
-
-    def getproxies():
-        return getproxies_environment() or getproxies_macosx_sysconf()
-
-elif os.name == 'nt':
-    def getproxies_registry():
-        """Return a dictionary of scheme -> proxy server URL mappings.
-
-        Win32 uses the registry to store proxies.
-
-        """
-        proxies = {}
-        try:
-            import winreg
-        except ImportError:
-            # Std module, so should be around - but you never know!
-            return proxies
-        try:
-            internetSettings = winreg.OpenKey(winreg.HKEY_CURRENT_USER,
-                r'Software\Microsoft\Windows\CurrentVersion\Internet Settings')
-            proxyEnable = winreg.QueryValueEx(internetSettings,
-                                              'ProxyEnable')[0]
-            if proxyEnable:
-                # Returned as Unicode but problems if not converted to ASCII
-                proxyServer = str(winreg.QueryValueEx(internetSettings,
-                                                      'ProxyServer')[0])
-                if '=' in proxyServer:
-                    # Per-protocol settings
-                    for p in proxyServer.split(';'):
-                        protocol, address = p.split('=', 1)
-                        # See if address has a type:// prefix
-                        import re
-                        if not re.match('^([^/:]+)://', address):
-                            address = '%s://%s' % (protocol, address)
-                        proxies[protocol] = address
-                else:
-                    # Use one setting for all protocols
-                    if proxyServer[:5] == 'http:':
-                        proxies['http'] = proxyServer
-                    else:
-                        proxies['http'] = 'http://%s' % proxyServer
-                        proxies['ftp'] = 'ftp://%s' % proxyServer
-            internetSettings.Close()
-        except (WindowsError, ValueError, TypeError):
-            # Either registry key not found etc, or the value in an
-            # unexpected format.
-            # proxies already set up to be empty so nothing to do
-            pass
-        return proxies
-
-    def getproxies():
-        """Return a dictionary of scheme -> proxy server URL mappings.
-
-        Returns settings gathered from the environment, if specified,
-        or the registry.
-
-        """
-        return getproxies_environment() or getproxies_registry()
+      g:h        = <URL:g:h>
+      http:g     = <URL:http://a/b/c/g>
+      http:      = <URL:http://a/b/c/d>
+      g          = <URL:http://a/b/c/g>
+      ./g        = <URL:http://a/b/c/g>
+      g/         = <URL:http://a/b/c/g/>
+      /g         = <URL:http://a/g>
+      //g        = <URL:http://g>
+      ?y         = <URL:http://a/b/c/d?y>
+      g?y        = <URL:http://a/b/c/g?y>
+      g?y/./x    = <URL:http://a/b/c/g?y/./x>
+      .          = <URL:http://a/b/c/>
+      ./         = <URL:http://a/b/c/>
+      ..         = <URL:http://a/b/>
+      ../        = <URL:http://a/b/>
+      ../g       = <URL:http://a/b/g>
+      ../..      = <URL:http://a/>
+      ../../g    = <URL:http://a/g>
+      ../../../g = <URL:http://a/../g>
+      ./../g     = <URL:http://a/b/g>
+      ./g/.      = <URL:http://a/b/c/g/>
+      /./g       = <URL:http://a/./g>
+      g/./h      = <URL:http://a/b/c/g/h>
+      g/../h     = <URL:http://a/b/c/h>
+      http:g     = <URL:http://a/b/c/g>
+      http:      = <URL:http://a/b/c/d>
+      http:?y         = <URL:http://a/b/c/d?y>
+      http:g?y        = <URL:http://a/b/c/g?y>
+      http:g?y/./x    = <URL:http://a/b/c/g?y/./x>
+"""
 
-    def proxy_bypass_registry(host):
-        try:
-            import winreg
-            import re
-        except ImportError:
-            # Std modules, so should be around - but you never know!
-            return 0
-        try:
-            internetSettings = winreg.OpenKey(winreg.HKEY_CURRENT_USER,
-                r'Software\Microsoft\Windows\CurrentVersion\Internet Settings')
-            proxyEnable = winreg.QueryValueEx(internetSettings,
-                                              'ProxyEnable')[0]
-            proxyOverride = str(winreg.QueryValueEx(internetSettings,
-                                                    'ProxyOverride')[0])
-            # ^^^^ Returned as Unicode but problems if not converted to ASCII
-        except WindowsError:
-            return 0
-        if not proxyEnable or not proxyOverride:
-            return 0
-        # try to make a host list from name and IP address.
-        rawHost, port = splitport(host)
-        host = [rawHost]
-        try:
-            addr = socket.gethostbyname(rawHost)
-            if addr != rawHost:
-                host.append(addr)
-        except socket.error:
-            pass
-        try:
-            fqdn = socket.getfqdn(rawHost)
-            if fqdn != rawHost:
-                host.append(fqdn)
-        except socket.error:
-            pass
-        # make a check value list from the registry entry: replace the
-        # '<local>' string by the localhost entry and the corresponding
-        # canonical entry.
-        proxyOverride = proxyOverride.split(';')
-        i = 0
-        while i < len(proxyOverride):
-            if proxyOverride[i] == '<local>':
-                proxyOverride[i:i+1] = ['localhost',
-                                        '127.0.0.1',
-                                        socket.gethostname(),
-                                        socket.gethostbyname(
-                                            socket.gethostname())]
-            i += 1
-        # print proxyOverride
-        # now check if we match one of the registry values.
-        for test in proxyOverride:
-            test = test.replace(".", r"\.")     # mask dots
-            test = test.replace("*", r".*")     # change glob sequence
-            test = test.replace("?", r".")      # change glob char
-            for val in host:
-                # print "%s <--> %s" %( test, val )
-                if re.match(test, val, re.I):
-                    return 1
-        return 0
-
-    def proxy_bypass(host):
-        """Return a dictionary of scheme -> proxy server URL mappings.
-
-        Returns settings gathered from the environment, if specified,
-        or the registry.
-
-        """
-        if getproxies_environment():
-            return proxy_bypass_environment(host)
+def test():
+    import sys
+    base = ''
+    if sys.argv[1:]:
+        fn = sys.argv[1]
+        if fn == '-':
+            fp = sys.stdin
         else:
-            return proxy_bypass_registry(host)
-
-else:
-    # By default use environment variables
-    getproxies = getproxies_environment
-    proxy_bypass = proxy_bypass_environment
-
-# Test and time quote() and unquote()
-def test1():
-    s = ''
-    for i in range(256): s = s + chr(i)
-    s = s*4
-    t0 = time.time()
-    qs = quote(s)
-    uqs = unquote(qs)
-    t1 = time.time()
-    if uqs != s:
-        print('Wrong!')
-    print(repr(s))
-    print(repr(qs))
-    print(repr(uqs))
-    print(round(t1 - t0, 3), 'sec')
-
-
-def reporthook(blocknum, blocksize, totalsize):
-    # Report during remote transfers
-    print("Block number: %d, Block size: %d, Total size: %d" % (
-        blocknum, blocksize, totalsize))
-
-# Test program
-def test(args=[]):
-    if not args:
-        args = [
-            '/etc/passwd',
-            'file:/etc/passwd',
-            'file://localhost/etc/passwd',
-            'ftp://ftp.gnu.org/pub/README',
-            'http://www.python.org/index.html',
-            ]
-        if hasattr(URLopener, "open_https"):
-            args.append('https://synergy.as.cmu.edu/~geek/')
-    try:
-        for url in args:
-            print('-'*10, url, '-'*10)
-            fn, h = urlretrieve(url, None, reporthook)
-            print(fn)
-            if h:
-                print('======')
-                for k in h.keys(): print(k + ':', h[k])
-                print('======')
-            fp = open(fn, 'rb')
-            data = fp.read()
-            del fp
-            data = data.replace("\r", "")
-            print(data)
-            fn, h = None, None
-        print('-'*40)
-    finally:
-        urlcleanup()
-
-def main():
-    import getopt, sys
-    try:
-        opts, args = getopt.getopt(sys.argv[1:], "th")
-    except getopt.error as msg:
-        print(msg)
-        print("Use -h for help")
-        return
-    t = 0
-    for o, a in opts:
-        if o == '-t':
-            t = t + 1
-        if o == '-h':
-            print("Usage: python urllib.py [-t] [url ...]")
-            print("-t runs self-test;", end=' ')
-            print("otherwise, contents of urls are printed")
-            return
-    if t:
-        if t > 1:
-            test1()
-        test(args)
+            fp = open(fn)
     else:
-        if not args:
-            print("Use -h for help")
-        for url in args:
-            print(urlopen(url).read(), end=' ')
+        from io import StringIO
+        fp = StringIO(test_input)
+    for line in fp:
+        words = line.split()
+        if not words:
+            continue
+        url = words[0]
+        parts = urlparse(url)
+        print('%-10s : %s' % (url, parts))
+        abs = urljoin(base, url)
+        if not base:
+            base = abs
+        wrapped = '<URL:%s>' % abs
+        print('%-10s = %s' % (url, wrapped))
+        if len(words) == 3 and words[1] == '=':
+            if wrapped != words[2]:
+                print('EXPECTED', words[2], '!!!!!!!!!!')
 
-# Run test program when run as a script
 if __name__ == '__main__':
-    main()
+    test()

Copied: python/branches/py3k-urllib/Lib/urllib/request.py (from r64345, /python/branches/py3k-urllib/Lib/urllib2.py)
==============================================================================
--- /python/branches/py3k-urllib/Lib/urllib2.py	(original)
+++ python/branches/py3k-urllib/Lib/urllib/request.py	Tue Jun 17 23:01:35 2008
@@ -1,3 +1,6 @@
+# Issues in merging urllib and urllib2:
+# 1. They both define a function named urlopen()
+
 """An extensible library for opening URLs using a variety of protocols
 
 The simplest way to use this module is to call the urlopen function,
@@ -38,13 +41,6 @@
 
 BaseHandler --
 
-exceptions:
-URLError -- A subclass of IOError, individual protocols have their own
-specific subclass.
-
-HTTPError -- Also a valid HTTP response, so you can treat an HTTP error
-as an exceptional event or valid response.
-
 internals:
 BaseHandler and parent
 _call_chain conventions
@@ -69,8 +65,6 @@
 urllib2.install_opener(opener)
 
 f = urllib2.urlopen('http://www.python.org/')
-
-
 """
 
 # XXX issues:
@@ -88,10 +82,10 @@
 # abstract factory for opener
 
 import base64
+import email
 import hashlib
 import http.client
 import io
-import email
 import os
 import posixpath
 import random
@@ -99,17 +93,19 @@
 import socket
 import sys
 import time
-import urlparse
+import urllib.parse, urllib.error, urllib.response
 import bisect
 
 from io import StringIO
 
-from urllib import (unwrap, unquote, splittype, splithost, quote,
-     addinfourl, splitport, splitquery,
-     splitattr, ftpwrapper, noheaders, splituser, splitpasswd, splitvalue)
-
-# support for FileHandler, proxies via environment variables
-from urllib import localhost, url2pathname, getproxies
+# check for SSL
+try:
+    import ssl
+except:
+    _have_ssl = False
+else:
+    _have_ssl = True
+assert _have_ssl
 
 # used in User-Agent header sent
 __version__ = sys.version[:3]
@@ -125,42 +121,20 @@
     global _opener
     _opener = opener
 
-# do these error classes make sense?
-# make sure all of the IOError stuff is overridden.  we just want to be
-# subtypes.
-
-class URLError(IOError):
-    # URLError is a sub-type of IOError, but it doesn't share any of
-    # the implementation.  need to override __init__ and __str__.
-    # It sets self.args for compatibility with other EnvironmentError
-    # subclasses, but args doesn't have the typical format with errno in
-    # slot 0 and strerror in slot 1.  This may be better than nothing.
-    def __init__(self, reason):
-        self.args = reason,
-        self.reason = reason
-
-    def __str__(self):
-        return '<urlopen error %s>' % self.reason
-
-class HTTPError(URLError, addinfourl):
-    """Raised when HTTP error occurs, but also acts like non-error return"""
-    __super_init = addinfourl.__init__
-
-    def __init__(self, url, code, msg, hdrs, fp):
-        self.code = code
-        self.msg = msg
-        self.hdrs = hdrs
-        self.fp = fp
-        self.filename = url
-        # The addinfourl classes depend on fp being a valid file
-        # object.  In some cases, the HTTPError may not have a valid
-        # file object.  If this happens, the simplest workaround is to
-        # not initialize the base classes.
-        if fp is not None:
-            self.__super_init(fp, hdrs, url, code)
-
-    def __str__(self):
-        return 'HTTP Error %s: %s' % (self.code, self.msg)
+# TODO(jhylton): Make this work with the same global opener.
+_urlopener = None
+def urlretrieve(url, filename=None, reporthook=None, data=None):
+    global _urlopener
+    if not _urlopener:
+        _urlopener = FancyURLopener()
+    return _urlopener.retrieve(url, filename, reporthook, data)
+
+def urlcleanup():
+    if _urlopener:
+        _urlopener.cleanup()
+    global _opener
+    if _opener:
+        _opener = None
 
 # copied from cookielib.py
 _cut_port_re = re.compile(r":\d+$")
@@ -172,7 +146,7 @@
 
     """
     url = request.get_full_url()
-    host = urlparse.urlparse(url)[1]
+    host = urllib.parse.urlparse(url)[1]
     if host == "":
         host = request.get_header("Host", "")
 
@@ -185,7 +159,7 @@
     def __init__(self, url, data=None, headers={},
                  origin_req_host=None, unverifiable=False):
         # unwrap('<URL:type://host/path>') --> 'type://host/path'
-        self.__original = unwrap(url)
+        self.__original = urllib.parse.unwrap(url)
         self.type = None
         # self.__r_type is what's left after doing the splittype
         self.host = None
@@ -234,16 +208,16 @@
 
     def get_type(self):
         if self.type is None:
-            self.type, self.__r_type = splittype(self.__original)
+            self.type, self.__r_type = urllib.parse.splittype(self.__original)
             if self.type is None:
                 raise ValueError("unknown url type: %s" % self.__original)
         return self.type
 
     def get_host(self):
         if self.host is None:
-            self.host, self.__r_host = splithost(self.__r_type)
+            self.host, self.__r_host = urllib.parse.splithost(self.__r_type)
             if self.host:
-                self.host = unquote(self.host)
+                self.host = urllib.parse.unquote(self.host)
         return self.host
 
     def get_selector(self):
@@ -441,8 +415,10 @@
     default_classes = [ProxyHandler, UnknownHandler, HTTPHandler,
                        HTTPDefaultErrorHandler, HTTPRedirectHandler,
                        FTPHandler, FileHandler, HTTPErrorProcessor]
-    if hasattr(http.client, 'HTTPS'):
+    if hasattr(http.client, "HTTPSConnection"):
         default_classes.append(HTTPSHandler)
+    else:
+        import pdb; pdb.set_trace()
     skip = set()
     for klass in default_classes:
         for check in handlers:
@@ -501,7 +477,7 @@
 
 class HTTPDefaultErrorHandler(BaseHandler):
     def http_error_default(self, req, fp, code, msg, hdrs):
-        raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
+        raise urllib.error.HTTPError(req.get_full_url(), code, msg, hdrs, fp)
 
 class HTTPRedirectHandler(BaseHandler):
     # maximum number of redirections to any single URL
@@ -522,24 +498,25 @@
         but another Handler might.
         """
         m = req.get_method()
-        if (code in (301, 302, 303, 307) and m in ("GET", "HEAD")
-            or code in (301, 302, 303) and m == "POST"):
-            # Strictly (according to RFC 2616), 301 or 302 in response
-            # to a POST MUST NOT cause a redirection without confirmation
-            # from the user (of urllib2, in this case).  In practice,
-            # essentially all clients do redirect in this case, so we
-            # do the same.
-            # be conciliant with URIs containing a space
-            newurl = newurl.replace(' ', '%20')
-            newheaders = dict((k,v) for k,v in req.headers.items()
-                              if k.lower() not in ("content-length", "content-type")
-                             )
-            return Request(newurl,
-                           headers=newheaders,
-                           origin_req_host=req.get_origin_req_host(),
-                           unverifiable=True)
-        else:
-            raise HTTPError(req.get_full_url(), code, msg, headers, fp)
+        if (not (code in (301, 302, 303, 307) and m in ("GET", "HEAD")
+            or code in (301, 302, 303) and m == "POST")):
+            raise urllib.error.HTTPError(req.get_full_url(),
+                                         code, msg, headers, fp)
+
+        # Strictly (according to RFC 2616), 301 or 302 in response to
+        # a POST MUST NOT cause a redirection without confirmation
+        # from the user (of urllib2, in this case).  In practice,
+        # essentially all clients do redirect in this case, so we do
+        # the same.
+        # be conciliant with URIs containing a space
+        newurl = newurl.replace(' ', '%20')
+        CONTENT_HEADERS = ("content-length", "content-type")
+        newheaders = dict((k, v) for k, v in req.headers.items()
+                          if k.lower() not in CONTENT_HEADERS)
+        return Request(newurl,
+                       headers=newheaders,
+                       origin_req_host=req.get_origin_req_host(),
+                       unverifiable=True)
 
     # Implementation note: To avoid the server sending us into an
     # infinite loop, the request object needs to track what URLs we
@@ -548,13 +525,13 @@
     def http_error_302(self, req, fp, code, msg, headers):
         # Some servers (incorrectly) return multiple Location headers
         # (so probably same goes for URI).  Use first header.
-        if 'location' in headers:
-            newurl = headers['location']
-        elif 'uri' in headers:
-            newurl = headers['uri']
+        if "location" in headers:
+            newurl = headers["location"][0]
+        elif "uri" in headers:
+            newurl = headers["uri"][0]
         else:
             return
-        newurl = urlparse.urljoin(req.get_full_url(), newurl)
+        newurl = urllib.parse.urljoin(req.get_full_url(), newurl)
 
         # XXX Probably want to forget about the state of the current
         # request, although that might interact poorly with other
@@ -569,8 +546,8 @@
             visited = new.redirect_dict = req.redirect_dict
             if (visited.get(newurl, 0) >= self.max_repeats or
                 len(visited) >= self.max_redirections):
-                raise HTTPError(req.get_full_url(), code,
-                                self.inf_msg + msg, headers, fp)
+                raise urllib.error.HTTPError(req.get_full_url(), code,
+                                             self.inf_msg + msg, headers, fp)
         else:
             visited = new.redirect_dict = req.redirect_dict = {}
         visited[newurl] = visited.get(newurl, 0) + 1
@@ -639,7 +616,7 @@
     ('http', 'joe', 'password', 'proxy.example.com')
 
     """
-    scheme, r_scheme = splittype(proxy)
+    scheme, r_scheme = urllib.parse.splittype(proxy)
     if not r_scheme.startswith("/"):
         # authority
         scheme = None
@@ -654,9 +631,9 @@
         if end == -1:
             end = None
         authority = r_scheme[2:end]
-    userinfo, hostport = splituser(authority)
+    userinfo, hostport = urllib.parse.splituser(authority)
     if userinfo is not None:
-        user, password = splitpasswd(userinfo)
+        user, password = urllib.parse.splitpasswd(userinfo)
     else:
         user = password = None
     return scheme, user, password, hostport
@@ -681,10 +658,11 @@
         if proxy_type is None:
             proxy_type = orig_type
         if user and password:
-            user_pass = '%s:%s' % (unquote(user), unquote(password))
+            user_pass = '%s:%s' % (unquote(user),
+                                   urllib.parse.unquote(password))
             creds = base64.b64encode(user_pass.encode()).decode("ascii")
             req.add_header('Proxy-authorization', 'Basic ' + creds)
-        hostport = unquote(hostport)
+        hostport = urllib.parse.unquote(hostport)
         req.set_proxy(hostport, proxy_type)
         if orig_type == proxy_type:
             # let other handlers take care of it
@@ -727,7 +705,7 @@
     def reduce_uri(self, uri, default_port=True):
         """Accept authority or URI and extract only the authority and path."""
         # note HTTP URLs do not have a userinfo component
-        parts = urlparse.urlsplit(uri)
+        parts = urllib.parse.urlsplit(uri)
         if parts[1]:
             # URI
             scheme = parts[0]
@@ -738,7 +716,7 @@
             scheme = None
             authority = uri
             path = '/'
-        host, port = splitport(authority)
+        host, port = urllib.parse.splitport(authority)
         if default_port and port is None and scheme is not None:
             dport = {"http": 80,
                      "https": 443,
@@ -875,8 +853,9 @@
             # prompting for the information. Crap. This isn't great
             # but it's better than the current 'repeat until recursion
             # depth exceeded' approach <wink>
-            raise HTTPError(req.get_full_url(), 401, "digest auth failed",
-                            headers, None)
+            raise urllib.error.HTTPError(req.get_full_url(), 401,
+                                         "digest auth failed",
+                                         headers, None)
         else:
             self.retried += 1
         if authreq:
@@ -886,7 +865,7 @@
 
     def retry_http_digest_auth(self, req, auth):
         token, challenge = auth.split(' ', 1)
-        chal = parse_keqv_list(parse_http_list(challenge))
+        chal = parse_keqv_list(filter(None, parse_http_list(challenge)))
         auth = self.get_authorization(req, chal)
         if auth:
             auth_val = 'Digest %s' % auth
@@ -947,7 +926,7 @@
             respdig = KD(H(A1), "%s:%s" % (nonce, H(A2)))
         else:
             # XXX handle auth-int.
-            raise URLError("qop '%s' is not supported." % qop)
+            raise urllib.error.URLError("qop '%s' is not supported." % qop)
 
         # XXX should the partial digests be encoded too?
 
@@ -964,8 +943,6 @@
         return base
 
     def get_algorithm_impls(self, algorithm):
-        # algorithm should be case-insensitive according to RFC2617
-        algorithm = algorithm.upper()
         # lambdas assume digest modules are imported at the top level
         if algorithm == 'MD5':
             H = lambda x: hashlib.md5(x.encode("ascii")).hexdigest()
@@ -991,7 +968,7 @@
     handler_order = 490  # before Basic auth
 
     def http_error_401(self, req, fp, code, msg, headers):
-        host = urlparse.urlparse(req.get_full_url())[1]
+        host = urllib.parse.urlparse(req.get_full_url())[1]
         retry = self.http_error_auth_reqed('www-authenticate',
                                            host, req, headers)
         self.reset_retry_count()
@@ -1021,7 +998,7 @@
     def do_request_(self, request):
         host = request.get_host()
         if not host:
-            raise URLError('no host given')
+            raise urllib.error.URLError('no host given')
 
         if request.has_data():  # POST
             data = request.get_data()
@@ -1033,8 +1010,8 @@
                 request.add_unredirected_header(
                     'Content-length', '%d' % len(data))
 
-        scheme, sel = splittype(request.get_selector())
-        sel_host, sel_path = splithost(sel)
+        scheme, sel = urllib.parse.splittype(request.get_selector())
+        sel_host, sel_path = urllib.parse.splithost(sel)
         if not request.has_header('Host'):
             request.add_unredirected_header('Host', sel_host or host)
         for name, value in self.parent.addheaders:
@@ -1050,19 +1027,21 @@
         http_class must implement the HTTPConnection API from http.client.
         The addinfourl return value is a file-like object.  It also
         has methods and attributes including:
-            - info(): return a email.message.Message object for the headers
+            - info(): return a mimetools.Message object for the headers
             - geturl(): return the original request URL
             - code: HTTP status code
         """
         host = req.get_host()
         if not host:
-            raise URLError('no host given')
+            raise urllib.error.URLError('no host given')
 
         h = http_class(host, timeout=req.timeout) # will parse host:port
-        h.set_debuglevel(self._debuglevel)
-
         headers = dict(req.headers)
         headers.update(req.unredirected_hdrs)
+
+        # TODO(jhylton): Should this be redesigned to handle
+        # persistent connections?
+
         # We want to make an HTTP/1.1 request, but the addinfourl
         # class isn't prepared to deal with a persistent connection.
         # It will try to read all remaining data from the socket,
@@ -1076,23 +1055,9 @@
             h.request(req.get_method(), req.get_selector(), req.data, headers)
             r = h.getresponse()
         except socket.error as err: # XXX what error?
-            raise URLError(err)
-
-        # Pick apart the HTTPResponse object to get the addinfourl
-        # object initialized properly.
+            raise urllib.error.URLError(err)
 
-        # XXX Should an HTTPResponse object really be passed to
-        # BufferedReader?  If so, we should change http.client to support
-        # this use directly.
-
-        # Add some fake methods to the reader to satisfy BufferedReader.
-        r.readable = lambda: True
-        r.writable = r.seekable = lambda: False
-        r._checkReadable = lambda: True
-        r._checkWritable = lambda: False
-        fp = io.BufferedReader(r)
-
-        resp = addinfourl(fp, r.msg, req.get_full_url())
+        resp = urllib.response.addinfourl(r.fp, r.msg, req.get_full_url())
         resp.code = r.status
         resp.msg = r.reason
         return resp
@@ -1105,7 +1070,7 @@
 
     http_request = AbstractHTTPHandler.do_request_
 
-if hasattr(http.client, 'HTTPS'):
+if hasattr(http.client, 'HTTPSConnection'):
     class HTTPSHandler(AbstractHTTPHandler):
 
         def https_open(self, req):
@@ -1134,16 +1099,12 @@
 class UnknownHandler(BaseHandler):
     def unknown_open(self, req):
         type = req.get_type()
-        raise URLError('unknown url type: %s' % type)
+        raise urllib.error.URLError('unknown url type: %s' % type)
 
 def parse_keqv_list(l):
     """Parse list of key=value strings where keys are not duplicated."""
     parsed = {}
     for elt in l:
-        # Because of a trailing comma in the auth string, elt could be the
-        # empty string.
-        if not elt:
-            continue
         k, v = elt.split('=', 1)
         if v[0] == '"' and v[-1] == '"':
             v = v[1:-1]
@@ -1230,15 +1191,15 @@
                 'Content-type: %s\nContent-length: %d\nLast-modified: %s\n' %
                 (mtype or 'text/plain', size, modified))
             if host:
-                host, port = splitport(host)
+                host, port = urllib.parse.splitport(host)
             if not host or \
                 (not port and _safe_gethostbyname(host) in self.get_names()):
-                return addinfourl(open(localfile, 'rb'),
-                                  headers, 'file:'+file)
+                return urllib.response.addinfourl(open(localfile, 'rb'),
+                                                  headers, 'file:'+file)
         except OSError as msg:
             # urllib2 users shouldn't expect OSErrors coming from urlopen()
-            raise URLError(msg)
-        raise URLError('file not on local host')
+            raise urllib.error.URLError(msg)
+        raise urllib.error.URLError('file not on local host')
 
 def _safe_gethostbyname(host):
     try:
@@ -1252,30 +1213,30 @@
         import mimetypes
         host = req.get_host()
         if not host:
-            raise URLError('ftp error: no host given')
-        host, port = splitport(host)
+            raise urllib.error.URLError('ftp error: no host given')
+        host, port = urllib.parse.splitport(host)
         if port is None:
             port = ftplib.FTP_PORT
         else:
             port = int(port)
 
         # username/password handling
-        user, host = splituser(host)
+        user, host = urllib.parse.splituser(host)
         if user:
-            user, passwd = splitpasswd(user)
+            user, passwd = urllib.parse.splitpasswd(user)
         else:
             passwd = None
-        host = unquote(host)
-        user = unquote(user or '')
-        passwd = unquote(passwd or '')
+        host = urllib.parse.unquote(host)
+        user = urllib.parse.unquote(user or '')
+        passwd = urllib.parse.unquote(passwd or '')
 
         try:
             host = socket.gethostbyname(host)
         except socket.error as msg:
-            raise URLError(msg)
-        path, attrs = splitattr(req.get_selector())
+            raise urllib.error.URLError(msg)
+        path, attrs = urllib.parse.splitattr(req.get_selector())
         dirs = path.split('/')
-        dirs = list(map(unquote, dirs))
+        dirs = list(map(urllib.parse.unquote, dirs))
         dirs, file = dirs[:-1], dirs[-1]
         if dirs and not dirs[0]:
             dirs = dirs[1:]
@@ -1283,7 +1244,7 @@
             fw = self.connect_ftp(user, passwd, host, port, dirs, req.timeout)
             type = file and 'I' or 'D'
             for attr in attrs:
-                attr, value = splitvalue(attr)
+                attr, value = urllib.parse.splitvalue(attr)
                 if attr.lower() == 'type' and \
                    value in ('a', 'A', 'i', 'I', 'd', 'D'):
                     type = value.upper()
@@ -1295,10 +1256,10 @@
             if retrlen is not None and retrlen >= 0:
                 headers += "Content-length: %d\n" % retrlen
             headers = email.message_from_string(headers)
-            sf = StringIO(str(headers))
-            return addinfourl(fp, headers, req.get_full_url())
+            return urllib.response.addinfourl(fp, headers, req.get_full_url())
         except ftplib.all_errors as msg:
-            raise URLError('ftp error: %s' % msg).with_traceback(sys.exc_info()[2])
+            exc = urllib.error.URLError('ftp error: %s' % msg)
+            raise exc.with_traceback(sys.exc_info()[2])
 
     def connect_ftp(self, user, passwd, host, port, dirs, timeout):
         fw = ftpwrapper(user, passwd, host, port, dirs, timeout)
@@ -1325,7 +1286,8 @@
         if key in self.cache:
             self.timeout[key] = time.time() + self.delay
         else:
-            self.cache[key] = ftpwrapper(user, passwd, host, port, dirs, timeout)
+            self.cache[key] = ftpwrapper(user, passwd, host, port,
+                                         dirs, timeout)
             self.timeout[key] = time.time() + self.delay
         self.check_cache()
         return self.cache[key]
@@ -1349,3 +1311,985 @@
                     del self.timeout[k]
                     break
             self.soonest = min(list(self.timeout.values()))
+
+# Code move from the old urllib module
+
+MAXFTPCACHE = 10        # Trim the ftp cache beyond this size
+
+# Helper for non-unix systems
+if os.name == 'mac':
+    from macurl2path import url2pathname, pathname2url
+elif os.name == 'nt':
+    from nturl2path import url2pathname, pathname2url
+else:
+    def url2pathname(pathname):
+        """OS-specific conversion from a relative URL of the 'file' scheme
+        to a file system path; not recommended for general use."""
+        return urllib.parse.unquote(pathname)
+
+    def pathname2url(pathname):
+        """OS-specific conversion from a file system path to a relative URL
+        of the 'file' scheme; not recommended for general use."""
+        return urllib.parse.quote(pathname)
+
+# This really consists of two pieces:
+# (1) a class which handles opening of all sorts of URLs
+#     (plus assorted utilities etc.)
+# (2) a set of functions for parsing URLs
+# XXX Should these be separated out into different modules?
+
+
+ftpcache = {}
+class URLopener:
+    """Class to open URLs.
+    This is a class rather than just a subroutine because we may need
+    more than one set of global protocol-specific options.
+    Note -- this is a base class for those who don't want the
+    automatic handling of errors type 302 (relocated) and 401
+    (authorization needed)."""
+
+    __tempfiles = None
+
+    version = "Python-urllib/%s" % __version__
+
+    # Constructor
+    def __init__(self, proxies=None, **x509):
+        if proxies is None:
+            proxies = getproxies()
+        assert hasattr(proxies, 'keys'), "proxies must be a mapping"
+        self.proxies = proxies
+        self.key_file = x509.get('key_file')
+        self.cert_file = x509.get('cert_file')
+        self.addheaders = [('User-Agent', self.version)]
+        self.__tempfiles = []
+        self.__unlink = os.unlink # See cleanup()
+        self.tempcache = None
+        # Undocumented feature: if you assign {} to tempcache,
+        # it is used to cache files retrieved with
+        # self.retrieve().  This is not enabled by default
+        # since it does not work for changing documents (and I
+        # haven't got the logic to check expiration headers
+        # yet).
+        self.ftpcache = ftpcache
+        # Undocumented feature: you can use a different
+        # ftp cache by assigning to the .ftpcache member;
+        # in case you want logically independent URL openers
+        # XXX This is not threadsafe.  Bah.
+
+    def __del__(self):
+        self.close()
+
+    def close(self):
+        self.cleanup()
+
+    def cleanup(self):
+        # This code sometimes runs when the rest of this module
+        # has already been deleted, so it can't use any globals
+        # or import anything.
+        if self.__tempfiles:
+            for file in self.__tempfiles:
+                try:
+                    self.__unlink(file)
+                except OSError:
+                    pass
+            del self.__tempfiles[:]
+        if self.tempcache:
+            self.tempcache.clear()
+
+    def addheader(self, *args):
+        """Add a header to be used by the HTTP interface only
+        e.g. u.addheader('Accept', 'sound/basic')"""
+        self.addheaders.append(args)
+
+    # External interface
+    def open(self, fullurl, data=None):
+        """Use URLopener().open(file) instead of open(file, 'r')."""
+        fullurl = urllib.parse.unwrap(urllib.parse.toBytes(fullurl))
+        if self.tempcache and fullurl in self.tempcache:
+            filename, headers = self.tempcache[fullurl]
+            fp = open(filename, 'rb')
+            return urllib.response.addinfourl(fp, headers, fullurl)
+        urltype, url = urllib.parse.splittype(fullurl)
+        if not urltype:
+            urltype = 'file'
+        if urltype in self.proxies:
+            proxy = self.proxies[urltype]
+            urltype, proxyhost = urllib.parse.splittype(proxy)
+            host, selector = urllib.parse.splithost(proxyhost)
+            url = (host, fullurl) # Signal special case to open_*()
+        else:
+            proxy = None
+        name = 'open_' + urltype
+        self.type = urltype
+        name = name.replace('-', '_')
+        if not hasattr(self, name):
+            if proxy:
+                return self.open_unknown_proxy(proxy, fullurl, data)
+            else:
+                return self.open_unknown(fullurl, data)
+        try:
+            if data is None:
+                return getattr(self, name)(url)
+            else:
+                return getattr(self, name)(url, data)
+        except socket.error as msg:
+            raise IOError('socket error', msg).with_traceback(sys.exc_info()[2])
+
+    def open_unknown(self, fullurl, data=None):
+        """Overridable interface to open unknown URL type."""
+        type, url = urllib.parse.splittype(fullurl)
+        raise IOError('url error', 'unknown url type', type)
+
+    def open_unknown_proxy(self, proxy, fullurl, data=None):
+        """Overridable interface to open unknown URL type."""
+        type, url = urllib.parse.splittype(fullurl)
+        raise IOError('url error', 'invalid proxy for %s' % type, proxy)
+
+    # External interface
+    def retrieve(self, url, filename=None, reporthook=None, data=None):
+        """retrieve(url) returns (filename, headers) for a local object
+        or (tempfilename, headers) for a remote object."""
+        url = urllib.parse.unwrap(urllib.parse.toBytes(url))
+        if self.tempcache and url in self.tempcache:
+            return self.tempcache[url]
+        type, url1 = urllib.parse.splittype(url)
+        if filename is None and (not type or type == 'file'):
+            try:
+                fp = self.open_local_file(url1)
+                hdrs = fp.info()
+                del fp
+                return url2pathname(urllib.parse.splithost(url1)[1]), hdrs
+            except IOError as msg:
+                pass
+        fp = self.open(url, data)
+        headers = fp.info()
+        if filename:
+            tfp = open(filename, 'wb')
+        else:
+            import tempfile
+            garbage, path = urllib.parse.splittype(url)
+            garbage, path = urllib.parse.splithost(path or "")
+            path, garbage = urllib.parse.splitquery(path or "")
+            path, garbage = urllib.parse.splitattr(path or "")
+            suffix = os.path.splitext(path)[1]
+            (fd, filename) = tempfile.mkstemp(suffix)
+            self.__tempfiles.append(filename)
+            tfp = os.fdopen(fd, 'wb')
+        result = filename, headers
+        if self.tempcache is not None:
+            self.tempcache[url] = result
+        bs = 1024*8
+        size = -1
+        read = 0
+        blocknum = 0
+        if reporthook:
+            if "content-length" in headers:
+                size = int(headers["Content-Length"])
+            reporthook(blocknum, bs, size)
+        while 1:
+            block = fp.read(bs)
+            if not block:
+                break
+            read += len(block)
+            tfp.write(block)
+            blocknum += 1
+            if reporthook:
+                reporthook(blocknum, bs, size)
+        fp.close()
+        tfp.close()
+        del fp
+        del tfp
+
+        # raise exception if actual size does not match content-length header
+        if size >= 0 and read < size:
+            raise urllib.error.ContentTooShortError(
+                "retrieval incomplete: got only %i out of %i bytes"
+                % (read, size), result)
+
+        return result
+
+    # Each method named open_<type> knows how to open that type of URL
+
+    def _open_generic_http(self, connection_factory, url, data):
+        """Make an HTTP connection using connection_class.
+
+        This is an internal method that should be called from
+        open_http() or open_https().
+
+        Arguments:
+        - connection_factory should take a host name and return an
+          HTTPConnection instance.
+        - url is the url to retrieval or a host, relative-path pair.
+        - data is payload for a POST request or None.
+        """
+
+        user_passwd = None
+        proxy_passwd= None
+        if isinstance(url, str):
+            host, selector = urllib.parse.splithost(url)
+            if host:
+                user_passwd, host = urllib.parse.splituser(host)
+                host = urllib.parse.unquote(host)
+            realhost = host
+        else:
+            host, selector = url
+            # check whether the proxy contains authorization information
+            proxy_passwd, host = urllib.parse.splituser(host)
+            # now we proceed with the url we want to obtain
+            urltype, rest = urllib.parse.splittype(selector)
+            url = rest
+            user_passwd = None
+            if urltype.lower() != 'http':
+                realhost = None
+            else:
+                realhost, rest = urllib.parse.splithost(rest)
+                if realhost:
+                    user_passwd, realhost = urllib.parse.splituser(realhost)
+                if user_passwd:
+                    selector = "%s://%s%s" % (urltype, realhost, rest)
+                if proxy_bypass(realhost):
+                    host = realhost
+
+            #print "proxy via http:", host, selector
+        if not host: raise IOError('http error', 'no host given')
+
+        if proxy_passwd:
+            import base64
+            proxy_auth = base64.b64encode(proxy_passwd).strip()
+        else:
+            proxy_auth = None
+
+        if user_passwd:
+            import base64
+            auth = base64.b64encode(user_passwd).strip()
+        else:
+            auth = None
+        http_conn = connection_factory(host)
+        # XXX We should fix urllib so that it works with HTTP/1.1.
+        http_conn._http_vsn = 10
+        http_conn._http_vsn_str = "HTTP/1.0"
+
+        headers = {}
+        if proxy_auth:
+            headers["Proxy-Authorization"] = "Basic %s" % proxy_auth
+        if auth:
+            headers["Authorization"] =  "Basic %s" % auth
+        if realhost:
+            headers["Host"] = realhost
+        for header, value in self.addheaders:
+            headers[header] = value
+
+        if data is not None:
+            headers["Content-Type"] = "application/x-www-form-urlencoded"
+            http_conn.request("POST", selector, data, headers)
+        else:
+            http_conn.request("GET", selector, headers=headers)
+
+        try:
+            response = http_conn.getresponse()
+        except http.client.BadStatusLine:
+            # something went wrong with the HTTP status line
+            raise urllib.error.URLError("http protocol error: bad status line")
+
+        # According to RFC 2616, "2xx" code indicates that the client's
+        # request was successfully received, understood, and accepted.
+        if 200 <= response.status < 300:
+            return urllib.response.addinfourl(response.fp, response.msg,
+                                              "http:" + url,
+                                              response.status)
+        else:
+            return self.http_error(
+                url, response.fp,
+                response.status, response.reason, response.msg, data)
+
+    def open_http(self, url, data=None):
+        """Use HTTP protocol."""
+        return self._open_generic_http(http.client.HTTPConnection, url, data)
+
+    def http_error(self, url, fp, errcode, errmsg, headers, data=None):
+        """Handle http errors.
+
+        Derived class can override this, or provide specific handlers
+        named http_error_DDD where DDD is the 3-digit error code."""
+        # First check if there's a specific handler for this error
+        name = 'http_error_%d' % errcode
+        if hasattr(self, name):
+            method = getattr(self, name)
+            if data is None:
+                result = method(url, fp, errcode, errmsg, headers)
+            else:
+                result = method(url, fp, errcode, errmsg, headers, data)
+            if result: return result
+        return self.http_error_default(url, fp, errcode, errmsg, headers)
+
+    def http_error_default(self, url, fp, errcode, errmsg, headers):
+        """Default error handler: close the connection and raise IOError."""
+        void = fp.read()
+        fp.close()
+        raise urllib.error.HTTPError(url, errcode, errmsg, headers, None)
+
+    if _have_ssl:
+        def _https_connection(self, host):
+            return http.client.HTTPSConnection(host,
+                                           key_file=self.key_file,
+                                           cert_file=self.cert_file)
+
+        def open_https(self, url, data=None):
+            """Use HTTPS protocol."""
+            return self._open_generic_http(self._https_connection, url, data)
+
+    def open_file(self, url):
+        """Use local file or FTP depending on form of URL."""
+        if not isinstance(url, str):
+            raise URLError('file error', 'proxy support for file protocol currently not implemented')
+        if url[:2] == '//' and url[2:3] != '/' and url[2:12].lower() != 'localhost/':
+            return self.open_ftp(url)
+        else:
+            return self.open_local_file(url)
+
+    def open_local_file(self, url):
+        """Use local file."""
+        import mimetypes, email.utils
+        from io import StringIO
+        host, file = urllib.parse.splithost(url)
+        localname = url2pathname(file)
+        try:
+            stats = os.stat(localname)
+        except OSError as e:
+            raise URLError(e.errno, e.strerror, e.filename)
+        size = stats.st_size
+        modified = email.utils.formatdate(stats.st_mtime, usegmt=True)
+        mtype = mimetypes.guess_type(url)[0]
+        headers = email.message_from_string(
+            'Content-Type: %s\nContent-Length: %d\nLast-modified: %s\n' %
+            (mtype or 'text/plain', size, modified))
+        if not host:
+            urlfile = file
+            if file[:1] == '/':
+                urlfile = 'file://' + file
+            return urllib.response.addinfourl(open(localname, 'rb'),
+                                              headers, urlfile)
+        host, port = urllib.parse.splitport(host)
+        if (not port
+           and socket.gethostbyname(host) in (localhost(), thishost())):
+            urlfile = file
+            if file[:1] == '/':
+                urlfile = 'file://' + file
+            return urllib.response.addinfourl(open(localname, 'rb'),
+                                              headers, urlfile)
+        raise URLError('local file error', 'not on local host')
+
+    def open_ftp(self, url):
+        """Use FTP protocol."""
+        if not isinstance(url, str):
+            raise URLError('ftp error', 'proxy support for ftp protocol currently not implemented')
+        import mimetypes
+        from io import StringIO
+        host, path = urllib.parse.splithost(url)
+        if not host: raise URLError('ftp error', 'no host given')
+        host, port = urllib.parse.splitport(host)
+        user, host = urllib.parse.splituser(host)
+        if user: user, passwd = urllib.parse.splitpasswd(user)
+        else: passwd = None
+        host = urllib.parse.unquote(host)
+        user = urllib.parse.unquote(user or '')
+        passwd = urllib.parse.unquote(passwd or '')
+        host = socket.gethostbyname(host)
+        if not port:
+            import ftplib
+            port = ftplib.FTP_PORT
+        else:
+            port = int(port)
+        path, attrs = urllib.parse.splitattr(path)
+        path = urllib.parse.unquote(path)
+        dirs = path.split('/')
+        dirs, file = dirs[:-1], dirs[-1]
+        if dirs and not dirs[0]: dirs = dirs[1:]
+        if dirs and not dirs[0]: dirs[0] = '/'
+        key = user, host, port, '/'.join(dirs)
+        # XXX thread unsafe!
+        if len(self.ftpcache) > MAXFTPCACHE:
+            # Prune the cache, rather arbitrarily
+            for k in self.ftpcache.keys():
+                if k != key:
+                    v = self.ftpcache[k]
+                    del self.ftpcache[k]
+                    v.close()
+        try:
+            if not key in self.ftpcache:
+                self.ftpcache[key] = \
+                    ftpwrapper(user, passwd, host, port, dirs)
+            if not file: type = 'D'
+            else: type = 'I'
+            for attr in attrs:
+                attr, value = urllib.parse.splitvalue(attr)
+                if attr.lower() == 'type' and \
+                   value in ('a', 'A', 'i', 'I', 'd', 'D'):
+                    type = value.upper()
+            (fp, retrlen) = self.ftpcache[key].retrfile(file, type)
+            mtype = mimetypes.guess_type("ftp:" + url)[0]
+            headers = ""
+            if mtype:
+                headers += "Content-Type: %s\n" % mtype
+            if retrlen is not None and retrlen >= 0:
+                headers += "Content-Length: %d\n" % retrlen
+            headers = email.message_from_string(headers)
+            return urllib.response.addinfourl(fp, headers, "ftp:" + url)
+        except ftperrors() as msg:
+            raise URLError('ftp error', msg).with_traceback(sys.exc_info()[2])
+
+    def open_data(self, url, data=None):
+        """Use "data" URL."""
+        if not isinstance(url, str):
+            raise URLError('data error', 'proxy support for data protocol currently not implemented')
+        # ignore POSTed data
+        #
+        # syntax of data URLs:
+        # dataurl   := "data:" [ mediatype ] [ ";base64" ] "," data
+        # mediatype := [ type "/" subtype ] *( ";" parameter )
+        # data      := *urlchar
+        # parameter := attribute "=" value
+        try:
+            [type, data] = url.split(',', 1)
+        except ValueError:
+            raise IOError('data error', 'bad data URL')
+        if not type:
+            type = 'text/plain;charset=US-ASCII'
+        semi = type.rfind(';')
+        if semi >= 0 and '=' not in type[semi:]:
+            encoding = type[semi+1:]
+            type = type[:semi]
+        else:
+            encoding = ''
+        msg = []
+        msg.append('Date: %s'%time.strftime('%a, %d %b %Y %T GMT',
+                                            time.gmtime(time.time())))
+        msg.append('Content-type: %s' % type)
+        if encoding == 'base64':
+            import base64
+            data = base64.decodestring(data)
+        else:
+            data = urllib.parse.unquote(data)
+        msg.append('Content-Length: %d' % len(data))
+        msg.append('')
+        msg.append(data)
+        msg = '\n'.join(msg)
+        headers = mimetools.message_from_string(msg)
+        #f.fileno = None     # needed for addinfourl
+        return urllib.response.addinfourl(f, headers, url)
+
+
+class FancyURLopener(URLopener):
+    """Derived class with handlers for errors we can handle (perhaps)."""
+
+    def __init__(self, *args, **kwargs):
+        URLopener.__init__(self, *args, **kwargs)
+        self.auth_cache = {}
+        self.tries = 0
+        self.maxtries = 10
+
+    def http_error_default(self, url, fp, errcode, errmsg, headers):
+        """Default error handling -- don't raise an exception."""
+        return urllib.response.addinfourl(fp, headers, "http:" + url, errcode)
+
+    def http_error_302(self, url, fp, errcode, errmsg, headers, data=None):
+        """Error 302 -- relocated (temporarily)."""
+        self.tries += 1
+        if self.maxtries and self.tries >= self.maxtries:
+            if hasattr(self, "http_error_500"):
+                meth = self.http_error_500
+            else:
+                meth = self.http_error_default
+            self.tries = 0
+            return meth(url, fp, 500,
+                        "Internal Server Error: Redirect Recursion", headers)
+        result = self.redirect_internal(url, fp, errcode, errmsg, headers,
+                                        data)
+        self.tries = 0
+        return result
+
+    def redirect_internal(self, url, fp, errcode, errmsg, headers, data):
+        if 'location' in headers:
+            newurl = headers['location']
+        elif 'uri' in headers:
+            newurl = headers['uri']
+        else:
+            return
+        void = fp.read()
+        fp.close()
+        # In case the server sent a relative URL, join with original:
+        newurl = basejoin(self.type + ":" + url, newurl)
+        return self.open(newurl)
+
+    def http_error_301(self, url, fp, errcode, errmsg, headers, data=None):
+        """Error 301 -- also relocated (permanently)."""
+        return self.http_error_302(url, fp, errcode, errmsg, headers, data)
+
+    def http_error_303(self, url, fp, errcode, errmsg, headers, data=None):
+        """Error 303 -- also relocated (essentially identical to 302)."""
+        return self.http_error_302(url, fp, errcode, errmsg, headers, data)
+
+    def http_error_307(self, url, fp, errcode, errmsg, headers, data=None):
+        """Error 307 -- relocated, but turn POST into error."""
+        if data is None:
+            return self.http_error_302(url, fp, errcode, errmsg, headers, data)
+        else:
+            return self.http_error_default(url, fp, errcode, errmsg, headers)
+
+    def http_error_401(self, url, fp, errcode, errmsg, headers, data=None):
+        """Error 401 -- authentication required.
+        This function supports Basic authentication only."""
+        if not 'www-authenticate' in headers:
+            URLopener.http_error_default(self, url, fp,
+                                         errcode, errmsg, headers)
+        stuff = headers['www-authenticate']
+        import re
+        match = re.match('[ \t]*([^ \t]+)[ \t]+realm="([^"]*)"', stuff)
+        if not match:
+            URLopener.http_error_default(self, url, fp,
+                                         errcode, errmsg, headers)
+        scheme, realm = match.groups()
+        if scheme.lower() != 'basic':
+            URLopener.http_error_default(self, url, fp,
+                                         errcode, errmsg, headers)
+        name = 'retry_' + self.type + '_basic_auth'
+        if data is None:
+            return getattr(self,name)(url, realm)
+        else:
+            return getattr(self,name)(url, realm, data)
+
+    def http_error_407(self, url, fp, errcode, errmsg, headers, data=None):
+        """Error 407 -- proxy authentication required.
+        This function supports Basic authentication only."""
+        if not 'proxy-authenticate' in headers:
+            URLopener.http_error_default(self, url, fp,
+                                         errcode, errmsg, headers)
+        stuff = headers['proxy-authenticate']
+        import re
+        match = re.match('[ \t]*([^ \t]+)[ \t]+realm="([^"]*)"', stuff)
+        if not match:
+            URLopener.http_error_default(self, url, fp,
+                                         errcode, errmsg, headers)
+        scheme, realm = match.groups()
+        if scheme.lower() != 'basic':
+            URLopener.http_error_default(self, url, fp,
+                                         errcode, errmsg, headers)
+        name = 'retry_proxy_' + self.type + '_basic_auth'
+        if data is None:
+            return getattr(self,name)(url, realm)
+        else:
+            return getattr(self,name)(url, realm, data)
+
+    def retry_proxy_http_basic_auth(self, url, realm, data=None):
+        host, selector = urllib.parse.splithost(url)
+        newurl = 'http://' + host + selector
+        proxy = self.proxies['http']
+        urltype, proxyhost = urllib.parse.splittype(proxy)
+        proxyhost, proxyselector = urllib.parse.splithost(proxyhost)
+        i = proxyhost.find('@') + 1
+        proxyhost = proxyhost[i:]
+        user, passwd = self.get_user_passwd(proxyhost, realm, i)
+        if not (user or passwd): return None
+        proxyhost = "%s:%s@%s" % (urllib.parse.quote(user, safe=''),
+                                  quote(passwd, safe=''), proxyhost)
+        self.proxies['http'] = 'http://' + proxyhost + proxyselector
+        if data is None:
+            return self.open(newurl)
+        else:
+            return self.open(newurl, data)
+
+    def retry_proxy_https_basic_auth(self, url, realm, data=None):
+        host, selector = urllib.parse.splithost(url)
+        newurl = 'https://' + host + selector
+        proxy = self.proxies['https']
+        urltype, proxyhost = urllib.parse.splittype(proxy)
+        proxyhost, proxyselector = urllib.parse.splithost(proxyhost)
+        i = proxyhost.find('@') + 1
+        proxyhost = proxyhost[i:]
+        user, passwd = self.get_user_passwd(proxyhost, realm, i)
+        if not (user or passwd): return None
+        proxyhost = "%s:%s@%s" % (urllib.parse.quote(user, safe=''),
+                                  quote(passwd, safe=''), proxyhost)
+        self.proxies['https'] = 'https://' + proxyhost + proxyselector
+        if data is None:
+            return self.open(newurl)
+        else:
+            return self.open(newurl, data)
+
+    def retry_http_basic_auth(self, url, realm, data=None):
+        host, selector = urllib.parse.splithost(url)
+        i = host.find('@') + 1
+        host = host[i:]
+        user, passwd = self.get_user_passwd(host, realm, i)
+        if not (user or passwd): return None
+        host = "%s:%s@%s" % (urllib.parse.quote(user, safe=''),
+                             quote(passwd, safe=''), host)
+        newurl = 'http://' + host + selector
+        if data is None:
+            return self.open(newurl)
+        else:
+            return self.open(newurl, data)
+
+    def retry_https_basic_auth(self, url, realm, data=None):
+        host, selector = urllib.parse.splithost(url)
+        i = host.find('@') + 1
+        host = host[i:]
+        user, passwd = self.get_user_passwd(host, realm, i)
+        if not (user or passwd): return None
+        host = "%s:%s@%s" % (urllib.parse.quote(user, safe=''),
+                             quote(passwd, safe=''), host)
+        newurl = 'https://' + host + selector
+        if data is None:
+            return self.open(newurl)
+        else:
+            return self.open(newurl, data)
+
+    def get_user_passwd(self, host, realm, clear_cache = 0):
+        key = realm + '@' + host.lower()
+        if key in self.auth_cache:
+            if clear_cache:
+                del self.auth_cache[key]
+            else:
+                return self.auth_cache[key]
+        user, passwd = self.prompt_user_passwd(host, realm)
+        if user or passwd: self.auth_cache[key] = (user, passwd)
+        return user, passwd
+
+    def prompt_user_passwd(self, host, realm):
+        """Override this in a GUI environment!"""
+        import getpass
+        try:
+            user = input("Enter username for %s at %s: " % (realm, host))
+            passwd = getpass.getpass("Enter password for %s in %s at %s: " %
+                (user, realm, host))
+            return user, passwd
+        except KeyboardInterrupt:
+            print()
+            return None, None
+
+
+# Utility functions
+
+_localhost = None
+def localhost():
+    """Return the IP address of the magic hostname 'localhost'."""
+    global _localhost
+    if _localhost is None:
+        _localhost = socket.gethostbyname('localhost')
+    return _localhost
+
+_thishost = None
+def thishost():
+    """Return the IP address of the current host."""
+    global _thishost
+    if _thishost is None:
+        _thishost = socket.gethostbyname(socket.gethostname())
+    return _thishost
+
+_ftperrors = None
+def ftperrors():
+    """Return the set of errors raised by the FTP class."""
+    global _ftperrors
+    if _ftperrors is None:
+        import ftplib
+        _ftperrors = ftplib.all_errors
+    return _ftperrors
+
+_noheaders = None
+def noheaders():
+    """Return an empty mimetools.Message object."""
+    global _noheaders
+    if _noheaders is None:
+        _noheaders = mimetools.message_from_string("")
+    return _noheaders
+
+
+# Utility classes
+
+class ftpwrapper:
+    """Class used by open_ftp() for cache of open FTP connections."""
+
+    def __init__(self, user, passwd, host, port, dirs, timeout=None):
+        self.user = user
+        self.passwd = passwd
+        self.host = host
+        self.port = port
+        self.dirs = dirs
+        self.timeout = timeout
+        self.init()
+
+    def init(self):
+        import ftplib
+        self.busy = 0
+        self.ftp = ftplib.FTP()
+        self.ftp.connect(self.host, self.port, self.timeout)
+        self.ftp.login(self.user, self.passwd)
+        for dir in self.dirs:
+            self.ftp.cwd(dir)
+
+    def retrfile(self, file, type):
+        import ftplib
+        self.endtransfer()
+        if type in ('d', 'D'): cmd = 'TYPE A'; isdir = 1
+        else: cmd = 'TYPE ' + type; isdir = 0
+        try:
+            self.ftp.voidcmd(cmd)
+        except ftplib.all_errors:
+            self.init()
+            self.ftp.voidcmd(cmd)
+        conn = None
+        if file and not isdir:
+            # Try to retrieve as a file
+            try:
+                cmd = 'RETR ' + file
+                conn = self.ftp.ntransfercmd(cmd)
+            except ftplib.error_perm as reason:
+                if str(reason)[:3] != '550':
+                    raise urllib.error.URLError('ftp error', reason).with_traceback(sys.exc_info()[2])
+        if not conn:
+            # Set transfer mode to ASCII!
+            self.ftp.voidcmd('TYPE A')
+            # Try a directory listing. Verify that directory exists.
+            if file:
+                pwd = self.ftp.pwd()
+                try:
+                    try:
+                        self.ftp.cwd(file)
+                    except ftplib.error_perm as reason:
+                        raise urllib.error.URLError('ftp error', reason) from reason
+                finally:
+                    self.ftp.cwd(pwd)
+                cmd = 'LIST ' + file
+            else:
+                cmd = 'LIST'
+            conn = self.ftp.ntransfercmd(cmd)
+        self.busy = 1
+        # Pass back both a suitably decorated object and a retrieval length
+        return (urllib.response.addclosehook(conn[0].makefile('rb'),
+                                             self.endtransfer), conn[1])
+    def endtransfer(self):
+        if not self.busy:
+            return
+        self.busy = 0
+        try:
+            self.ftp.voidresp()
+        except ftperrors():
+            pass
+
+    def close(self):
+        self.endtransfer()
+        try:
+            self.ftp.close()
+        except ftperrors():
+            pass
+
+# Proxy handling
+def getproxies_environment():
+    """Return a dictionary of scheme -> proxy server URL mappings.
+
+    Scan the environment for variables named <scheme>_proxy;
+    this seems to be the standard convention.  If you need a
+    different way, you can pass a proxies dictionary to the
+    [Fancy]URLopener constructor.
+
+    """
+    proxies = {}
+    for name, value in os.environ.items():
+        name = name.lower()
+        if name == 'no_proxy':
+            # handled in proxy_bypass_environment
+            continue
+        if value and name[-6:] == '_proxy':
+            proxies[name[:-6]] = value
+    return proxies
+
+def proxy_bypass_environment(host):
+    """Test if proxies should not be used for a particular host.
+
+    Checks the environment for a variable named no_proxy, which should
+    be a list of DNS suffixes separated by commas, or '*' for all hosts.
+    """
+    no_proxy = os.environ.get('no_proxy', '') or os.environ.get('NO_PROXY', '')
+    # '*' is special case for always bypass
+    if no_proxy == '*':
+        return 1
+    # strip port off host
+    hostonly, port = urllib.parse.splitport(host)
+    # check if the host ends with any of the DNS suffixes
+    for name in no_proxy.split(','):
+        if name and (hostonly.endswith(name) or host.endswith(name)):
+            return 1
+    # otherwise, don't bypass
+    return 0
+
+
+if sys.platform == 'darwin':
+    def getproxies_internetconfig():
+        """Return a dictionary of scheme -> proxy server URL mappings.
+
+        By convention the mac uses Internet Config to store
+        proxies.  An HTTP proxy, for instance, is stored under
+        the HttpProxy key.
+
+        """
+        try:
+            import ic
+        except ImportError:
+            return {}
+
+        try:
+            config = ic.IC()
+        except ic.error:
+            return {}
+        proxies = {}
+        # HTTP:
+        if 'UseHTTPProxy' in config and config['UseHTTPProxy']:
+            try:
+                value = config['HTTPProxyHost']
+            except ic.error:
+                pass
+            else:
+                proxies['http'] = 'http://%s' % value
+        # FTP: XXX To be done.
+        # Gopher: XXX To be done.
+        return proxies
+
+    def proxy_bypass(host):
+        if getproxies_environment():
+            return proxy_bypass_environment(host)
+        else:
+            return 0
+
+    def getproxies():
+        return getproxies_environment() or getproxies_internetconfig()
+
+elif os.name == 'nt':
+    def getproxies_registry():
+        """Return a dictionary of scheme -> proxy server URL mappings.
+
+        Win32 uses the registry to store proxies.
+
+        """
+        proxies = {}
+        try:
+            import _winreg
+        except ImportError:
+            # Std module, so should be around - but you never know!
+            return proxies
+        try:
+            internetSettings = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER,
+                r'Software\Microsoft\Windows\CurrentVersion\Internet Settings')
+            proxyEnable = _winreg.QueryValueEx(internetSettings,
+                                               'ProxyEnable')[0]
+            if proxyEnable:
+                # Returned as Unicode but problems if not converted to ASCII
+                proxyServer = str(_winreg.QueryValueEx(internetSettings,
+                                                       'ProxyServer')[0])
+                if '=' in proxyServer:
+                    # Per-protocol settings
+                    for p in proxyServer.split(';'):
+                        protocol, address = p.split('=', 1)
+                        # See if address has a type:// prefix
+                        import re
+                        if not re.match('^([^/:]+)://', address):
+                            address = '%s://%s' % (protocol, address)
+                        proxies[protocol] = address
+                else:
+                    # Use one setting for all protocols
+                    if proxyServer[:5] == 'http:':
+                        proxies['http'] = proxyServer
+                    else:
+                        proxies['http'] = 'http://%s' % proxyServer
+                        proxies['ftp'] = 'ftp://%s' % proxyServer
+            internetSettings.Close()
+        except (WindowsError, ValueError, TypeError):
+            # Either registry key not found etc, or the value in an
+            # unexpected format.
+            # proxies already set up to be empty so nothing to do
+            pass
+        return proxies
+
+    def getproxies():
+        """Return a dictionary of scheme -> proxy server URL mappings.
+
+        Returns settings gathered from the environment, if specified,
+        or the registry.
+
+        """
+        return getproxies_environment() or getproxies_registry()
+
+    def proxy_bypass_registry(host):
+        try:
+            import _winreg
+            import re
+        except ImportError:
+            # Std modules, so should be around - but you never know!
+            return 0
+        try:
+            internetSettings = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER,
+                r'Software\Microsoft\Windows\CurrentVersion\Internet Settings')
+            proxyEnable = _winreg.QueryValueEx(internetSettings,
+                                               'ProxyEnable')[0]
+            proxyOverride = str(_winreg.QueryValueEx(internetSettings,
+                                                     'ProxyOverride')[0])
+            # ^^^^ Returned as Unicode but problems if not converted to ASCII
+        except WindowsError:
+            return 0
+        if not proxyEnable or not proxyOverride:
+            return 0
+        # try to make a host list from name and IP address.
+        rawHost, port = urllib.parse.splitport(host)
+        host = [rawHost]
+        try:
+            addr = socket.gethostbyname(rawHost)
+            if addr != rawHost:
+                host.append(addr)
+        except socket.error:
+            pass
+        try:
+            fqdn = socket.getfqdn(rawHost)
+            if fqdn != rawHost:
+                host.append(fqdn)
+        except socket.error:
+            pass
+        # make a check value list from the registry entry: replace the
+        # '<local>' string by the localhost entry and the corresponding
+        # canonical entry.
+        proxyOverride = proxyOverride.split(';')
+        i = 0
+        while i < len(proxyOverride):
+            if proxyOverride[i] == '<local>':
+                proxyOverride[i:i+1] = ['localhost',
+                                        '127.0.0.1',
+                                        socket.gethostname(),
+                                        socket.gethostbyname(
+                                            socket.gethostname())]
+            i += 1
+        # print proxyOverride
+        # now check if we match one of the registry values.
+        for test in proxyOverride:
+            test = test.replace(".", r"\.")     # mask dots
+            test = test.replace("*", r".*")     # change glob sequence
+            test = test.replace("?", r".")      # change glob char
+            for val in host:
+                # print "%s <--> %s" %( test, val )
+                if re.match(test, val, re.I):
+                    return 1
+        return 0
+
+    def proxy_bypass(host):
+        """Return a dictionary of scheme -> proxy server URL mappings.
+
+        Returns settings gathered from the environment, if specified,
+        or the registry.
+
+        """
+        if getproxies_environment():
+            return proxy_bypass_environment(host)
+        else:
+            return proxy_bypass_registry(host)
+
+else:
+    # By default use environment variables
+    getproxies = getproxies_environment
+    proxy_bypass = proxy_bypass_environment

Added: python/branches/py3k-urllib/Lib/urllib/response.py
==============================================================================
--- (empty file)
+++ python/branches/py3k-urllib/Lib/urllib/response.py	Tue Jun 17 23:01:35 2008
@@ -0,0 +1,83 @@
+"""Response classes used by urllib.
+
+The base class, addbase, defines a minimal file-like interface,
+including read() and readline().  The typical response object is an
+addinfourl instance, which defines an info() method that returns
+headers and a geturl() method that returns the url.
+"""
+
+class addbase(object):
+    """Base class for addinfo and addclosehook."""
+
+    # XXX Add a method to expose the timeout on the underlying socket?
+
+    def __init__(self, fp):
+        # TODO(jhylton): Is there a better way to delegate using io?
+        self.fp = fp
+        self.read = self.fp.read
+        self.readline = self.fp.readline
+        # TODO(jhylton): Make sure an object with readlines() is also iterable
+        if hasattr(self.fp, "readlines"): self.readlines = self.fp.readlines
+        if hasattr(self.fp, "fileno"):
+            self.fileno = self.fp.fileno
+        else:
+            self.fileno = lambda: None
+        if hasattr(self.fp, "__iter__"):
+            self.__iter__ = self.fp.__iter__
+            if hasattr(self.fp, "__next__"):
+                self.__next__ = self.fp.__next__
+
+    def __repr__(self):
+        return '<%s at %r whose fp = %r>' % (self.__class__.__name__,
+                                             id(self), self.fp)
+
+    def close(self):
+        self.read = None
+        self.readline = None
+        self.readlines = None
+        self.fileno = None
+        if self.fp: self.fp.close()
+        self.fp = None
+
+class addclosehook(addbase):
+    """Class to add a close hook to an open file."""
+
+    def __init__(self, fp, closehook, *hookargs):
+        addbase.__init__(self, fp)
+        self.closehook = closehook
+        self.hookargs = hookargs
+
+    def close(self):
+        addbase.close(self)
+        if self.closehook:
+            self.closehook(*self.hookargs)
+            self.closehook = None
+            self.hookargs = None
+
+class addinfo(addbase):
+    """class to add an info() method to an open file."""
+
+    def __init__(self, fp, headers):
+        addbase.__init__(self, fp)
+        self.headers = headers
+
+    def info(self):
+        return self.headers
+
+class addinfourl(addbase):
+    """class to add info() and geturl() methods to an open file."""
+
+    def __init__(self, fp, headers, url, code=None):
+        addbase.__init__(self, fp)
+        self.headers = headers
+        self.url = url
+        self.code = code
+
+    def info(self):
+        return self.headers
+
+    def getcode(self):
+        return self.code
+
+    def geturl(self):
+        return self.url

Copied: python/branches/py3k-urllib/Lib/urllib/robotparser.py (from r64345, /python/branches/py3k-urllib/Lib/robotparser.py)
==============================================================================
--- /python/branches/py3k-urllib/Lib/robotparser.py	(original)
+++ python/branches/py3k-urllib/Lib/urllib/robotparser.py	Tue Jun 17 23:01:35 2008
@@ -9,8 +9,8 @@
     The robots.txt Exclusion Protocol is implemented as specified in
     http://info.webcrawler.com/mak/projects/robots/norobots-rfc.html
 """
-import urlparse
-import urllib
+
+import urllib.parse, urllib.request
 
 __all__ = ["RobotFileParser"]
 
@@ -48,24 +48,19 @@
     def set_url(self, url):
         """Sets the URL referring to a robots.txt file."""
         self.url = url
-        self.host, self.path = urlparse.urlparse(url)[1:3]
+        self.host, self.path = urllib.parse.urlparse(url)[1:3]
 
     def read(self):
         """Reads the robots.txt URL and feeds it to the parser."""
-        opener = URLopener()
-        f = opener.open(self.url)
-        lines = []
-        line = f.readline()
-        while line:
-            lines.append(line.strip())
-            line = f.readline()
-        self.errcode = opener.errcode
-        if self.errcode in (401, 403):
-            self.disallow_all = True
-        elif self.errcode >= 400:
-            self.allow_all = True
-        elif self.errcode == 200 and lines:
-            self.parse(lines)
+        try:
+            f = urllib.request.urlopen(self.url)
+        except urllib.error.HTTPError as err:
+            if err.code in (401, 403):
+                self.disallow_all = True
+            elif err.code >= 400:
+                self.allow_all = True
+        else:
+            self.parse(f.read().splitlines())
 
     def _add_entry(self, entry):
         if "*" in entry.useragents:
@@ -75,15 +70,15 @@
             self.entries.append(entry)
 
     def parse(self, lines):
-        """parse the input lines from a robots.txt file.
-           We allow that a user-agent: line is not preceded by
-           one or more blank lines."""
+        """Parse the input lines from a robots.txt file.
+
+        We allow that a user-agent: line is not preceded by
+        one or more blank lines.
+        """
         state = 0
-        linenumber = 0
         entry = Entry()
 
         for line in lines:
-            linenumber = linenumber + 1
             if not line:
                 if state == 1:
                     entry = Entry()
@@ -102,7 +97,7 @@
             line = line.split(':', 1)
             if len(line) == 2:
                 line[0] = line[0].strip().lower()
-                line[1] = urllib.unquote(line[1].strip())
+                line[1] = urllib.parse.unquote(line[1].strip())
                 if line[0] == "user-agent":
                     if state == 2:
                         self._add_entry(entry)
@@ -128,7 +123,7 @@
             return True
         # search for given user agent matches
         # the first match counts
-        url = urllib.quote(urlparse.urlparse(urllib.unquote(url))[2]) or "/"
+        url = urllib.parse.quote(urllib.parse.urlparse(urllib.parse.unquote(url))[2]) or "/"
         for entry in self.entries:
             if entry.applies_to(useragent):
                 return entry.allowance(url)
@@ -138,7 +133,6 @@
         # agent not found ==> access granted
         return True
 
-
     def __str__(self):
         return ''.join([str(entry) + "\n" for entry in self.entries])
 
@@ -150,7 +144,7 @@
         if path == '' and not allowance:
             # an empty value means allow all
             allowance = True
-        self.path = urllib.quote(path)
+        self.path = urllib.parse.quote(path)
         self.allowance = allowance
 
     def applies_to(self, filename):
@@ -195,18 +189,3 @@
             if line.applies_to(filename):
                 return line.allowance
         return True
-
-class URLopener(urllib.FancyURLopener):
-    def __init__(self, *args):
-        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,
-                                                        errmsg, headers)

Deleted: python/branches/py3k-urllib/Lib/urllib2.py
==============================================================================
--- python/branches/py3k-urllib/Lib/urllib2.py	Tue Jun 17 23:01:35 2008
+++ (empty file)
@@ -1,1351 +0,0 @@
-"""An extensible library for opening URLs using a variety of protocols
-
-The simplest way to use this module is to call the urlopen function,
-which accepts a string containing a URL or a Request object (described
-below).  It opens the URL and returns the results as file-like
-object; the returned object has some extra methods described below.
-
-The OpenerDirector manages a collection of Handler objects that do
-all the actual work.  Each Handler implements a particular protocol or
-option.  The OpenerDirector is a composite object that invokes the
-Handlers needed to open the requested URL.  For example, the
-HTTPHandler performs HTTP GET and POST requests and deals with
-non-error returns.  The HTTPRedirectHandler automatically deals with
-HTTP 301, 302, 303 and 307 redirect errors, and the HTTPDigestAuthHandler
-deals with digest authentication.
-
-urlopen(url, data=None) -- Basic usage is the same as original
-urllib.  pass the url and optionally data to post to an HTTP URL, and
-get a file-like object back.  One difference is that you can also pass
-a Request instance instead of URL.  Raises a URLError (subclass of
-IOError); for HTTP errors, raises an HTTPError, which can also be
-treated as a valid response.
-
-build_opener -- Function that creates a new OpenerDirector instance.
-Will install the default handlers.  Accepts one or more Handlers as
-arguments, either instances or Handler classes that it will
-instantiate.  If one of the argument is a subclass of the default
-handler, the argument will be installed instead of the default.
-
-install_opener -- Installs a new opener as the default opener.
-
-objects of interest:
-OpenerDirector --
-
-Request -- An object that encapsulates the state of a request.  The
-state can be as simple as the URL.  It can also include extra HTTP
-headers, e.g. a User-Agent.
-
-BaseHandler --
-
-exceptions:
-URLError -- A subclass of IOError, individual protocols have their own
-specific subclass.
-
-HTTPError -- Also a valid HTTP response, so you can treat an HTTP error
-as an exceptional event or valid response.
-
-internals:
-BaseHandler and parent
-_call_chain conventions
-
-Example usage:
-
-import urllib2
-
-# set up authentication info
-authinfo = urllib2.HTTPBasicAuthHandler()
-authinfo.add_password(realm='PDQ Application',
-                      uri='https://mahler:8092/site-updates.py',
-                      user='klem',
-                      passwd='geheim$parole')
-
-proxy_support = urllib2.ProxyHandler({"http" : "http://ahad-haam:3128"})
-
-# build a new opener that adds authentication and caching FTP handlers
-opener = urllib2.build_opener(proxy_support, authinfo, urllib2.CacheFTPHandler)
-
-# install it
-urllib2.install_opener(opener)
-
-f = urllib2.urlopen('http://www.python.org/')
-
-
-"""
-
-# XXX issues:
-# If an authentication error handler that tries to perform
-# authentication for some reason but fails, how should the error be
-# signalled?  The client needs to know the HTTP error code.  But if
-# the handler knows that the problem was, e.g., that it didn't know
-# that hash algo that requested in the challenge, it would be good to
-# pass that information along to the client, too.
-# ftp errors aren't handled cleanly
-# check digest against correct (i.e. non-apache) implementation
-
-# Possible extensions:
-# complex proxies  XXX not sure what exactly was meant by this
-# abstract factory for opener
-
-import base64
-import hashlib
-import http.client
-import io
-import email
-import os
-import posixpath
-import random
-import re
-import socket
-import sys
-import time
-import urlparse
-import bisect
-
-from io import StringIO
-
-from urllib import (unwrap, unquote, splittype, splithost, quote,
-     addinfourl, splitport, splitquery,
-     splitattr, ftpwrapper, noheaders, splituser, splitpasswd, splitvalue)
-
-# support for FileHandler, proxies via environment variables
-from urllib import localhost, url2pathname, getproxies
-
-# used in User-Agent header sent
-__version__ = sys.version[:3]
-
-_opener = None
-def urlopen(url, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
-    global _opener
-    if _opener is None:
-        _opener = build_opener()
-    return _opener.open(url, data, timeout)
-
-def install_opener(opener):
-    global _opener
-    _opener = opener
-
-# do these error classes make sense?
-# make sure all of the IOError stuff is overridden.  we just want to be
-# subtypes.
-
-class URLError(IOError):
-    # URLError is a sub-type of IOError, but it doesn't share any of
-    # the implementation.  need to override __init__ and __str__.
-    # It sets self.args for compatibility with other EnvironmentError
-    # subclasses, but args doesn't have the typical format with errno in
-    # slot 0 and strerror in slot 1.  This may be better than nothing.
-    def __init__(self, reason):
-        self.args = reason,
-        self.reason = reason
-
-    def __str__(self):
-        return '<urlopen error %s>' % self.reason
-
-class HTTPError(URLError, addinfourl):
-    """Raised when HTTP error occurs, but also acts like non-error return"""
-    __super_init = addinfourl.__init__
-
-    def __init__(self, url, code, msg, hdrs, fp):
-        self.code = code
-        self.msg = msg
-        self.hdrs = hdrs
-        self.fp = fp
-        self.filename = url
-        # The addinfourl classes depend on fp being a valid file
-        # object.  In some cases, the HTTPError may not have a valid
-        # file object.  If this happens, the simplest workaround is to
-        # not initialize the base classes.
-        if fp is not None:
-            self.__super_init(fp, hdrs, url, code)
-
-    def __str__(self):
-        return 'HTTP Error %s: %s' % (self.code, self.msg)
-
-# copied from cookielib.py
-_cut_port_re = re.compile(r":\d+$")
-def request_host(request):
-    """Return request-host, as defined by RFC 2965.
-
-    Variation from RFC: returned value is lowercased, for convenient
-    comparison.
-
-    """
-    url = request.get_full_url()
-    host = urlparse.urlparse(url)[1]
-    if host == "":
-        host = request.get_header("Host", "")
-
-    # remove port, if present
-    host = _cut_port_re.sub("", host, 1)
-    return host.lower()
-
-class Request:
-
-    def __init__(self, url, data=None, headers={},
-                 origin_req_host=None, unverifiable=False):
-        # unwrap('<URL:type://host/path>') --> 'type://host/path'
-        self.__original = unwrap(url)
-        self.type = None
-        # self.__r_type is what's left after doing the splittype
-        self.host = None
-        self.port = None
-        self.data = data
-        self.headers = {}
-        for key, value in headers.items():
-            self.add_header(key, value)
-        self.unredirected_hdrs = {}
-        if origin_req_host is None:
-            origin_req_host = request_host(self)
-        self.origin_req_host = origin_req_host
-        self.unverifiable = unverifiable
-
-    def __getattr__(self, attr):
-        # XXX this is a fallback mechanism to guard against these
-        # methods getting called in a non-standard order.  this may be
-        # too complicated and/or unnecessary.
-        # XXX should the __r_XXX attributes be public?
-        if attr[:12] == '_Request__r_':
-            name = attr[12:]
-            if hasattr(Request, 'get_' + name):
-                getattr(self, 'get_' + name)()
-                return getattr(self, attr)
-        raise AttributeError(attr)
-
-    def get_method(self):
-        if self.has_data():
-            return "POST"
-        else:
-            return "GET"
-
-    # XXX these helper methods are lame
-
-    def add_data(self, data):
-        self.data = data
-
-    def has_data(self):
-        return self.data is not None
-
-    def get_data(self):
-        return self.data
-
-    def get_full_url(self):
-        return self.__original
-
-    def get_type(self):
-        if self.type is None:
-            self.type, self.__r_type = splittype(self.__original)
-            if self.type is None:
-                raise ValueError("unknown url type: %s" % self.__original)
-        return self.type
-
-    def get_host(self):
-        if self.host is None:
-            self.host, self.__r_host = splithost(self.__r_type)
-            if self.host:
-                self.host = unquote(self.host)
-        return self.host
-
-    def get_selector(self):
-        return self.__r_host
-
-    def set_proxy(self, host, type):
-        self.host, self.type = host, type
-        self.__r_host = self.__original
-
-    def get_origin_req_host(self):
-        return self.origin_req_host
-
-    def is_unverifiable(self):
-        return self.unverifiable
-
-    def add_header(self, key, val):
-        # useful for something like authentication
-        self.headers[key.capitalize()] = val
-
-    def add_unredirected_header(self, key, val):
-        # will not be added to a redirected request
-        self.unredirected_hdrs[key.capitalize()] = val
-
-    def has_header(self, header_name):
-        return (header_name in self.headers or
-                header_name in self.unredirected_hdrs)
-
-    def get_header(self, header_name, default=None):
-        return self.headers.get(
-            header_name,
-            self.unredirected_hdrs.get(header_name, default))
-
-    def header_items(self):
-        hdrs = self.unredirected_hdrs.copy()
-        hdrs.update(self.headers)
-        return list(hdrs.items())
-
-class OpenerDirector:
-    def __init__(self):
-        client_version = "Python-urllib/%s" % __version__
-        self.addheaders = [('User-agent', client_version)]
-        # manage the individual handlers
-        self.handlers = []
-        self.handle_open = {}
-        self.handle_error = {}
-        self.process_response = {}
-        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"]:
-                # oops, coincidental match
-                continue
-
-            i = meth.find("_")
-            protocol = meth[:i]
-            condition = meth[i+1:]
-
-            if condition.startswith("error"):
-                j = condition.find("_") + i + 1
-                kind = meth[j+1:]
-                try:
-                    kind = int(kind)
-                except ValueError:
-                    pass
-                lookup = self.handle_error.get(protocol, {})
-                self.handle_error[protocol] = lookup
-            elif condition == "open":
-                kind = protocol
-                lookup = self.handle_open
-            elif condition == "response":
-                kind = protocol
-                lookup = self.process_response
-            elif condition == "request":
-                kind = protocol
-                lookup = self.process_request
-            else:
-                continue
-
-            handlers = lookup.setdefault(kind, [])
-            if handlers:
-                bisect.insort(handlers, handler)
-            else:
-                handlers.append(handler)
-            added = True
-
-        if added:
-            # the handlers must work in an specific order, the order
-            # is specified in a Handler attribute
-            bisect.insort(self.handlers, handler)
-            handler.add_parent(self)
-
-    def close(self):
-        # Only exists for backwards compatibility.
-        pass
-
-    def _call_chain(self, chain, kind, meth_name, *args):
-        # Handlers raise an exception if no one else should try to handle
-        # the request, or return None if they can't but another handler
-        # could.  Otherwise, they return the response.
-        handlers = chain.get(kind, ())
-        for handler in handlers:
-            func = getattr(handler, meth_name)
-
-            result = func(*args)
-            if result is not None:
-                return result
-
-    def open(self, fullurl, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
-        # accept a URL or a Request object
-        if isinstance(fullurl, str):
-            req = Request(fullurl, data)
-        else:
-            req = fullurl
-            if data is not None:
-                req.add_data(data)
-
-        req.timeout = timeout
-        protocol = req.get_type()
-
-        # pre-process request
-        meth_name = protocol+"_request"
-        for processor in self.process_request.get(protocol, []):
-            meth = getattr(processor, meth_name)
-            req = meth(req)
-
-        response = self._open(req, data)
-
-        # post-process response
-        meth_name = protocol+"_response"
-        for processor in self.process_response.get(protocol, []):
-            meth = getattr(processor, meth_name)
-            response = meth(req, response)
-
-        return response
-
-    def _open(self, req, data=None):
-        result = self._call_chain(self.handle_open, 'default',
-                                  'default_open', req)
-        if result:
-            return result
-
-        protocol = req.get_type()
-        result = self._call_chain(self.handle_open, protocol, protocol +
-                                  '_open', req)
-        if result:
-            return result
-
-        return self._call_chain(self.handle_open, 'unknown',
-                                'unknown_open', req)
-
-    def error(self, proto, *args):
-        if proto in ('http', 'https'):
-            # XXX http[s] protocols are special-cased
-            dict = self.handle_error['http'] # https is not different than http
-            proto = args[2]  # YUCK!
-            meth_name = 'http_error_%s' % proto
-            http_err = 1
-            orig_args = args
-        else:
-            dict = self.handle_error
-            meth_name = proto + '_error'
-            http_err = 0
-        args = (dict, proto, meth_name) + args
-        result = self._call_chain(*args)
-        if result:
-            return result
-
-        if http_err:
-            args = (dict, 'default', 'http_error_default') + orig_args
-            return self._call_chain(*args)
-
-# XXX probably also want an abstract factory that knows when it makes
-# sense to skip a superclass in favor of a subclass and when it might
-# make sense to include both
-
-def build_opener(*handlers):
-    """Create an opener object from a list of handlers.
-
-    The opener will use several default handlers, including support
-    for HTTP and FTP.
-
-    If any of the handlers passed as arguments are subclasses of the
-    default handlers, the default handlers will not be used.
-    """
-    def isclass(obj):
-        return isinstance(obj, type) or hasattr(obj, "__bases__")
-
-    opener = OpenerDirector()
-    default_classes = [ProxyHandler, UnknownHandler, HTTPHandler,
-                       HTTPDefaultErrorHandler, HTTPRedirectHandler,
-                       FTPHandler, FileHandler, HTTPErrorProcessor]
-    if hasattr(http.client, 'HTTPS'):
-        default_classes.append(HTTPSHandler)
-    skip = set()
-    for klass in default_classes:
-        for check in handlers:
-            if isclass(check):
-                if issubclass(check, klass):
-                    skip.add(klass)
-            elif isinstance(check, klass):
-                skip.add(klass)
-    for klass in skip:
-        default_classes.remove(klass)
-
-    for klass in default_classes:
-        opener.add_handler(klass())
-
-    for h in handlers:
-        if isclass(h):
-            h = h()
-        opener.add_handler(h)
-    return opener
-
-class BaseHandler:
-    handler_order = 500
-
-    def add_parent(self, parent):
-        self.parent = parent
-
-    def close(self):
-        # Only exists for backwards compatibility
-        pass
-
-    def __lt__(self, other):
-        if not hasattr(other, "handler_order"):
-            # Try to preserve the old behavior of having custom classes
-            # inserted after default ones (works only for custom user
-            # classes which are not aware of handler_order).
-            return True
-        return self.handler_order < other.handler_order
-
-
-class HTTPErrorProcessor(BaseHandler):
-    """Process HTTP error responses."""
-    handler_order = 1000  # after all other processing
-
-    def http_response(self, request, response):
-        code, msg, hdrs = response.code, response.msg, response.info()
-
-        # According to RFC 2616, "2xx" code indicates that the client's
-        # request was successfully received, understood, and accepted.
-        if not (200 <= code < 300):
-            response = self.parent.error(
-                'http', request, response, code, msg, hdrs)
-
-        return response
-
-    https_response = http_response
-
-class HTTPDefaultErrorHandler(BaseHandler):
-    def http_error_default(self, req, fp, code, msg, hdrs):
-        raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
-
-class HTTPRedirectHandler(BaseHandler):
-    # maximum number of redirections to any single URL
-    # this is needed because of the state that cookies introduce
-    max_repeats = 4
-    # maximum total number of redirections (regardless of URL) before
-    # assuming we're in a loop
-    max_redirections = 10
-
-    def redirect_request(self, req, fp, code, msg, headers, newurl):
-        """Return a Request or None in response to a redirect.
-
-        This is called by the http_error_30x methods when a
-        redirection response is received.  If a redirection should
-        take place, return a new Request to allow http_error_30x to
-        perform the redirect.  Otherwise, raise HTTPError if no-one
-        else should try to handle this url.  Return None if you can't
-        but another Handler might.
-        """
-        m = req.get_method()
-        if (code in (301, 302, 303, 307) and m in ("GET", "HEAD")
-            or code in (301, 302, 303) and m == "POST"):
-            # Strictly (according to RFC 2616), 301 or 302 in response
-            # to a POST MUST NOT cause a redirection without confirmation
-            # from the user (of urllib2, in this case).  In practice,
-            # essentially all clients do redirect in this case, so we
-            # do the same.
-            # be conciliant with URIs containing a space
-            newurl = newurl.replace(' ', '%20')
-            newheaders = dict((k,v) for k,v in req.headers.items()
-                              if k.lower() not in ("content-length", "content-type")
-                             )
-            return Request(newurl,
-                           headers=newheaders,
-                           origin_req_host=req.get_origin_req_host(),
-                           unverifiable=True)
-        else:
-            raise HTTPError(req.get_full_url(), code, msg, headers, fp)
-
-    # Implementation note: To avoid the server sending us into an
-    # infinite loop, the request object needs to track what URLs we
-    # have already seen.  Do this by adding a handler-specific
-    # attribute to the Request object.
-    def http_error_302(self, req, fp, code, msg, headers):
-        # Some servers (incorrectly) return multiple Location headers
-        # (so probably same goes for URI).  Use first header.
-        if 'location' in headers:
-            newurl = headers['location']
-        elif 'uri' in headers:
-            newurl = headers['uri']
-        else:
-            return
-        newurl = urlparse.urljoin(req.get_full_url(), newurl)
-
-        # XXX Probably want to forget about the state of the current
-        # request, although that might interact poorly with other
-        # handlers that also use handler-specific request attributes
-        new = self.redirect_request(req, fp, code, msg, headers, newurl)
-        if new is None:
-            return
-
-        # loop detection
-        # .redirect_dict has a key url if url was previously visited.
-        if hasattr(req, 'redirect_dict'):
-            visited = new.redirect_dict = req.redirect_dict
-            if (visited.get(newurl, 0) >= self.max_repeats or
-                len(visited) >= self.max_redirections):
-                raise HTTPError(req.get_full_url(), code,
-                                self.inf_msg + msg, headers, fp)
-        else:
-            visited = new.redirect_dict = req.redirect_dict = {}
-        visited[newurl] = visited.get(newurl, 0) + 1
-
-        # Don't close the fp until we are sure that we won't use it
-        # with HTTPError.
-        fp.read()
-        fp.close()
-
-        return self.parent.open(new)
-
-    http_error_301 = http_error_303 = http_error_307 = http_error_302
-
-    inf_msg = "The HTTP server returned a redirect error that would " \
-              "lead to an infinite loop.\n" \
-              "The last 30x error message was:\n"
-
-
-def _parse_proxy(proxy):
-    """Return (scheme, user, password, host/port) given a URL or an authority.
-
-    If a URL is supplied, it must have an authority (host:port) component.
-    According to RFC 3986, having an authority component means the URL must
-    have two slashes after the scheme:
-
-    >>> _parse_proxy('file:/ftp.example.com/')
-    Traceback (most recent call last):
-    ValueError: proxy URL with no authority: 'file:/ftp.example.com/'
-
-    The first three items of the returned tuple may be None.
-
-    Examples of authority parsing:
-
-    >>> _parse_proxy('proxy.example.com')
-    (None, None, None, 'proxy.example.com')
-    >>> _parse_proxy('proxy.example.com:3128')
-    (None, None, None, 'proxy.example.com:3128')
-
-    The authority component may optionally include userinfo (assumed to be
-    username:password):
-
-    >>> _parse_proxy('joe:password at proxy.example.com')
-    (None, 'joe', 'password', 'proxy.example.com')
-    >>> _parse_proxy('joe:password at proxy.example.com:3128')
-    (None, 'joe', 'password', 'proxy.example.com:3128')
-
-    Same examples, but with URLs instead:
-
-    >>> _parse_proxy('http://proxy.example.com/')
-    ('http', None, None, 'proxy.example.com')
-    >>> _parse_proxy('http://proxy.example.com:3128/')
-    ('http', None, None, 'proxy.example.com:3128')
-    >>> _parse_proxy('http://joe:password at proxy.example.com/')
-    ('http', 'joe', 'password', 'proxy.example.com')
-    >>> _parse_proxy('http://joe:password at proxy.example.com:3128')
-    ('http', 'joe', 'password', 'proxy.example.com:3128')
-
-    Everything after the authority is ignored:
-
-    >>> _parse_proxy('ftp://joe:password at proxy.example.com/rubbish:3128')
-    ('ftp', 'joe', 'password', 'proxy.example.com')
-
-    Test for no trailing '/' case:
-
-    >>> _parse_proxy('http://joe:password at proxy.example.com')
-    ('http', 'joe', 'password', 'proxy.example.com')
-
-    """
-    scheme, r_scheme = splittype(proxy)
-    if not r_scheme.startswith("/"):
-        # authority
-        scheme = None
-        authority = proxy
-    else:
-        # URL
-        if not r_scheme.startswith("//"):
-            raise ValueError("proxy URL with no authority: %r" % proxy)
-        # We have an authority, so for RFC 3986-compliant URLs (by ss 3.
-        # and 3.3.), path is empty or starts with '/'
-        end = r_scheme.find("/", 2)
-        if end == -1:
-            end = None
-        authority = r_scheme[2:end]
-    userinfo, hostport = splituser(authority)
-    if userinfo is not None:
-        user, password = splitpasswd(userinfo)
-    else:
-        user = password = None
-    return scheme, user, password, hostport
-
-class ProxyHandler(BaseHandler):
-    # Proxies must be in front
-    handler_order = 100
-
-    def __init__(self, proxies=None):
-        if proxies is None:
-            proxies = getproxies()
-        assert hasattr(proxies, 'keys'), "proxies must be a mapping"
-        self.proxies = proxies
-        for type, url in proxies.items():
-            setattr(self, '%s_open' % type,
-                    lambda r, proxy=url, type=type, meth=self.proxy_open: \
-                    meth(r, proxy, type))
-
-    def proxy_open(self, req, proxy, type):
-        orig_type = req.get_type()
-        proxy_type, user, password, hostport = _parse_proxy(proxy)
-        if proxy_type is None:
-            proxy_type = orig_type
-        if user and password:
-            user_pass = '%s:%s' % (unquote(user), unquote(password))
-            creds = base64.b64encode(user_pass.encode()).decode("ascii")
-            req.add_header('Proxy-authorization', 'Basic ' + creds)
-        hostport = unquote(hostport)
-        req.set_proxy(hostport, proxy_type)
-        if orig_type == proxy_type:
-            # let other handlers take care of it
-            return None
-        else:
-            # need to start over, because the other handlers don't
-            # grok the proxy's URL type
-            # e.g. if we have a constructor arg proxies like so:
-            # {'http': 'ftp://proxy.example.com'}, we may end up turning
-            # a request for http://acme.example.com/a into one for
-            # ftp://proxy.example.com/a
-            return self.parent.open(req)
-
-class HTTPPasswordMgr:
-
-    def __init__(self):
-        self.passwd = {}
-
-    def add_password(self, realm, uri, user, passwd):
-        # uri could be a single URI or a sequence
-        if isinstance(uri, str):
-            uri = [uri]
-        if not realm in self.passwd:
-            self.passwd[realm] = {}
-        for default_port in True, False:
-            reduced_uri = tuple(
-                [self.reduce_uri(u, default_port) for u in uri])
-            self.passwd[realm][reduced_uri] = (user, passwd)
-
-    def find_user_password(self, realm, authuri):
-        domains = self.passwd.get(realm, {})
-        for default_port in True, False:
-            reduced_authuri = self.reduce_uri(authuri, default_port)
-            for uris, authinfo in domains.items():
-                for uri in uris:
-                    if self.is_suburi(uri, reduced_authuri):
-                        return authinfo
-        return None, None
-
-    def reduce_uri(self, uri, default_port=True):
-        """Accept authority or URI and extract only the authority and path."""
-        # note HTTP URLs do not have a userinfo component
-        parts = urlparse.urlsplit(uri)
-        if parts[1]:
-            # URI
-            scheme = parts[0]
-            authority = parts[1]
-            path = parts[2] or '/'
-        else:
-            # host or host:port
-            scheme = None
-            authority = uri
-            path = '/'
-        host, port = splitport(authority)
-        if default_port and port is None and scheme is not None:
-            dport = {"http": 80,
-                     "https": 443,
-                     }.get(scheme)
-            if dport is not None:
-                authority = "%s:%d" % (host, dport)
-        return authority, path
-
-    def is_suburi(self, base, test):
-        """Check if test is below base in a URI tree
-
-        Both args must be URIs in reduced form.
-        """
-        if base == test:
-            return True
-        if base[0] != test[0]:
-            return False
-        common = posixpath.commonprefix((base[1], test[1]))
-        if len(common) == len(base[1]):
-            return True
-        return False
-
-
-class HTTPPasswordMgrWithDefaultRealm(HTTPPasswordMgr):
-
-    def find_user_password(self, realm, authuri):
-        user, password = HTTPPasswordMgr.find_user_password(self, realm,
-                                                            authuri)
-        if user is not None:
-            return user, password
-        return HTTPPasswordMgr.find_user_password(self, None, authuri)
-
-
-class AbstractBasicAuthHandler:
-
-    # XXX this allows for multiple auth-schemes, but will stupidly pick
-    # the last one with a realm specified.
-
-    # allow for double- and single-quoted realm values
-    # (single quotes are a violation of the RFC, but appear in the wild)
-    rx = re.compile('(?:.*,)*[ \t]*([^ \t]+)[ \t]+'
-                    'realm=(["\'])(.*?)\\2', re.I)
-
-    # XXX could pre-emptively send auth info already accepted (RFC 2617,
-    # end of section 2, and section 1.2 immediately after "credentials"
-    # production).
-
-    def __init__(self, password_mgr=None):
-        if password_mgr is None:
-            password_mgr = HTTPPasswordMgr()
-        self.passwd = password_mgr
-        self.add_password = self.passwd.add_password
-
-    def http_error_auth_reqed(self, authreq, host, req, headers):
-        # host may be an authority (without userinfo) or a URL with an
-        # authority
-        # XXX could be multiple headers
-        authreq = headers.get(authreq, None)
-        if authreq:
-            mo = AbstractBasicAuthHandler.rx.search(authreq)
-            if mo:
-                scheme, quote, realm = mo.groups()
-                if scheme.lower() == 'basic':
-                    return self.retry_http_basic_auth(host, req, realm)
-
-    def retry_http_basic_auth(self, host, req, realm):
-        user, pw = self.passwd.find_user_password(realm, host)
-        if pw is not None:
-            raw = "%s:%s" % (user, pw)
-            auth = "Basic " + base64.b64encode(raw.encode()).decode("ascii")
-            if req.headers.get(self.auth_header, None) == auth:
-                return None
-            req.add_header(self.auth_header, auth)
-            return self.parent.open(req)
-        else:
-            return None
-
-
-class HTTPBasicAuthHandler(AbstractBasicAuthHandler, BaseHandler):
-
-    auth_header = 'Authorization'
-
-    def http_error_401(self, req, fp, code, msg, headers):
-        url = req.get_full_url()
-        return self.http_error_auth_reqed('www-authenticate',
-                                          url, req, headers)
-
-
-class ProxyBasicAuthHandler(AbstractBasicAuthHandler, BaseHandler):
-
-    auth_header = 'Proxy-authorization'
-
-    def http_error_407(self, req, fp, code, msg, headers):
-        # http_error_auth_reqed requires that there is no userinfo component in
-        # authority.  Assume there isn't one, since urllib2 does not (and
-        # should not, RFC 3986 s. 3.2.1) support requests for URLs containing
-        # userinfo.
-        authority = req.get_host()
-        return self.http_error_auth_reqed('proxy-authenticate',
-                                          authority, req, headers)
-
-
-def randombytes(n):
-    """Return n random bytes."""
-    return os.urandom(n)
-
-class AbstractDigestAuthHandler:
-    # Digest authentication is specified in RFC 2617.
-
-    # XXX The client does not inspect the Authentication-Info header
-    # in a successful response.
-
-    # XXX It should be possible to test this implementation against
-    # a mock server that just generates a static set of challenges.
-
-    # XXX qop="auth-int" supports is shaky
-
-    def __init__(self, passwd=None):
-        if passwd is None:
-            passwd = HTTPPasswordMgr()
-        self.passwd = passwd
-        self.add_password = self.passwd.add_password
-        self.retried = 0
-        self.nonce_count = 0
-
-    def reset_retry_count(self):
-        self.retried = 0
-
-    def http_error_auth_reqed(self, auth_header, host, req, headers):
-        authreq = headers.get(auth_header, None)
-        if self.retried > 5:
-            # Don't fail endlessly - if we failed once, we'll probably
-            # fail a second time. Hm. Unless the Password Manager is
-            # prompting for the information. Crap. This isn't great
-            # but it's better than the current 'repeat until recursion
-            # depth exceeded' approach <wink>
-            raise HTTPError(req.get_full_url(), 401, "digest auth failed",
-                            headers, None)
-        else:
-            self.retried += 1
-        if authreq:
-            scheme = authreq.split()[0]
-            if scheme.lower() == 'digest':
-                return self.retry_http_digest_auth(req, authreq)
-
-    def retry_http_digest_auth(self, req, auth):
-        token, challenge = auth.split(' ', 1)
-        chal = parse_keqv_list(parse_http_list(challenge))
-        auth = self.get_authorization(req, chal)
-        if auth:
-            auth_val = 'Digest %s' % auth
-            if req.headers.get(self.auth_header, None) == auth_val:
-                return None
-            req.add_unredirected_header(self.auth_header, auth_val)
-            resp = self.parent.open(req)
-            return resp
-
-    def get_cnonce(self, nonce):
-        # The cnonce-value is an opaque
-        # quoted string value provided by the client and used by both client
-        # and server to avoid chosen plaintext attacks, to provide mutual
-        # authentication, and to provide some message integrity protection.
-        # This isn't a fabulous effort, but it's probably Good Enough.
-        s = "%s:%s:%s:" % (self.nonce_count, nonce, time.ctime())
-        b = s.encode("ascii") + randombytes(8)
-        dig = hashlib.sha1(b).hexdigest()
-        return dig[:16]
-
-    def get_authorization(self, req, chal):
-        try:
-            realm = chal['realm']
-            nonce = chal['nonce']
-            qop = chal.get('qop')
-            algorithm = chal.get('algorithm', 'MD5')
-            # mod_digest doesn't send an opaque, even though it isn't
-            # supposed to be optional
-            opaque = chal.get('opaque', None)
-        except KeyError:
-            return None
-
-        H, KD = self.get_algorithm_impls(algorithm)
-        if H is None:
-            return None
-
-        user, pw = self.passwd.find_user_password(realm, req.get_full_url())
-        if user is None:
-            return None
-
-        # XXX not implemented yet
-        if req.has_data():
-            entdig = self.get_entity_digest(req.get_data(), chal)
-        else:
-            entdig = None
-
-        A1 = "%s:%s:%s" % (user, realm, pw)
-        A2 = "%s:%s" % (req.get_method(),
-                        # XXX selector: what about proxies and full urls
-                        req.get_selector())
-        if qop == 'auth':
-            self.nonce_count += 1
-            ncvalue = '%08x' % self.nonce_count
-            cnonce = self.get_cnonce(nonce)
-            noncebit = "%s:%s:%s:%s:%s" % (nonce, ncvalue, cnonce, qop, H(A2))
-            respdig = KD(H(A1), noncebit)
-        elif qop is None:
-            respdig = KD(H(A1), "%s:%s" % (nonce, H(A2)))
-        else:
-            # XXX handle auth-int.
-            raise URLError("qop '%s' is not supported." % qop)
-
-        # XXX should the partial digests be encoded too?
-
-        base = 'username="%s", realm="%s", nonce="%s", uri="%s", ' \
-               'response="%s"' % (user, realm, nonce, req.get_selector(),
-                                  respdig)
-        if opaque:
-            base += ', opaque="%s"' % opaque
-        if entdig:
-            base += ', digest="%s"' % entdig
-        base += ', algorithm="%s"' % algorithm
-        if qop:
-            base += ', qop=auth, nc=%s, cnonce="%s"' % (ncvalue, cnonce)
-        return base
-
-    def get_algorithm_impls(self, algorithm):
-        # algorithm should be case-insensitive according to RFC2617
-        algorithm = algorithm.upper()
-        # lambdas assume digest modules are imported at the top level
-        if algorithm == 'MD5':
-            H = lambda x: hashlib.md5(x.encode("ascii")).hexdigest()
-        elif algorithm == 'SHA':
-            H = lambda x: hashlib.sha1(x.encode("ascii")).hexdigest()
-        # XXX MD5-sess
-        KD = lambda s, d: H("%s:%s" % (s, d))
-        return H, KD
-
-    def get_entity_digest(self, data, chal):
-        # XXX not implemented yet
-        return None
-
-
-class HTTPDigestAuthHandler(BaseHandler, AbstractDigestAuthHandler):
-    """An authentication protocol defined by RFC 2069
-
-    Digest authentication improves on basic authentication because it
-    does not transmit passwords in the clear.
-    """
-
-    auth_header = 'Authorization'
-    handler_order = 490  # before Basic auth
-
-    def http_error_401(self, req, fp, code, msg, headers):
-        host = urlparse.urlparse(req.get_full_url())[1]
-        retry = self.http_error_auth_reqed('www-authenticate',
-                                           host, req, headers)
-        self.reset_retry_count()
-        return retry
-
-
-class ProxyDigestAuthHandler(BaseHandler, AbstractDigestAuthHandler):
-
-    auth_header = 'Proxy-Authorization'
-    handler_order = 490  # before Basic auth
-
-    def http_error_407(self, req, fp, code, msg, headers):
-        host = req.get_host()
-        retry = self.http_error_auth_reqed('proxy-authenticate',
-                                           host, req, headers)
-        self.reset_retry_count()
-        return retry
-
-class AbstractHTTPHandler(BaseHandler):
-
-    def __init__(self, debuglevel=0):
-        self._debuglevel = debuglevel
-
-    def set_http_debuglevel(self, level):
-        self._debuglevel = level
-
-    def do_request_(self, request):
-        host = request.get_host()
-        if not host:
-            raise URLError('no host given')
-
-        if request.has_data():  # POST
-            data = request.get_data()
-            if not request.has_header('Content-type'):
-                request.add_unredirected_header(
-                    'Content-type',
-                    'application/x-www-form-urlencoded')
-            if not request.has_header('Content-length'):
-                request.add_unredirected_header(
-                    'Content-length', '%d' % len(data))
-
-        scheme, sel = splittype(request.get_selector())
-        sel_host, sel_path = splithost(sel)
-        if not request.has_header('Host'):
-            request.add_unredirected_header('Host', sel_host or host)
-        for name, value in self.parent.addheaders:
-            name = name.capitalize()
-            if not request.has_header(name):
-                request.add_unredirected_header(name, value)
-
-        return request
-
-    def do_open(self, http_class, req):
-        """Return an addinfourl object for the request, using http_class.
-
-        http_class must implement the HTTPConnection API from http.client.
-        The addinfourl return value is a file-like object.  It also
-        has methods and attributes including:
-            - info(): return a email.message.Message object for the headers
-            - geturl(): return the original request URL
-            - code: HTTP status code
-        """
-        host = req.get_host()
-        if not host:
-            raise URLError('no host given')
-
-        h = http_class(host, timeout=req.timeout) # will parse host:port
-        h.set_debuglevel(self._debuglevel)
-
-        headers = dict(req.headers)
-        headers.update(req.unredirected_hdrs)
-        # We want to make an HTTP/1.1 request, but the addinfourl
-        # class isn't prepared to deal with a persistent connection.
-        # It will try to read all remaining data from the socket,
-        # which will block while the server waits for the next request.
-        # So make sure the connection gets closed after the (only)
-        # request.
-        headers["Connection"] = "close"
-        headers = dict(
-            (name.title(), val) for name, val in headers.items())
-        try:
-            h.request(req.get_method(), req.get_selector(), req.data, headers)
-            r = h.getresponse()
-        except socket.error as err: # XXX what error?
-            raise URLError(err)
-
-        # Pick apart the HTTPResponse object to get the addinfourl
-        # object initialized properly.
-
-        # XXX Should an HTTPResponse object really be passed to
-        # BufferedReader?  If so, we should change http.client to support
-        # this use directly.
-
-        # Add some fake methods to the reader to satisfy BufferedReader.
-        r.readable = lambda: True
-        r.writable = r.seekable = lambda: False
-        r._checkReadable = lambda: True
-        r._checkWritable = lambda: False
-        fp = io.BufferedReader(r)
-
-        resp = addinfourl(fp, r.msg, req.get_full_url())
-        resp.code = r.status
-        resp.msg = r.reason
-        return resp
-
-
-class HTTPHandler(AbstractHTTPHandler):
-
-    def http_open(self, req):
-        return self.do_open(http.client.HTTPConnection, req)
-
-    http_request = AbstractHTTPHandler.do_request_
-
-if hasattr(http.client, 'HTTPS'):
-    class HTTPSHandler(AbstractHTTPHandler):
-
-        def https_open(self, req):
-            return self.do_open(http.client.HTTPSConnection, req)
-
-        https_request = AbstractHTTPHandler.do_request_
-
-class HTTPCookieProcessor(BaseHandler):
-    def __init__(self, cookiejar=None):
-        import http.cookiejar
-        if cookiejar is None:
-            cookiejar = http.cookiejar.CookieJar()
-        self.cookiejar = cookiejar
-
-    def http_request(self, request):
-        self.cookiejar.add_cookie_header(request)
-        return request
-
-    def http_response(self, request, response):
-        self.cookiejar.extract_cookies(response, request)
-        return response
-
-    https_request = http_request
-    https_response = http_response
-
-class UnknownHandler(BaseHandler):
-    def unknown_open(self, req):
-        type = req.get_type()
-        raise URLError('unknown url type: %s' % type)
-
-def parse_keqv_list(l):
-    """Parse list of key=value strings where keys are not duplicated."""
-    parsed = {}
-    for elt in l:
-        # Because of a trailing comma in the auth string, elt could be the
-        # empty string.
-        if not elt:
-            continue
-        k, v = elt.split('=', 1)
-        if v[0] == '"' and v[-1] == '"':
-            v = v[1:-1]
-        parsed[k] = v
-    return parsed
-
-def parse_http_list(s):
-    """Parse lists as described by RFC 2068 Section 2.
-
-    In particular, parse comma-separated lists where the elements of
-    the list may include quoted-strings.  A quoted-string could
-    contain a comma.  A non-quoted string could have quotes in the
-    middle.  Neither commas nor quotes count if they are escaped.
-    Only double-quotes count, not single-quotes.
-    """
-    res = []
-    part = ''
-
-    escape = quote = False
-    for cur in s:
-        if escape:
-            part += cur
-            escape = False
-            continue
-        if quote:
-            if cur == '\\':
-                escape = True
-                continue
-            elif cur == '"':
-                quote = False
-            part += cur
-            continue
-
-        if cur == ',':
-            res.append(part)
-            part = ''
-            continue
-
-        if cur == '"':
-            quote = True
-
-        part += cur
-
-    # append last part
-    if part:
-        res.append(part)
-
-    return [part.strip() for part in res]
-
-class FileHandler(BaseHandler):
-    # Use local file or FTP depending on form of URL
-    def file_open(self, req):
-        url = req.get_selector()
-        if url[:2] == '//' and url[2:3] != '/':
-            req.type = 'ftp'
-            return self.parent.open(req)
-        else:
-            return self.open_local_file(req)
-
-    # names for the localhost
-    names = None
-    def get_names(self):
-        if FileHandler.names is None:
-            try:
-                FileHandler.names = (socket.gethostbyname('localhost'),
-                                    socket.gethostbyname(socket.gethostname()))
-            except socket.gaierror:
-                FileHandler.names = (socket.gethostbyname('localhost'),)
-        return FileHandler.names
-
-    # not entirely sure what the rules are here
-    def open_local_file(self, req):
-        import email.utils
-        import mimetypes
-        host = req.get_host()
-        file = req.get_selector()
-        localfile = url2pathname(file)
-        try:
-            stats = os.stat(localfile)
-            size = stats.st_size
-            modified = email.utils.formatdate(stats.st_mtime, usegmt=True)
-            mtype = mimetypes.guess_type(file)[0]
-            headers = email.message_from_string(
-                'Content-type: %s\nContent-length: %d\nLast-modified: %s\n' %
-                (mtype or 'text/plain', size, modified))
-            if host:
-                host, port = splitport(host)
-            if not host or \
-                (not port and _safe_gethostbyname(host) in self.get_names()):
-                return addinfourl(open(localfile, 'rb'),
-                                  headers, 'file:'+file)
-        except OSError as msg:
-            # urllib2 users shouldn't expect OSErrors coming from urlopen()
-            raise URLError(msg)
-        raise URLError('file not on local host')
-
-def _safe_gethostbyname(host):
-    try:
-        return socket.gethostbyname(host)
-    except socket.gaierror:
-        return None
-
-class FTPHandler(BaseHandler):
-    def ftp_open(self, req):
-        import ftplib
-        import mimetypes
-        host = req.get_host()
-        if not host:
-            raise URLError('ftp error: no host given')
-        host, port = splitport(host)
-        if port is None:
-            port = ftplib.FTP_PORT
-        else:
-            port = int(port)
-
-        # username/password handling
-        user, host = splituser(host)
-        if user:
-            user, passwd = splitpasswd(user)
-        else:
-            passwd = None
-        host = unquote(host)
-        user = unquote(user or '')
-        passwd = unquote(passwd or '')
-
-        try:
-            host = socket.gethostbyname(host)
-        except socket.error as msg:
-            raise URLError(msg)
-        path, attrs = splitattr(req.get_selector())
-        dirs = path.split('/')
-        dirs = list(map(unquote, dirs))
-        dirs, file = dirs[:-1], dirs[-1]
-        if dirs and not dirs[0]:
-            dirs = dirs[1:]
-        try:
-            fw = self.connect_ftp(user, passwd, host, port, dirs, req.timeout)
-            type = file and 'I' or 'D'
-            for attr in attrs:
-                attr, value = splitvalue(attr)
-                if attr.lower() == 'type' and \
-                   value in ('a', 'A', 'i', 'I', 'd', 'D'):
-                    type = value.upper()
-            fp, retrlen = fw.retrfile(file, type)
-            headers = ""
-            mtype = mimetypes.guess_type(req.get_full_url())[0]
-            if mtype:
-                headers += "Content-type: %s\n" % mtype
-            if retrlen is not None and retrlen >= 0:
-                headers += "Content-length: %d\n" % retrlen
-            headers = email.message_from_string(headers)
-            sf = StringIO(str(headers))
-            return addinfourl(fp, headers, req.get_full_url())
-        except ftplib.all_errors as msg:
-            raise URLError('ftp error: %s' % msg).with_traceback(sys.exc_info()[2])
-
-    def connect_ftp(self, user, passwd, host, port, dirs, timeout):
-        fw = ftpwrapper(user, passwd, host, port, dirs, timeout)
-        return fw
-
-class CacheFTPHandler(FTPHandler):
-    # XXX would be nice to have pluggable cache strategies
-    # XXX this stuff is definitely not thread safe
-    def __init__(self):
-        self.cache = {}
-        self.timeout = {}
-        self.soonest = 0
-        self.delay = 60
-        self.max_conns = 16
-
-    def setTimeout(self, t):
-        self.delay = t
-
-    def setMaxConns(self, m):
-        self.max_conns = m
-
-    def connect_ftp(self, user, passwd, host, port, dirs, timeout):
-        key = user, host, port, '/'.join(dirs), timeout
-        if key in self.cache:
-            self.timeout[key] = time.time() + self.delay
-        else:
-            self.cache[key] = ftpwrapper(user, passwd, host, port, dirs, timeout)
-            self.timeout[key] = time.time() + self.delay
-        self.check_cache()
-        return self.cache[key]
-
-    def check_cache(self):
-        # first check for old ones
-        t = time.time()
-        if self.soonest <= t:
-            for k, v in list(self.timeout.items()):
-                if v < t:
-                    self.cache[k].close()
-                    del self.cache[k]
-                    del self.timeout[k]
-        self.soonest = min(list(self.timeout.values()))
-
-        # then check the size
-        if len(self.cache) == self.max_conns:
-            for k, v in list(self.timeout.items()):
-                if v == self.soonest:
-                    del self.cache[k]
-                    del self.timeout[k]
-                    break
-            self.soonest = min(list(self.timeout.values()))

Deleted: python/branches/py3k-urllib/Lib/urlparse.py
==============================================================================
--- python/branches/py3k-urllib/Lib/urlparse.py	Tue Jun 17 23:01:35 2008
+++ (empty file)
@@ -1,325 +0,0 @@
-"""Parse (absolute and relative) URLs.
-
-See RFC 1808: "Relative Uniform Resource Locators", by R. Fielding,
-UC Irvine, June 1995.
-"""
-
-__all__ = ["urlparse", "urlunparse", "urljoin", "urldefrag",
-           "urlsplit", "urlunsplit"]
-
-# A classification of schemes ('' means apply by default)
-uses_relative = ['ftp', 'http', 'gopher', 'nntp', 'imap',
-                 'wais', 'file', 'https', 'shttp', 'mms',
-                 'prospero', 'rtsp', 'rtspu', '', 'sftp']
-uses_netloc = ['ftp', 'http', 'gopher', 'nntp', 'telnet',
-               'imap', 'wais', 'file', 'mms', 'https', 'shttp',
-               'snews', 'prospero', 'rtsp', 'rtspu', 'rsync', '',
-               'svn', 'svn+ssh', 'sftp']
-non_hierarchical = ['gopher', 'hdl', 'mailto', 'news',
-                    'telnet', 'wais', 'imap', 'snews', 'sip', 'sips']
-uses_params = ['ftp', 'hdl', 'prospero', 'http', 'imap',
-               'https', 'shttp', 'rtsp', 'rtspu', 'sip', 'sips',
-               'mms', '', 'sftp']
-uses_query = ['http', 'wais', 'imap', 'https', 'shttp', 'mms',
-              'gopher', 'rtsp', 'rtspu', 'sip', 'sips', '']
-uses_fragment = ['ftp', 'hdl', 'http', 'gopher', 'news',
-                 'nntp', 'wais', 'https', 'shttp', 'snews',
-                 'file', 'prospero', '']
-
-# Characters valid in scheme names
-scheme_chars = ('abcdefghijklmnopqrstuvwxyz'
-                'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
-                '0123456789'
-                '+-.')
-
-MAX_CACHE_SIZE = 20
-_parse_cache = {}
-
-def clear_cache():
-    """Clear the parse cache."""
-    _parse_cache.clear()
-
-
-class ResultMixin(object):
-    """Shared methods for the parsed result objects."""
-
-    @property
-    def username(self):
-        netloc = self.netloc
-        if "@" in netloc:
-            userinfo = netloc.rsplit("@", 1)[0]
-            if ":" in userinfo:
-                userinfo = userinfo.split(":", 1)[0]
-            return userinfo
-        return None
-
-    @property
-    def password(self):
-        netloc = self.netloc
-        if "@" in netloc:
-            userinfo = netloc.rsplit("@", 1)[0]
-            if ":" in userinfo:
-                return userinfo.split(":", 1)[1]
-        return None
-
-    @property
-    def hostname(self):
-        netloc = self.netloc
-        if "@" in netloc:
-            netloc = netloc.rsplit("@", 1)[1]
-        if ":" in netloc:
-            netloc = netloc.split(":", 1)[0]
-        return netloc.lower() or None
-
-    @property
-    def port(self):
-        netloc = self.netloc
-        if "@" in netloc:
-            netloc = netloc.rsplit("@", 1)[1]
-        if ":" in netloc:
-            port = netloc.split(":", 1)[1]
-            return int(port, 10)
-        return None
-
-from collections import namedtuple
-
-class SplitResult(namedtuple('SplitResult', 'scheme netloc path query fragment'), ResultMixin):
-
-    __slots__ = ()
-
-    def geturl(self):
-        return urlunsplit(self)
-
-
-class ParseResult(namedtuple('ParseResult', 'scheme netloc path params query fragment'), ResultMixin):
-
-    __slots__ = ()
-
-    def geturl(self):
-        return urlunparse(self)
-
-
-def urlparse(url, scheme='', allow_fragments=True):
-    """Parse a URL into 6 components:
-    <scheme>://<netloc>/<path>;<params>?<query>#<fragment>
-    Return a 6-tuple: (scheme, netloc, path, params, query, fragment).
-    Note that we don't break the components up in smaller bits
-    (e.g. netloc is a single string) and we don't expand % escapes."""
-    tuple = urlsplit(url, scheme, allow_fragments)
-    scheme, netloc, url, query, fragment = tuple
-    if scheme in uses_params and ';' in url:
-        url, params = _splitparams(url)
-    else:
-        params = ''
-    return ParseResult(scheme, netloc, url, params, query, fragment)
-
-def _splitparams(url):
-    if '/'  in url:
-        i = url.find(';', url.rfind('/'))
-        if i < 0:
-            return url, ''
-    else:
-        i = url.find(';')
-    return url[:i], url[i+1:]
-
-def _splitnetloc(url, start=0):
-    delim = len(url)   # position of end of domain part of url, default is end
-    for c in '/?#':    # look for delimiters; the order is NOT important
-        wdelim = url.find(c, start)        # find first of this delim
-        if wdelim >= 0:                    # if found
-            delim = min(delim, wdelim)     # use earliest delim position
-    return url[start:delim], url[delim:]   # return (domain, rest)
-
-def urlsplit(url, scheme='', allow_fragments=True):
-    """Parse a URL into 5 components:
-    <scheme>://<netloc>/<path>?<query>#<fragment>
-    Return a 5-tuple: (scheme, netloc, path, query, fragment).
-    Note that we don't break the components up in smaller bits
-    (e.g. netloc is a single string) and we don't expand % escapes."""
-    allow_fragments = bool(allow_fragments)
-    key = url, scheme, allow_fragments, type(url), type(scheme)
-    cached = _parse_cache.get(key, None)
-    if cached:
-        return cached
-    if len(_parse_cache) >= MAX_CACHE_SIZE: # avoid runaway growth
-        clear_cache()
-    netloc = query = fragment = ''
-    i = url.find(':')
-    if i > 0:
-        if url[:i] == 'http': # optimize the common case
-            scheme = url[:i].lower()
-            url = url[i+1:]
-            if url[:2] == '//':
-                netloc, url = _splitnetloc(url, 2)
-            if allow_fragments and '#' in url:
-                url, fragment = url.split('#', 1)
-            if '?' in url:
-                url, query = url.split('?', 1)
-            v = SplitResult(scheme, netloc, url, query, fragment)
-            _parse_cache[key] = v
-            return v
-        for c in url[:i]:
-            if c not in scheme_chars:
-                break
-        else:
-            scheme, url = url[:i].lower(), url[i+1:]
-    if scheme in uses_netloc and url[:2] == '//':
-        netloc, url = _splitnetloc(url, 2)
-    if allow_fragments and scheme in uses_fragment and '#' in url:
-        url, fragment = url.split('#', 1)
-    if scheme in uses_query and '?' in url:
-        url, query = url.split('?', 1)
-    v = SplitResult(scheme, netloc, url, query, fragment)
-    _parse_cache[key] = v
-    return v
-
-def urlunparse(components):
-    """Put a parsed URL back together again.  This may result in a
-    slightly different, but equivalent URL, if the URL that was parsed
-    originally had redundant delimiters, e.g. a ? with an empty query
-    (the draft states that these are equivalent)."""
-    scheme, netloc, url, params, query, fragment = components
-    if params:
-        url = "%s;%s" % (url, params)
-    return urlunsplit((scheme, netloc, url, query, fragment))
-
-def urlunsplit(components):
-    scheme, netloc, url, query, fragment = components
-    if netloc or (scheme and scheme in uses_netloc and url[:2] != '//'):
-        if url and url[:1] != '/': url = '/' + url
-        url = '//' + (netloc or '') + url
-    if scheme:
-        url = scheme + ':' + url
-    if query:
-        url = url + '?' + query
-    if fragment:
-        url = url + '#' + fragment
-    return url
-
-def urljoin(base, url, allow_fragments=True):
-    """Join a base URL and a possibly relative URL to form an absolute
-    interpretation of the latter."""
-    if not base:
-        return url
-    if not url:
-        return base
-    bscheme, bnetloc, bpath, bparams, bquery, bfragment = \
-            urlparse(base, '', allow_fragments)
-    scheme, netloc, path, params, query, fragment = \
-            urlparse(url, bscheme, allow_fragments)
-    if scheme != bscheme or scheme not in uses_relative:
-        return url
-    if scheme in uses_netloc:
-        if netloc:
-            return urlunparse((scheme, netloc, path,
-                               params, query, fragment))
-        netloc = bnetloc
-    if path[:1] == '/':
-        return urlunparse((scheme, netloc, path,
-                           params, query, fragment))
-    if not (path or params or query):
-        return urlunparse((scheme, netloc, bpath,
-                           bparams, bquery, fragment))
-    segments = bpath.split('/')[:-1] + path.split('/')
-    # XXX The stuff below is bogus in various ways...
-    if segments[-1] == '.':
-        segments[-1] = ''
-    while '.' in segments:
-        segments.remove('.')
-    while 1:
-        i = 1
-        n = len(segments) - 1
-        while i < n:
-            if (segments[i] == '..'
-                and segments[i-1] not in ('', '..')):
-                del segments[i-1:i+1]
-                break
-            i = i+1
-        else:
-            break
-    if segments == ['', '..']:
-        segments[-1] = ''
-    elif len(segments) >= 2 and segments[-1] == '..':
-        segments[-2:] = ['']
-    return urlunparse((scheme, netloc, '/'.join(segments),
-                       params, query, fragment))
-
-def urldefrag(url):
-    """Removes any existing fragment from URL.
-
-    Returns a tuple of the defragmented URL and the fragment.  If
-    the URL contained no fragments, the second element is the
-    empty string.
-    """
-    if '#' in url:
-        s, n, p, a, q, frag = urlparse(url)
-        defrag = urlunparse((s, n, p, a, q, ''))
-        return defrag, frag
-    else:
-        return url, ''
-
-
-test_input = """
-      http://a/b/c/d
-
-      g:h        = <URL:g:h>
-      http:g     = <URL:http://a/b/c/g>
-      http:      = <URL:http://a/b/c/d>
-      g          = <URL:http://a/b/c/g>
-      ./g        = <URL:http://a/b/c/g>
-      g/         = <URL:http://a/b/c/g/>
-      /g         = <URL:http://a/g>
-      //g        = <URL:http://g>
-      ?y         = <URL:http://a/b/c/d?y>
-      g?y        = <URL:http://a/b/c/g?y>
-      g?y/./x    = <URL:http://a/b/c/g?y/./x>
-      .          = <URL:http://a/b/c/>
-      ./         = <URL:http://a/b/c/>
-      ..         = <URL:http://a/b/>
-      ../        = <URL:http://a/b/>
-      ../g       = <URL:http://a/b/g>
-      ../..      = <URL:http://a/>
-      ../../g    = <URL:http://a/g>
-      ../../../g = <URL:http://a/../g>
-      ./../g     = <URL:http://a/b/g>
-      ./g/.      = <URL:http://a/b/c/g/>
-      /./g       = <URL:http://a/./g>
-      g/./h      = <URL:http://a/b/c/g/h>
-      g/../h     = <URL:http://a/b/c/h>
-      http:g     = <URL:http://a/b/c/g>
-      http:      = <URL:http://a/b/c/d>
-      http:?y         = <URL:http://a/b/c/d?y>
-      http:g?y        = <URL:http://a/b/c/g?y>
-      http:g?y/./x    = <URL:http://a/b/c/g?y/./x>
-"""
-
-def test():
-    import sys
-    base = ''
-    if sys.argv[1:]:
-        fn = sys.argv[1]
-        if fn == '-':
-            fp = sys.stdin
-        else:
-            fp = open(fn)
-    else:
-        from io import StringIO
-        fp = StringIO(test_input)
-    for line in fp:
-        words = line.split()
-        if not words:
-            continue
-        url = words[0]
-        parts = urlparse(url)
-        print('%-10s : %s' % (url, parts))
-        abs = urljoin(base, url)
-        if not base:
-            base = abs
-        wrapped = '<URL:%s>' % abs
-        print('%-10s = %s' % (url, wrapped))
-        if len(words) == 3 and words[1] == '=':
-            if wrapped != words[2]:
-                print('EXPECTED', words[2], '!!!!!!!!!!')
-
-if __name__ == '__main__':
-    test()

Modified: python/branches/py3k-urllib/Lib/wsgiref/simple_server.py
==============================================================================
--- python/branches/py3k-urllib/Lib/wsgiref/simple_server.py	(original)
+++ python/branches/py3k-urllib/Lib/wsgiref/simple_server.py	Tue Jun 17 23:01:35 2008
@@ -11,7 +11,8 @@
 """
 
 from http.server import BaseHTTPRequestHandler, HTTPServer
-import urllib, sys
+import sys
+import urllib.parse
 from wsgiref.handlers import SimpleHandler
 
 __version__ = "0.1"
@@ -93,7 +94,7 @@
         else:
             path,query = self.path,''
 
-        env['PATH_INFO'] = urllib.unquote(path)
+        env['PATH_INFO'] = urllib.parse.unquote(path)
         env['QUERY_STRING'] = query
 
         host = self.address_string()

Modified: python/branches/py3k-urllib/Lib/wsgiref/util.py
==============================================================================
--- python/branches/py3k-urllib/Lib/wsgiref/util.py	(original)
+++ python/branches/py3k-urllib/Lib/wsgiref/util.py	Tue Jun 17 23:01:35 2008
@@ -50,7 +50,7 @@
 def application_uri(environ):
     """Return the application's base URI (no PATH_INFO or QUERY_STRING)"""
     url = environ['wsgi.url_scheme']+'://'
-    from urllib import quote
+    from urllib.parse import quote
 
     if environ.get('HTTP_HOST'):
         url += environ['HTTP_HOST']
@@ -70,7 +70,7 @@
 def request_uri(environ, include_query=1):
     """Return the full request URI, optionally including the query string"""
     url = application_uri(environ)
-    from urllib import quote
+    from urllib.parse import quote
     path_info = quote(environ.get('PATH_INFO',''))
     if not environ.get('SCRIPT_NAME'):
         url += path_info[1:]

Modified: python/branches/py3k-urllib/Lib/xmlrpc/client.py
==============================================================================
--- python/branches/py3k-urllib/Lib/xmlrpc/client.py	(original)
+++ python/branches/py3k-urllib/Lib/xmlrpc/client.py	Tue Jun 17 23:01:35 2008
@@ -1160,12 +1160,12 @@
         if isinstance(host, tuple):
             host, x509 = host
 
-        import urllib
-        auth, host = urllib.splituser(host)
+        import urllib.parse
+        auth, host = urllib.parse.splituser(host)
 
         if auth:
             import base64
-            auth = base64.encodestring(urllib.unquote(auth))
+            auth = base64.encodestring(urllib.parse.unquote(auth))
             auth = "".join(auth.split()) # get rid of whitespace
             extra_headers = [
                 ("Authorization", "Basic " + auth)
@@ -1321,11 +1321,11 @@
         # establish a "logical" server connection
 
         # get the url
-        import urllib
-        type, uri = urllib.splittype(uri)
+        import urllib.parse
+        type, uri = urllib.parse.splittype(uri)
         if type not in ("http", "https"):
             raise IOError("unsupported XML-RPC protocol")
-        self.__host, self.__handler = urllib.splithost(uri)
+        self.__host, self.__handler = urllib.parse.splithost(uri)
         if not self.__handler:
             self.__handler = "/RPC2"
 

Modified: python/branches/py3k-urllib/Makefile.pre.in
==============================================================================
--- python/branches/py3k-urllib/Makefile.pre.in	(original)
+++ python/branches/py3k-urllib/Makefile.pre.in	Tue Jun 17 23:01:35 2008
@@ -809,7 +809,7 @@
 		email email/mime email/test email/test/data \
 		html json json/tests http dbm xmlrpc \
 		sqlite3 sqlite3/test \
-		logging bsddb bsddb/test csv wsgiref \
+		logging bsddb bsddb/test csv wsgiref urllib \
 		lib2to3 lib2to3/fixes lib2to3/pgen2 lib2to3/tests \
 		ctypes ctypes/test ctypes/macholib idlelib idlelib/Icons \
 		distutils distutils/command distutils/tests $(XMLLIBSUBDIRS) \

From python-3000-checkins at python.org  Tue Jun 17 23:11:30 2008
From: python-3000-checkins at python.org (amaury.forgeotdarc)
Date: Tue, 17 Jun 2008 23:11:30 +0200 (CEST)
Subject: [Python-3000-checkins] r64348 - in python/branches/py3k:
	Doc/conf.py Doc/library/optparse.rst Doc/whatsnew/2.6.rst
	Lib/logging/__init__.py Lib/multiprocessing Lib/platform.py
	Lib/test/crashers/loosing_mro_ref.py Lib/test/test_grammar.py
	Lib/test/test_heapq.py Lib/test/test_struct.py
	Lib/test/test_sys.py Misc/ACKS Misc/developers.txt
	Modules/_ctypes/callproc.c Modules/_struct.c
	Modules/arraymodule.c Objects/tupleobject.c Python/marshal.c
	Tools/msi/msilib.py
Message-ID: <20080617211130.819B81E4010@bag.python.org>

Author: amaury.forgeotdarc
Date: Tue Jun 17 23:11:29 2008
New Revision: 64348

Log:
Merged revisions 64119,64147,64150,64165,64219-64221,64229-64230,64233,64235,64253,64278,64280,64301,64303,64320,64328,64338-64339 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/trunk

........
  r64119 | andrew.kuchling | 2008-06-11 14:53:14 +0200 (mer., 11 juin 2008) | 1 line
  
  Note PEP 371 section
........
  r64147 | benjamin.peterson | 2008-06-11 22:04:30 +0200 (mer., 11 juin 2008) | 2 lines
  
  update ACKS and NEWs for multiprocessing
........
  r64150 | georg.brandl | 2008-06-11 22:28:06 +0200 (mer., 11 juin 2008) | 2 lines
  
  Can we agree to put dots at entry ends? Thanks.
........
  r64165 | armin.rigo | 2008-06-12 11:50:58 +0200 (jeu., 12 juin 2008) | 3 lines
  
  Sounds obvious, but I didn't even realize that you can put non-string
  keys in type dictionaries without using this locals() hack.
........
  r64219 | neal.norwitz | 2008-06-13 08:00:46 +0200 (ven., 13 juin 2008) | 1 line
  
  Check for memory alloc failure
........
  r64220 | neal.norwitz | 2008-06-13 08:02:26 +0200 (ven., 13 juin 2008) | 3 lines
  
  Fix some memory dealloc problems when exceptions occur.
  It caused: "Fatal Python error: UNREF invalid object" in the DoubleTest.
........
  r64221 | neal.norwitz | 2008-06-13 08:03:25 +0200 (ven., 13 juin 2008) | 3 lines
  
  Fix typo in method name.  The LT class implemented less than.  The LE class
  should implement less than or equal to (as the code does).
........
  r64229 | georg.brandl | 2008-06-13 15:26:54 +0200 (ven., 13 juin 2008) | 2 lines
  
  Clarification.
........
  r64230 | robert.schuppenies | 2008-06-13 15:29:37 +0200 (ven., 13 juin 2008) | 2 lines
  
  Fixed: sys.getsizeof does not take the actual length of the tuples into account.
........
  r64233 | benjamin.peterson | 2008-06-13 17:11:50 +0200 (ven., 13 juin 2008) | 2 lines
  
  platform.uname now tries to fill empty values even when os.uname is present
........
  r64235 | benjamin.peterson | 2008-06-13 17:41:09 +0200 (ven., 13 juin 2008) | 1 line
  
  set svn:ignore on multiprocessing
........
  r64253 | andrew.kuchling | 2008-06-13 21:38:18 +0200 (ven., 13 juin 2008) | 1 line
  
  Typo fixes
........
  r64278 | martin.v.loewis | 2008-06-14 16:24:47 +0200 (sam., 14 juin 2008) | 2 lines
  
  Disable UAC by default.
........
  r64280 | gregory.p.smith | 2008-06-14 19:34:09 +0200 (sam., 14 juin 2008) | 3 lines
  
  silence the test when it is skipped on some platforms.  should fix a
  buildbot.
........
  r64301 | georg.brandl | 2008-06-15 21:54:36 +0200 (dim., 15 juin 2008) | 2 lines
  
  Forward-port new test from r64300.
........
  r64303 | raymond.hettinger | 2008-06-16 03:42:40 +0200 (lun., 16 juin 2008) | 1 line
  
  Issue 3116: fix quadratic behavior in marshal.dumps().
........
  r64320 | georg.brandl | 2008-06-16 23:00:47 +0200 (lun., 16 juin 2008) | 2 lines
  
  Add Jesse Noller to the developers list.
........
  r64328 | georg.brandl | 2008-06-17 11:01:35 +0200 (mar., 17 juin 2008) | 2 lines
  
  Split the HTML index.
........
  r64338 | vinay.sajip | 2008-06-17 13:02:14 +0200 (mar., 17 juin 2008) | 1 line
  
  Bug #3126: StreamHandler and FileHandler check before calling "flush" and "close" that the stream object has these, using hasattr (thanks to bobf for the patch).
........
  r64339 | vinay.sajip | 2008-06-17 13:04:02 +0200 (mar., 17 juin 2008) | 1 line
  
  Updated with fix for #3126.
........


Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Doc/conf.py
   python/branches/py3k/Doc/library/optparse.rst
   python/branches/py3k/Doc/whatsnew/2.6.rst
   python/branches/py3k/Lib/logging/__init__.py
   python/branches/py3k/Lib/multiprocessing/   (props changed)
   python/branches/py3k/Lib/platform.py
   python/branches/py3k/Lib/test/crashers/loosing_mro_ref.py
   python/branches/py3k/Lib/test/test_grammar.py
   python/branches/py3k/Lib/test/test_heapq.py
   python/branches/py3k/Lib/test/test_struct.py
   python/branches/py3k/Lib/test/test_sys.py
   python/branches/py3k/Misc/ACKS
   python/branches/py3k/Misc/developers.txt
   python/branches/py3k/Modules/_ctypes/callproc.c
   python/branches/py3k/Modules/_struct.c
   python/branches/py3k/Modules/arraymodule.c
   python/branches/py3k/Objects/tupleobject.c
   python/branches/py3k/Python/marshal.c
   python/branches/py3k/Tools/msi/msilib.py

Modified: python/branches/py3k/Doc/conf.py
==============================================================================
--- python/branches/py3k/Doc/conf.py	(original)
+++ python/branches/py3k/Doc/conf.py	Tue Jun 17 23:11:29 2008
@@ -95,6 +95,9 @@
 # Output file base name for HTML help builder.
 htmlhelp_basename = 'python' + release.replace('.', '')
 
+# Split the index
+html_split_index = True
+
 
 # Options for LaTeX output
 # ------------------------

Modified: python/branches/py3k/Doc/library/optparse.rst
==============================================================================
--- python/branches/py3k/Doc/library/optparse.rst	(original)
+++ python/branches/py3k/Doc/library/optparse.rst	Tue Jun 17 23:11:29 2008
@@ -636,9 +636,9 @@
 option involved in the error; be sure to do the same when calling
 ``parser.error()`` from your application code.
 
-If :mod:`optparse`'s default error-handling behaviour does not suite your needs,
-you'll need to subclass OptionParser and override ``exit()`` and/or
-:meth:`error`.
+If :mod:`optparse`'s default error-handling behaviour does not suit your needs,
+you'll need to subclass OptionParser and override its :meth:`exit` and/or
+:meth:`error` methods.
 
 
 .. _optparse-putting-it-all-together:

Modified: python/branches/py3k/Doc/whatsnew/2.6.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/2.6.rst	(original)
+++ python/branches/py3k/Doc/whatsnew/2.6.rst	Tue Jun 17 23:11:29 2008
@@ -521,6 +521,21 @@
   
 .. ======================================================================
 
+.. _pep-0371:
+
+PEP 371: The ``multiprocessing`` Package
+=====================================================
+
+XXX write this.
+
+.. seealso::
+
+   :pep:`371` - Per-user ``site-packages`` Directory
+     PEP written by Jesse Noller and Richard Oudkerk; 
+     implemented by Jesse Noller.
+
+.. ======================================================================
+
 .. _pep-3101:
 
 PEP 3101: Advanced String Formatting

Modified: python/branches/py3k/Lib/logging/__init__.py
==============================================================================
--- python/branches/py3k/Lib/logging/__init__.py	(original)
+++ python/branches/py3k/Lib/logging/__init__.py	Tue Jun 17 23:11:29 2008
@@ -731,7 +731,7 @@
         """
         Flushes the stream.
         """
-        if self.stream:
+        if self.stream and hasattr(self.stream, "flush"):
             self.stream.flush()
 
     def emit(self, record):
@@ -787,7 +787,8 @@
         """
         if self.stream:
             self.flush()
-            self.stream.close()
+            if hasattr(self.stream, "close"):
+                self.stream.close()
             StreamHandler.close(self)
             self.stream = None
 

Modified: python/branches/py3k/Lib/platform.py
==============================================================================
--- python/branches/py3k/Lib/platform.py	(original)
+++ python/branches/py3k/Lib/platform.py	Tue Jun 17 23:11:29 2008
@@ -1066,23 +1066,30 @@
 
     """
     global _uname_cache
+    no_os_uname = 0
 
     if _uname_cache is not None:
         return _uname_cache
 
+    processor = ''
+
     # Get some infos from the builtin os.uname API...
     try:
         system,node,release,version,machine = os.uname()
-
     except AttributeError:
-        # Hmm, no uname... we'll have to poke around the system then.
-        system = sys.platform
-        release = ''
-        version = ''
-        node = _node()
-        machine = ''
-        processor = ''
-        use_syscmd_ver = 1
+        no_os_uname = 1
+
+    if no_os_uname or not filter(None, (system, node, release, version, machine)):
+        # Hmm, no there is either no uname or uname has returned
+        #'unknowns'... we'll have to poke around the system then.
+        if no_os_uname:
+            system = sys.platform
+            release = ''
+            version = ''
+            node = _node()
+            machine = ''
+
+        use_syscmd_ver = 01
 
         # Try win32_ver() on win32 platforms
         if system == 'win32':
@@ -1093,8 +1100,10 @@
             # available on Win XP and later; see
             # http://support.microsoft.com/kb/888731 and
             # http://www.geocities.com/rick_lively/MANUALS/ENV/MSWIN/PROCESSI.HTM
-            machine = os.environ.get('PROCESSOR_ARCHITECTURE', '')
-            processor = os.environ.get('PROCESSOR_IDENTIFIER', machine)
+            if not machine:
+                machine = os.environ.get('PROCESSOR_ARCHITECTURE', '')
+            if not processor:
+                processor = os.environ.get('PROCESSOR_IDENTIFIER', machine)
 
         # Try the 'ver' system command available on some
         # platforms
@@ -1136,30 +1145,28 @@
             release,(version,stage,nonrel),machine = mac_ver()
             system = 'MacOS'
 
-    else:
-        # System specific extensions
-        if system == 'OpenVMS':
-            # OpenVMS seems to have release and version mixed up
-            if not release or release == '0':
-                release = version
-                version = ''
-            # Get processor information
-            try:
-                import vms_lib
-            except ImportError:
-                pass
-            else:
-                csid, cpu_number = vms_lib.getsyi('SYI$_CPU',0)
-                if (cpu_number >= 128):
-                    processor = 'Alpha'
-                else:
-                    processor = 'VAX'
+    # System specific extensions
+    if system == 'OpenVMS':
+        # OpenVMS seems to have release and version mixed up
+        if not release or release == '0':
+            release = version
+            version = ''
+        # Get processor information
+        try:
+            import vms_lib
+        except ImportError:
+            pass
         else:
-            # Get processor information from the uname system command
-            processor = _syscmd_uname('-p','')
+            csid, cpu_number = vms_lib.getsyi('SYI$_CPU',0)
+            if (cpu_number >= 128):
+                processor = 'Alpha'
+            else:
+                processor = 'VAX'
+    if not processor:
+        # Get processor information from the uname system command
+        processor = _syscmd_uname('-p','')
 
-    # 'unknown' is not really any useful as information; we'll convert
-    # it to '' which is more portable
+    #If any unknowns still exist, replace them with ''s, which are more portable
     if system == 'unknown':
         system = ''
     if node == 'unknown':

Modified: python/branches/py3k/Lib/test/crashers/loosing_mro_ref.py
==============================================================================
--- python/branches/py3k/Lib/test/crashers/loosing_mro_ref.py	(original)
+++ python/branches/py3k/Lib/test/crashers/loosing_mro_ref.py	Tue Jun 17 23:11:29 2008
@@ -27,10 +27,9 @@
 class Base2(object):
     mykey = 'from Base2'
 
-class X(Base):
-    # you can't add a non-string key to X.__dict__, but it can be
-    # there from the beginning :-)
-    locals()[MyKey()] = 5
+# you can't add a non-string key to X.__dict__, but it can be
+# there from the beginning :-)
+X = type('X', (Base,), {MyKey(): 5})
 
 print(X.mykey)
 # I get a segfault, or a slightly wrong assertion error in a debug build.

Modified: python/branches/py3k/Lib/test/test_grammar.py
==============================================================================
--- python/branches/py3k/Lib/test/test_grammar.py	(original)
+++ python/branches/py3k/Lib/test/test_grammar.py	Tue Jun 17 23:11:29 2008
@@ -335,6 +335,7 @@
         self.assertEquals(l5(1, 2), 5)
         self.assertEquals(l5(1, 2, 3), 6)
         check_syntax_error(self, "lambda x: x = 2")
+        check_syntax_error(self, "lambda (None,): None")
         l6 = lambda x, y, *, k=20: x+y+k
         self.assertEquals(l6(1,2), 1+2+20)
         self.assertEquals(l6(1,2,k=10), 1+2+10)

Modified: python/branches/py3k/Lib/test/test_heapq.py
==============================================================================
--- python/branches/py3k/Lib/test/test_heapq.py	(original)
+++ python/branches/py3k/Lib/test/test_heapq.py	Tue Jun 17 23:11:29 2008
@@ -211,10 +211,11 @@
         class LE:
             def __init__(self, x):
                 self.x = x
-            def __lt__(self, other):
+            def __le__(self, other):
                 return self.x >= other.x
         data = [random.random() for i in range(100)]
         target = sorted(data, reverse=True)
+        print("HASATTR", hasattr(LE(0), "__lt__"), LE(0).__lt__)
         self.assertEqual(hsort(data, LT), target)
         self.assertEqual(hsort(data, LE), target)
 

Modified: python/branches/py3k/Lib/test/test_struct.py
==============================================================================
--- python/branches/py3k/Lib/test/test_struct.py	(original)
+++ python/branches/py3k/Lib/test/test_struct.py	Tue Jun 17 23:11:29 2008
@@ -8,6 +8,7 @@
 
 import sys
 ISBIGENDIAN = sys.byteorder == "big"
+IS32BIT = sys.maxsize == 0x7fffffff
 del sys
 
 try:
@@ -580,6 +581,11 @@
             for c in [b'\x01', b'\x7f', b'\xff', b'\x0f', b'\xf0']:
                 self.assertTrue(struct.unpack('>?', c)[0])
 
+    if IS32BIT:
+        def test_crasher(self):
+            self.assertRaises(MemoryError, struct.pack, "357913941b", "a")
+
+
 def test_main():
     run_unittest(StructTest)
 

Modified: python/branches/py3k/Lib/test/test_sys.py
==============================================================================
--- python/branches/py3k/Lib/test/test_sys.py	(original)
+++ python/branches/py3k/Lib/test/test_sys.py	Tue Jun 17 23:11:29 2008
@@ -520,6 +520,9 @@
         self.check_sizeof(32768, h + self.align(2) + 2)
         self.check_sizeof(32768*32768-1, h + self.align(2) + 2)
         self.check_sizeof(32768*32768, h + self.align(2) + 4)
+        # tuple
+        self.check_sizeof((), h)
+        self.check_sizeof((1,2,3), h + 3*p)
 
 
 def test_main():

Modified: python/branches/py3k/Misc/ACKS
==============================================================================
--- python/branches/py3k/Misc/ACKS	(original)
+++ python/branches/py3k/Misc/ACKS	Tue Jun 17 23:11:29 2008
@@ -486,6 +486,7 @@
 Gustavo Niemeyer
 Oscar Nierstrasz
 Hrvoje Niksic
+Jesse Noller
 Bill Noon
 Stefan Norberg
 Tim Northover
@@ -502,6 +503,7 @@
 Douglas Orr
 Denis S. Otkidach
 Michael Otteneder
+R. M. Oudkerk
 Russel Owen
 Ondrej Palkovsky
 Mike Pall
@@ -673,6 +675,7 @@
 Monty Taylor
 Amy Taylor
 Tobias Thelen
+James Thomas
 Robin Thomas
 Eric Tiedemann
 Tracy Tims

Modified: python/branches/py3k/Misc/developers.txt
==============================================================================
--- python/branches/py3k/Misc/developers.txt	(original)
+++ python/branches/py3k/Misc/developers.txt	Tue Jun 17 23:11:29 2008
@@ -17,6 +17,9 @@
 Permissions History
 -------------------
 
+- Jesse Noller was given SVN access on 16 June 2008 by Georg Brandl,
+  for work on the multiprocessing module.
+
 - Gregor Lingl was given SVN access on 10 June 2008 by MvL,
   for work on the turtle module.
 

Modified: python/branches/py3k/Modules/_ctypes/callproc.c
==============================================================================
--- python/branches/py3k/Modules/_ctypes/callproc.c	(original)
+++ python/branches/py3k/Modules/_ctypes/callproc.c	Tue Jun 17 23:11:29 2008
@@ -1815,6 +1815,8 @@
 		return NULL;
 	}
 	shape = PyTuple_New(dict->ndim);
+	if (shape == NULL)
+		return NULL;
 	for (i = 0; i < (int)dict->ndim; ++i)
 		PyTuple_SET_ITEM(shape, i, PyLong_FromSsize_t(dict->shape[i]));
 

Modified: python/branches/py3k/Modules/_struct.c
==============================================================================
--- python/branches/py3k/Modules/_struct.c	(original)
+++ python/branches/py3k/Modules/_struct.c	Tue Jun 17 23:11:29 2008
@@ -1383,6 +1383,12 @@
 		}
 	}
 
+	/* check for overflow */
+	if ((len + 1) > (PY_SSIZE_T_MAX / sizeof(formatcode))) {
+		PyErr_NoMemory();
+		return -1;
+	}
+
 	self->s_size = size;
 	self->s_len = len;
 	codes = PyMem_MALLOC((len + 1) * sizeof(formatcode));

Modified: python/branches/py3k/Modules/arraymodule.c
==============================================================================
--- python/branches/py3k/Modules/arraymodule.c	(original)
+++ python/branches/py3k/Modules/arraymodule.c	Tue Jun 17 23:11:29 2008
@@ -421,6 +421,9 @@
 	if (op == NULL) {
 		return NULL;
 	}
+	op->ob_descr = descr;
+	op->allocated = size;
+	op->weakreflist = NULL;
 	Py_SIZE(op) = size;
 	if (size <= 0) {
 		op->ob_item = NULL;
@@ -428,13 +431,10 @@
 	else {
 		op->ob_item = PyMem_NEW(char, nbytes);
 		if (op->ob_item == NULL) {
-			PyObject_Del(op);
+			Py_DECREF(op);
 			return PyErr_NoMemory();
 		}
 	}
-	op->ob_descr = descr;
-	op->allocated = size;
-	op->weakreflist = NULL;
         op->ob_exports = 0;
 	return (PyObject *) op;
 }
@@ -808,11 +808,15 @@
 			     "can only extend with array of same kind");
 		return -1;
 	}
+	if ((Py_SIZE(self) > PY_SSIZE_T_MAX - Py_SIZE(b)) ||
+		((Py_SIZE(self) + Py_SIZE(b)) > PY_SSIZE_T_MAX / self->ob_descr->itemsize)) {
+		PyErr_NoMemory();
+		return -1;
+	}
 	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();
+		PyErr_NoMemory();
 		return -1;
         }
 	memcpy(self->ob_item + Py_SIZE(self)*self->ob_descr->itemsize,

Modified: python/branches/py3k/Objects/tupleobject.c
==============================================================================
--- python/branches/py3k/Objects/tupleobject.c	(original)
+++ python/branches/py3k/Objects/tupleobject.c	Tue Jun 17 23:11:29 2008
@@ -683,13 +683,25 @@
 	
 }
 
+static PyObject *
+tuple_sizeof(PyTupleObject *self)
+{
+	Py_ssize_t res;
+
+	res = PyTuple_Type.tp_basicsize + Py_SIZE(self) * sizeof(PyObject *);
+	return PyLong_FromSsize_t(res);
+}
+
 PyDoc_STRVAR(index_doc,
 "T.index(value, [start, [stop]]) -> integer -- return first index of value");
 PyDoc_STRVAR(count_doc,
 "T.count(value) -> integer -- return number of occurrences of value");
+PyDoc_STRVAR(sizeof_doc,
+"T.__sizeof__() -- size of T in memory, in bytes");
 
 static PyMethodDef tuple_methods[] = {
 	{"__getnewargs__",	(PyCFunction)tuple_getnewargs,	METH_NOARGS},
+	{"__sizeof__",	(PyCFunction)tuple_sizeof, METH_NOARGS, sizeof_doc},
 	{"index",	(PyCFunction)tupleindex,  METH_VARARGS, index_doc},
 	{"count",	(PyCFunction)tuplecount,  METH_O, count_doc},
 	{NULL,		NULL}		/* sentinel */

Modified: python/branches/py3k/Python/marshal.c
==============================================================================
--- python/branches/py3k/Python/marshal.c	(original)
+++ python/branches/py3k/Python/marshal.c	Tue Jun 17 23:11:29 2008
@@ -70,7 +70,7 @@
 	size = PyBytes_Size(p->str);
 	newsize = size + size + 1024;
 	if (newsize > 32*1024*1024) {
-		newsize = size + 1024*1024;
+		newsize = size + (size >> 3);	/* 12.5% overallocation */
 	}
 	if (_PyBytes_Resize(&p->str, newsize) != 0) {
 		p->ptr = p->end = NULL;

Modified: python/branches/py3k/Tools/msi/msilib.py
==============================================================================
--- python/branches/py3k/Tools/msi/msilib.py	(original)
+++ python/branches/py3k/Tools/msi/msilib.py	Tue Jun 17 23:11:29 2008
@@ -284,7 +284,8 @@
 
 def init_database(name, schema,
                   ProductName, ProductCode, ProductVersion,
-                  Manufacturer):
+                  Manufacturer,
+                  request_uac = False):
     try:
         os.unlink(name)
     except OSError:
@@ -306,7 +307,11 @@
     si.SetProperty(PID_AUTHOR, Manufacturer)
     si.SetProperty(PID_TEMPLATE, msi_type)
     si.SetProperty(PID_REVNUMBER, gen_uuid())
-    si.SetProperty(PID_WORDCOUNT, 2) # long file names, compressed, original media
+    if request_uac:
+        wc = 2 # long file names, compressed, original media
+    else:
+        wc = 2 | 8 # +never invoke UAC
+    si.SetProperty(PID_WORDCOUNT, wc)
     si.SetProperty(PID_PAGECOUNT, 200)
     si.SetProperty(PID_APPNAME, "Python MSI Library")
     # XXX more properties

From python-3000-checkins at python.org  Tue Jun 17 23:25:36 2008
From: python-3000-checkins at python.org (amaury.forgeotdarc)
Date: Tue, 17 Jun 2008 23:25:36 +0200 (CEST)
Subject: [Python-3000-checkins] r64351 - in python/branches/py3k:
	Lib/test/test_heapq.py Modules/_heapqmodule.c
Message-ID: <20080617212536.4D49D1E4004@bag.python.org>

Author: amaury.forgeotdarc
Date: Tue Jun 17 23:25:35 2008
New Revision: 64351

Log:
Remove 2.6 compatibility code:
now heapqueue items must implement the "<" operator.

The compatibility code could not work: all 3.0 objects have a __lt__ method
(which returns NotImplemented)

Twisted will have to adapt its DelayedCall class.


Modified:
   python/branches/py3k/Lib/test/test_heapq.py
   python/branches/py3k/Modules/_heapqmodule.c

Modified: python/branches/py3k/Lib/test/test_heapq.py
==============================================================================
--- python/branches/py3k/Lib/test/test_heapq.py	(original)
+++ python/branches/py3k/Lib/test/test_heapq.py	Tue Jun 17 23:25:35 2008
@@ -198,7 +198,8 @@
     module = c_heapq
 
     def test_comparison_operator(self):
-        # Issue 3501: Make sure heapq works with both __lt__ and __le__
+        # Issue 3501: Make sure heapq works with both __lt__
+        # For python 3.0, __le__ alone is not enough
         def hsort(data, comp):
             data = [comp(x) for x in data]
             self.module.heapify(data)
@@ -215,9 +216,8 @@
                 return self.x >= other.x
         data = [random.random() for i in range(100)]
         target = sorted(data, reverse=True)
-        print("HASATTR", hasattr(LE(0), "__lt__"), LE(0).__lt__)
         self.assertEqual(hsort(data, LT), target)
-        self.assertEqual(hsort(data, LE), target)
+        self.assertRaises(TypeError, data, LE)
 
 
 #==============================================================================

Modified: python/branches/py3k/Modules/_heapqmodule.c
==============================================================================
--- python/branches/py3k/Modules/_heapqmodule.c	(original)
+++ python/branches/py3k/Modules/_heapqmodule.c	Tue Jun 17 23:25:35 2008
@@ -8,28 +8,10 @@
 
 #include "Python.h"
 
-/* Older implementations of heapq used Py_LE for comparisons.  Now, it uses
-   Py_LT so it will match min(), sorted(), and bisect().  Unfortunately, some
-   client code (Twisted for example) relied on Py_LE, so this little function
-   restores compatability by trying both.
-*/
 static int
 cmp_lt(PyObject *x, PyObject *y)
 {
-	int cmp;
-	static PyObject *lt = NULL;
-
-	if (lt == NULL) {
-		lt = PyUnicode_FromString("__lt__");
-		if (lt == NULL)
-			return -1;
-	}
-	if (PyObject_HasAttr(x, lt))
-		return PyObject_RichCompareBool(x, y, Py_LT);
-	cmp = PyObject_RichCompareBool(y, x, Py_LE);
-	if (cmp != -1)
-		cmp = 1 - cmp;
-	return cmp;
+	return PyObject_RichCompareBool(x, y, Py_LT);
 }
 
 static int

From python-3000-checkins at python.org  Tue Jun 17 23:39:47 2008
From: python-3000-checkins at python.org (amaury.forgeotdarc)
Date: Tue, 17 Jun 2008 23:39:47 +0200 (CEST)
Subject: [Python-3000-checkins] r64352 - python/branches/py3k/PC/_msi.c
Message-ID: <20080617213947.3A3A81E4004@bag.python.org>

Author: amaury.forgeotdarc
Date: Tue Jun 17 23:39:46 2008
New Revision: 64352

Log:
Return the module at the end of its init function.
"import _msi" used to raise a SystemError.


Modified:
   python/branches/py3k/PC/_msi.c

Modified: python/branches/py3k/PC/_msi.c
==============================================================================
--- python/branches/py3k/PC/_msi.c	(original)
+++ python/branches/py3k/PC/_msi.c	Tue Jun 17 23:39:46 2008
@@ -1065,5 +1065,5 @@
     if (!MSIError)
 	return NULL;
     PyModule_AddObject(m, "MSIError", MSIError);
-    return NULL;
+    return m;
 }

From musiccomposition at gmail.com  Tue Jun 17 23:40:45 2008
From: musiccomposition at gmail.com (Benjamin Peterson)
Date: Tue, 17 Jun 2008 16:40:45 -0500
Subject: [Python-3000-checkins] r64352 - python/branches/py3k/PC/_msi.c
In-Reply-To: <20080617213947.3A3A81E4004@bag.python.org>
References: <20080617213947.3A3A81E4004@bag.python.org>
Message-ID: <1afaf6160806171440h74ebb84el5a3c1baf16afaa97@mail.gmail.com>

On Tue, Jun 17, 2008 at 4:39 PM, amaury.forgeotdarc
<python-3000-checkins at python.org> wrote:
> Author: amaury.forgeotdarc
> Date: Tue Jun 17 23:39:46 2008
> New Revision: 64352
>
> Log:
> Return the module at the end of its init function.
> "import _msi" used to raise a SystemError.

It seems you also broke test_struct with your merges.

-- 
Cheers,
Benjamin Peterson
"There's no place like 127.0.0.1."

From python-3000-checkins at python.org  Tue Jun 17 23:42:47 2008
From: python-3000-checkins at python.org (amaury.forgeotdarc)
Date: Tue, 17 Jun 2008 23:42:47 +0200 (CEST)
Subject: [Python-3000-checkins] r64353 - python/branches/py3k/Lib/platform.py
Message-ID: <20080617214247.518D51E4004@bag.python.org>

Author: amaury.forgeotdarc
Date: Tue Jun 17 23:42:46 2008
New Revision: 64353

Log:
Merge error: platform.py would not import


Modified:
   python/branches/py3k/Lib/platform.py

Modified: python/branches/py3k/Lib/platform.py
==============================================================================
--- python/branches/py3k/Lib/platform.py	(original)
+++ python/branches/py3k/Lib/platform.py	Tue Jun 17 23:42:46 2008
@@ -1089,7 +1089,7 @@
             node = _node()
             machine = ''
 
-        use_syscmd_ver = 01
+        use_syscmd_ver = 1
 
         # Try win32_ver() on win32 platforms
         if system == 'win32':

From python-3000-checkins at python.org  Tue Jun 17 23:56:01 2008
From: python-3000-checkins at python.org (amaury.forgeotdarc)
Date: Tue, 17 Jun 2008 23:56:01 +0200 (CEST)
Subject: [Python-3000-checkins] r64354 -
	python/branches/py3k/Lib/test/test_struct.py
Message-ID: <20080617215601.686CF1E4022@bag.python.org>

Author: amaury.forgeotdarc
Date: Tue Jun 17 23:56:01 2008
New Revision: 64354

Log:
Another merge error, seen on bigendian machines


Modified:
   python/branches/py3k/Lib/test/test_struct.py

Modified: python/branches/py3k/Lib/test/test_struct.py
==============================================================================
--- python/branches/py3k/Lib/test/test_struct.py	(original)
+++ python/branches/py3k/Lib/test/test_struct.py	Tue Jun 17 23:56:01 2008
@@ -84,7 +84,7 @@
             self.fail("did not raise error for float coerce")
 
     def test_isbigendian(self):
-        self.assertEqual((struct.pack('=i', 1)[0] == chr(0)), ISBIGENDIAN)
+        self.assertEqual((struct.pack('=i', 1)[0] == 0), ISBIGENDIAN)
 
     def test_consistence(self):
         self.assertRaises(struct.error, struct.calcsize, 'Z')

From python-3000-checkins at python.org  Wed Jun 18 00:39:26 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Wed, 18 Jun 2008 00:39:26 +0200 (CEST)
Subject: [Python-3000-checkins] r64355 - in python/branches/py3k:
	Modules/mathmodule.c
Message-ID: <20080617223926.981F91E4004@bag.python.org>

Author: benjamin.peterson
Date: Wed Jun 18 00:39:26 2008
New Revision: 64355

Log:
Merged revisions 64349 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/trunk

........
  r64349 | mark.dickinson | 2008-06-17 16:16:55 -0500 (Tue, 17 Jun 2008) | 4 lines
  
  Issue 3118: make test_math pass on Ubuntu/ia64.  exp(-745.0) was raising 
  OverflowError incorrectly on this platform, presumably as a result of 
  the libm setting errno = ERANGE for this call.
........


Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Modules/mathmodule.c

Modified: python/branches/py3k/Modules/mathmodule.c
==============================================================================
--- python/branches/py3k/Modules/mathmodule.c	(original)
+++ python/branches/py3k/Modules/mathmodule.c	Wed Jun 18 00:39:26 2008
@@ -82,12 +82,17 @@
 		 * should return a zero on underflow, and +- HUGE_VAL on
 		 * overflow, so testing the result for zero suffices to
 		 * distinguish the cases).
+		 *
+		 * On some platforms (Ubuntu/ia64) it seems that errno can be
+		 * set to ERANGE for subnormal results that do *not* underflow
+		 * to zero.  So to be safe, we'll ignore ERANGE whenever the
+		 * function result is less than one in absolute value.
 		 */
-		if (x)
+		if (fabs(x) < 1.0)
+			result = 0;
+		else
 			PyErr_SetString(PyExc_OverflowError,
 					"math range error");
-		else
-			result = 0;
 	}
 	else
                 /* Unexpected math error */

From python-3000-checkins at python.org  Wed Jun 18 00:43:48 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Wed, 18 Jun 2008 00:43:48 +0200 (CEST)
Subject: [Python-3000-checkins] r64357 - in python/branches/py3k:
	Lib/test/test_multiprocessing.py
Message-ID: <20080617224348.62D6F1E4004@bag.python.org>

Author: benjamin.peterson
Date: Wed Jun 18 00:43:48 2008
New Revision: 64357

Log:
Merged revisions 64356 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/trunk

........
  r64356 | benjamin.peterson | 2008-06-17 17:40:44 -0500 (Tue, 17 Jun 2008) | 1 line
  
  skip test_multiprocessing when /dev/shm doesn't exist. This seems to be a chroot problem in the buildbot env.
........


Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Lib/test/test_multiprocessing.py

Modified: python/branches/py3k/Lib/test/test_multiprocessing.py
==============================================================================
--- python/branches/py3k/Lib/test/test_multiprocessing.py	(original)
+++ python/branches/py3k/Lib/test/test_multiprocessing.py	Wed Jun 18 00:43:48 2008
@@ -1755,6 +1755,9 @@
 #
 
 def test_main(run=None):
+    if sys.platform.startswith("linux") and not os.path.exists("/dev/shm"):
+        raise TestSkipped("Missing required /dev/shm device on Linux!")
+
     if run is None:
         from test.support import run_unittest as run
 

From python-3000-checkins at python.org  Wed Jun 18 01:05:33 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Wed, 18 Jun 2008 01:05:33 +0200 (CEST)
Subject: [Python-3000-checkins] r64359 - in python/branches/py3k:
	Lib/test/test_multiprocessing.py
Message-ID: <20080617230533.ECF761E4004@bag.python.org>

Author: benjamin.peterson
Date: Wed Jun 18 01:05:33 2008
New Revision: 64359

Log:
Merged revisions 64358 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/trunk

........
  r64358 | benjamin.peterson | 2008-06-17 18:01:59 -0500 (Tue, 17 Jun 2008) | 1 line
  
  add needed import
........


Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Lib/test/test_multiprocessing.py

Modified: python/branches/py3k/Lib/test/test_multiprocessing.py
==============================================================================
--- python/branches/py3k/Lib/test/test_multiprocessing.py	(original)
+++ python/branches/py3k/Lib/test/test_multiprocessing.py	Wed Jun 18 01:05:33 2008
@@ -1756,6 +1756,7 @@
 
 def test_main(run=None):
     if sys.platform.startswith("linux") and not os.path.exists("/dev/shm"):
+        from test.test_support import TestSkipped
         raise TestSkipped("Missing required /dev/shm device on Linux!")
 
     if run is None:

From python-3000-checkins at python.org  Wed Jun 18 01:16:28 2008
From: python-3000-checkins at python.org (amaury.forgeotdarc)
Date: Wed, 18 Jun 2008 01:16:28 +0200 (CEST)
Subject: [Python-3000-checkins] r64362 - in python/branches/py3k:
	Lib/lib2to3/refactor.py
Message-ID: <20080617231628.E2AD81E4004@bag.python.org>

Author: amaury.forgeotdarc
Date: Wed Jun 18 01:16:28 2008
New Revision: 64362

Log:
Merged revisions 64360-64361 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/trunk

........
  r64360 | amaury.forgeotdarc | 2008-06-18 01:09:19 +0200 (mer., 18 juin 2008) | 3 lines
  
  On windows, lib2to3 should accept / and \ in the fixer_dir argument
  Needed to let the tests pass
........
  r64361 | amaury.forgeotdarc | 2008-06-18 01:14:19 +0200 (mer., 18 juin 2008) | 2 lines
  
  Fix the previous fix
........


Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Lib/lib2to3/refactor.py

Modified: python/branches/py3k/Lib/lib2to3/refactor.py
==============================================================================
--- python/branches/py3k/Lib/lib2to3/refactor.py	(original)
+++ python/branches/py3k/Lib/lib2to3/refactor.py	Wed Jun 18 01:16:28 2008
@@ -172,7 +172,9 @@
           want a pre-order AST traversal, and post_order is the list that want
           post-order traversal.
         """
-        fixer_pkg = ".".join(self.fixer_dir.split(os.path.sep))
+        fixer_pkg = self.fixer_dir.replace(os.path.sep, ".")
+        if os.path.altsep:
+            fixer_pkg = fixer_pkg.replace(os.path.altsep, ".")
         pre_order_fixers = []
         post_order_fixers = []
         fix_names = self.options.fix

From python-3000-checkins at python.org  Wed Jun 18 02:01:46 2008
From: python-3000-checkins at python.org (jeremy.hylton)
Date: Wed, 18 Jun 2008 02:01:46 +0200 (CEST)
Subject: [Python-3000-checkins] r64363 -
	python/branches/py3k-urllib/Lib/test/test_urllib2net.py
Message-ID: <20080618000146.4CC4E1E4005@bag.python.org>

Author: jeremy.hylton
Date: Wed Jun 18 02:01:45 2008
New Revision: 64363

Log:
Fix some test failures that look deep into the internals of response objects.


Modified:
   python/branches/py3k-urllib/Lib/test/test_urllib2net.py

Modified: python/branches/py3k-urllib/Lib/test/test_urllib2net.py
==============================================================================
--- python/branches/py3k-urllib/Lib/test/test_urllib2net.py	(original)
+++ python/branches/py3k-urllib/Lib/test/test_urllib2net.py	Wed Jun 18 02:01:45 2008
@@ -80,17 +80,11 @@
         # calling .close() on urllib2's response objects should close the
         # underlying socket
 
-        # delve deep into response to fetch socket._socketobject
         response = _urlopen_with_retry("http://www.python.org/")
-        abused_fileobject = response.fp
-        httpresponse = abused_fileobject.raw
-        self.assert_(httpresponse.__class__ is http.client.HTTPResponse,
-                     httpresponse.__class__)
-        fileobject = httpresponse.fp
-
-        self.assert_(not fileobject.closed)
+        sock = response.fp
+        self.assert_(not sock.closed)
         response.close()
-        self.assert_(fileobject.closed)
+        self.assert_(sock.closed)
 
 class OtherNetworkTests(unittest.TestCase):
     def setUp(self):
@@ -201,7 +195,7 @@
     def test_http_basic(self):
         self.assertTrue(socket.getdefaulttimeout() is None)
         u = _urlopen_with_retry("http://www.python.org")
-        self.assertTrue(u.fp.raw.fp._sock.gettimeout() is None)
+        self.assertTrue(u.fp._sock.gettimeout() is None)
 
     def test_http_default_timeout(self):
         self.assertTrue(socket.getdefaulttimeout() is None)
@@ -210,7 +204,7 @@
             u = _urlopen_with_retry("http://www.python.org")
         finally:
             socket.setdefaulttimeout(None)
-        self.assertEqual(u.fp.raw.fp._sock.gettimeout(), 60)
+        self.assertEqual(u.fp._sock.gettimeout(), 60)
 
     def test_http_no_timeout(self):
         self.assertTrue(socket.getdefaulttimeout() is None)
@@ -219,11 +213,11 @@
             u = _urlopen_with_retry("http://www.python.org", timeout=None)
         finally:
             socket.setdefaulttimeout(None)
-        self.assertTrue(u.fp.raw.fp._sock.gettimeout() is None)
+        self.assertTrue(u.fp._sock.gettimeout() is None)
 
     def test_http_timeout(self):
         u = _urlopen_with_retry("http://www.python.org", timeout=120)
-        self.assertEqual(u.fp.raw.fp._sock.gettimeout(), 120)
+        self.assertEqual(u.fp._sock.gettimeout(), 120)
 
     FTP_HOST = "ftp://ftp.mirror.nl/pub/mirror/gnu/"
 

From python-3000-checkins at python.org  Wed Jun 18 02:47:37 2008
From: python-3000-checkins at python.org (amaury.forgeotdarc)
Date: Wed, 18 Jun 2008 02:47:37 +0200 (CEST)
Subject: [Python-3000-checkins] r64364 - in python/branches/py3k:
	Include/pymem.h Include/pyport.h Lib/test/test_array.py
	Modules/_csv.c Modules/arraymodule.c Modules/audioop.c
	Modules/binascii.c Modules/cjkcodecs/multibytecodec.c
	Modules/datetimemodule.c Objects/listobject.c
	Objects/memoryobject.c Objects/obmalloc.c Parser/node.c
	Python/asdl.c Python/ast.c Python/compile.c
Message-ID: <20080618004737.522341E4004@bag.python.org>

Author: amaury.forgeotdarc
Date: Wed Jun 18 02:47:36 2008
New Revision: 64364

Log:
Merged revisions 64114 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/trunk

........
  r64114 | gregory.p.smith | 2008-06-11 09:41:16 +0200 (mer., 11 juin 2008) | 6 lines
  
  Merge in release25-maint r60793:
  
   Added checks for integer overflows, contributed by Google. Some are
   only available if asserts are left in the code, in cases where they
   can't be triggered from Python code.
........


Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Include/pymem.h
   python/branches/py3k/Include/pyport.h
   python/branches/py3k/Lib/test/test_array.py
   python/branches/py3k/Modules/_csv.c
   python/branches/py3k/Modules/arraymodule.c
   python/branches/py3k/Modules/audioop.c
   python/branches/py3k/Modules/binascii.c
   python/branches/py3k/Modules/cjkcodecs/multibytecodec.c
   python/branches/py3k/Modules/datetimemodule.c
   python/branches/py3k/Objects/listobject.c
   python/branches/py3k/Objects/memoryobject.c
   python/branches/py3k/Objects/obmalloc.c
   python/branches/py3k/Parser/node.c
   python/branches/py3k/Python/asdl.c
   python/branches/py3k/Python/ast.c
   python/branches/py3k/Python/compile.c

Modified: python/branches/py3k/Include/pymem.h
==============================================================================
--- python/branches/py3k/Include/pymem.h	(original)
+++ python/branches/py3k/Include/pymem.h	Wed Jun 18 02:47:36 2008
@@ -85,14 +85,18 @@
  */
 
 #define PyMem_New(type, n) \
-	( (type *) PyMem_Malloc((n) * sizeof(type)) )
+  ( assert((n) <= PY_SIZE_MAX / sizeof(type)) , \
+	( (type *) PyMem_Malloc((n) * sizeof(type)) ) )
 #define PyMem_NEW(type, n) \
-	( (type *) PyMem_MALLOC((n) * sizeof(type)) )
+  ( assert((n) <= PY_SIZE_MAX / sizeof(type)) , \
+	( (type *) PyMem_MALLOC((n) * sizeof(type)) ) )
 
 #define PyMem_Resize(p, type, n) \
-	( (p) = (type *) PyMem_Realloc((p), (n) * sizeof(type)) )
+  ( assert((n) <= PY_SIZE_MAX / sizeof(type)) , \
+	( (p) = (type *) PyMem_Realloc((p), (n) * sizeof(type)) ) )
 #define PyMem_RESIZE(p, type, n) \
-	( (p) = (type *) PyMem_REALLOC((p), (n) * sizeof(type)) )
+  ( assert((n) <= PY_SIZE_MAX / sizeof(type)) , \
+	( (p) = (type *) PyMem_REALLOC((p), (n) * sizeof(type)) ) )
 
 /* PyMem{Del,DEL} are left over from ancient days, and shouldn't be used
  * anymore.  They're just confusing aliases for PyMem_{Free,FREE} now.

Modified: python/branches/py3k/Include/pyport.h
==============================================================================
--- python/branches/py3k/Include/pyport.h	(original)
+++ python/branches/py3k/Include/pyport.h	Wed Jun 18 02:47:36 2008
@@ -106,6 +106,17 @@
 #   error "Python needs a typedef for Py_ssize_t in pyport.h."
 #endif
 
+/* Largest possible value of size_t.
+   SIZE_MAX is part of C99, so it might be defined on some
+   platforms. If it is not defined, (size_t)-1 is a portable
+   definition for C89, due to the way signed->unsigned 
+   conversion is defined. */
+#ifdef SIZE_MAX
+#define PY_SIZE_MAX SIZE_MAX
+#else
+#define PY_SIZE_MAX ((size_t)-1)
+#endif
+
 /* Largest positive value of type Py_ssize_t. */
 #define PY_SSIZE_T_MAX ((Py_ssize_t)(((size_t)-1)>>1))
 /* Smallest negative value of type Py_ssize_t. */

Modified: python/branches/py3k/Lib/test/test_array.py
==============================================================================
--- python/branches/py3k/Lib/test/test_array.py	(original)
+++ python/branches/py3k/Lib/test/test_array.py	Wed Jun 18 02:47:36 2008
@@ -962,6 +962,23 @@
 class DoubleTest(FPTest):
     typecode = 'd'
     minitemsize = 8
+
+    def test_alloc_overflow(self):
+        a = array.array('d', [-1]*65536)
+        try:
+            a *= 65536
+        except MemoryError:
+            pass
+        else:
+            self.fail("a *= 2**16 didn't raise MemoryError")
+        b = array.array('d', [ 2.71828183, 3.14159265, -1])
+        try:
+            b * 1431655766
+        except MemoryError:
+            pass
+        else:
+            self.fail("a * 1431655766 didn't raise MemoryError")
+
 tests.append(DoubleTest)
 
 def test_main(verbose=None):

Modified: python/branches/py3k/Modules/_csv.c
==============================================================================
--- python/branches/py3k/Modules/_csv.c	(original)
+++ python/branches/py3k/Modules/_csv.c	Wed Jun 18 02:47:36 2008
@@ -533,6 +533,10 @@
 		self->field = PyMem_New(Py_UNICODE, self->field_size);
 	}
 	else {
+		if (self->field_size > INT_MAX / 2) {
+			PyErr_NoMemory();
+			return 0;
+		} 
 		self->field_size *= 2;
 		self->field = PyMem_Resize(self->field, Py_UNICODE,
 					   self->field_size);
@@ -1038,6 +1042,12 @@
 static int
 join_check_rec_size(WriterObj *self, int rec_len)
 {
+
+	if (rec_len < 0 || rec_len > INT_MAX - MEM_INCR) {
+		PyErr_NoMemory();
+		return 0;
+	}
+
 	if (rec_len > self->rec_size) {
 		if (self->rec_size == 0) {
 			self->rec_size = (rec_len / MEM_INCR + 1) * MEM_INCR;

Modified: python/branches/py3k/Modules/arraymodule.c
==============================================================================
--- python/branches/py3k/Modules/arraymodule.c	(original)
+++ python/branches/py3k/Modules/arraymodule.c	Wed Jun 18 02:47:36 2008
@@ -642,6 +642,9 @@
 		PyErr_BadArgument();
 		return NULL;
 	}
+	if (Py_SIZE(a) > PY_SSIZE_T_MAX - Py_SIZE(b)) {
+		return PyErr_NoMemory();
+	}
 	size = Py_SIZE(a) + Py_SIZE(b);
 	np = (arrayobject *) newarrayobject(&Arraytype, size, a->ob_descr);
 	if (np == NULL) {
@@ -664,6 +667,9 @@
 	Py_ssize_t nbytes;
 	if (n < 0)
 		n = 0;
+	if ((Py_SIZE(a) != 0) && (n > PY_SSIZE_T_MAX / Py_SIZE(a))) {
+		return PyErr_NoMemory();
+	}
 	size = Py_SIZE(a) * n;
 	np = (arrayobject *) newarrayobject(&Arraytype, size, a->ob_descr);
 	if (np == NULL)
@@ -853,6 +859,10 @@
 		if (n < 0)
 			n = 0;
 		items = self->ob_item;
+		if ((self->ob_descr->itemsize != 0) && 
+			(Py_SIZE(self) > PY_SSIZE_T_MAX / self->ob_descr->itemsize)) {
+			return PyErr_NoMemory();
+		}
 		size = Py_SIZE(self) * self->ob_descr->itemsize;
 		if (n == 0) {
 			PyMem_FREE(items);
@@ -861,6 +871,9 @@
 			self->allocated = 0;
 		}
 		else {
+			if (size > PY_SSIZE_T_MAX / n) {
+				return PyErr_NoMemory();
+			}
 			PyMem_Resize(items, char, n * size);
 			if (items == NULL)
 				return PyErr_NoMemory();
@@ -1142,6 +1155,10 @@
 		Py_INCREF(dict);
 	}
 	if (Py_SIZE(array) > 0) {
+		if (array->ob_descr->itemsize 
+				> PY_SSIZE_T_MAX / Py_SIZE(array)) {
+			return PyErr_NoMemory();
+		}
 		result = Py_BuildValue("O(cy#)O", 
 			Py_TYPE(array), 
 			array->ob_descr->typecode,
@@ -1315,6 +1332,9 @@
 			if ((*self->ob_descr->setitem)(self,
 					Py_SIZE(self) - n + i, v) != 0) {
 				Py_SIZE(self) -= n;
+				if (itemsize && (Py_SIZE(self) > PY_SSIZE_T_MAX / itemsize)) {
+					return PyErr_NoMemory();
+				}
 				PyMem_RESIZE(item, char,
 					          Py_SIZE(self) * itemsize);
 				self->ob_item = item;
@@ -1373,6 +1393,10 @@
 	n = n / itemsize;
 	if (n > 0) {
 		char *item = self->ob_item;
+		if ((n > PY_SSIZE_T_MAX - Py_SIZE(self)) ||
+			((Py_SIZE(self) + n) > PY_SSIZE_T_MAX / itemsize)) {
+				return PyErr_NoMemory();
+		}
 		PyMem_RESIZE(item, char, (Py_SIZE(self) + n) * itemsize);
 		if (item == NULL) {
 			PyErr_NoMemory();
@@ -1398,8 +1422,12 @@
 static PyObject *
 array_tostring(arrayobject *self, PyObject *unused)
 {
-	return PyBytes_FromStringAndSize(self->ob_item,
-                                         Py_SIZE(self) * self->ob_descr->itemsize);
+	if (Py_SIZE(self) <= PY_SSIZE_T_MAX / self->ob_descr->itemsize) {
+		return PyBytes_FromStringAndSize(self->ob_item,
+				    Py_SIZE(self) * self->ob_descr->itemsize);
+	} else {
+		return PyErr_NoMemory();
+	}
 }
 
 PyDoc_STRVAR(tostring_doc,
@@ -1428,6 +1456,9 @@
 	}
 	if (n > 0) {
 		Py_UNICODE *item = (Py_UNICODE *) self->ob_item;
+		if (Py_SIZE(self) > PY_SSIZE_T_MAX - n) {
+			return PyErr_NoMemory();
+		}
 		PyMem_RESIZE(item, Py_UNICODE, Py_SIZE(self) + n);
 		if (item == NULL) {
 			PyErr_NoMemory();

Modified: python/branches/py3k/Modules/audioop.c
==============================================================================
--- python/branches/py3k/Modules/audioop.c	(original)
+++ python/branches/py3k/Modules/audioop.c	Wed Jun 18 02:47:36 2008
@@ -829,7 +829,7 @@
 audioop_tostereo(PyObject *self, PyObject *args)
 {
         signed char *cp, *ncp;
-        int len, size, val1, val2, val = 0;
+        int len, new_len, size, val1, val2, val = 0;
         double fac1, fac2, fval, maxval;
         PyObject *rv;
         int i;
@@ -846,7 +846,14 @@
                 return 0;
         }
     
-        rv = PyBytes_FromStringAndSize(NULL, len*2);
+        new_len = len*2;
+        if (new_len < 0) {
+                PyErr_SetString(PyExc_MemoryError,
+                                "not enough memory for output buffer");
+                return 0;
+        }
+
+        rv = PyBytes_FromStringAndSize(NULL, new_len);
         if ( rv == 0 )
                 return 0;
         ncp = (signed char *)PyBytes_AsString(rv);
@@ -1009,7 +1016,7 @@
 {
         signed char *cp;
         unsigned char *ncp;
-        int len, size, size2, val = 0;
+        int len, new_len, size, size2, val = 0;
         PyObject *rv;
         int i, j;
 
@@ -1023,7 +1030,13 @@
                 return 0;
         }
     
-        rv = PyBytes_FromStringAndSize(NULL, (len/size)*size2);
+        new_len = (len/size)*size2;
+        if (new_len < 0) {
+                PyErr_SetString(PyExc_MemoryError,
+                                "not enough memory for output buffer");
+                return 0;
+        }
+        rv = PyBytes_FromStringAndSize(NULL, new_len);
         if ( rv == 0 )
                 return 0;
         ncp = (unsigned char *)PyBytes_AsString(rv);
@@ -1059,6 +1072,7 @@
         int chan, d, *prev_i, *cur_i, cur_o;
         PyObject *state, *samps, *str, *rv = NULL;
         int bytes_per_frame;
+        size_t alloc_size;
 
         weightA = 1;
         weightB = 0;
@@ -1101,8 +1115,14 @@
         inrate /= d;
         outrate /= d;
 
-        prev_i = (int *) malloc(nchannels * sizeof(int));
-        cur_i = (int *) malloc(nchannels * sizeof(int));
+        alloc_size = sizeof(int) * (unsigned)nchannels;
+        if (alloc_size < nchannels) {
+                PyErr_SetString(PyExc_MemoryError,
+                                "not enough memory for output buffer");
+                return 0;
+        }
+        prev_i = (int *) malloc(alloc_size);
+        cur_i = (int *) malloc(alloc_size);
         if (prev_i == NULL || cur_i == NULL) {
                 (void) PyErr_NoMemory();
                 goto exit;
@@ -1275,7 +1295,7 @@
         unsigned char *cp;
         unsigned char cval;
         signed char *ncp;
-        int len, size, val;
+        int len, new_len, size, val;
         PyObject *rv;
         int i;
 
@@ -1288,12 +1308,18 @@
                 return 0;
         }
     
-        rv = PyBytes_FromStringAndSize(NULL, len*size);
+        new_len = len*size;
+        if (new_len < 0) {
+                PyErr_SetString(PyExc_MemoryError,
+                                "not enough memory for output buffer");
+                return 0;
+        }
+        rv = PyBytes_FromStringAndSize(NULL, new_len);
         if ( rv == 0 )
                 return 0;
         ncp = (signed char *)PyBytes_AsString(rv);
     
-        for ( i=0; i < len*size; i += size ) {
+        for ( i=0; i < new_len; i += size ) {
                 cval = *cp++;
                 val = st_ulaw2linear16(cval);
         
@@ -1343,7 +1369,7 @@
         unsigned char *cp;
         unsigned char cval;
         signed char *ncp;
-        int len, size, val;
+        int len, new_len, size, val;
         PyObject *rv;
         int i;
 
@@ -1356,12 +1382,18 @@
                 return 0;
         }
     
-        rv = PyBytes_FromStringAndSize(NULL, len*size);
+        new_len = len*size;
+        if (new_len < 0) {
+                PyErr_SetString(PyExc_MemoryError,
+                                "not enough memory for output buffer");
+                return 0;
+        }
+        rv = PyBytes_FromStringAndSize(NULL, new_len);
         if ( rv == 0 )
                 return 0;
         ncp = (signed char *)PyBytes_AsString(rv);
     
-        for ( i=0; i < len*size; i += size ) {
+        for ( i=0; i < new_len; i += size ) {
                 cval = *cp++;
                 val = st_alaw2linear16(cval);
         
@@ -1486,7 +1518,7 @@
 {
         signed char *cp;
         signed char *ncp;
-        int len, size, valpred, step, delta, index, sign, vpdiff;
+        int len, new_len, size, valpred, step, delta, index, sign, vpdiff;
         PyObject *rv, *str, *state;
         int i, inputbuffer = 0, bufferstep;
 
@@ -1508,7 +1540,13 @@
         } else if ( !PyArg_ParseTuple(state, "ii", &valpred, &index) )
                 return 0;
     
-        str = PyBytes_FromStringAndSize(NULL, len*size*2);
+        new_len = len*size*2;
+        if (new_len < 0) {
+                PyErr_SetString(PyExc_MemoryError,
+                                "not enough memory for output buffer");
+                return 0;
+        }
+        str = PyBytes_FromStringAndSize(NULL, new_len);
         if ( str == 0 )
                 return 0;
         ncp = (signed char *)PyBytes_AsString(str);
@@ -1516,7 +1554,7 @@
         step = stepsizeTable[index];
         bufferstep = 0;
     
-        for ( i=0; i < len*size*2; i += size ) {
+        for ( i=0; i < new_len; i += size ) {
                 /* Step 1 - get the delta value and compute next index */
                 if ( bufferstep ) {
                         delta = inputbuffer & 0xf;

Modified: python/branches/py3k/Modules/binascii.c
==============================================================================
--- python/branches/py3k/Modules/binascii.c	(original)
+++ python/branches/py3k/Modules/binascii.c	Wed Jun 18 02:47:36 2008
@@ -198,6 +198,8 @@
 	if ( !PyArg_ParseTuple(args, "t#:a2b_uu", &ascii_data, &ascii_len) )
 		return NULL;
 
+	assert(ascii_len >= 0);
+
 	/* First byte: binary data length (in bytes) */
 	bin_len = (*ascii_data++ - ' ') & 077;
 	ascii_len--;
@@ -355,6 +357,11 @@
 	if ( !PyArg_ParseTuple(args, "t#:a2b_base64", &ascii_data, &ascii_len) )
 		return NULL;
 
+	assert(ascii_len >= 0);
+
+	if (ascii_len > PY_SSIZE_T_MAX - 3)
+		return PyErr_NoMemory();
+
 	bin_len = ((ascii_len+3)/4)*3; /* Upper bound, corrected later */
 
 	/* Allocate the buffer */
@@ -448,6 +455,9 @@
 
 	if ( !PyArg_ParseTuple(args, "s#:b2a_base64", &bin_data, &bin_len) )
 		return NULL;
+
+	assert(bin_len >= 0);
+
 	if ( bin_len > BASE64_MAXBIN ) {
 		PyErr_SetString(Error, "Too much data for base64 line");
 		return NULL;
@@ -507,6 +517,11 @@
 	if ( !PyArg_ParseTuple(args, "t#:a2b_hqx", &ascii_data, &len) )
 		return NULL;
 
+	assert(len >= 0);
+
+	if (len > PY_SSIZE_T_MAX - 2)
+		return PyErr_NoMemory();
+
 	/* Allocate a string that is too big (fixed later) 
 	   Add two to the initial length to prevent interning which
 	   would preclude subsequent resizing.  */
@@ -574,6 +589,11 @@
 	if ( !PyArg_ParseTuple(args, "s#:rlecode_hqx", &in_data, &len) )
 		return NULL;
 
+	assert(len >= 0);
+
+	if (len > PY_SSIZE_T_MAX / 2 - 2)
+		return PyErr_NoMemory();
+
 	/* Worst case: output is twice as big as input (fixed later) */
 	if ( (rv=PyBytes_FromStringAndSize(NULL, len*2+2)) == NULL )
 		return NULL;
@@ -627,6 +647,11 @@
 	if ( !PyArg_ParseTuple(args, "s#:b2a_hqx", &bin_data, &len) )
 		return NULL;
 
+	assert(len >= 0);
+
+	if (len > PY_SSIZE_T_MAX / 2 - 2)
+		return PyErr_NoMemory();
+
 	/* Allocate a buffer that is at least large enough */
 	if ( (rv=PyBytes_FromStringAndSize(NULL, len*2+2)) == NULL )
 		return NULL;
@@ -669,9 +694,13 @@
 	if ( !PyArg_ParseTuple(args, "s#:rledecode_hqx", &in_data, &in_len) )
 		return NULL;
 
+	assert(in_len >= 0);
+
 	/* Empty string is a special case */
 	if ( in_len == 0 )
 		return PyBytes_FromStringAndSize("", 0);
+	else if (in_len > PY_SSIZE_T_MAX / 2)
+		return PyErr_NoMemory();
 
 	/* Allocate a buffer of reasonable size. Resized when needed */
 	out_len = in_len*2;
@@ -697,6 +726,7 @@
 #define OUTBYTE(b) \
 	do { \
 		 if ( --out_len_left < 0 ) { \
+			  if ( out_len > PY_SSIZE_T_MAX / 2) return PyErr_NoMemory(); \
 			  if (_PyBytes_Resize(&rv, 2*out_len) < 0) \
 			    { Py_DECREF(rv); return NULL; } \
 			  out_data = (unsigned char *)PyBytes_AS_STRING(rv) \
@@ -769,7 +799,7 @@
 	if ( !PyArg_ParseTuple(args, "s#i:crc_hqx", &bin_data, &len, &crc) )
 		return NULL;
 
-	while(len--) {
+	while(len-- > 0) {
 		crc=((crc<<8)&0xff00)^crctab_hqx[((crc>>8)&0xff)^*bin_data++];
 	}
 
@@ -925,7 +955,7 @@
 		return NULL;
 
 	crc = ~ crc;
-	while (len--) {
+	while (len-- > 0) {
 		crc = crc_32_tab[(crc ^ *bin_data++) & 0xff] ^ (crc >> 8);
 		/* Note:  (crc >> 8) MUST zero fill on left */
 	}
@@ -948,6 +978,10 @@
 	if (!PyArg_ParseTuple(args, "s#:b2a_hex", &argbuf, &arglen))
 		return NULL;
 
+	assert(arglen >= 0);
+	if (arglen > PY_SSIZE_T_MAX / 2)
+		return PyErr_NoMemory();
+
 	retval = PyBytes_FromStringAndSize(NULL, arglen*2);
 	if (!retval)
 		return NULL;
@@ -999,6 +1033,8 @@
 	if (!PyArg_ParseTuple(args, "s#:a2b_hex", &argbuf, &arglen))
 		return NULL;
 
+	assert(arglen >= 0);
+
 	/* XXX What should we do about strings with an odd length?  Should
 	 * we add an implicit leading zero, or a trailing zero?  For now,
 	 * raise an exception.

Modified: python/branches/py3k/Modules/cjkcodecs/multibytecodec.c
==============================================================================
--- python/branches/py3k/Modules/cjkcodecs/multibytecodec.c	(original)
+++ python/branches/py3k/Modules/cjkcodecs/multibytecodec.c	Wed Jun 18 02:47:36 2008
@@ -172,13 +172,17 @@
 static int
 expand_encodebuffer(MultibyteEncodeBuffer *buf, Py_ssize_t esize)
 {
-	Py_ssize_t orgpos, orgsize;
+	Py_ssize_t orgpos, orgsize, incsize;
 
 	orgpos = (Py_ssize_t)((char *)buf->outbuf -
 				PyBytes_AS_STRING(buf->outobj));
 	orgsize = PyBytes_GET_SIZE(buf->outobj);
-	if (_PyBytes_Resize(&buf->outobj, orgsize + (
-	    esize < (orgsize >> 1) ? (orgsize >> 1) | 1 : esize)) == -1)
+	incsize = (esize < (orgsize >> 1) ? (orgsize >> 1) | 1 : esize);
+
+	if (orgsize > PY_SSIZE_T_MAX - incsize)
+		return -1;
+
+	if (_PyBytes_Resize(&buf->outobj, orgsize + incsize) == -1)
 		return -1;
 
 	buf->outbuf = (unsigned char *)PyBytes_AS_STRING(buf->outobj) +orgpos;
@@ -481,6 +485,12 @@
 	buf.excobj = NULL;
 	buf.inbuf = buf.inbuf_top = *data;
 	buf.inbuf_end = buf.inbuf_top + datalen;
+
+	if (datalen > (PY_SSIZE_T_MAX - 16) / 2) {
+		PyErr_NoMemory();
+		goto errorexit;
+	}
+
 	buf.outobj = PyBytes_FromStringAndSize(NULL, datalen * 2 + 16);
 	if (buf.outobj == NULL)
 		goto errorexit;
@@ -743,6 +753,11 @@
 	origpending = ctx->pendingsize;
 
 	if (origpending > 0) {
+		if (datalen > PY_SSIZE_T_MAX - ctx->pendingsize) {
+			PyErr_NoMemory();
+			/* inbuf_tmp == NULL */
+			goto errorexit;
+		}
 		inbuf_tmp = PyMem_New(Py_UNICODE, datalen + ctx->pendingsize);
 		if (inbuf_tmp == NULL)
 			goto errorexit;
@@ -805,9 +820,10 @@
 	Py_ssize_t npendings;
 
 	npendings = (Py_ssize_t)(buf->inbuf_end - buf->inbuf);
-	if (npendings + ctx->pendingsize > MAXDECPENDING) {
-		PyErr_SetString(PyExc_UnicodeError, "pending buffer overflow");
-		return -1;
+	if (npendings + ctx->pendingsize > MAXDECPENDING ||
+		npendings > PY_SSIZE_T_MAX - ctx->pendingsize) {
+			PyErr_SetString(PyExc_UnicodeError, "pending buffer overflow");
+			return -1;
 	}
 	memcpy(ctx->pending + ctx->pendingsize, buf->inbuf, npendings);
 	ctx->pendingsize += npendings;
@@ -1009,7 +1025,7 @@
 		  PyObject *args, PyObject *kwargs)
 {
 	MultibyteDecodeBuffer buf;
-	char *data, *wdata;
+	char *data, *wdata = NULL;
 	Py_ssize_t wsize, finalsize = 0, size, origpending;
 	int final = 0;
 
@@ -1025,6 +1041,10 @@
 		wdata = data;
 	}
 	else {
+		if (size > PY_SSIZE_T_MAX - self->pendingsize) {
+			PyErr_NoMemory();
+			goto errorexit;
+		}
 		wsize = size + self->pendingsize;
 		wdata = PyMem_Malloc(wsize);
 		if (wdata == NULL)
@@ -1244,6 +1264,10 @@
 			PyObject *ctr;
 			char *ctrdata;
 
+			if (PyBytes_GET_SIZE(cres) > PY_SSIZE_T_MAX - self->pendingsize) {
+				PyErr_NoMemory();
+				goto errorexit;
+            }
 			rsize = PyBytes_GET_SIZE(cres) + self->pendingsize;
 			ctr = PyBytes_FromStringAndSize(NULL, rsize);
 			if (ctr == NULL)

Modified: python/branches/py3k/Modules/datetimemodule.c
==============================================================================
--- python/branches/py3k/Modules/datetimemodule.c	(original)
+++ python/branches/py3k/Modules/datetimemodule.c	Wed Jun 18 02:47:36 2008
@@ -1111,6 +1111,8 @@
 	char sign;
 	int none;
 
+	assert(buflen >= 1);
+
 	offset = call_utcoffset(tzinfo, tzinfoarg, &none);
 	if (offset == -1 && PyErr_Occurred())
 		return -1;
@@ -1250,6 +1252,11 @@
 	 * a new format.  Since computing the replacements for those codes
 	 * is expensive, don't unless they're actually used.
 	 */
+	if (flen > INT_MAX - 1) {
+		PyErr_NoMemory();
+		goto Done;
+	}
+
 	totalnew = flen + 1;	/* realistic if no %z/%Z */
 	newfmt = PyBytes_FromStringAndSize(NULL, totalnew);
 	if (newfmt == NULL) goto Done;

Modified: python/branches/py3k/Objects/listobject.c
==============================================================================
--- python/branches/py3k/Objects/listobject.c	(original)
+++ python/branches/py3k/Objects/listobject.c	Wed Jun 18 02:47:36 2008
@@ -45,7 +45,16 @@
 	 * system realloc().
 	 * The growth pattern is:  0, 4, 8, 16, 25, 35, 46, 58, 72, 88, ...
 	 */
-	new_allocated = (newsize >> 3) + (newsize < 9 ? 3 : 6) + newsize;
+	new_allocated = (newsize >> 3) + (newsize < 9 ? 3 : 6);
+
+	/* check for integer overflow */
+	if (new_allocated > PY_SIZE_MAX - newsize) {
+		PyErr_NoMemory();
+		return -1;
+	} else {
+		new_allocated += newsize;
+	}
+
 	if (newsize == 0)
 		new_allocated = 0;
 	items = self->ob_item;
@@ -118,8 +127,9 @@
 		return NULL;
 	}
 	nbytes = size * sizeof(PyObject *);
-	/* Check for overflow */
-	if (nbytes / sizeof(PyObject *) != (size_t)size)
+	/* Check for overflow without an actual overflow,
+	 *  which can cause compiler to optimise out */
+	if (size > PY_SIZE_MAX / sizeof(PyObject *))
 		return PyErr_NoMemory();
 	if (numfree) {
 		numfree--;
@@ -1323,6 +1333,10 @@
 	 * we don't care what's in the block.
 	 */
 	merge_freemem(ms);
+	if (need > PY_SSIZE_T_MAX / sizeof(PyObject*)) {
+		PyErr_NoMemory();
+		return -1;
+	}
 	ms->a = (PyObject **)PyMem_Malloc(need * sizeof(PyObject*));
 	if (ms->a) {
 		ms->alloced = need;
@@ -2415,6 +2429,8 @@
 				step = -step;
 			}
 
+			assert(slicelength <= PY_SIZE_MAX / sizeof(PyObject*));
+
 			garbage = (PyObject**)
 				PyMem_MALLOC(slicelength*sizeof(PyObject*));
 			if (!garbage) {

Modified: python/branches/py3k/Objects/memoryobject.c
==============================================================================
--- python/branches/py3k/Objects/memoryobject.c	(original)
+++ python/branches/py3k/Objects/memoryobject.c	Wed Jun 18 02:47:36 2008
@@ -151,8 +151,11 @@
         char *ptr;
         void (*func)(int, Py_ssize_t *, Py_ssize_t *);
 
+        if (view->ndim > PY_SSIZE_T_MAX / sizeof(Py_ssize_t)) {
+                PyErr_NoMemory();
+                return -1;
+        }
 
-        /* XXX(nnorwitz): need to check for overflow! */
         indices = (Py_ssize_t *)PyMem_Malloc(sizeof(Py_ssize_t)*view->ndim);
         if (indices == NULL) {
                 PyErr_NoMemory();

Modified: python/branches/py3k/Objects/obmalloc.c
==============================================================================
--- python/branches/py3k/Objects/obmalloc.c	(original)
+++ python/branches/py3k/Objects/obmalloc.c	Wed Jun 18 02:47:36 2008
@@ -526,9 +526,9 @@
 		numarenas = maxarenas ? maxarenas << 1 : INITIAL_ARENA_OBJECTS;
 		if (numarenas <= maxarenas)
 			return NULL;	/* overflow */
-		nbytes = numarenas * sizeof(*arenas);
-		if (nbytes / sizeof(*arenas) != numarenas)
+		if (numarenas > PY_SIZE_MAX / sizeof(*arenas))
 			return NULL;	/* overflow */
+		nbytes = numarenas * sizeof(*arenas);
 		arenaobj = (struct arena_object *)realloc(arenas, nbytes);
 		if (arenaobj == NULL)
 			return NULL;

Modified: python/branches/py3k/Parser/node.c
==============================================================================
--- python/branches/py3k/Parser/node.c	(original)
+++ python/branches/py3k/Parser/node.c	Wed Jun 18 02:47:36 2008
@@ -91,6 +91,9 @@
 	if (current_capacity < 0 || required_capacity < 0)
 		return E_OVERFLOW;
 	if (current_capacity < required_capacity) {
+		if (required_capacity > PY_SIZE_MAX / sizeof(node)) {
+			return E_NOMEM;
+		}
 		n = n1->n_child;
 		n = (node *) PyObject_REALLOC(n,
 					      required_capacity * sizeof(node));

Modified: python/branches/py3k/Python/asdl.c
==============================================================================
--- python/branches/py3k/Python/asdl.c	(original)
+++ python/branches/py3k/Python/asdl.c	Wed Jun 18 02:47:36 2008
@@ -5,8 +5,22 @@
 asdl_seq_new(int size, PyArena *arena)
 {
 	asdl_seq *seq = NULL;
-	size_t n = sizeof(asdl_seq) +
-			(size ? (sizeof(void *) * (size - 1)) : 0);
+	size_t n = (size ? (sizeof(void *) * (size - 1)) : 0);
+
+	/* check size is sane */
+	if (size < 0 || size == INT_MIN || 
+		(size && ((size - 1) > (PY_SIZE_MAX / sizeof(void *))))) {
+		PyErr_NoMemory();
+		return NULL;
+	}
+
+	/* check if size can be added safely */
+	if (n > PY_SIZE_MAX - sizeof(asdl_seq)) {
+		PyErr_NoMemory();
+		return NULL;
+	}
+
+	n += sizeof(asdl_seq);
 
 	seq = (asdl_seq *)PyArena_Malloc(arena, n);
 	if (!seq) {
@@ -22,8 +36,22 @@
 asdl_int_seq_new(int size, PyArena *arena)
 {
 	asdl_int_seq *seq = NULL;
-	size_t n = sizeof(asdl_seq) +
-			(size ? (sizeof(int) * (size - 1)) : 0);
+	size_t n = (size ? (sizeof(void *) * (size - 1)) : 0);
+
+	/* check size is sane */
+	if (size < 0 || size == INT_MIN || 
+		(size && ((size - 1) > (PY_SIZE_MAX / sizeof(void *))))) {
+			PyErr_NoMemory();
+			return NULL;
+	}
+
+	/* check if size can be added safely */
+	if (n > PY_SIZE_MAX - sizeof(asdl_seq)) {
+		PyErr_NoMemory();
+		return NULL;
+	}
+
+	n += sizeof(asdl_seq);
 
 	seq = (asdl_int_seq *)PyArena_Malloc(arena, n);
 	if (!seq) {

Modified: python/branches/py3k/Python/ast.c
==============================================================================
--- python/branches/py3k/Python/ast.c	(original)
+++ python/branches/py3k/Python/ast.c	Wed Jun 18 02:47:36 2008
@@ -3145,6 +3145,9 @@
         buf = (char *)s;
         u = NULL;
     } else {
+        /* check for integer overflow */
+        if (len > PY_SIZE_MAX / 4)
+            return NULL;
         /* "\XX" may become "\u005c\uHHLL" (12 bytes) */
         u = PyBytes_FromStringAndSize((char *)NULL, len * 4);
         if (u == NULL)

Modified: python/branches/py3k/Python/compile.c
==============================================================================
--- python/branches/py3k/Python/compile.c	(original)
+++ python/branches/py3k/Python/compile.c	Wed Jun 18 02:47:36 2008
@@ -227,6 +227,10 @@
 		return ident; /* Don't mangle if class is just underscores */
 	}
 	plen = Py_UNICODE_strlen(p);
+
+	assert(1 <= PY_SSIZE_T_MAX - nlen);
+	assert(1 + nlen <= PY_SSIZE_T_MAX - plen);
+
 	ident = PyUnicode_FromStringAndSize(NULL, 1 + nlen + plen);
 	if (!ident)
 		return 0;
@@ -635,6 +639,12 @@
 		size_t oldsize, newsize;
 		oldsize = b->b_ialloc * sizeof(struct instr);
 		newsize = oldsize << 1;
+
+		if (oldsize > (PY_SIZE_MAX >> 1)) {
+			PyErr_NoMemory();
+			return -1;
+		}
+
 		if (newsize == 0) {
 			PyErr_NoMemory();
 			return -1;
@@ -3711,6 +3721,10 @@
 	a->a_lnotab = PyBytes_FromStringAndSize(NULL, DEFAULT_LNOTAB_SIZE);
 	if (!a->a_lnotab)
 		return 0;
+	if (nblocks > PY_SIZE_MAX / sizeof(basicblock *)) {
+		PyErr_NoMemory();
+		return 0;
+	}
 	a->a_postorder = (basicblock **)PyObject_Malloc(
 					    sizeof(basicblock *) * nblocks);
 	if (!a->a_postorder) {
@@ -3819,10 +3833,14 @@
 		nbytes = a->a_lnotab_off + 2 * ncodes;
 		len = PyBytes_GET_SIZE(a->a_lnotab);
 		if (nbytes >= len) {
-			if (len * 2 < nbytes)
+			if ((len <= INT_MAX / 2) && (len * 2 < nbytes))
 				len = nbytes;
-			else
+			else if (len <= INT_MAX / 2)
 				len *= 2;
+			else {
+				PyErr_NoMemory();
+				return 0;
+			}
 			if (_PyBytes_Resize(&a->a_lnotab, len) < 0)
 				return 0;
 		}
@@ -3841,10 +3859,14 @@
 		nbytes = a->a_lnotab_off + 2 * ncodes;
 		len = PyBytes_GET_SIZE(a->a_lnotab);
 		if (nbytes >= len) {
-			if (len * 2 < nbytes)
+			if ((len <= INT_MAX / 2) && len * 2 < nbytes)
 				len = nbytes;
-			else
+			else if (len <= INT_MAX / 2)
 				len *= 2;
+			else {
+				PyErr_NoMemory();
+				return 0;
+			}
 			if (_PyBytes_Resize(&a->a_lnotab, len) < 0)
 				return 0;
 		}
@@ -3903,6 +3925,8 @@
 	if (i->i_lineno && !assemble_lnotab(a, i))
 		return 0;
 	if (a->a_offset + size >= len) {
+		if (len > PY_SSIZE_T_MAX / 2)
+			return 0;
 		if (_PyBytes_Resize(&a->a_bytecode, len * 2) < 0)
 		    return 0;
 	}

From python-3000-checkins at python.org  Wed Jun 18 04:55:54 2008
From: python-3000-checkins at python.org (senthil.kumaran)
Date: Wed, 18 Jun 2008 04:55:54 +0200 (CEST)
Subject: [Python-3000-checkins] r64366 - in python/branches/py3k-urllib/Lib:
	test/support.py xml/dom/xmlbuilder.py xml/sax/saxutils.py
Message-ID: <20080618025554.B70241E400C@bag.python.org>

Author: senthil.kumaran
Date: Wed Jun 18 04:55:54 2008
New Revision: 64366

Log:
changes to urllib references in xml/dom xml/sax and test/support.py

Modified:
   python/branches/py3k-urllib/Lib/test/support.py
   python/branches/py3k-urllib/Lib/xml/dom/xmlbuilder.py
   python/branches/py3k-urllib/Lib/xml/sax/saxutils.py

Modified: python/branches/py3k-urllib/Lib/test/support.py
==============================================================================
--- python/branches/py3k-urllib/Lib/test/support.py	(original)
+++ python/branches/py3k-urllib/Lib/test/support.py	Wed Jun 18 04:55:54 2008
@@ -352,10 +352,10 @@
         testcase.fail('Missing SyntaxError: "%s"' % statement)
 
 def open_urlresource(url, *args, **kw):
-    import urllib, urlparse
+    import urllib.request, urllib.parse
 
     requires('urlfetch')
-    filename = urlparse.urlparse(url)[2].split('/')[-1] # '/': it's URL!
+    filename = urllib.parse.urlparse(url)[2].split('/')[-1] # '/': it's URL!
 
     for path in [os.path.curdir, os.path.pardir]:
         fn = os.path.join(path, filename)
@@ -363,7 +363,7 @@
             return open(fn, *args, **kw)
 
     print('\tfetching %s ...' % url, file=get_original_stdout())
-    fn, _ = urllib.urlretrieve(url, filename)
+    fn, _ = urllib.request.urlretrieve(url, filename)
     return open(fn, *args, **kw)
 
 

Modified: python/branches/py3k-urllib/Lib/xml/dom/xmlbuilder.py
==============================================================================
--- python/branches/py3k-urllib/Lib/xml/dom/xmlbuilder.py	(original)
+++ python/branches/py3k-urllib/Lib/xml/dom/xmlbuilder.py	Wed Jun 18 04:55:54 2008
@@ -223,14 +223,14 @@
         source.encoding = self._guess_media_encoding(source)
 
         # determine the base URI is we can
-        import posixpath, urlparse
-        parts = urlparse.urlparse(systemId)
+        import posixpath, urllib.parse
+        parts = urllib.parse.urlparse(systemId)
         scheme, netloc, path, params, query, fragment = parts
         # XXX should we check the scheme here as well?
         if path and not path.endswith("/"):
             path = posixpath.dirname(path) + "/"
             parts = scheme, netloc, path, params, query, fragment
-            source.baseURI = urlparse.urlunparse(parts)
+            source.baseURI = urllib.parse.urlunparse(parts)
 
         return source
 

Modified: python/branches/py3k-urllib/Lib/xml/sax/saxutils.py
==============================================================================
--- python/branches/py3k-urllib/Lib/xml/sax/saxutils.py	(original)
+++ python/branches/py3k-urllib/Lib/xml/sax/saxutils.py	Wed Jun 18 04:55:54 2008
@@ -3,7 +3,7 @@
 convenience of application and driver writers.
 """
 
-import os, urlparse, urllib
+import os, urllib.parse, urllib.request
 from . import handler
 from . import xmlreader
 
@@ -289,8 +289,8 @@
             source.setSystemId(sysidfilename)
             f = open(sysidfilename, "rb")
         else:
-            source.setSystemId(urlparse.urljoin(base, sysid))
-            f = urllib.urlopen(source.getSystemId())
+            source.setSystemId(urllib.parse.urljoin(base, sysid))
+            f = urllib.request.urlopen(source.getSystemId())
 
         source.setByteStream(f)
 

From python-3000-checkins at python.org  Wed Jun 18 06:12:32 2008
From: python-3000-checkins at python.org (senthil.kumaran)
Date: Wed, 18 Jun 2008 06:12:32 +0200 (CEST)
Subject: [Python-3000-checkins] r64367 - in python/branches/py3k-urllib/Lib:
	test/test_urllib2_localnet.py xml/dom/xmlbuilder.py
Message-ID: <20080618041232.4ABED1E4002@bag.python.org>

Author: senthil.kumaran
Date: Wed Jun 18 06:12:31 2008
New Revision: 64367

Log:
some more cleanup in urllib2 references

Modified:
   python/branches/py3k-urllib/Lib/test/test_urllib2_localnet.py
   python/branches/py3k-urllib/Lib/xml/dom/xmlbuilder.py

Modified: python/branches/py3k-urllib/Lib/test/test_urllib2_localnet.py
==============================================================================
--- python/branches/py3k-urllib/Lib/test/test_urllib2_localnet.py	(original)
+++ python/branches/py3k-urllib/Lib/test/test_urllib2_localnet.py	Wed Jun 18 06:12:31 2008
@@ -425,7 +425,7 @@
         self.assertEqual(info_obj.getsubtype(), "plain")
 
         try:
-            open_url = urllib2.urlopen("http://localhost:%s" % handler.port)
+            open_url = urllib.request.urlopen("http://localhost:%s" % handler.port)
             info_obj = open_url.info()
             self.assert_(isinstance(info_obj, email.message.Message),
                          "object returned by 'info' is not an instance of "

Modified: python/branches/py3k-urllib/Lib/xml/dom/xmlbuilder.py
==============================================================================
--- python/branches/py3k-urllib/Lib/xml/dom/xmlbuilder.py	(original)
+++ python/branches/py3k-urllib/Lib/xml/dom/xmlbuilder.py	Wed Jun 18 06:12:31 2008
@@ -190,8 +190,8 @@
         options.errorHandler = self.errorHandler
         fp = input.byteStream
         if fp is None and options.systemId:
-            import urllib2
-            fp = urllib2.urlopen(input.systemId)
+            import urllib.request
+            fp = urllib.request.urlopen(input.systemId)
         return self._parse_bytestream(fp, options)
 
     def parseWithContext(self, input, cnode, action):
@@ -242,8 +242,8 @@
             return self._opener
 
     def _create_opener(self):
-        import urllib2
-        return urllib2.build_opener()
+        import urllib.request
+        return urllib.request.build_opener()
 
     def _guess_media_encoding(self, source):
         info = source.byteStream.info()

From python-3000-checkins at python.org  Wed Jun 18 12:04:31 2008
From: python-3000-checkins at python.org (mark.dickinson)
Date: Wed, 18 Jun 2008 12:04:31 +0200 (CEST)
Subject: [Python-3000-checkins] r64372 - in python/branches/py3k:
	Lib/test/ieee754.txt Modules/mathmodule.c
Message-ID: <20080618100431.676FC1E4005@bag.python.org>

Author: mark.dickinson
Date: Wed Jun 18 12:04:31 2008
New Revision: 64372

Log:
Quick fix for test_math failures on Solaris 10 buildbot.  For future 
reference, note that that asin(float('inf')) doesn't seem to return the 
expected NaN on this platform.


Modified:
   python/branches/py3k/Lib/test/ieee754.txt
   python/branches/py3k/Modules/mathmodule.c

Modified: python/branches/py3k/Lib/test/ieee754.txt
==============================================================================
--- python/branches/py3k/Lib/test/ieee754.txt	(original)
+++ python/branches/py3k/Lib/test/ieee754.txt	Wed Jun 18 12:04:31 2008
@@ -127,31 +127,31 @@
 >>> sin(INF)
 Traceback (most recent call last):
 ...
-ValueError: math domain error (invalid argument)
+ValueError: math domain error
 >>> sin(NINF)
 Traceback (most recent call last):
 ...
-ValueError: math domain error (invalid argument)
+ValueError: math domain error
 >>> sin(NAN)
 nan
 >>> cos(INF)
 Traceback (most recent call last):
 ...
-ValueError: math domain error (invalid argument)
+ValueError: math domain error
 >>> cos(NINF)
 Traceback (most recent call last):
 ...
-ValueError: math domain error (invalid argument)
+ValueError: math domain error
 >>> cos(NAN)
 nan
 >>> tan(INF)
 Traceback (most recent call last):
 ...
-ValueError: math domain error (invalid argument)
+ValueError: math domain error
 >>> tan(NINF)
 Traceback (most recent call last):
 ...
-ValueError: math domain error (invalid argument)
+ValueError: math domain error
 >>> tan(NAN)
 nan
 
@@ -169,11 +169,11 @@
 >>> asin(INF), asin(NINF)
 Traceback (most recent call last):
 ...
-ValueError: math domain error (invalid argument)
+ValueError: math domain error
 >>> acos(INF), acos(NINF)
 Traceback (most recent call last):
 ...
-ValueError: math domain error (invalid argument)
+ValueError: math domain error
 >>> equal(atan(INF), PI/2), equal(atan(NINF), -PI/2)
 (True, True)
 

Modified: python/branches/py3k/Modules/mathmodule.c
==============================================================================
--- python/branches/py3k/Modules/mathmodule.c	(original)
+++ python/branches/py3k/Modules/mathmodule.c	Wed Jun 18 12:04:31 2008
@@ -181,16 +181,16 @@
 	PyFPE_END_PROTECT(r);
 	if (Py_IS_NAN(r) && !Py_IS_NAN(x)) {
 		PyErr_SetString(PyExc_ValueError,
-				"math domain error (invalid argument)");
+				"math domain error"); /* invalid arg */
 		return NULL;
 	}
 	if (Py_IS_INFINITY(r) && Py_IS_FINITE(x)) {
 			if (can_overflow)
 				PyErr_SetString(PyExc_OverflowError,
-					"math range error (overflow)");
+					"math range error"); /* overflow */
 			else
 				PyErr_SetString(PyExc_ValueError,
-					"math domain error (singularity)");
+					"math domain error"); /* singularity */
 			return NULL;
 	}
 	if (Py_IS_FINITE(r) && errno && is_error(r))

From python-3000-checkins at python.org  Wed Jun 18 16:22:48 2008
From: python-3000-checkins at python.org (jesse.noller)
Date: Wed, 18 Jun 2008 16:22:48 +0200 (CEST)
Subject: [Python-3000-checkins] r64376 - in python/branches/py3k:
	Lib/test/test_multiprocessing.py
Message-ID: <20080618142248.646441E4002@bag.python.org>

Author: jesse.noller
Date: Wed Jun 18 16:22:48 2008
New Revision: 64376

Log:
Merge r64375 to py3k

Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Lib/test/test_multiprocessing.py

Modified: python/branches/py3k/Lib/test/test_multiprocessing.py
==============================================================================
--- python/branches/py3k/Lib/test/test_multiprocessing.py	(original)
+++ python/branches/py3k/Lib/test/test_multiprocessing.py	Wed Jun 18 16:22:48 2008
@@ -1755,9 +1755,12 @@
 #
 
 def test_main(run=None):
-    if sys.platform.startswith("linux") and not os.path.exists("/dev/shm"):
-        from test.test_support import TestSkipped
-        raise TestSkipped("Missing required /dev/shm device on Linux!")
+    if sys.platform.startswith("linux"):
+        try:
+            lock = multiprocessing.RLock()
+        except OSError:
+            from test.test_support import TestSkipped
+            raise TestSkipped("OSError raises on RLock creation, see issue 3111!")
 
     if run is None:
         from test.support import run_unittest as run

From python-3000-checkins at python.org  Wed Jun 18 16:29:57 2008
From: python-3000-checkins at python.org (jeremy.hylton)
Date: Wed, 18 Jun 2008 16:29:57 +0200 (CEST)
Subject: [Python-3000-checkins] r64377 -
	python/branches/py3k-urllib/Lib/test/test_urllib2_localnet.py
Message-ID: <20080618142957.052911E4002@bag.python.org>

Author: jeremy.hylton
Date: Wed Jun 18 16:29:56 2008
New Revision: 64377

Log:
Fix corrupted info() test.

The server only has a single response, so a second urlopen() will
always fail.  Revise this to be a simple test of a single info() call.


Modified:
   python/branches/py3k-urllib/Lib/test/test_urllib2_localnet.py

Modified: python/branches/py3k-urllib/Lib/test/test_urllib2_localnet.py
==============================================================================
--- python/branches/py3k-urllib/Lib/test/test_urllib2_localnet.py	(original)
+++ python/branches/py3k-urllib/Lib/test/test_urllib2_localnet.py	Wed Jun 18 16:29:56 2008
@@ -420,12 +420,9 @@
 
     def test_info(self):
         handler = self.start_server()
-        open_url = urllib.request.urlopen("http://localhost:%s" % handler.port)
-        info_obj = open_url.info()
-        self.assertEqual(info_obj.getsubtype(), "plain")
-
         try:
-            open_url = urllib.request.urlopen("http://localhost:%s" % handler.port)
+            open_url = urllib.request.urlopen(
+                "http://localhost:%s" % handler.port)
             info_obj = open_url.info()
             self.assert_(isinstance(info_obj, email.message.Message),
                          "object returned by 'info' is not an instance of "

From python-3000-checkins at python.org  Wed Jun 18 20:01:30 2008
From: python-3000-checkins at python.org (jesse.noller)
Date: Wed, 18 Jun 2008 20:01:30 +0200 (CEST)
Subject: [Python-3000-checkins] r64379 - in python/branches/py3k:
	Lib/test/test_multiprocessing.py
Message-ID: <20080618180130.410811E4002@bag.python.org>

Author: jesse.noller
Date: Wed Jun 18 20:01:29 2008
New Revision: 64379

Log:
merge 64378

Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Lib/test/test_multiprocessing.py

Modified: python/branches/py3k/Lib/test/test_multiprocessing.py
==============================================================================
--- python/branches/py3k/Lib/test/test_multiprocessing.py	(original)
+++ python/branches/py3k/Lib/test/test_multiprocessing.py	Wed Jun 18 20:01:29 2008
@@ -1333,7 +1333,7 @@
 
         self.assertRaises(ValueError, a.send_bytes, msg, 4, -1)
 
-
+"""
 class _TestListenerClient(BaseTestCase):
 
     ALLOWED_TYPES = ('processes', 'threads')
@@ -1353,7 +1353,7 @@
             self.assertEqual(conn.recv(), 'hello')
             p.join()
             l.close()
-
+"""
 #
 # Test of sending connection and socket objects between processes
 #

From python-3000-checkins at python.org  Wed Jun 18 21:53:05 2008
From: python-3000-checkins at python.org (senthil.kumaran)
Date: Wed, 18 Jun 2008 21:53:05 +0200 (CEST)
Subject: [Python-3000-checkins] r64384 -
	python/branches/py3k-urllib/Lib/urllib/request.py
Message-ID: <20080618195305.A60C81E4002@bag.python.org>

Author: senthil.kumaran
Date: Wed Jun 18 21:53:05 2008
New Revision: 64384

Log:
Fix the test_redirect and cookie_redirect. Headers are plain dicts

Modified:
   python/branches/py3k-urllib/Lib/urllib/request.py

Modified: python/branches/py3k-urllib/Lib/urllib/request.py
==============================================================================
--- python/branches/py3k-urllib/Lib/urllib/request.py	(original)
+++ python/branches/py3k-urllib/Lib/urllib/request.py	Wed Jun 18 21:53:05 2008
@@ -526,9 +526,9 @@
         # Some servers (incorrectly) return multiple Location headers
         # (so probably same goes for URI).  Use first header.
         if "location" in headers:
-            newurl = headers["location"][0]
+            newurl = headers["location"]
         elif "uri" in headers:
-            newurl = headers["uri"][0]
+            newurl = headers["uri"]
         else:
             return
         newurl = urllib.parse.urljoin(req.get_full_url(), newurl)

From python-3000-checkins at python.org  Wed Jun 18 22:50:02 2008
From: python-3000-checkins at python.org (jeremy.hylton)
Date: Wed, 18 Jun 2008 22:50:02 +0200 (CEST)
Subject: [Python-3000-checkins] r64385 - in python/branches/py3k: Lib/cgi.py
	Lib/distutils/command/register.py
	Lib/distutils/command/upload.py Lib/email/utils.py
	Lib/http/client.py Lib/http/cookiejar.py Lib/http/server.py
	Lib/macurl2path.py Lib/mimetypes.py Lib/robotparser.py
	Lib/test/regrtest.py Lib/test/support.py
	Lib/test/test___all__.py Lib/test/test_http_cookiejar.py
	Lib/test/test_httpservers.py Lib/test/test_importhooks.py
	Lib/test/test_pyclbr.py Lib/test/test_robotparser.py
	Lib/test/test_ssl.py Lib/test/test_urllib.py
	Lib/test/test_urllib2.py Lib/test/test_urllib2_localnet.py
	Lib/test/test_urllib2net.py Lib/test/test_urllibnet.py
	Lib/test/test_urlparse.py Lib/test/test_xmlrpc.py Lib/urllib
	Lib/urllib.py Lib/urllib2.py Lib/urlparse.py
	Lib/wsgiref/simple_server.py Lib/wsgiref/util.py
	Lib/xml/dom/xmlbuilder.py Lib/xml/sax/saxutils.py
	Lib/xmlrpc/client.py Makefile.pre.in Misc/NEWS
Message-ID: <20080618205002.8FFA91E4013@bag.python.org>

Author: jeremy.hylton
Date: Wed Jun 18 22:49:58 2008
New Revision: 64385

Log:
Make a new urllib package .

It consists of code from urllib, urllib2, urlparse, and robotparser.
The old modules have all been removed.  The new package has five
submodules: urllib.parse, urllib.request, urllib.response,
urllib.error, and urllib.robotparser.  The urllib.request.urlopen()
function uses the url opener from urllib2.

Note that the unittests have not been renamed for the
beta, but they will be renamed in the future.

Joint work with Senthil Kumaran.



Added:
   python/branches/py3k/Lib/urllib/
      - copied from r64384, /python/branches/py3k-urllib/Lib/urllib/
Removed:
   python/branches/py3k/Lib/robotparser.py
   python/branches/py3k/Lib/urllib.py
   python/branches/py3k/Lib/urllib2.py
   python/branches/py3k/Lib/urlparse.py
Modified:
   python/branches/py3k/Lib/cgi.py
   python/branches/py3k/Lib/distutils/command/register.py
   python/branches/py3k/Lib/distutils/command/upload.py
   python/branches/py3k/Lib/email/utils.py
   python/branches/py3k/Lib/http/client.py
   python/branches/py3k/Lib/http/cookiejar.py
   python/branches/py3k/Lib/http/server.py
   python/branches/py3k/Lib/macurl2path.py
   python/branches/py3k/Lib/mimetypes.py
   python/branches/py3k/Lib/test/regrtest.py
   python/branches/py3k/Lib/test/support.py
   python/branches/py3k/Lib/test/test___all__.py
   python/branches/py3k/Lib/test/test_http_cookiejar.py
   python/branches/py3k/Lib/test/test_httpservers.py
   python/branches/py3k/Lib/test/test_importhooks.py
   python/branches/py3k/Lib/test/test_pyclbr.py
   python/branches/py3k/Lib/test/test_robotparser.py
   python/branches/py3k/Lib/test/test_ssl.py
   python/branches/py3k/Lib/test/test_urllib.py
   python/branches/py3k/Lib/test/test_urllib2.py
   python/branches/py3k/Lib/test/test_urllib2_localnet.py
   python/branches/py3k/Lib/test/test_urllib2net.py
   python/branches/py3k/Lib/test/test_urllibnet.py
   python/branches/py3k/Lib/test/test_urlparse.py
   python/branches/py3k/Lib/test/test_xmlrpc.py
   python/branches/py3k/Lib/wsgiref/simple_server.py
   python/branches/py3k/Lib/wsgiref/util.py
   python/branches/py3k/Lib/xml/dom/xmlbuilder.py
   python/branches/py3k/Lib/xml/sax/saxutils.py
   python/branches/py3k/Lib/xmlrpc/client.py
   python/branches/py3k/Makefile.pre.in
   python/branches/py3k/Misc/NEWS

Modified: python/branches/py3k/Lib/cgi.py
==============================================================================
--- python/branches/py3k/Lib/cgi.py	(original)
+++ python/branches/py3k/Lib/cgi.py	Wed Jun 18 22:49:58 2008
@@ -35,7 +35,7 @@
 from io import StringIO
 import sys
 import os
-import urllib
+import urllib.parse
 import email.parser
 
 __all__ = ["MiniFieldStorage", "FieldStorage",
@@ -216,8 +216,8 @@
             else:
                 continue
         if len(nv[1]) or keep_blank_values:
-            name = urllib.unquote(nv[0].replace('+', ' '))
-            value = urllib.unquote(nv[1].replace('+', ' '))
+            name = urllib.parse.unquote(nv[0].replace('+', ' '))
+            value = urllib.parse.unquote(nv[1].replace('+', ' '))
             r.append((name, value))
 
     return r

Modified: python/branches/py3k/Lib/distutils/command/register.py
==============================================================================
--- python/branches/py3k/Lib/distutils/command/register.py	(original)
+++ python/branches/py3k/Lib/distutils/command/register.py	Wed Jun 18 22:49:58 2008
@@ -7,8 +7,9 @@
 
 __revision__ = "$Id$"
 
-import os, string, urllib2, getpass, urlparse
+import os, string, getpass
 import io
+import urllib.parse, urllib.request
 
 from distutils.core import PyPIRCCommand
 from distutils.errors import *
@@ -94,7 +95,8 @@
     def classifiers(self):
         ''' Fetch the list of classifiers from the server.
         '''
-        response = urllib2.urlopen(self.repository+'?:action=list_classifiers')
+        url = self.repository+'?:action=list_classifiers'
+        response = urllib.request.urlopen(url)
         print(response.read())
 
     def verify_metadata(self):
@@ -166,8 +168,8 @@
                 password = getpass.getpass('Password: ')
 
             # set up the authentication
-            auth = urllib2.HTTPPasswordMgr()
-            host = urlparse.urlparse(self.repository)[1]
+            auth = urllib.request.HTTPPasswordMgr()
+            host = urllib.parse.urlparse(self.repository)[1]
             auth.add_password(self.realm, host, username, password)
             # send the info to the server and report the result
             code, result = self.post_to_server(self.build_post_data('submit'),
@@ -276,20 +278,20 @@
             'Content-type': 'multipart/form-data; boundary=%s; charset=utf-8'%boundary,
             'Content-length': str(len(body))
         }
-        req = urllib2.Request(self.repository, body, headers)
+        req = urllib.request.Request(self.repository, body, headers)
 
         # handle HTTP and include the Basic Auth handler
-        opener = urllib2.build_opener(
-            urllib2.HTTPBasicAuthHandler(password_mgr=auth)
+        opener = urllib.request.build_opener(
+            urllib.request.HTTPBasicAuthHandler(password_mgr=auth)
         )
         data = ''
         try:
             result = opener.open(req)
-        except urllib2.HTTPError as e:
+        except urllib.error.HTTPError as e:
             if self.show_response:
                 data = e.fp.read()
             result = e.code, e.msg
-        except urllib2.URLError as e:
+        except urllib.error.URLError as e:
             result = 500, str(e)
         else:
             if self.show_response:

Modified: python/branches/py3k/Lib/distutils/command/upload.py
==============================================================================
--- python/branches/py3k/Lib/distutils/command/upload.py	(original)
+++ python/branches/py3k/Lib/distutils/command/upload.py	Wed Jun 18 22:49:58 2008
@@ -13,7 +13,7 @@
 import configparser
 import http.client
 import base64
-import urlparse
+import urllib.parse
 
 class upload(PyPIRCCommand):
 
@@ -145,10 +145,11 @@
         self.announce("Submitting %s to %s" % (filename, self.repository), log.INFO)
 
         # build the Request
-        # We can't use urllib2 since we need to send the Basic
+        # We can't use urllib since we need to send the Basic
         # auth right with the first request
+        # TODO(jhylton): Can we fix urllib?
         schema, netloc, url, params, query, fragments = \
-            urlparse.urlparse(self.repository)
+            urllib.parse.urlparse(self.repository)
         assert not params and not query and not fragments
         if schema == 'http':
             http = http.client.HTTPConnection(netloc)

Modified: python/branches/py3k/Lib/email/utils.py
==============================================================================
--- python/branches/py3k/Lib/email/utils.py	(original)
+++ python/branches/py3k/Lib/email/utils.py	Wed Jun 18 22:49:58 2008
@@ -25,6 +25,7 @@
 import base64
 import random
 import socket
+import urllib.parse
 import warnings
 from io import StringIO
 
@@ -218,8 +219,7 @@
     charset is given but not language, the string is encoded using the empty
     string for language.
     """
-    import urllib
-    s = urllib.quote(s, safe='')
+    s = urllib.parse.quote(s, safe='')
     if charset is None and language is None:
         return s
     if language is None:
@@ -234,7 +234,6 @@
 
     params is a sequence of 2-tuples containing (param name, string value).
     """
-    import urllib
     # Copy params so we don't mess with the original
     params = params[:]
     new_params = []
@@ -272,7 +271,7 @@
             # language specifiers at the beginning of the string.
             for num, s, encoded in continuations:
                 if encoded:
-                    s = urllib.unquote(s)
+                    s = urllib.parse.unquote(s)
                     extended = True
                 value.append(s)
             value = quote(EMPTYSTRING.join(value))

Modified: python/branches/py3k/Lib/http/client.py
==============================================================================
--- python/branches/py3k/Lib/http/client.py	(original)
+++ python/branches/py3k/Lib/http/client.py	Wed Jun 18 22:49:58 2008
@@ -70,7 +70,7 @@
 import socket
 import email.parser
 import email.message
-from urlparse import urlsplit
+from urllib.parse import urlsplit
 import warnings
 
 __all__ = ["HTTPResponse", "HTTPConnection",

Modified: python/branches/py3k/Lib/http/cookiejar.py
==============================================================================
--- python/branches/py3k/Lib/http/cookiejar.py	(original)
+++ python/branches/py3k/Lib/http/cookiejar.py	Wed Jun 18 22:49:58 2008
@@ -28,7 +28,10 @@
 __all__ = ['Cookie', 'CookieJar', 'CookiePolicy', 'DefaultCookiePolicy',
            'FileCookieJar', 'LWPCookieJar', 'LoadError', 'MozillaCookieJar']
 
-import re, urlparse, copy, time, urllib
+import copy
+import re
+import time
+import urllib.parse, urllib.request
 try:
     import threading as _threading
 except ImportError:
@@ -580,7 +583,7 @@
 
     """
     url = request.get_full_url()
-    host = urlparse.urlparse(url)[1]
+    host = urllib.parse.urlparse(url)[1]
     if host == "":
         host = request.get_header("Host", "")
 
@@ -602,13 +605,11 @@
 def request_path(request):
     """request-URI, as defined by RFC 2965."""
     url = request.get_full_url()
-    #scheme, netloc, path, parameters, query, frag = urlparse.urlparse(url)
-    #req_path = escape_path("".join(urlparse.urlparse(url)[2:]))
-    path, parameters, query, frag = urlparse.urlparse(url)[2:]
+    path, parameters, query, frag = urllib.parse.urlparse(url)[2:]
     if parameters:
         path = "%s;%s" % (path, parameters)
     path = escape_path(path)
-    req_path = urlparse.urlunparse(("", "", path, "", query, frag))
+    req_path = urllib.parse.urlunparse(("", "", path, "", query, frag))
     if not req_path.startswith("/"):
         # fix bad RFC 2396 absoluteURI
         req_path = "/"+req_path
@@ -644,7 +645,7 @@
     # And here, kind of: draft-fielding-uri-rfc2396bis-03
     # (And in draft IRI specification: draft-duerst-iri-05)
     # (And here, for new URI schemes: RFC 2718)
-    path = urllib.quote(path, HTTP_PATH_SAFE)
+    path = urllib.parse.quote(path, HTTP_PATH_SAFE)
     path = ESCAPED_CHAR_RE.sub(uppercase_escaped_char, path)
     return path
 
@@ -1197,8 +1198,7 @@
     """Collection of HTTP cookies.
 
     You may not need to know about this class: try
-    urllib2.build_opener(HTTPCookieProcessor).open(url).
-
+    urllib.request.build_opener(HTTPCookieProcessor).open(url).
     """
 
     non_word_re = re.compile(r"\W")

Modified: python/branches/py3k/Lib/http/server.py
==============================================================================
--- python/branches/py3k/Lib/http/server.py	(original)
+++ python/branches/py3k/Lib/http/server.py	Wed Jun 18 22:49:58 2008
@@ -93,7 +93,7 @@
 import time
 import socket # For gethostbyaddr()
 import shutil
-import urllib
+import urllib.parse
 import select
 import mimetypes
 import posixpath
@@ -683,7 +683,7 @@
             return None
         list.sort(key=lambda a: a.lower())
         r = []
-        displaypath = cgi.escape(urllib.unquote(self.path))
+        displaypath = cgi.escape(urllib.parse.unquote(self.path))
         r.append('<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">')
         r.append("<html>\n<title>Directory listing for %s</title>\n" % displaypath)
         r.append("<body>\n<h2>Directory listing for %s</h2>\n" % displaypath)
@@ -699,7 +699,7 @@
                 displayname = name + "@"
                 # Note: a link to a directory displays with @ and links with /
             r.append('<li><a href="%s">%s</a>\n'
-                    % (urllib.quote(linkname), cgi.escape(displayname)))
+                    % (urllib.parse.quote(linkname), cgi.escape(displayname)))
         r.append("</ul>\n<hr>\n</body>\n</html>\n")
         enc = sys.getfilesystemencoding()
         encoded = ''.join(r).encode(enc)
@@ -723,7 +723,7 @@
         # abandon query parameters
         path = path.split('?',1)[0]
         path = path.split('#',1)[0]
-        path = posixpath.normpath(urllib.unquote(path))
+        path = posixpath.normpath(urllib.parse.unquote(path))
         words = path.split('/')
         words = filter(None, words)
         path = os.getcwd()
@@ -947,7 +947,7 @@
         env['SERVER_PROTOCOL'] = self.protocol_version
         env['SERVER_PORT'] = str(self.server.server_port)
         env['REQUEST_METHOD'] = self.command
-        uqrest = urllib.unquote(rest)
+        uqrest = urllib.parse.unquote(rest)
         env['PATH_INFO'] = uqrest
         env['PATH_TRANSLATED'] = self.translate_path(uqrest)
         env['SCRIPT_NAME'] = scriptname

Modified: python/branches/py3k/Lib/macurl2path.py
==============================================================================
--- python/branches/py3k/Lib/macurl2path.py	(original)
+++ python/branches/py3k/Lib/macurl2path.py	Wed Jun 18 22:49:58 2008
@@ -2,7 +2,7 @@
 
 Do not import directly; use urllib instead."""
 
-import urllib
+import urllib.parse
 import os
 
 __all__ = ["url2pathname","pathname2url"]
@@ -13,7 +13,7 @@
     #
     # XXXX The .. handling should be fixed...
     #
-    tp = urllib.splittype(pathname)[0]
+    tp = urllib.parsesplittype(pathname)[0]
     if tp and tp != 'file':
         raise RuntimeError('Cannot convert non-local URL to pathname')
     # Turn starting /// into /, an empty hostname means current host
@@ -47,7 +47,7 @@
             i = i + 1
         rv = ':' + ':'.join(components)
     # and finally unquote slashes and other funny characters
-    return urllib.unquote(rv)
+    return urllib.parseunquote(rv)
 
 def pathname2url(pathname):
     """OS-specific conversion from a file system path to a relative URL
@@ -73,8 +73,8 @@
         return '/'.join(components)
 
 def _pncomp2url(component):
-    component = urllib.quote(component[:31], safe='')  # We want to quote slashes
-    return component
+    # We want to quote slashes
+    return urllib.parsequote(component[:31], safe='')
 
 def test():
     for url in ["index.html",

Modified: python/branches/py3k/Lib/mimetypes.py
==============================================================================
--- python/branches/py3k/Lib/mimetypes.py	(original)
+++ python/branches/py3k/Lib/mimetypes.py	Wed Jun 18 22:49:58 2008
@@ -24,7 +24,7 @@
 
 import os
 import posixpath
-import urllib
+import urllib.parse
 
 __all__ = [
     "guess_type","guess_extension","guess_all_extensions",
@@ -104,7 +104,7 @@
         Optional `strict' argument when False adds a bunch of commonly found,
         but non-standard types.
         """
-        scheme, url = urllib.splittype(url)
+        scheme, url = urllib.parse.splittype(url)
         if scheme == 'data':
             # syntax of data URLs:
             # dataurl   := "data:" [ mediatype ] [ ";base64" ] "," data

Deleted: python/branches/py3k/Lib/robotparser.py
==============================================================================
--- python/branches/py3k/Lib/robotparser.py	Wed Jun 18 22:49:58 2008
+++ (empty file)
@@ -1,212 +0,0 @@
-""" robotparser.py
-
-    Copyright (C) 2000  Bastian Kleineidam
-
-    You can choose between two licenses when using this package:
-    1) GNU GPLv2
-    2) PSF license for Python 2.2
-
-    The robots.txt Exclusion Protocol is implemented as specified in
-    http://info.webcrawler.com/mak/projects/robots/norobots-rfc.html
-"""
-import urlparse
-import urllib
-
-__all__ = ["RobotFileParser"]
-
-class RobotFileParser:
-    """ This class provides a set of methods to read, parse and answer
-    questions about a single robots.txt file.
-
-    """
-
-    def __init__(self, url=''):
-        self.entries = []
-        self.default_entry = None
-        self.disallow_all = False
-        self.allow_all = False
-        self.set_url(url)
-        self.last_checked = 0
-
-    def mtime(self):
-        """Returns the time the robots.txt file was last fetched.
-
-        This is useful for long-running web spiders that need to
-        check for new robots.txt files periodically.
-
-        """
-        return self.last_checked
-
-    def modified(self):
-        """Sets the time the robots.txt file was last fetched to the
-        current time.
-
-        """
-        import time
-        self.last_checked = time.time()
-
-    def set_url(self, url):
-        """Sets the URL referring to a robots.txt file."""
-        self.url = url
-        self.host, self.path = urlparse.urlparse(url)[1:3]
-
-    def read(self):
-        """Reads the robots.txt URL and feeds it to the parser."""
-        opener = URLopener()
-        f = opener.open(self.url)
-        lines = []
-        line = f.readline()
-        while line:
-            lines.append(line.strip())
-            line = f.readline()
-        self.errcode = opener.errcode
-        if self.errcode in (401, 403):
-            self.disallow_all = True
-        elif self.errcode >= 400:
-            self.allow_all = True
-        elif self.errcode == 200 and lines:
-            self.parse(lines)
-
-    def _add_entry(self, entry):
-        if "*" in entry.useragents:
-            # the default entry is considered last
-            self.default_entry = entry
-        else:
-            self.entries.append(entry)
-
-    def parse(self, lines):
-        """parse the input lines from a robots.txt file.
-           We allow that a user-agent: line is not preceded by
-           one or more blank lines."""
-        state = 0
-        linenumber = 0
-        entry = Entry()
-
-        for line in lines:
-            linenumber = linenumber + 1
-            if not line:
-                if state == 1:
-                    entry = Entry()
-                    state = 0
-                elif state == 2:
-                    self._add_entry(entry)
-                    entry = Entry()
-                    state = 0
-            # remove optional comment and strip line
-            i = line.find('#')
-            if i >= 0:
-                line = line[:i]
-            line = line.strip()
-            if not line:
-                continue
-            line = line.split(':', 1)
-            if len(line) == 2:
-                line[0] = line[0].strip().lower()
-                line[1] = urllib.unquote(line[1].strip())
-                if line[0] == "user-agent":
-                    if state == 2:
-                        self._add_entry(entry)
-                        entry = Entry()
-                    entry.useragents.append(line[1])
-                    state = 1
-                elif line[0] == "disallow":
-                    if state != 0:
-                        entry.rulelines.append(RuleLine(line[1], False))
-                        state = 2
-                elif line[0] == "allow":
-                    if state != 0:
-                        entry.rulelines.append(RuleLine(line[1], True))
-        if state == 2:
-            self.entries.append(entry)
-
-
-    def can_fetch(self, useragent, url):
-        """using the parsed robots.txt decide if useragent can fetch url"""
-        if self.disallow_all:
-            return False
-        if self.allow_all:
-            return True
-        # search for given user agent matches
-        # the first match counts
-        url = urllib.quote(urlparse.urlparse(urllib.unquote(url))[2]) or "/"
-        for entry in self.entries:
-            if entry.applies_to(useragent):
-                return entry.allowance(url)
-        # try the default entry last
-        if self.default_entry:
-            return self.default_entry.allowance(url)
-        # agent not found ==> access granted
-        return True
-
-
-    def __str__(self):
-        return ''.join([str(entry) + "\n" for entry in self.entries])
-
-
-class RuleLine:
-    """A rule line is a single "Allow:" (allowance==True) or "Disallow:"
-       (allowance==False) followed by a path."""
-    def __init__(self, path, allowance):
-        if path == '' and not allowance:
-            # an empty value means allow all
-            allowance = True
-        self.path = urllib.quote(path)
-        self.allowance = allowance
-
-    def applies_to(self, filename):
-        return self.path == "*" or filename.startswith(self.path)
-
-    def __str__(self):
-        return (self.allowance and "Allow" or "Disallow") + ": " + self.path
-
-
-class Entry:
-    """An entry has one or more user-agents and zero or more rulelines"""
-    def __init__(self):
-        self.useragents = []
-        self.rulelines = []
-
-    def __str__(self):
-        ret = []
-        for agent in self.useragents:
-            ret.extend(["User-agent: ", agent, "\n"])
-        for line in self.rulelines:
-            ret.extend([str(line), "\n"])
-        return ''.join(ret)
-
-    def applies_to(self, useragent):
-        """check if this entry applies to the specified agent"""
-        # split the name token and make it lower case
-        useragent = useragent.split("/")[0].lower()
-        for agent in self.useragents:
-            if agent == '*':
-                # we have the catch-all agent
-                return True
-            agent = agent.lower()
-            if agent in useragent:
-                return True
-        return False
-
-    def allowance(self, filename):
-        """Preconditions:
-        - our agent applies to this entry
-        - filename is URL decoded"""
-        for line in self.rulelines:
-            if line.applies_to(filename):
-                return line.allowance
-        return True
-
-class URLopener(urllib.FancyURLopener):
-    def __init__(self, *args):
-        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,
-                                                        errmsg, headers)

Modified: python/branches/py3k/Lib/test/regrtest.py
==============================================================================
--- python/branches/py3k/Lib/test/regrtest.py	(original)
+++ python/branches/py3k/Lib/test/regrtest.py	Wed Jun 18 22:49:58 2008
@@ -725,7 +725,7 @@
 def dash_R_cleanup(fs, ps, pic, abcs):
     import gc, copyreg
     import _strptime, linecache
-    import urlparse, urllib, urllib2, mimetypes, doctest
+    import urllib.parse, urllib.request, mimetypes, doctest
     import struct, filecmp, _abcoll
     from distutils.dir_util import _path_created
     from weakref import WeakSet
@@ -758,9 +758,8 @@
     _path_created.clear()
     re.purge()
     _strptime._regex_cache.clear()
-    urlparse.clear_cache()
-    urllib.urlcleanup()
-    urllib2.install_opener(None)
+    urllib.parse.clear_cache()
+    urllib.request.urlcleanup()
     linecache.clearcache()
     mimetypes._default_mime_types()
     filecmp._cache.clear()

Modified: python/branches/py3k/Lib/test/support.py
==============================================================================
--- python/branches/py3k/Lib/test/support.py	(original)
+++ python/branches/py3k/Lib/test/support.py	Wed Jun 18 22:49:58 2008
@@ -352,10 +352,10 @@
         testcase.fail('Missing SyntaxError: "%s"' % statement)
 
 def open_urlresource(url, *args, **kw):
-    import urllib, urlparse
+    import urllib.request, urllib.parse
 
     requires('urlfetch')
-    filename = urlparse.urlparse(url)[2].split('/')[-1] # '/': it's URL!
+    filename = urllib.parse.urlparse(url)[2].split('/')[-1] # '/': it's URL!
 
     for path in [os.path.curdir, os.path.pardir]:
         fn = os.path.join(path, filename)
@@ -363,7 +363,7 @@
             return open(fn, *args, **kw)
 
     print('\tfetching %s ...' % url, file=get_original_stdout())
-    fn, _ = urllib.urlretrieve(url, filename)
+    fn, _ = urllib.request.urlretrieve(url, filename)
     return open(fn, *args, **kw)
 
 

Modified: python/branches/py3k/Lib/test/test___all__.py
==============================================================================
--- python/branches/py3k/Lib/test/test___all__.py	(original)
+++ python/branches/py3k/Lib/test/test___all__.py	Wed Jun 18 22:49:58 2008
@@ -111,7 +111,7 @@
         self.check_all("re")
         self.check_all("reprlib")
         self.check_all("rlcompleter")
-        self.check_all("robotparser")
+        self.check_all("urllib.robotparser")
         self.check_all("sched")
         self.check_all("shelve")
         self.check_all("shlex")
@@ -134,8 +134,6 @@
         self.check_all("traceback")
         self.check_all("tty")
         self.check_all("unittest")
-        self.check_all("urllib")
-        self.check_all("urlparse")
         self.check_all("uu")
         self.check_all("warnings")
         self.check_all("wave")

Modified: python/branches/py3k/Lib/test/test_http_cookiejar.py
==============================================================================
--- python/branches/py3k/Lib/test/test_http_cookiejar.py	(original)
+++ python/branches/py3k/Lib/test/test_http_cookiejar.py	Wed Jun 18 22:49:58 2008
@@ -1,6 +1,6 @@
 """Tests for http/cookiejar.py."""
 
-import re, os, time, urllib2
+import re, os, time, urllib.request
 from unittest import TestCase
 
 from test import support
@@ -206,7 +206,7 @@
 
 def _interact(cookiejar, url, set_cookie_hdrs, hdr_name):
     """Perform a single request / response cycle, returning Cookie: header."""
-    req = urllib2.Request(url)
+    req = urllib.request.Request(url)
     cookiejar.add_cookie_header(req)
     cookie_hdr = req.get_header("Cookie", "")
     headers = []
@@ -330,7 +330,7 @@
             ("http://foo/", "foo.local", True),
             ("http://foo/", ".local", True),
             ]:
-            request = urllib2.Request(url)
+            request = urllib.request.Request(url)
             r = pol.domain_return_ok(domain, request)
             if ok: self.assert_(r)
             else: self.assert_(not r)
@@ -547,46 +547,48 @@
 
     def test_request_path(self):
         # with parameters
-        req = urllib2.Request("http://www.example.com/rheum/rhaponicum;"
-                              "foo=bar;sing=song?apples=pears&spam=eggs#ni")
+        req = urllib.request.Request(
+            "http://www.example.com/rheum/rhaponicum;"
+            "foo=bar;sing=song?apples=pears&spam=eggs#ni")
         self.assertEquals(request_path(req), "/rheum/rhaponicum;"
                      "foo=bar;sing=song?apples=pears&spam=eggs#ni")
         # without parameters
-        req = urllib2.Request("http://www.example.com/rheum/rhaponicum?"
-                              "apples=pears&spam=eggs#ni")
+        req = urllib.request.Request(
+            "http://www.example.com/rheum/rhaponicum?"
+            "apples=pears&spam=eggs#ni")
         self.assertEquals(request_path(req), "/rheum/rhaponicum?"
                      "apples=pears&spam=eggs#ni")
         # missing final slash
-        req = urllib2.Request("http://www.example.com")
+        req = urllib.request.Request("http://www.example.com")
         self.assertEquals(request_path(req), "/")
 
     def test_request_port(self):
-        req = urllib2.Request("http://www.acme.com:1234/",
-                              headers={"Host": "www.acme.com:4321"})
+        req = urllib.request.Request("http://www.acme.com:1234/",
+                                     headers={"Host": "www.acme.com:4321"})
         self.assertEquals(request_port(req), "1234")
-        req = urllib2.Request("http://www.acme.com/",
-                              headers={"Host": "www.acme.com:4321"})
+        req = urllib.request.Request("http://www.acme.com/",
+                                     headers={"Host": "www.acme.com:4321"})
         self.assertEquals(request_port(req), DEFAULT_HTTP_PORT)
 
     def test_request_host(self):
         # this request is illegal (RFC2616, 14.2.3)
-        req = urllib2.Request("http://1.1.1.1/",
-                              headers={"Host": "www.acme.com:80"})
+        req = urllib.request.Request("http://1.1.1.1/",
+                                     headers={"Host": "www.acme.com:80"})
         # libwww-perl wants this response, but that seems wrong (RFC 2616,
         # section 5.2, point 1., and RFC 2965 section 1, paragraph 3)
         #self.assertEquals(request_host(req), "www.acme.com")
         self.assertEquals(request_host(req), "1.1.1.1")
-        req = urllib2.Request("http://www.acme.com/",
-                              headers={"Host": "irrelevant.com"})
+        req = urllib.request.Request("http://www.acme.com/",
+                                     headers={"Host": "irrelevant.com"})
         self.assertEquals(request_host(req), "www.acme.com")
         # not actually sure this one is valid Request object, so maybe should
         # remove test for no host in url in request_host function?
-        req = urllib2.Request("/resource.html",
-                              headers={"Host": "www.acme.com"})
+        req = urllib.request.Request("/resource.html",
+                                     headers={"Host": "www.acme.com"})
         self.assertEquals(request_host(req), "www.acme.com")
         # port shouldn't be in request-host
-        req = urllib2.Request("http://www.acme.com:2345/resource.html",
-                              headers={"Host": "www.acme.com:5432"})
+        req = urllib.request.Request("http://www.acme.com:2345/resource.html",
+                                     headers={"Host": "www.acme.com:5432"})
         self.assertEquals(request_host(req), "www.acme.com")
 
     def test_is_HDN(self):
@@ -766,24 +768,24 @@
             blocked_domains=["acme.com"],
             allowed_domains=["www.acme.com"]))
 
-        req = urllib2.Request("http://acme.com/")
+        req = urllib.request.Request("http://acme.com/")
         headers = ["Set-Cookie: CUSTOMER=WILE_E_COYOTE; path=/"]
         res = FakeResponse(headers, "http://acme.com/")
         c.extract_cookies(res, req)
         self.assertEquals(len(c), 0)
 
-        req = urllib2.Request("http://www.acme.com/")
+        req = urllib.request.Request("http://www.acme.com/")
         res = FakeResponse(headers, "http://www.acme.com/")
         c.extract_cookies(res, req)
         self.assertEquals(len(c), 1)
 
-        req = urllib2.Request("http://www.coyote.com/")
+        req = urllib.request.Request("http://www.coyote.com/")
         res = FakeResponse(headers, "http://www.coyote.com/")
         c.extract_cookies(res, req)
         self.assertEquals(len(c), 1)
 
         # set a cookie with non-allowed domain...
-        req = urllib2.Request("http://www.coyote.com/")
+        req = urllib.request.Request("http://www.coyote.com/")
         res = FakeResponse(headers, "http://www.coyote.com/")
         cookies = c.make_cookies(res, req)
         c.set_cookie(cookies[0])
@@ -798,7 +800,7 @@
         c = CookieJar(policy=pol)
         headers = ["Set-Cookie: CUSTOMER=WILE_E_COYOTE; path=/"]
 
-        req = urllib2.Request("http://www.acme.com/")
+        req = urllib.request.Request("http://www.acme.com/")
         res = FakeResponse(headers, "http://www.acme.com/")
         c.extract_cookies(res, req)
         self.assertEquals(len(c), 0)
@@ -808,11 +810,11 @@
         self.assertEquals(len(c), 1)
 
         c.clear()
-        req = urllib2.Request("http://www.roadrunner.net/")
+        req = urllib.request.Request("http://www.roadrunner.net/")
         res = FakeResponse(headers, "http://www.roadrunner.net/")
         c.extract_cookies(res, req)
         self.assertEquals(len(c), 1)
-        req = urllib2.Request("http://www.roadrunner.net/")
+        req = urllib.request.Request("http://www.roadrunner.net/")
         c.add_cookie_header(req)
         self.assert_((req.has_header("Cookie") and
                       req.has_header("Cookie2")))
@@ -823,7 +825,7 @@
         self.assertEquals(len(c), 1)
 
         # set a cookie with blocked domain...
-        req = urllib2.Request("http://www.acme.com/")
+        req = urllib.request.Request("http://www.acme.com/")
         res = FakeResponse(headers, "http://www.acme.com/")
         cookies = c.make_cookies(res, req)
         c.set_cookie(cookies[0])
@@ -866,7 +868,7 @@
         url = "http://www.acme.com"
         c = CookieJar(DefaultCookiePolicy(rfc2965=True))
         interact_2965(c, url, "foo=bar; Version=1")
-        req = urllib2.Request(url)
+        req = urllib.request.Request(url)
         self.assertEquals(len(c), 1)
         c.add_cookie_header(req)
         self.assert_(req.has_header("Cookie"))
@@ -1009,7 +1011,7 @@
 
         def cookiejar_from_cookie_headers(headers):
             c = CookieJar()
-            req = urllib2.Request("http://www.example.com/")
+            req = urllib.request.Request("http://www.example.com/")
             r = FakeResponse(headers, "http://www.example.com/")
             c.extract_cookies(r, req)
             return c
@@ -1080,9 +1082,9 @@
 
         c = CookieJar(DefaultCookiePolicy(rfc2965 = True))
 
-        #req = urllib2.Request("http://1.1.1.1/",
+        #req = urllib.request.Request("http://1.1.1.1/",
         #              headers={"Host": "www.acme.com:80"})
-        req = urllib2.Request("http://www.acme.com:80/",
+        req = urllib.request.Request("http://www.acme.com:80/",
                       headers={"Host": "www.acme.com:80"})
 
         headers.append(
@@ -1091,7 +1093,7 @@
         res = FakeResponse(headers, "http://www.acme.com/")
         c.extract_cookies(res, req)
 
-        req = urllib2.Request("http://www.acme.com/")
+        req = urllib.request.Request("http://www.acme.com/")
         c.add_cookie_header(req)
 
         self.assertEqual(req.get_header("Cookie"), "CUSTOMER=WILE_E_COYOTE")
@@ -1101,7 +1103,7 @@
         res = FakeResponse(headers, "http://www.acme.com/")
         c.extract_cookies(res, req)
 
-        req = urllib2.Request("http://www.acme.com/foo/bar")
+        req = urllib.request.Request("http://www.acme.com/foo/bar")
         c.add_cookie_header(req)
 
         h = req.get_header("Cookie")
@@ -1112,7 +1114,7 @@
         res = FakeResponse(headers, "http://www.acme.com")
         c.extract_cookies(res, req)
 
-        req = urllib2.Request("http://www.acme.com/")
+        req = urllib.request.Request("http://www.acme.com/")
         c.add_cookie_header(req)
 
         h = req.get_header("Cookie")
@@ -1120,7 +1122,7 @@
                      "CUSTOMER=WILE_E_COYOTE" in h and
                      "SHIPPING=FEDEX" not in h)
 
-        req = urllib2.Request("http://www.acme.com/foo/")
+        req = urllib.request.Request("http://www.acme.com/foo/")
         c.add_cookie_header(req)
 
         h = req.get_header("Cookie")
@@ -1155,13 +1157,13 @@
         c = CookieJar()
         headers = []
 
-        req = urllib2.Request("http://www.acme.com/")
+        req = urllib.request.Request("http://www.acme.com/")
         headers.append("Set-Cookie: PART_NUMBER=ROCKET_LAUNCHER_0001; path=/")
         res = FakeResponse(headers, "http://www.acme.com/")
 
         c.extract_cookies(res, req)
 
-        req = urllib2.Request("http://www.acme.com/")
+        req = urllib.request.Request("http://www.acme.com/")
         c.add_cookie_header(req)
 
         self.assertEquals(req.get_header("Cookie"),
@@ -1172,7 +1174,7 @@
         res = FakeResponse(headers, "http://www.acme.com/")
         c.extract_cookies(res, req)
 
-        req = urllib2.Request("http://www.acme.com/ammo")
+        req = urllib.request.Request("http://www.acme.com/ammo")
         c.add_cookie_header(req)
 
         self.assert_(re.search(r"PART_NUMBER=RIDING_ROCKET_0023;\s*"
@@ -1503,7 +1505,7 @@
         # Some additional Netscape cookies tests.
         c = CookieJar()
         headers = []
-        req = urllib2.Request("http://foo.bar.acme.com/foo")
+        req = urllib.request.Request("http://foo.bar.acme.com/foo")
 
         # Netscape allows a host part that contains dots
         headers.append("Set-Cookie: Customer=WILE_E_COYOTE; domain=.acme.com")
@@ -1517,7 +1519,7 @@
         res = FakeResponse(headers, "http://www.acme.com/foo")
         c.extract_cookies(res, req)
 
-        req = urllib2.Request("http://foo.bar.acme.com/foo")
+        req = urllib.request.Request("http://foo.bar.acme.com/foo")
         c.add_cookie_header(req)
         self.assert_(
             "PART_NUMBER=3,4" in req.get_header("Cookie") and
@@ -1559,12 +1561,12 @@
         c = CookieJar(DefaultCookiePolicy(rfc2965 = True))
         headers = []
 
-        req = urllib2.Request("http://www.ants.com/")
+        req = urllib.request.Request("http://www.ants.com/")
         headers.append("Set-Cookie: JSESSIONID=ABCDERANDOM123; Path=")
         res = FakeResponse(headers, "http://www.ants.com/")
         c.extract_cookies(res, req)
 
-        req = urllib2.Request("http://www.ants.com/")
+        req = urllib.request.Request("http://www.ants.com/")
         c.add_cookie_header(req)
 
         self.assertEquals(req.get_header("Cookie"),
@@ -1572,7 +1574,7 @@
         self.assertEquals(req.get_header("Cookie2"), '$Version="1"')
 
         # missing path in the request URI
-        req = urllib2.Request("http://www.ants.com:8080")
+        req = urllib.request.Request("http://www.ants.com:8080")
         c.add_cookie_header(req)
 
         self.assertEquals(req.get_header("Cookie"),
@@ -1585,7 +1587,7 @@
         # Check session cookies are deleted properly by
         # CookieJar.clear_session_cookies method
 
-        req = urllib2.Request('http://www.perlmeister.com/scripts')
+        req = urllib.request.Request('http://www.perlmeister.com/scripts')
         headers = []
         headers.append("Set-Cookie: s1=session;Path=/scripts")
         headers.append("Set-Cookie: p1=perm; Domain=.perlmeister.com;"

Modified: python/branches/py3k/Lib/test/test_httpservers.py
==============================================================================
--- python/branches/py3k/Lib/test/test_httpservers.py	(original)
+++ python/branches/py3k/Lib/test/test_httpservers.py	Wed Jun 18 22:49:58 2008
@@ -11,7 +11,7 @@
 import sys
 import base64
 import shutil
-import urllib
+import urllib.parse
 import http.client
 import tempfile
 import threading
@@ -322,7 +322,8 @@
              (res.read(), res.getheader('Content-type'), res.status))
 
     def test_post(self):
-        params = urllib.urlencode({'spam' : 1, 'eggs' : 'python', 'bacon' : 123456})
+        params = urllib.parse.urlencode(
+            {'spam' : 1, 'eggs' : 'python', 'bacon' : 123456})
         headers = {'Content-type' : 'application/x-www-form-urlencoded'}
         res = self.request('/cgi-bin/file2.py', 'POST', params, headers)
 

Modified: python/branches/py3k/Lib/test/test_importhooks.py
==============================================================================
--- python/branches/py3k/Lib/test/test_importhooks.py	(original)
+++ python/branches/py3k/Lib/test/test_importhooks.py	Wed Jun 18 22:49:58 2008
@@ -247,22 +247,22 @@
         i = ImpWrapper()
         sys.meta_path.append(i)
         sys.path_hooks.append(ImpWrapper)
-        mnames = ("colorsys", "urlparse", "distutils.core")
+        mnames = ("colorsys", "urllib.parse", "distutils.core")
         for mname in mnames:
             parent = mname.split(".")[0]
-            for n in list(sys.modules.keys()):
+            for n in list(sys.modules):
                 if n.startswith(parent):
                     del sys.modules[n]
         for mname in mnames:
             m = __import__(mname, globals(), locals(), ["__dummy__"])
             m.__loader__  # to make sure we actually handled the import
-        # Delete urllib from modules because urlparse was imported above.
-        # Without this hack, test_socket_ssl fails if run in this order:
-        # regrtest.py test_codecmaps_tw test_importhooks test_socket_ssl
-        try:
-            del sys.modules['urllib']
-        except KeyError:
-            pass
+##        # Delete urllib from modules because urlparse was imported above.
+##        # Without this hack, test_socket_ssl fails if run in this order:
+##        # regrtest.py test_codecmaps_tw test_importhooks test_socket_ssl
+##        try:
+##            del sys.modules['urllib']
+##        except KeyError:
+##            pass
 
 def test_main():
     support.run_unittest(ImportHooksTestCase)

Modified: python/branches/py3k/Lib/test/test_pyclbr.py
==============================================================================
--- python/branches/py3k/Lib/test/test_pyclbr.py	(original)
+++ python/branches/py3k/Lib/test/test_pyclbr.py	Wed Jun 18 22:49:58 2008
@@ -156,16 +156,6 @@
         # These were once about the 10 longest modules
         cm('random', ignore=('Random',))  # from _random import Random as CoreGenerator
         cm('cgi', ignore=('log',))      # set with = in module
-        cm('urllib', ignore=('_CFNumberToInt32',
-                             '_CStringFromCFString',
-                             '_CFSetup',
-                             'getproxies_registry',
-                             'proxy_bypass_registry',
-                             'proxy_bypass_macosx_sysconf',
-                             'open_https',
-                             '_https_connection',
-                             'getproxies_macosx_sysconf',
-                             'getproxies_internetconfig',)) # not on all platforms
         cm('pickle')
         cm('aifc', ignore=('openfp',))  # set with = in module
         cm('sre_parse', ignore=('dump',)) # from sre_constants import *

Modified: python/branches/py3k/Lib/test/test_robotparser.py
==============================================================================
--- python/branches/py3k/Lib/test/test_robotparser.py	(original)
+++ python/branches/py3k/Lib/test/test_robotparser.py	Wed Jun 18 22:49:58 2008
@@ -1,5 +1,6 @@
-import unittest, robotparser
 import io
+import unittest
+import urllib.robotparser
 from test import support
 
 class RobotTestCase(unittest.TestCase):
@@ -34,7 +35,7 @@
               agent="test_robotparser"):
 
     lines = io.StringIO(robots_txt).readlines()
-    parser = robotparser.RobotFileParser()
+    parser = urllib.robotparser.RobotFileParser()
     parser.parse(lines)
     for url in good_urls:
         tests.addTest(RobotTestCase(index, parser, url, 1, agent))
@@ -140,7 +141,7 @@
         support.requires('network')
         # whole site is password-protected.
         url = 'http://mueblesmoraleda.com'
-        parser = robotparser.RobotFileParser()
+        parser = urllib.robotparser.RobotFileParser()
         parser.set_url(url)
         parser.read()
         self.assertEqual(parser.can_fetch("*", url+"/robots.txt"), False)

Modified: python/branches/py3k/Lib/test/test_ssl.py
==============================================================================
--- python/branches/py3k/Lib/test/test_ssl.py	(original)
+++ python/branches/py3k/Lib/test/test_ssl.py	Wed Jun 18 22:49:58 2008
@@ -10,7 +10,7 @@
 import time
 import os
 import pprint
-import urllib, urlparse
+import urllib.parse, urllib.request
 import shutil
 import traceback
 import asyncore
@@ -440,8 +440,8 @@
 
                 """
                 # abandon query parameters
-                path = urlparse.urlparse(path)[2]
-                path = os.path.normpath(urllib.unquote(path))
+                path = urllib.parse.urlparse(path)[2]
+                path = os.path.normpath(urllib.parse.unquote(path))
                 words = path.split('/')
                 words = filter(None, words)
                 path = self.root
@@ -943,7 +943,7 @@
                 # now fetch the same data from the HTTPS server
                 url = 'https://%s:%d/%s' % (
                     HOST, server.port, os.path.split(CERTFILE)[1])
-                f = urllib.urlopen(url)
+                f = urllib.request.urlopen(url)
                 dlen = f.info().get("content-length")
                 if dlen and (int(dlen) > 0):
                     d2 = f.read(int(dlen))

Modified: python/branches/py3k/Lib/test/test_urllib.py
==============================================================================
--- python/branches/py3k/Lib/test/test_urllib.py	(original)
+++ python/branches/py3k/Lib/test/test_urllib.py	Wed Jun 18 22:49:58 2008
@@ -1,6 +1,7 @@
 """Regresssion tests for urllib"""
 
-import urllib
+import urllib.parse
+import urllib.request
 import http.client
 import email.message
 import io
@@ -16,6 +17,23 @@
         hex_repr = "0%s" % hex_repr
     return "%" + hex_repr
 
+# Shortcut for testing FancyURLopener
+_urlopener = None
+def urlopen(url, data=None, proxies=None):
+    """urlopen(url [, data]) -> open file-like object"""
+    global _urlopener
+    if proxies is not None:
+        opener = urllib.request.FancyURLopener(proxies=proxies)
+    elif not _urlopener:
+        opener = urllib.request.FancyURLopener()
+        _urlopener = opener
+    else:
+        opener = _urlopener
+    if data is None:
+        return opener.open(url)
+    else:
+        return opener.open(url, data)
+
 class urlopen_FileTests(unittest.TestCase):
     """Test urlopen() opening a temporary file.
 
@@ -25,15 +43,16 @@
     """
 
     def setUp(self):
-        """Setup of a temp file to use for testing"""
-        self.text = bytes("test_urllib: %s\n" % self.__class__.__name__, "ascii")
-        FILE = open(support.TESTFN, 'wb')
+        # Create a temp file to use for testing
+        self.text = bytes("test_urllib: %s\n" % self.__class__.__name__,
+                          "ascii")
+        f = open(support.TESTFN, 'wb')
         try:
-            FILE.write(self.text)
+            f.write(self.text)
         finally:
-            FILE.close()
+            f.close()
         self.pathname = support.TESTFN
-        self.returned_obj = urllib.urlopen("file:%s" % self.pathname)
+        self.returned_obj = urlopen("file:%s" % self.pathname)
 
     def tearDown(self):
         """Shut down the open object"""
@@ -119,7 +138,7 @@
     def test_read(self):
         self.fakehttp(b"Hello!")
         try:
-            fp = urllib.urlopen("http://python.org/")
+            fp = urlopen("http://python.org/")
             self.assertEqual(fp.readline(), b"Hello!")
             self.assertEqual(fp.readline(), b"")
             self.assertEqual(fp.geturl(), 'http://python.org/')
@@ -136,7 +155,7 @@
 Content-Type: text/html; charset=iso-8859-1
 ''')
         try:
-            self.assertRaises(IOError, urllib.urlopen, "http://python.org/")
+            self.assertRaises(IOError, urlopen, "http://python.org/")
         finally:
             self.unfakehttp()
 
@@ -145,7 +164,7 @@
         # data. (#1680230)
         self.fakehttp(b'')
         try:
-            self.assertRaises(IOError, urllib.urlopen, "http://something")
+            self.assertRaises(IOError, urlopen, "http://something")
         finally:
             self.unfakehttp()
 
@@ -180,7 +199,8 @@
             except: pass
 
     def constructLocalFileUrl(self, filePath):
-        return "file://%s" % urllib.pathname2url(os.path.abspath(filePath))
+        return "file://%s" % urllib.request.pathname2url(
+            os.path.abspath(filePath))
 
     def createNewTempFile(self, data=b""):
         """Creates a new temporary file containing the specified data,
@@ -204,7 +224,7 @@
     def test_basic(self):
         # Make sure that a local file just gets its own location returned and
         # a headers value is returned.
-        result = urllib.urlretrieve("file:%s" % support.TESTFN)
+        result = urllib.request.urlretrieve("file:%s" % support.TESTFN)
         self.assertEqual(result[0], support.TESTFN)
         self.assert_(isinstance(result[1], email.message.Message),
                      "did not get a email.message.Message instance as second "
@@ -214,7 +234,7 @@
         # Test that setting the filename argument works.
         second_temp = "%s.2" % support.TESTFN
         self.registerFileForCleanUp(second_temp)
-        result = urllib.urlretrieve(self.constructLocalFileUrl(
+        result = urllib.request.urlretrieve(self.constructLocalFileUrl(
             support.TESTFN), second_temp)
         self.assertEqual(second_temp, result[0])
         self.assert_(os.path.exists(second_temp), "copy of the file was not "
@@ -238,7 +258,8 @@
             count_holder[0] = count_holder[0] + 1
         second_temp = "%s.2" % support.TESTFN
         self.registerFileForCleanUp(second_temp)
-        urllib.urlretrieve(self.constructLocalFileUrl(support.TESTFN),
+        urllib.request.urlretrieve(
+            self.constructLocalFileUrl(support.TESTFN),
             second_temp, hooktester)
 
     def test_reporthook_0_bytes(self):
@@ -247,7 +268,7 @@
         def hooktester(count, block_size, total_size, _report=report):
             _report.append((count, block_size, total_size))
         srcFileName = self.createNewTempFile()
-        urllib.urlretrieve(self.constructLocalFileUrl(srcFileName),
+        urllib.request.urlretrieve(self.constructLocalFileUrl(srcFileName),
             support.TESTFN, hooktester)
         self.assertEqual(len(report), 1)
         self.assertEqual(report[0][2], 0)
@@ -261,7 +282,7 @@
         def hooktester(count, block_size, total_size, _report=report):
             _report.append((count, block_size, total_size))
         srcFileName = self.createNewTempFile(b"x" * 5)
-        urllib.urlretrieve(self.constructLocalFileUrl(srcFileName),
+        urllib.request.urlretrieve(self.constructLocalFileUrl(srcFileName),
             support.TESTFN, hooktester)
         self.assertEqual(len(report), 2)
         self.assertEqual(report[0][1], 8192)
@@ -275,7 +296,7 @@
         def hooktester(count, block_size, total_size, _report=report):
             _report.append((count, block_size, total_size))
         srcFileName = self.createNewTempFile(b"x" * 8193)
-        urllib.urlretrieve(self.constructLocalFileUrl(srcFileName),
+        urllib.request.urlretrieve(self.constructLocalFileUrl(srcFileName),
             support.TESTFN, hooktester)
         self.assertEqual(len(report), 3)
         self.assertEqual(report[0][1], 8192)
@@ -284,10 +305,10 @@
 class QuotingTests(unittest.TestCase):
     """Tests for urllib.quote() and urllib.quote_plus()
 
-    According to RFC 2396 ("Uniform Resource Identifiers), to escape a
-    character you write it as '%' + <2 character US-ASCII hex value>.  The Python
-    code of ``'%' + hex(ord(<character>))[2:]`` escapes a character properly.
-    Case does not matter on the hex letters.
+    According to RFC 2396 (Uniform Resource Identifiers), to escape a
+    character you write it as '%' + <2 character US-ASCII hex value>.
+    The Python code of ``'%' + hex(ord(<character>))[2:]`` escapes a
+    character properly. Case does not matter on the hex letters.
 
     The various character sets specified are:
 
@@ -313,24 +334,24 @@
                                  "abcdefghijklmnopqrstuvwxyz",
                                  "0123456789",
                                  "_.-"])
-        result = urllib.quote(do_not_quote)
+        result = urllib.parse.quote(do_not_quote)
         self.assertEqual(do_not_quote, result,
                          "using quote(): %s != %s" % (do_not_quote, result))
-        result = urllib.quote_plus(do_not_quote)
+        result = urllib.parse.quote_plus(do_not_quote)
         self.assertEqual(do_not_quote, result,
                         "using quote_plus(): %s != %s" % (do_not_quote, result))
 
     def test_default_safe(self):
         # Test '/' is default value for 'safe' parameter
-        self.assertEqual(urllib.quote.__defaults__[0], '/')
+        self.assertEqual(urllib.parse.quote.__defaults__[0], '/')
 
     def test_safe(self):
         # Test setting 'safe' parameter does what it should do
         quote_by_default = "<>"
-        result = urllib.quote(quote_by_default, safe=quote_by_default)
+        result = urllib.parse.quote(quote_by_default, safe=quote_by_default)
         self.assertEqual(quote_by_default, result,
                          "using quote(): %s != %s" % (quote_by_default, result))
-        result = urllib.quote_plus(quote_by_default, safe=quote_by_default)
+        result = urllib.parse.quote_plus(quote_by_default, safe=quote_by_default)
         self.assertEqual(quote_by_default, result,
                          "using quote_plus(): %s != %s" %
                          (quote_by_default, result))
@@ -343,11 +364,11 @@
         should_quote.append(chr(127)) # For 0x7F
         should_quote = ''.join(should_quote)
         for char in should_quote:
-            result = urllib.quote(char)
+            result = urllib.parse.quote(char)
             self.assertEqual(hexescape(char), result,
                              "using quote(): %s should be escaped to %s, not %s" %
                              (char, hexescape(char), result))
-            result = urllib.quote_plus(char)
+            result = urllib.parse.quote_plus(char)
             self.assertEqual(hexescape(char), result,
                              "using quote_plus(): "
                              "%s should be escapes to %s, not %s" %
@@ -355,7 +376,7 @@
         del should_quote
         partial_quote = "ab[]cd"
         expected = "ab%5B%5Dcd"
-        result = urllib.quote(partial_quote)
+        result = urllib.parse.quote(partial_quote)
         self.assertEqual(expected, result,
                          "using quote(): %s != %s" % (expected, result))
         self.assertEqual(expected, result,
@@ -364,26 +385,26 @@
     def test_quoting_space(self):
         # Make sure quote() and quote_plus() handle spaces as specified in
         # their unique way
-        result = urllib.quote(' ')
+        result = urllib.parse.quote(' ')
         self.assertEqual(result, hexescape(' '),
                          "using quote(): %s != %s" % (result, hexescape(' ')))
-        result = urllib.quote_plus(' ')
+        result = urllib.parse.quote_plus(' ')
         self.assertEqual(result, '+',
                          "using quote_plus(): %s != +" % result)
         given = "a b cd e f"
         expect = given.replace(' ', hexescape(' '))
-        result = urllib.quote(given)
+        result = urllib.parse.quote(given)
         self.assertEqual(expect, result,
                          "using quote(): %s != %s" % (expect, result))
         expect = given.replace(' ', '+')
-        result = urllib.quote_plus(given)
+        result = urllib.parse.quote_plus(given)
         self.assertEqual(expect, result,
                          "using quote_plus(): %s != %s" % (expect, result))
 
     def test_quoting_plus(self):
-        self.assertEqual(urllib.quote_plus('alpha+beta gamma'),
+        self.assertEqual(urllib.parse.quote_plus('alpha+beta gamma'),
                          'alpha%2Bbeta+gamma')
-        self.assertEqual(urllib.quote_plus('alpha+beta gamma', '+'),
+        self.assertEqual(urllib.parse.quote_plus('alpha+beta gamma', '+'),
                          'alpha+beta+gamma')
 
 class UnquotingTests(unittest.TestCase):
@@ -399,21 +420,21 @@
         for num in range(128):
             given = hexescape(chr(num))
             expect = chr(num)
-            result = urllib.unquote(given)
+            result = urllib.parse.unquote(given)
             self.assertEqual(expect, result,
                              "using unquote(): %s != %s" % (expect, result))
-            result = urllib.unquote_plus(given)
+            result = urllib.parse.unquote_plus(given)
             self.assertEqual(expect, result,
                              "using unquote_plus(): %s != %s" %
                              (expect, result))
             escape_list.append(given)
         escape_string = ''.join(escape_list)
         del escape_list
-        result = urllib.unquote(escape_string)
+        result = urllib.parse.unquote(escape_string)
         self.assertEqual(result.count('%'), 1,
                          "using quote(): not all characters escaped; %s" %
                          result)
-        result = urllib.unquote(escape_string)
+        result = urllib.parse.unquote(escape_string)
         self.assertEqual(result.count('%'), 1,
                          "using unquote(): not all characters escaped: "
                          "%s" % result)
@@ -423,10 +444,10 @@
         # interspersed
         given = 'ab%sd' % hexescape('c')
         expect = "abcd"
-        result = urllib.unquote(given)
+        result = urllib.parse.unquote(given)
         self.assertEqual(expect, result,
                          "using quote(): %s != %s" % (expect, result))
-        result = urllib.unquote_plus(given)
+        result = urllib.parse.unquote_plus(given)
         self.assertEqual(expect, result,
                          "using unquote_plus(): %s != %s" % (expect, result))
 
@@ -434,16 +455,16 @@
         # Test difference between unquote() and unquote_plus()
         given = "are+there+spaces..."
         expect = given
-        result = urllib.unquote(given)
+        result = urllib.parse.unquote(given)
         self.assertEqual(expect, result,
                          "using unquote(): %s != %s" % (expect, result))
         expect = given.replace('+', ' ')
-        result = urllib.unquote_plus(given)
+        result = urllib.parse.unquote_plus(given)
         self.assertEqual(expect, result,
                          "using unquote_plus(): %s != %s" % (expect, result))
 
     def test_unquote_with_unicode(self):
-        r = urllib.unquote('br%C3%BCckner_sapporo_20050930.doc')
+        r = urllib.parse.unquote('br%C3%BCckner_sapporo_20050930.doc')
         self.assertEqual(r, 'br\xc3\xbcckner_sapporo_20050930.doc')
 
 class urlencode_Tests(unittest.TestCase):
@@ -462,7 +483,7 @@
 
         """
         expect_somewhere = ["1st=1", "2nd=2", "3rd=3"]
-        result = urllib.urlencode(given)
+        result = urllib.parse.urlencode(given)
         for expected in expect_somewhere:
             self.assert_(expected in result,
                          "testing %s: %s not found in %s" %
@@ -495,20 +516,20 @@
         # Make sure keys and values are quoted using quote_plus()
         given = {"&":"="}
         expect = "%s=%s" % (hexescape('&'), hexescape('='))
-        result = urllib.urlencode(given)
+        result = urllib.parse.urlencode(given)
         self.assertEqual(expect, result)
         given = {"key name":"A bunch of pluses"}
         expect = "key+name=A+bunch+of+pluses"
-        result = urllib.urlencode(given)
+        result = urllib.parse.urlencode(given)
         self.assertEqual(expect, result)
 
     def test_doseq(self):
         # Test that passing True for 'doseq' parameter works correctly
         given = {'sequence':['1', '2', '3']}
-        expect = "sequence=%s" % urllib.quote_plus(str(['1', '2', '3']))
-        result = urllib.urlencode(given)
+        expect = "sequence=%s" % urllib.parse.quote_plus(str(['1', '2', '3']))
+        result = urllib.parse.urlencode(given)
         self.assertEqual(expect, result)
-        result = urllib.urlencode(given, True)
+        result = urllib.parse.urlencode(given, True)
         for value in given["sequence"]:
             expect = "sequence=%s" % value
             self.assert_(expect in result,
@@ -523,11 +544,11 @@
         # Make sure simple tests pass
         expected_path = os.path.join("parts", "of", "a", "path")
         expected_url = "parts/of/a/path"
-        result = urllib.pathname2url(expected_path)
+        result = urllib.request.pathname2url(expected_path)
         self.assertEqual(expected_url, result,
                          "pathname2url() failed; %s != %s" %
                          (result, expected_url))
-        result = urllib.url2pathname(expected_url)
+        result = urllib.request.url2pathname(expected_url)
         self.assertEqual(expected_path, result,
                          "url2pathame() failed; %s != %s" %
                          (result, expected_path))
@@ -536,25 +557,25 @@
         # Test automatic quoting and unquoting works for pathnam2url() and
         # url2pathname() respectively
         given = os.path.join("needs", "quot=ing", "here")
-        expect = "needs/%s/here" % urllib.quote("quot=ing")
-        result = urllib.pathname2url(given)
+        expect = "needs/%s/here" % urllib.parse.quote("quot=ing")
+        result = urllib.request.pathname2url(given)
         self.assertEqual(expect, result,
                          "pathname2url() failed; %s != %s" %
                          (expect, result))
         expect = given
-        result = urllib.url2pathname(result)
+        result = urllib.request.url2pathname(result)
         self.assertEqual(expect, result,
                          "url2pathname() failed; %s != %s" %
                          (expect, result))
         given = os.path.join("make sure", "using_quote")
-        expect = "%s/using_quote" % urllib.quote("make sure")
-        result = urllib.pathname2url(given)
+        expect = "%s/using_quote" % urllib.parse.quote("make sure")
+        result = urllib.request.pathname2url(given)
         self.assertEqual(expect, result,
                          "pathname2url() failed; %s != %s" %
                          (expect, result))
         given = "make+sure/using_unquote"
         expect = os.path.join("make+sure", "using_unquote")
-        result = urllib.url2pathname(given)
+        result = urllib.request.url2pathname(given)
         self.assertEqual(expect, result,
                          "url2pathname() failed; %s != %s" %
                          (expect, result))

Modified: python/branches/py3k/Lib/test/test_urllib2.py
==============================================================================
--- python/branches/py3k/Lib/test/test_urllib2.py	(original)
+++ python/branches/py3k/Lib/test/test_urllib2.py	Wed Jun 18 22:49:58 2008
@@ -5,8 +5,8 @@
 import io
 import socket
 
-import urllib2
-from urllib2 import Request, OpenerDirector
+import urllib.request
+from urllib.request import Request, OpenerDirector
 
 # XXX
 # Request
@@ -17,10 +17,10 @@
     def test_trivial(self):
         # A couple trivial tests
 
-        self.assertRaises(ValueError, urllib2.urlopen, 'bogus url')
+        self.assertRaises(ValueError, urllib.request.urlopen, 'bogus url')
 
         # XXX Name hacking to get this to work on Windows.
-        fname = os.path.abspath(urllib2.__file__).replace('\\', '/')
+        fname = os.path.abspath(urllib.request.__file__).replace('\\', '/')
         if fname[1:2] == ":":
             fname = fname[2:]
         # And more hacking to get it to work on MacOS. This assumes
@@ -29,18 +29,21 @@
             fname = '/' + fname.replace(':', '/')
 
         file_url = "file://%s" % fname
-        f = urllib2.urlopen(file_url)
+        f = urllib.request.urlopen(file_url)
 
         buf = f.read()
         f.close()
 
     def test_parse_http_list(self):
-        tests = [('a,b,c', ['a', 'b', 'c']),
-                 ('path"o,l"og"i"cal, example', ['path"o,l"og"i"cal', 'example']),
-                 ('a, b, "c", "d", "e,f", g, h', ['a', 'b', '"c"', '"d"', '"e,f"', 'g', 'h']),
-                 ('a="b\\"c", d="e\\,f", g="h\\\\i"', ['a="b"c"', 'd="e,f"', 'g="h\\i"'])]
+        tests = [
+            ('a,b,c', ['a', 'b', 'c']),
+            ('path"o,l"og"i"cal, example', ['path"o,l"og"i"cal', 'example']),
+            ('a, b, "c", "d", "e,f", g, h',
+             ['a', 'b', '"c"', '"d"', '"e,f"', 'g', 'h']),
+            ('a="b\\"c", d="e\\,f", g="h\\\\i"',
+             ['a="b"c"', 'd="e,f"', 'g="h\\i"'])]
         for string, list in tests:
-            self.assertEquals(urllib2.parse_http_list(string), list)
+            self.assertEquals(urllib.request.parse_http_list(string), list)
 
 
 def test_request_headers_dict():
@@ -107,7 +110,7 @@
 
 def test_password_manager(self):
     """
-    >>> mgr = urllib2.HTTPPasswordMgr()
+    >>> mgr = urllib.request.HTTPPasswordMgr()
     >>> add = mgr.add_password
     >>> add("Some Realm", "http://example.com/", "joe", "password")
     >>> add("Some Realm", "http://example.com/ni", "ni", "ni")
@@ -172,7 +175,7 @@
 
 def test_password_manager_default_port(self):
     """
-    >>> mgr = urllib2.HTTPPasswordMgr()
+    >>> mgr = urllib.request.HTTPPasswordMgr()
     >>> add = mgr.add_password
 
     The point to note here is that we can't guess the default port if there's
@@ -288,7 +291,7 @@
             res = MockResponse(200, "OK", {}, "")
             return self.parent.error("http", args[0], res, code, "", {})
         elif action == "raise":
-            raise urllib2.URLError("blah")
+            raise urllib.error.URLError("blah")
         assert False
     def close(self): pass
     def add_parent(self, parent):
@@ -337,7 +340,7 @@
         opener.add_handler(h)
     return opener
 
-class MockHTTPHandler(urllib2.BaseHandler):
+class MockHTTPHandler(urllib.request.BaseHandler):
     # useful for testing redirections and auth
     # sends supplied headers and code as first response
     # sends 200 OK as second response
@@ -392,7 +395,7 @@
         # TypeError in real code; here, returning self from these mock
         # methods would either cause no exception, or AttributeError.
 
-        from urllib2 import URLError
+        from urllib.error import URLError
 
         o = OpenerDirector()
         meth_spec = [
@@ -400,7 +403,7 @@
             [("redirect_request", "return self")],
             ]
         handlers = add_ordered_mock_handlers(o, meth_spec)
-        o.add_handler(urllib2.UnknownHandler())
+        o.add_handler(urllib.request.UnknownHandler())
         for scheme in "do", "proxy", "redirect":
             self.assertRaises(URLError, o.open, scheme+"://example.com/")
 
@@ -458,7 +461,7 @@
         handlers = add_ordered_mock_handlers(o, meth_spec)
 
         req = Request("http://example.com/")
-        self.assertRaises(urllib2.URLError, o.open, req)
+        self.assertRaises(urllib.error.URLError, o.open, req)
         self.assertEqual(o.calls, [(handlers[0], "http_open", (req,), {})])
 
 ##     def test_error(self):
@@ -529,8 +532,7 @@
 
 
 def sanepathname2url(path):
-    import urllib
-    urlpath = urllib.pathname2url(path)
+    urlpath = urllib.request.pathname2url(path)
     if os.name == "nt" and urlpath.startswith("///"):
         urlpath = urlpath[2:]
     # XXX don't ask me about the mac...
@@ -545,7 +547,7 @@
                 self.filename, self.filetype = filename, filetype
                 return io.StringIO(self.data), len(self.data)
 
-        class NullFTPHandler(urllib2.FTPHandler):
+        class NullFTPHandler(urllib.request.FTPHandler):
             def __init__(self, data): self.data = data
             def connect_ftp(self, user, passwd, host, port, dirs,
                             timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
@@ -587,7 +589,7 @@
 
     def test_file(self):
         import email.utils, socket
-        h = urllib2.FileHandler()
+        h = urllib.request.FileHandler()
         o = h.parent = MockOpener()
 
         TESTFN = support.TESTFN
@@ -644,12 +646,12 @@
                 finally:
                     f.close()
 
-                self.assertRaises(urllib2.URLError,
+                self.assertRaises(urllib.error.URLError,
                                   h.file_open, Request(url))
             finally:
                 os.remove(TESTFN)
 
-        h = urllib2.FileHandler()
+        h = urllib.request.FileHandler()
         o = h.parent = MockOpener()
         # XXXX why does // mean ftp (and /// mean not ftp!), and where
         #  is file: scheme specified?  I think this is really a bug, and
@@ -668,7 +670,7 @@
             try:
                 h.file_open(req)
             # XXXX remove OSError when bug fixed
-            except (urllib2.URLError, OSError):
+            except (urllib.error.URLError, OSError):
                 self.assert_(not ftp)
             else:
                 self.assert_(o.req is req)
@@ -685,6 +687,7 @@
                 return ''
         class MockHTTPClass:
             def __init__(self):
+                self.level = 0
                 self.req_headers = []
                 self.data = None
                 self.raise_on_endheaders = False
@@ -707,7 +710,7 @@
             def getresponse(self):
                 return MockHTTPResponse(MockFile(), {}, 200, "OK")
 
-        h = urllib2.AbstractHTTPHandler()
+        h = urllib.request.AbstractHTTPHandler()
         o = h.parent = MockOpener()
 
         url = "http://example.com/"
@@ -737,7 +740,7 @@
 
         # check socket.error converted to URLError
         http.raise_on_endheaders = True
-        self.assertRaises(urllib2.URLError, h.do_open, http, req)
+        self.assertRaises(urllib.error.URLError, h.do_open, http, req)
 
         # check adding of standard headers
         o.addheaders = [("Spam", "eggs")]
@@ -768,7 +771,7 @@
             self.assertEqual(req.unredirected_hdrs["Spam"], "foo")
 
     def test_errors(self):
-        h = urllib2.HTTPErrorProcessor()
+        h = urllib.request.HTTPErrorProcessor()
         o = h.parent = MockOpener()
 
         url = "http://example.com/"
@@ -794,7 +797,7 @@
 
     def test_cookies(self):
         cj = MockCookieJar()
-        h = urllib2.HTTPCookieProcessor(cj)
+        h = urllib.request.HTTPCookieProcessor(cj)
         o = h.parent = MockOpener()
 
         req = Request("http://example.com/")
@@ -810,7 +813,7 @@
     def test_redirect(self):
         from_url = "http://example.com/a.html"
         to_url = "http://example.com/b.html"
-        h = urllib2.HTTPRedirectHandler()
+        h = urllib.request.HTTPRedirectHandler()
         o = h.parent = MockOpener()
 
         # ordinary redirect behaviour
@@ -825,7 +828,7 @@
                 try:
                     method(req, MockFile(), code, "Blah",
                            MockHeaders({"location": to_url}))
-                except urllib2.HTTPError:
+                except urllib.error.HTTPError:
                     # 307 in response to POST requires user OK
                     self.assert_(code == 307 and data is not None)
                 self.assertEqual(o.req.get_full_url(), to_url)
@@ -860,9 +863,9 @@
             while 1:
                 redirect(h, req, "http://example.com/")
                 count = count + 1
-        except urllib2.HTTPError:
+        except urllib.error.HTTPError:
             # don't stop until max_repeats, because cookies may introduce state
-            self.assertEqual(count, urllib2.HTTPRedirectHandler.max_repeats)
+            self.assertEqual(count, urllib.request.HTTPRedirectHandler.max_repeats)
 
         # detect endless non-repeating chain of redirects
         req = Request(from_url, origin_req_host="example.com")
@@ -871,9 +874,9 @@
             while 1:
                 redirect(h, req, "http://example.com/%d" % count)
                 count = count + 1
-        except urllib2.HTTPError:
+        except urllib.error.HTTPError:
             self.assertEqual(count,
-                             urllib2.HTTPRedirectHandler.max_redirections)
+                             urllib.request.HTTPRedirectHandler.max_redirections)
 
     def test_cookie_redirect(self):
         # cookies shouldn't leak into redirected requests
@@ -883,16 +886,16 @@
         cj = CookieJar()
         interact_netscape(cj, "http://www.example.com/", "spam=eggs")
         hh = MockHTTPHandler(302, "Location: http://www.cracker.com/\r\n\r\n")
-        hdeh = urllib2.HTTPDefaultErrorHandler()
-        hrh = urllib2.HTTPRedirectHandler()
-        cp = urllib2.HTTPCookieProcessor(cj)
+        hdeh = urllib.request.HTTPDefaultErrorHandler()
+        hrh = urllib.request.HTTPRedirectHandler()
+        cp = urllib.request.HTTPCookieProcessor(cj)
         o = build_test_opener(hh, hdeh, hrh, cp)
         o.open("http://www.example.com/")
         self.assert_(not hh.req.has_header("Cookie"))
 
     def test_proxy(self):
         o = OpenerDirector()
-        ph = urllib2.ProxyHandler(dict(http="proxy.example.com:3128"))
+        ph = urllib.request.ProxyHandler(dict(http="proxy.example.com:3128"))
         o.add_handler(ph)
         meth_spec = [
             [("http_open", "return response")]
@@ -910,7 +913,7 @@
     def test_basic_auth(self, quote_char='"'):
         opener = OpenerDirector()
         password_manager = MockPasswordManager()
-        auth_handler = urllib2.HTTPBasicAuthHandler(password_manager)
+        auth_handler = urllib.request.HTTPBasicAuthHandler(password_manager)
         realm = "ACME Widget Store"
         http_handler = MockHTTPHandler(
             401, 'WWW-Authenticate: Basic realm=%s%s%s\r\n\r\n' %
@@ -928,10 +931,10 @@
 
     def test_proxy_basic_auth(self):
         opener = OpenerDirector()
-        ph = urllib2.ProxyHandler(dict(http="proxy.example.com:3128"))
+        ph = urllib.request.ProxyHandler(dict(http="proxy.example.com:3128"))
         opener.add_handler(ph)
         password_manager = MockPasswordManager()
-        auth_handler = urllib2.ProxyBasicAuthHandler(password_manager)
+        auth_handler = urllib.request.ProxyBasicAuthHandler(password_manager)
         realm = "ACME Networks"
         http_handler = MockHTTPHandler(
             407, 'Proxy-Authenticate: Basic realm="%s"\r\n\r\n' % realm)
@@ -958,15 +961,15 @@
                 self.recorded = []
             def record(self, info):
                 self.recorded.append(info)
-        class TestDigestAuthHandler(urllib2.HTTPDigestAuthHandler):
+        class TestDigestAuthHandler(urllib.request.HTTPDigestAuthHandler):
             def http_error_401(self, *args, **kwds):
                 self.parent.record("digest")
-                urllib2.HTTPDigestAuthHandler.http_error_401(self,
+                urllib.request.HTTPDigestAuthHandler.http_error_401(self,
                                                              *args, **kwds)
-        class TestBasicAuthHandler(urllib2.HTTPBasicAuthHandler):
+        class TestBasicAuthHandler(urllib.request.HTTPBasicAuthHandler):
             def http_error_401(self, *args, **kwds):
                 self.parent.record("basic")
-                urllib2.HTTPBasicAuthHandler.http_error_401(self,
+                urllib.request.HTTPBasicAuthHandler.http_error_401(self,
                                                             *args, **kwds)
 
         opener = RecordingOpenerDirector()
@@ -1030,13 +1033,13 @@
 class MiscTests(unittest.TestCase):
 
     def test_build_opener(self):
-        class MyHTTPHandler(urllib2.HTTPHandler): pass
-        class FooHandler(urllib2.BaseHandler):
+        class MyHTTPHandler(urllib.request.HTTPHandler): pass
+        class FooHandler(urllib.request.BaseHandler):
             def foo_open(self): pass
-        class BarHandler(urllib2.BaseHandler):
+        class BarHandler(urllib.request.BaseHandler):
             def bar_open(self): pass
 
-        build_opener = urllib2.build_opener
+        build_opener = urllib.request.build_opener
 
         o = build_opener(FooHandler, BarHandler)
         self.opener_has_handler(o, FooHandler)
@@ -1054,14 +1057,14 @@
         # a particular case of overriding: default handlers can be passed
         # in explicitly
         o = build_opener()
-        self.opener_has_handler(o, urllib2.HTTPHandler)
-        o = build_opener(urllib2.HTTPHandler)
-        self.opener_has_handler(o, urllib2.HTTPHandler)
-        o = build_opener(urllib2.HTTPHandler())
-        self.opener_has_handler(o, urllib2.HTTPHandler)
+        self.opener_has_handler(o, urllib.request.HTTPHandler)
+        o = build_opener(urllib.request.HTTPHandler)
+        self.opener_has_handler(o, urllib.request.HTTPHandler)
+        o = build_opener(urllib.request.HTTPHandler())
+        self.opener_has_handler(o, urllib.request.HTTPHandler)
 
         # Issue2670: multiple handlers sharing the same base class
-        class MyOtherHTTPHandler(urllib2.HTTPHandler): pass
+        class MyOtherHTTPHandler(urllib.request.HTTPHandler): pass
         o = build_opener(MyHTTPHandler, MyOtherHTTPHandler)
         self.opener_has_handler(o, MyHTTPHandler)
         self.opener_has_handler(o, MyOtherHTTPHandler)
@@ -1077,7 +1080,7 @@
 def test_main(verbose=None):
     from test import test_urllib2
     support.run_doctest(test_urllib2, verbose)
-    support.run_doctest(urllib2, verbose)
+    support.run_doctest(urllib.request, verbose)
     tests = (TrivialTests,
              OpenerDirectorTests,
              HandlerTests,

Modified: python/branches/py3k/Lib/test/test_urllib2_localnet.py
==============================================================================
--- python/branches/py3k/Lib/test/test_urllib2_localnet.py	(original)
+++ python/branches/py3k/Lib/test/test_urllib2_localnet.py	Wed Jun 18 22:49:58 2008
@@ -2,8 +2,8 @@
 
 import email
 import threading
-import urlparse
-import urllib2
+import urllib.parse
+import urllib.request
 import http.server
 import unittest
 import hashlib
@@ -45,7 +45,7 @@
         self._stop_server = False
         self.ready = threading.Event()
         request_handler.protocol_version = "HTTP/1.0"
-        self.httpd = LoopbackHttpServer(('127.0.0.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)
@@ -154,11 +154,11 @@
         if len(self._users) == 0:
             return True
 
-        if 'Proxy-Authorization' not in request_handler.headers:
+        if "Proxy-Authorization" not in request_handler.headers:
             return self._return_auth_challenge(request_handler)
         else:
             auth_dict = self._create_auth_dict(
-                request_handler.headers['Proxy-Authorization']
+                request_handler.headers["Proxy-Authorization"]
                 )
             if auth_dict["username"] in self._users:
                 password = self._users[ auth_dict["username"] ]
@@ -199,12 +199,12 @@
 
     def log_message(self, format, *args):
         # Uncomment the next line for debugging.
-        #sys.stderr.write(format % args)
+        # sys.stderr.write(format % args)
         pass
 
     def do_GET(self):
-        (scm, netloc, path, params, query, fragment) = urlparse.urlparse(
-            self.path, 'http')
+        (scm, netloc, path, params, query, fragment) = urllib.parse.urlparse(
+            self.path, "http")
         self.short_path = path
         if self.digest_auth_handler.handle_request(self):
             self.send_response(200, "OK")
@@ -234,9 +234,10 @@
         self.server.start()
         self.server.ready.wait()
         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)
+        handler = urllib.request.ProxyHandler({"http" : proxy_url})
+        self._digest_auth_handler = urllib.request.ProxyDigestAuthHandler()
+        self.opener = urllib.request.build_opener(
+            handler, self._digest_auth_handler)
 
     def tearDown(self):
         self.server.stop()
@@ -245,13 +246,13 @@
         self._digest_auth_handler.add_password(self.REALM, self.URL,
                                                self.USER, self.PASSWD+"bad")
         FakeProxyHandler.digest_auth_handler.set_qop("auth")
-        self.assertRaises(urllib2.HTTPError,
+        self.assertRaises(urllib.error.HTTPError,
                           self.opener.open,
                           self.URL)
 
     def test_proxy_with_no_password_raises_httperror(self):
         FakeProxyHandler.digest_auth_handler.set_qop("auth")
-        self.assertRaises(urllib2.HTTPError,
+        self.assertRaises(urllib.error.HTTPError,
                           self.opener.open,
                           self.URL)
 
@@ -270,7 +271,7 @@
         FakeProxyHandler.digest_auth_handler.set_qop("auth-int")
         try:
             result = self.opener.open(self.URL)
-        except urllib2.URLError:
+        except urllib.error.URLError:
             # It's okay if we don't support auth-int, but we certainly
             # shouldn't receive any kind of exception here other than
             # a URLError.
@@ -296,7 +297,7 @@
                 self.wfile.write(body)
 
         def do_POST(self):
-            content_length = self.headers['Content-Length']
+            content_length = self.headers["Content-Length"]
             post_data = self.rfile.read(int(content_length))
             self.do_GET()
             self.requests.append(post_data)
@@ -311,7 +312,7 @@
             for (header, value) in headers:
                 self.send_header(header, value % self.port)
             if body:
-                self.send_header('Content-type', 'text/plain')
+                self.send_header("Content-type", "text/plain")
                 self.end_headers()
                 return body
             self.end_headers()
@@ -332,7 +333,22 @@
     for transparent redirection have been written.
     """
 
-    def start_server(self, responses):
+    def setUp(self):
+        self.server = None
+
+    def tearDown(self):
+        if self.server is not None:
+            self.server.stop()
+
+    def urlopen(self, url, data=None):
+        f = urllib.request.urlopen(url, data)
+        result = f.read()
+        f.close()
+        return result
+
+    def start_server(self, responses=None):
+        if responses is None:
+            responses = [(200, [], b"we don't care")]
         handler = GetRequestHandler(responses)
 
         self.server = LoopbackHttpServerThread(handler)
@@ -342,106 +358,71 @@
         handler.port = port
         return handler
 
-
     def test_redirection(self):
-        expected_response = b'We got here...'
+        expected_response = b"We got here..."
         responses = [
-            (302, [('Location', 'http://localhost:%s/somewhere_else')], ''),
+            (302, [("Location", "http://localhost:%s/somewhere_else")], ""),
             (200, [], expected_response)
         ]
 
         handler = self.start_server(responses)
-
-        try:
-            f = urllib2.urlopen('http://localhost:%s/' % handler.port)
-            data = f.read()
-            f.close()
-
-            self.assertEquals(data, expected_response)
-            self.assertEquals(handler.requests, ['/', '/somewhere_else'])
-        finally:
-            self.server.stop()
-
+        data = self.urlopen("http://localhost:%s/" % handler.port)
+        self.assertEquals(data, expected_response)
+        self.assertEquals(handler.requests, ["/", "/somewhere_else"])
 
     def test_404(self):
-        expected_response = b'Bad bad bad...'
+        expected_response = b"Bad bad bad..."
         handler = self.start_server([(404, [], expected_response)])
 
         try:
-            try:
-                urllib2.urlopen('http://localhost:%s/weeble' % handler.port)
-            except urllib2.URLError as f:
-                data = f.read()
-                f.close()
-            else:
-                self.fail('404 should raise URLError')
-
-            self.assertEquals(data, expected_response)
-            self.assertEquals(handler.requests, ['/weeble'])
-        finally:
-            self.server.stop()
+            self.urlopen("http://localhost:%s/weeble" % handler.port)
+        except urllib.error.URLError as f:
+            data = f.read()
+            f.close()
+        else:
+            self.fail("404 should raise URLError")
 
+        self.assertEquals(data, expected_response)
+        self.assertEquals(handler.requests, ["/weeble"])
 
     def test_200(self):
-        expected_response = b'pycon 2008...'
+        expected_response = b"pycon 2008..."
         handler = self.start_server([(200, [], expected_response)])
-
-        try:
-            f = urllib2.urlopen('http://localhost:%s/bizarre' % handler.port)
-            data = f.read()
-            f.close()
-
-            self.assertEquals(data, expected_response)
-            self.assertEquals(handler.requests, ['/bizarre'])
-        finally:
-            self.server.stop()
+        data = self.urlopen("http://localhost:%s/bizarre" % handler.port)
+        self.assertEquals(data, expected_response)
+        self.assertEquals(handler.requests, ["/bizarre"])
 
     def test_200_with_parameters(self):
-        expected_response = b'pycon 2008...'
+        expected_response = b"pycon 2008..."
         handler = self.start_server([(200, [], expected_response)])
-
-        try:
-            f = urllib2.urlopen('http://localhost:%s/bizarre' % handler.port, b'get=with_feeling')
-            data = f.read()
-            f.close()
-
-            self.assertEquals(data, expected_response)
-            self.assertEquals(handler.requests, ['/bizarre', b'get=with_feeling'])
-        finally:
-            self.server.stop()
-
+        data = self.urlopen("http://localhost:%s/bizarre" % handler.port,
+                             b"get=with_feeling")
+        self.assertEquals(data, expected_response)
+        self.assertEquals(handler.requests, ["/bizarre", b"get=with_feeling"])
 
     def test_sending_headers(self):
-        handler = self.start_server([(200, [], b"we don't care")])
-
-        try:
-            req = urllib2.Request("http://localhost:%s/" % handler.port,
-                                  headers={'Range': 'bytes=20-39'})
-            urllib2.urlopen(req)
-            self.assertEqual(handler.headers_received['Range'], 'bytes=20-39')
-        finally:
-            self.server.stop()
+        handler = self.start_server()
+        req = urllib.request.Request("http://localhost:%s/" % handler.port,
+                                     headers={"Range": "bytes=20-39"})
+        urllib.request.urlopen(req)
+        self.assertEqual(handler.headers_received["Range"], "bytes=20-39")
 
     def test_basic(self):
-        handler = self.start_server([(200, [], b"we don't care")])
-
+        handler = self.start_server()
+        open_url = urllib.request.urlopen("http://localhost:%s" % handler.port)
+        for attr in ("read", "close", "info", "geturl"):
+            self.assert_(hasattr(open_url, attr), "object returned from "
+                         "urlopen lacks the %s attribute" % attr)
         try:
-            open_url = urllib2.urlopen("http://localhost:%s" % handler.port)
-            for attr in ("read", "close", "info", "geturl"):
-                self.assert_(hasattr(open_url, attr), "object returned from "
-                             "urlopen lacks the %s attribute" % attr)
-            try:
-                self.assert_(open_url.read(), "calling 'read' failed")
-            finally:
-                open_url.close()
+            self.assert_(open_url.read(), "calling 'read' failed")
         finally:
-            self.server.stop()
+            open_url.close()
 
     def test_info(self):
-        handler = self.start_server([(200, [], b"we don't care")])
-
+        handler = self.start_server()
         try:
-            open_url = urllib2.urlopen("http://localhost:%s" % handler.port)
+            open_url = urllib.request.urlopen(
+                "http://localhost:%s" % handler.port)
             info_obj = open_url.info()
             self.assert_(isinstance(info_obj, email.message.Message),
                          "object returned by 'info' is not an instance of "
@@ -452,15 +433,10 @@
 
     def test_geturl(self):
         # Make sure same URL as opened is returned by geturl.
-        handler = self.start_server([(200, [], b"we don't care")])
-
-        try:
-            open_url = urllib2.urlopen("http://localhost:%s" % handler.port)
-            url = open_url.geturl()
-            self.assertEqual(url, "http://localhost:%s" % handler.port)
-        finally:
-            self.server.stop()
-
+        handler = self.start_server()
+        open_url = urllib.request.urlopen("http://localhost:%s" % handler.port)
+        url = open_url.geturl()
+        self.assertEqual(url, "http://localhost:%s" % handler.port)
 
     def test_bad_address(self):
         # Make sure proper exception is raised when connecting to a bogus
@@ -472,17 +448,10 @@
                           # started failing then.  One hopes the .invalid
                           # domain will be spared to serve its defined
                           # purpose.
-                          # urllib2.urlopen, "http://www.sadflkjsasadf.com/")
-                          urllib2.urlopen, "http://www.python.invalid./")
-
+                          urllib.request.urlopen,
+                          "http://www.python.invalid./")
 
 def test_main():
-    # We will NOT depend on the network resource flag
-    # (Lib/test/regrtest.py -u network) since all tests here are only
-    # localhost.  However, if this is a bad rationale, then uncomment
-    # the next line.
-    #support.requires("network")
-
     support.run_unittest(ProxyAuthTests)
     support.run_unittest(TestUrlopen)
 

Modified: python/branches/py3k/Lib/test/test_urllib2net.py
==============================================================================
--- python/branches/py3k/Lib/test/test_urllib2net.py	(original)
+++ python/branches/py3k/Lib/test/test_urllib2net.py	Wed Jun 18 22:49:58 2008
@@ -4,10 +4,11 @@
 from test import support
 from test.test_urllib2 import sanepathname2url
 
+import os
 import socket
-import urllib2
 import sys
-import os
+import urllib.error
+import urllib.request
 
 
 def _retry_thrice(func, exc, *args, **kwargs):
@@ -28,7 +29,8 @@
 
 # Connecting to remote hosts is flaky.  Make it more robust by retrying
 # the connection several times.
-_urlopen_with_retry = _wrap_with_retry_thrice(urllib2.urlopen, urllib2.URLError)
+_urlopen_with_retry = _wrap_with_retry_thrice(urllib.request.urlopen,
+                                              urllib.error.URLError)
 
 
 class AuthTests(unittest.TestCase):
@@ -78,16 +80,11 @@
         # calling .close() on urllib2's response objects should close the
         # underlying socket
 
-        # delve deep into response to fetch socket._socketobject
         response = _urlopen_with_retry("http://www.python.org/")
-        abused_fileobject = response.fp
-        httpresponse = abused_fileobject.raw
-        self.assert_(httpresponse.__class__ is http.client.HTTPResponse)
-        fileobject = httpresponse.fp
-
-        self.assert_(not fileobject.closed)
+        sock = response.fp
+        self.assert_(not sock.closed)
         response.close()
-        self.assert_(fileobject.closed)
+        self.assert_(sock.closed)
 
 class OtherNetworkTests(unittest.TestCase):
     def setUp(self):
@@ -116,8 +113,9 @@
             f.write('hi there\n')
             f.close()
             urls = [
-                'file:'+sanepathname2url(os.path.abspath(TESTFN)),
-                ('file:///nonsensename/etc/passwd', None, urllib2.URLError),
+                'file:' + sanepathname2url(os.path.abspath(TESTFN)),
+                ('file:///nonsensename/etc/passwd', None,
+                 urllib.error.URLError),
                 ]
             self._test_urls(urls, self._extra_handlers(), retry=True)
         finally:
@@ -157,9 +155,9 @@
         import logging
         debug = logging.getLogger("test_urllib2").debug
 
-        urlopen = urllib2.build_opener(*handlers).open
+        urlopen = urllib.request.build_opener(*handlers).open
         if retry:
-            urlopen = _wrap_with_retry_thrice(urlopen, urllib2.URLError)
+            urlopen = _wrap_with_retry_thrice(urlopen, urllib.error.URLError)
 
         for url in urls:
             if isinstance(url, tuple):
@@ -186,7 +184,7 @@
     def _extra_handlers(self):
         handlers = []
 
-        cfh = urllib2.CacheFTPHandler()
+        cfh = urllib.request.CacheFTPHandler()
         cfh.setTimeout(1)
         handlers.append(cfh)
 
@@ -197,7 +195,7 @@
     def test_http_basic(self):
         self.assertTrue(socket.getdefaulttimeout() is None)
         u = _urlopen_with_retry("http://www.python.org")
-        self.assertTrue(u.fp.raw.fp._sock.gettimeout() is None)
+        self.assertTrue(u.fp._sock.gettimeout() is None)
 
     def test_http_default_timeout(self):
         self.assertTrue(socket.getdefaulttimeout() is None)
@@ -206,7 +204,7 @@
             u = _urlopen_with_retry("http://www.python.org")
         finally:
             socket.setdefaulttimeout(None)
-        self.assertEqual(u.fp.raw.fp._sock.gettimeout(), 60)
+        self.assertEqual(u.fp._sock.gettimeout(), 60)
 
     def test_http_no_timeout(self):
         self.assertTrue(socket.getdefaulttimeout() is None)
@@ -215,11 +213,11 @@
             u = _urlopen_with_retry("http://www.python.org", timeout=None)
         finally:
             socket.setdefaulttimeout(None)
-        self.assertTrue(u.fp.raw.fp._sock.gettimeout() is None)
+        self.assertTrue(u.fp._sock.gettimeout() is None)
 
     def test_http_timeout(self):
         u = _urlopen_with_retry("http://www.python.org", timeout=120)
-        self.assertEqual(u.fp.raw.fp._sock.gettimeout(), 120)
+        self.assertEqual(u.fp._sock.gettimeout(), 120)
 
     FTP_HOST = "ftp://ftp.mirror.nl/pub/mirror/gnu/"
 

Modified: python/branches/py3k/Lib/test/test_urllibnet.py
==============================================================================
--- python/branches/py3k/Lib/test/test_urllibnet.py	(original)
+++ python/branches/py3k/Lib/test/test_urllibnet.py	Wed Jun 18 22:49:58 2008
@@ -4,7 +4,7 @@
 from test import support
 
 import socket
-import urllib
+import urllib.request
 import sys
 import os
 import email.message
@@ -36,11 +36,11 @@
         socket.setdefaulttimeout(None)
 
     def testURLread(self):
-        f = _open_with_retry(urllib.urlopen, "http://www.python.org/")
+        f = _open_with_retry(urllib.request.urlopen, "http://www.python.org/")
         x = f.read()
 
 class urlopenNetworkTests(unittest.TestCase):
-    """Tests urllib.urlopen using the network.
+    """Tests urllib.reqest.urlopen using the network.
 
     These tests are not exhaustive.  Assuming that testing using files does a
     good job overall of some of the basic interface features.  There are no
@@ -55,7 +55,7 @@
     """
 
     def urlopen(self, *args):
-        return _open_with_retry(urllib.urlopen, *args)
+        return _open_with_retry(urllib.request.urlopen, *args)
 
     def test_basic(self):
         # Simple test expected to pass.
@@ -105,7 +105,7 @@
     def test_getcode(self):
         # test getcode() with the fancy opener to get 404 error codes
         URL = "http://www.python.org/XXXinvalidXXX"
-        open_url = urllib.FancyURLopener().open(URL)
+        open_url = urllib.request.FancyURLopener().open(URL)
         try:
             code = open_url.getcode()
         finally:
@@ -114,7 +114,7 @@
 
     def test_fileno(self):
         if (sys.platform in ('win32',) or
-                not hasattr(os, 'fdopen')):
+            not hasattr(os, 'fdopen')):
             # On Windows, socket handles are not file descriptors; this
             # test can't pass on Windows.
             return
@@ -142,13 +142,14 @@
                           # domain will be spared to serve its defined
                           # purpose.
                           # urllib.urlopen, "http://www.sadflkjsasadf.com/")
-                          urllib.urlopen, "http://www.python.invalid./")
+                          urllib.request.urlopen,
+                          "http://www.python.invalid./")
 
 class urlretrieveNetworkTests(unittest.TestCase):
-    """Tests urllib.urlretrieve using the network."""
+    """Tests urllib.request.urlretrieve using the network."""
 
     def urlretrieve(self, *args):
-        return _open_with_retry(urllib.urlretrieve, *args)
+        return _open_with_retry(urllib.request.urlretrieve, *args)
 
     def test_basic(self):
         # Test basic functionality.

Modified: python/branches/py3k/Lib/test/test_urlparse.py
==============================================================================
--- python/branches/py3k/Lib/test/test_urlparse.py	(original)
+++ python/branches/py3k/Lib/test/test_urlparse.py	Wed Jun 18 22:49:58 2008
@@ -2,7 +2,7 @@
 
 from test import support
 import unittest
-import urlparse
+import urllib.parse
 
 RFC1808_BASE = "http://a/b/c/d;p?q#f"
 RFC2396_BASE = "http://a/b/c/d;p?q"
@@ -10,19 +10,19 @@
 class UrlParseTestCase(unittest.TestCase):
 
     def checkRoundtrips(self, url, parsed, split):
-        result = urlparse.urlparse(url)
+        result = urllib.parse.urlparse(url)
         self.assertEqual(result, parsed)
         t = (result.scheme, result.netloc, result.path,
              result.params, result.query, result.fragment)
         self.assertEqual(t, parsed)
         # put it back together and it should be the same
-        result2 = urlparse.urlunparse(result)
+        result2 = urllib.parse.urlunparse(result)
         self.assertEqual(result2, url)
         self.assertEqual(result2, result.geturl())
 
         # the result of geturl() is a fixpoint; we can always parse it
         # again to get the same result:
-        result3 = urlparse.urlparse(result.geturl())
+        result3 = urllib.parse.urlparse(result.geturl())
         self.assertEqual(result3.geturl(), result.geturl())
         self.assertEqual(result3,          result)
         self.assertEqual(result3.scheme,   result.scheme)
@@ -37,17 +37,17 @@
         self.assertEqual(result3.port,     result.port)
 
         # check the roundtrip using urlsplit() as well
-        result = urlparse.urlsplit(url)
+        result = urllib.parse.urlsplit(url)
         self.assertEqual(result, split)
         t = (result.scheme, result.netloc, result.path,
              result.query, result.fragment)
         self.assertEqual(t, split)
-        result2 = urlparse.urlunsplit(result)
+        result2 = urllib.parse.urlunsplit(result)
         self.assertEqual(result2, url)
         self.assertEqual(result2, result.geturl())
 
         # check the fixpoint property of re-parsing the result of geturl()
-        result3 = urlparse.urlsplit(result.geturl())
+        result3 = urllib.parse.urlsplit(result.geturl())
         self.assertEqual(result3.geturl(), result.geturl())
         self.assertEqual(result3,          result)
         self.assertEqual(result3.scheme,   result.scheme)
@@ -83,7 +83,7 @@
             self.checkRoundtrips(url, parsed, split)
 
     def test_http_roundtrips(self):
-        # urlparse.urlsplit treats 'http:' as an optimized special case,
+        # urllib.parse.urlsplit treats 'http:' as an optimized special case,
         # so we test both 'http:' and 'https:' in all the following.
         # Three cheers for white box knowledge!
         testcases = [
@@ -111,13 +111,13 @@
                 self.checkRoundtrips(url, parsed, split)
 
     def checkJoin(self, base, relurl, expected):
-        self.assertEqual(urlparse.urljoin(base, relurl), expected,
+        self.assertEqual(urllib.parse.urljoin(base, relurl), expected,
                          (base, relurl, expected))
 
     def test_unparse_parse(self):
         for u in ['Python', './Python']:
-            self.assertEqual(urlparse.urlunsplit(urlparse.urlsplit(u)), u)
-            self.assertEqual(urlparse.urlunparse(urlparse.urlparse(u)), u)
+            self.assertEqual(urllib.parse.urlunsplit(urllib.parse.urlsplit(u)), u)
+            self.assertEqual(urllib.parse.urlunparse(urllib.parse.urlparse(u)), u)
 
     def test_RFC1808(self):
         # "normal" cases from RFC 1808:
@@ -223,11 +223,11 @@
             (RFC1808_BASE, 'http://a/b/c/d;p?q', 'f'),
             (RFC2396_BASE, 'http://a/b/c/d;p?q', ''),
             ]:
-            self.assertEqual(urlparse.urldefrag(url), (defrag, frag))
+            self.assertEqual(urllib.parse.urldefrag(url), (defrag, frag))
 
     def test_urlsplit_attributes(self):
         url = "HTTP://WWW.PYTHON.ORG/doc/#frag"
-        p = urlparse.urlsplit(url)
+        p = urllib.parse.urlsplit(url)
         self.assertEqual(p.scheme, "http")
         self.assertEqual(p.netloc, "WWW.PYTHON.ORG")
         self.assertEqual(p.path, "/doc/")
@@ -242,7 +242,7 @@
         #self.assertEqual(p.geturl(), url)
 
         url = "http://User:Pass at www.python.org:080/doc/?query=yes#frag"
-        p = urlparse.urlsplit(url)
+        p = urllib.parse.urlsplit(url)
         self.assertEqual(p.scheme, "http")
         self.assertEqual(p.netloc, "User:Pass at www.python.org:080")
         self.assertEqual(p.path, "/doc/")
@@ -259,7 +259,7 @@
         # and request email addresses as usernames.
 
         url = "http://User at example.com:Pass at www.python.org:080/doc/?query=yes#frag"
-        p = urlparse.urlsplit(url)
+        p = urllib.parse.urlsplit(url)
         self.assertEqual(p.scheme, "http")
         self.assertEqual(p.netloc, "User at example.com:Pass at www.python.org:080")
         self.assertEqual(p.path, "/doc/")
@@ -274,11 +274,11 @@
 
     def test_attributes_bad_port(self):
         """Check handling of non-integer ports."""
-        p = urlparse.urlsplit("http://www.example.net:foo")
+        p = urllib.parse.urlsplit("http://www.example.net:foo")
         self.assertEqual(p.netloc, "www.example.net:foo")
         self.assertRaises(ValueError, lambda: p.port)
 
-        p = urlparse.urlparse("http://www.example.net:foo")
+        p = urllib.parse.urlparse("http://www.example.net:foo")
         self.assertEqual(p.netloc, "www.example.net:foo")
         self.assertRaises(ValueError, lambda: p.port)
 
@@ -289,7 +289,7 @@
         # scheme://netloc syntax, the netloc and related attributes
         # should be left empty.
         uri = "sip:alice at atlanta.com;maddr=239.255.255.1;ttl=15"
-        p = urlparse.urlsplit(uri)
+        p = urllib.parse.urlsplit(uri)
         self.assertEqual(p.netloc, "")
         self.assertEqual(p.username, None)
         self.assertEqual(p.password, None)
@@ -297,7 +297,7 @@
         self.assertEqual(p.port, None)
         self.assertEqual(p.geturl(), uri)
 
-        p = urlparse.urlparse(uri)
+        p = urllib.parse.urlparse(uri)
         self.assertEqual(p.netloc, "")
         self.assertEqual(p.username, None)
         self.assertEqual(p.password, None)
@@ -307,7 +307,7 @@
 
     def test_noslash(self):
         # Issue 1637: http://foo.com?query is legal
-        self.assertEqual(urlparse.urlparse("http://example.com?blahblah=/foo"),
+        self.assertEqual(urllib.parse.urlparse("http://example.com?blahblah=/foo"),
                          ('http', 'example.com', '', '', 'blahblah=/foo', ''))
 
 def test_main():

Modified: python/branches/py3k/Lib/test/test_xmlrpc.py
==============================================================================
--- python/branches/py3k/Lib/test/test_xmlrpc.py	(original)
+++ python/branches/py3k/Lib/test/test_xmlrpc.py	Wed Jun 18 22:49:58 2008
@@ -111,8 +111,10 @@
                               (int(2**34),))
 
         xmlrpclib.dumps((xmlrpclib.MAXINT, xmlrpclib.MININT))
-        self.assertRaises(OverflowError, xmlrpclib.dumps, (xmlrpclib.MAXINT+1,))
-        self.assertRaises(OverflowError, xmlrpclib.dumps, (xmlrpclib.MININT-1,))
+        self.assertRaises(OverflowError, xmlrpclib.dumps,
+                          (xmlrpclib.MAXINT+1,))
+        self.assertRaises(OverflowError, xmlrpclib.dumps,
+                          (xmlrpclib.MININT-1,))
 
         def dummy_write(s):
             pass
@@ -120,9 +122,10 @@
         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)
-
+        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]
@@ -132,7 +135,6 @@
                           xmlrpclib.loads(strg)[0][0])
         self.assertRaises(TypeError, xmlrpclib.dumps, (arg1,))
 
-
 class HelperTestCase(unittest.TestCase):
     def test_escape(self):
         self.assertEqual(xmlrpclib.escape("a&b"), "a&amp;b")
@@ -160,7 +162,6 @@
         # private methods
         self.assertRaises(AttributeError,
                           xmlrpc.server.resolve_dotted_attribute, str, '__add')
-
         self.assert_(xmlrpc.server.resolve_dotted_attribute(str, 'title'))
 
 class DateTimeTestCase(unittest.TestCase):
@@ -170,7 +171,8 @@
     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)))
+        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)
@@ -180,7 +182,7 @@
     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))
+        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)
@@ -350,12 +352,12 @@
         self.assertEqual(response.reason, 'Not Found')
 
     def test_introspection1(self):
+        expected_methods = set(['pow', 'div', 'my_function', 'add',
+                                'system.listMethods', 'system.methodHelp',
+                                'system.methodSignature', 'system.multicall'])
         try:
             p = xmlrpclib.ServerProxy('http://localhost:%d' % PORT)
             meth = p.system.listMethods()
-            expected_methods = set(['pow', 'div', 'my_function', 'add',
-                                    'system.listMethods', 'system.methodHelp',
-                                    'system.methodSignature', 'system.multicall'])
             self.assertEqual(set(meth), expected_methods)
         except (xmlrpclib.ProtocolError, socket.error) as e:
             # ignore failures due to non-blocking socket 'unavailable' errors
@@ -593,7 +595,8 @@
         # will respond exception, if so, our goal is achieved ;)
         handle = open(support.TESTFN, "r").read()
 
-        # start with 44th char so as not to get http header, we just need only xml
+        # start with 44th char so as not to get http header, we just
+        # need only xml
         self.assertRaises(xmlrpclib.Fault, xmlrpclib.loads, handle[44:])
 
         os.remove("xmldata.txt")

Deleted: python/branches/py3k/Lib/urllib.py
==============================================================================
--- python/branches/py3k/Lib/urllib.py	Wed Jun 18 22:49:58 2008
+++ (empty file)
@@ -1,1714 +0,0 @@
-"""Open an arbitrary URL.
-
-See the following document for more info on URLs:
-"Names and Addresses, URIs, URLs, URNs, URCs", at
-http://www.w3.org/pub/WWW/Addressing/Overview.html
-
-See also the HTTP spec (from which the error codes are derived):
-"HTTP - Hypertext Transfer Protocol", at
-http://www.w3.org/pub/WWW/Protocols/
-
-Related standards and specs:
-- RFC1808: the "relative URL" spec. (authoritative status)
-- RFC1738 - the "URL standard". (authoritative status)
-- RFC1630 - the "URI spec". (informational status)
-
-The object returned by URLopener().open(file) will differ per
-protocol.  All you know is that is has methods read(), readline(),
-readlines(), fileno(), close() and info().  The read*(), fileno()
-and close() methods work like those of open files.
-The info() method returns a email.message.Message object which can be
-used to query various info about the object, if available.
-(email.message.Message objects provide a dict-like interface.)
-"""
-
-import http.client
-import email.message
-import email
-import os
-import socket
-import sys
-import time
-from urlparse import urljoin as basejoin
-
-__all__ = ["urlopen", "URLopener", "FancyURLopener", "urlretrieve",
-           "urlcleanup", "quote", "quote_plus", "unquote", "unquote_plus",
-           "urlencode", "url2pathname", "pathname2url", "splittag",
-           "localhost", "thishost", "ftperrors", "basejoin", "unwrap",
-           "splittype", "splithost", "splituser", "splitpasswd", "splitport",
-           "splitnport", "splitquery", "splitattr", "splitvalue",
-           "getproxies"]
-
-__version__ = '1.17'    # XXX This version is not always updated :-(
-
-MAXFTPCACHE = 10        # Trim the ftp cache beyond this size
-
-# Helper for non-unix systems
-if os.name == 'mac':
-    from macurl2path import url2pathname, pathname2url
-elif os.name == 'nt':
-    from nturl2path import url2pathname, pathname2url
-else:
-    def url2pathname(pathname):
-        """OS-specific conversion from a relative URL of the 'file' scheme
-        to a file system path; not recommended for general use."""
-        return unquote(pathname)
-
-    def pathname2url(pathname):
-        """OS-specific conversion from a file system path to a relative URL
-        of the 'file' scheme; not recommended for general use."""
-        return quote(pathname)
-
-# This really consists of two pieces:
-# (1) a class which handles opening of all sorts of URLs
-#     (plus assorted utilities etc.)
-# (2) a set of functions for parsing URLs
-# XXX Should these be separated out into different modules?
-
-
-# Shortcut for basic usage
-_urlopener = None
-def urlopen(url, data=None, proxies=None):
-    """urlopen(url [, data]) -> open file-like object"""
-    global _urlopener
-    if proxies is not None:
-        opener = FancyURLopener(proxies=proxies)
-    elif not _urlopener:
-        opener = FancyURLopener()
-        _urlopener = opener
-    else:
-        opener = _urlopener
-    if data is None:
-        return opener.open(url)
-    else:
-        return opener.open(url, data)
-
-def urlretrieve(url, filename=None, reporthook=None, data=None):
-    global _urlopener
-    if not _urlopener:
-        _urlopener = FancyURLopener()
-    return _urlopener.retrieve(url, filename, reporthook, data)
-
-def urlcleanup():
-    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):
-        IOError.__init__(self, message)
-        self.content = content
-
-ftpcache = {}
-class URLopener:
-    """Class to open URLs.
-    This is a class rather than just a subroutine because we may need
-    more than one set of global protocol-specific options.
-    Note -- this is a base class for those who don't want the
-    automatic handling of errors type 302 (relocated) and 401
-    (authorization needed)."""
-
-    __tempfiles = None
-
-    version = "Python-urllib/%s" % __version__
-
-    # Constructor
-    def __init__(self, proxies=None, **x509):
-        if proxies is None:
-            proxies = getproxies()
-        assert hasattr(proxies, 'keys'), "proxies must be a mapping"
-        self.proxies = proxies
-        self.key_file = x509.get('key_file')
-        self.cert_file = x509.get('cert_file')
-        self.addheaders = [('User-Agent', self.version)]
-        self.__tempfiles = []
-        self.__unlink = os.unlink # See cleanup()
-        self.tempcache = None
-        # Undocumented feature: if you assign {} to tempcache,
-        # it is used to cache files retrieved with
-        # self.retrieve().  This is not enabled by default
-        # since it does not work for changing documents (and I
-        # haven't got the logic to check expiration headers
-        # yet).
-        self.ftpcache = ftpcache
-        # Undocumented feature: you can use a different
-        # ftp cache by assigning to the .ftpcache member;
-        # in case you want logically independent URL openers
-        # XXX This is not threadsafe.  Bah.
-
-    def __del__(self):
-        self.close()
-
-    def close(self):
-        self.cleanup()
-
-    def cleanup(self):
-        # This code sometimes runs when the rest of this module
-        # has already been deleted, so it can't use any globals
-        # or import anything.
-        if self.__tempfiles:
-            for file in self.__tempfiles:
-                try:
-                    self.__unlink(file)
-                except OSError:
-                    pass
-            del self.__tempfiles[:]
-        if self.tempcache:
-            self.tempcache.clear()
-
-    def addheader(self, *args):
-        """Add a header to be used by the HTTP interface only
-        e.g. u.addheader('Accept', 'sound/basic')"""
-        self.addheaders.append(args)
-
-    # External interface
-    def open(self, fullurl, data=None):
-        """Use URLopener().open(file) instead of open(file, 'r')."""
-        fullurl = unwrap(toBytes(fullurl))
-        if self.tempcache and fullurl in self.tempcache:
-            filename, headers = self.tempcache[fullurl]
-            fp = open(filename, 'rb')
-            return addinfourl(fp, headers, fullurl)
-        urltype, url = splittype(fullurl)
-        if not urltype:
-            urltype = 'file'
-        if urltype in self.proxies:
-            proxy = self.proxies[urltype]
-            urltype, proxyhost = splittype(proxy)
-            host, selector = splithost(proxyhost)
-            url = (host, fullurl) # Signal special case to open_*()
-        else:
-            proxy = None
-        name = 'open_' + urltype
-        self.type = urltype
-        name = name.replace('-', '_')
-        if not hasattr(self, name):
-            if proxy:
-                return self.open_unknown_proxy(proxy, fullurl, data)
-            else:
-                return self.open_unknown(fullurl, data)
-        try:
-            if data is None:
-                return getattr(self, name)(url)
-            else:
-                return getattr(self, name)(url, data)
-        except socket.error as msg:
-            raise IOError('socket error', msg).with_traceback(sys.exc_info()[2])
-
-    def open_unknown(self, fullurl, data=None):
-        """Overridable interface to open unknown URL type."""
-        type, url = splittype(fullurl)
-        raise IOError('url error', 'unknown url type', type)
-
-    def open_unknown_proxy(self, proxy, fullurl, data=None):
-        """Overridable interface to open unknown URL type."""
-        type, url = splittype(fullurl)
-        raise IOError('url error', 'invalid proxy for %s' % type, proxy)
-
-    # External interface
-    def retrieve(self, url, filename=None, reporthook=None, data=None):
-        """retrieve(url) returns (filename, headers) for a local object
-        or (tempfilename, headers) for a remote object."""
-        url = unwrap(toBytes(url))
-        if self.tempcache and url in self.tempcache:
-            return self.tempcache[url]
-        type, url1 = splittype(url)
-        if filename is None and (not type or type == 'file'):
-            try:
-                fp = self.open_local_file(url1)
-                hdrs = fp.info()
-                del fp
-                return url2pathname(splithost(url1)[1]), hdrs
-            except IOError as msg:
-                pass
-        fp = self.open(url, data)
-        headers = fp.info()
-        if filename:
-            tfp = open(filename, 'wb')
-        else:
-            import tempfile
-            garbage, path = splittype(url)
-            garbage, path = splithost(path or "")
-            path, garbage = splitquery(path or "")
-            path, garbage = splitattr(path or "")
-            suffix = os.path.splitext(path)[1]
-            (fd, filename) = tempfile.mkstemp(suffix)
-            self.__tempfiles.append(filename)
-            tfp = os.fdopen(fd, 'wb')
-        result = filename, headers
-        if self.tempcache is not None:
-            self.tempcache[url] = result
-        bs = 1024*8
-        size = -1
-        read = 0
-        blocknum = 0
-        if reporthook:
-            if "content-length" in headers:
-                size = int(headers["Content-Length"])
-            reporthook(blocknum, bs, size)
-        while 1:
-            block = fp.read(bs)
-            if not block:
-                break
-            read += len(block)
-            tfp.write(block)
-            blocknum += 1
-            if reporthook:
-                reporthook(blocknum, bs, size)
-        fp.close()
-        tfp.close()
-        del fp
-        del tfp
-
-        # raise exception if actual size does not match content-length header
-        if size >= 0 and read < size:
-            raise ContentTooShortError("retrieval incomplete: got only %i out "
-                                       "of %i bytes" % (read, size), result)
-
-        return result
-
-    # Each method named open_<type> knows how to open that type of URL
-
-    def _open_generic_http(self, connection_factory, url, data):
-        """Make an HTTP connection using connection_class.
-
-        This is an internal method that should be called from
-        open_http() or open_https().
-
-        Arguments:
-        - connection_factory should take a host name and return an
-          HTTPConnection instance.
-        - url is the url to retrieval or a host, relative-path pair.
-        - data is payload for a POST request or None.
-        """
-
-        user_passwd = None
-        proxy_passwd= None
-        if isinstance(url, str):
-            host, selector = splithost(url)
-            if host:
-                user_passwd, host = splituser(host)
-                host = unquote(host)
-            realhost = host
-        else:
-            host, selector = url
-            # check whether the proxy contains authorization information
-            proxy_passwd, host = splituser(host)
-            # now we proceed with the url we want to obtain
-            urltype, rest = splittype(selector)
-            url = rest
-            user_passwd = None
-            if urltype.lower() != 'http':
-                realhost = None
-            else:
-                realhost, rest = splithost(rest)
-                if realhost:
-                    user_passwd, realhost = splituser(realhost)
-                if user_passwd:
-                    selector = "%s://%s%s" % (urltype, realhost, rest)
-                if proxy_bypass(realhost):
-                    host = realhost
-
-            #print "proxy via http:", host, selector
-        if not host: raise IOError('http error', 'no host given')
-
-        if proxy_passwd:
-            import base64
-            proxy_auth = base64.b64encode(proxy_passwd).strip()
-        else:
-            proxy_auth = None
-
-        if user_passwd:
-            import base64
-            auth = base64.b64encode(user_passwd).strip()
-        else:
-            auth = None
-        http_conn = connection_factory(host)
-        # XXX We should fix urllib so that it works with HTTP/1.1.
-        http_conn._http_vsn = 10
-        http_conn._http_vsn_str = "HTTP/1.0"
-
-        headers = {}
-        if proxy_auth:
-            headers["Proxy-Authorization"] = "Basic %s" % proxy_auth
-        if auth:
-            headers["Authorization"] =  "Basic %s" % auth
-        if realhost:
-            headers["Host"] = realhost
-        for header, value in self.addheaders:
-            headers[header] = value
-
-        if data is not None:
-            headers["Content-Type"] = "application/x-www-form-urlencoded"
-            http_conn.request("POST", selector, data, headers)
-        else:
-            http_conn.request("GET", selector, headers=headers)
-
-        try:
-            response = http_conn.getresponse()
-        except http.client.BadStatusLine:
-            # something went wrong with the HTTP status line
-            raise IOError('http protocol error', 0,
-                          'got a bad status line', None)
-
-        # According to RFC 2616, "2xx" code indicates that the client's
-        # request was successfully received, understood, and accepted.
-        if (200 <= response.status < 300):
-            return addinfourl(response.fp, response.msg, "http:" + url,
-                              response.status)
-        else:
-            return self.http_error(
-                url, response.fp,
-                response.status, response.reason, response.msg, data)
-
-    def open_http(self, url, data=None):
-        """Use HTTP protocol."""
-        return self._open_generic_http(http.client.HTTPConnection, url, data)
-
-    def http_error(self, url, fp, errcode, errmsg, headers, data=None):
-        """Handle http errors.
-
-        Derived class can override this, or provide specific handlers
-        named http_error_DDD where DDD is the 3-digit error code."""
-        # First check if there's a specific handler for this error
-        name = 'http_error_%d' % errcode
-        if hasattr(self, name):
-            method = getattr(self, name)
-            if data is None:
-                result = method(url, fp, errcode, errmsg, headers)
-            else:
-                result = method(url, fp, errcode, errmsg, headers, data)
-            if result: return result
-        return self.http_error_default(url, fp, errcode, errmsg, headers)
-
-    def http_error_default(self, url, fp, errcode, errmsg, headers):
-        """Default error handler: close the connection and raise IOError."""
-        void = fp.read()
-        fp.close()
-        raise IOError('http error', errcode, errmsg, headers)
-
-    if _have_ssl:
-        def _https_connection(self, host):
-            return http.client.HTTPSConnection(host,
-                                               key_file=self.key_file,
-                                               cert_file=self.cert_file)
-
-        def open_https(self, url, data=None):
-            """Use HTTPS protocol."""
-            return self._open_generic_http(self._https_connection, url, data)
-
-    def open_file(self, url):
-        """Use local file or FTP depending on form of URL."""
-        if not isinstance(url, str):
-            raise IOError('file error', 'proxy support for file protocol currently not implemented')
-        if url[:2] == '//' and url[2:3] != '/' and url[2:12].lower() != 'localhost/':
-            return self.open_ftp(url)
-        else:
-            return self.open_local_file(url)
-
-    def open_local_file(self, url):
-        """Use local file."""
-        import mimetypes, email.utils
-        host, file = splithost(url)
-        localname = url2pathname(file)
-        try:
-            stats = os.stat(localname)
-        except OSError as e:
-            raise IOError(e.errno, e.strerror, e.filename)
-        size = stats.st_size
-        modified = email.utils.formatdate(stats.st_mtime, usegmt=True)
-        mtype = mimetypes.guess_type(url)[0]
-        headers = email.message_from_string(
-            'Content-Type: %s\nContent-Length: %d\nLast-modified: %s\n' %
-            (mtype or 'text/plain', size, modified))
-        if not host:
-            urlfile = file
-            if file[:1] == '/':
-                urlfile = 'file://' + file
-            return addinfourl(open(localname, 'rb'),
-                              headers, urlfile)
-        host, port = splitport(host)
-        if not port \
-           and socket.gethostbyname(host) in (localhost(), thishost()):
-            urlfile = file
-            if file[:1] == '/':
-                urlfile = 'file://' + file
-            return addinfourl(open(localname, 'rb'),
-                              headers, urlfile)
-        raise IOError('local file error', 'not on local host')
-
-    def open_ftp(self, url):
-        """Use FTP protocol."""
-        if not isinstance(url, str):
-            raise IOError('ftp error', 'proxy support for ftp protocol currently not implemented')
-        import mimetypes
-        host, path = splithost(url)
-        if not host: raise IOError('ftp error', 'no host given')
-        host, port = splitport(host)
-        user, host = splituser(host)
-        if user: user, passwd = splitpasswd(user)
-        else: passwd = None
-        host = unquote(host)
-        user = unquote(user or '')
-        passwd = unquote(passwd or '')
-        host = socket.gethostbyname(host)
-        if not port:
-            import ftplib
-            port = ftplib.FTP_PORT
-        else:
-            port = int(port)
-        path, attrs = splitattr(path)
-        path = unquote(path)
-        dirs = path.split('/')
-        dirs, file = dirs[:-1], dirs[-1]
-        if dirs and not dirs[0]: dirs = dirs[1:]
-        if dirs and not dirs[0]: dirs[0] = '/'
-        key = user, host, port, '/'.join(dirs)
-        # XXX thread unsafe!
-        if len(self.ftpcache) > MAXFTPCACHE:
-            # Prune the cache, rather arbitrarily
-            for k in self.ftpcache.keys():
-                if k != key:
-                    v = self.ftpcache[k]
-                    del self.ftpcache[k]
-                    v.close()
-        try:
-            if not key in self.ftpcache:
-                self.ftpcache[key] = \
-                    ftpwrapper(user, passwd, host, port, dirs)
-            if not file: type = 'D'
-            else: type = 'I'
-            for attr in attrs:
-                attr, value = splitvalue(attr)
-                if attr.lower() == 'type' and \
-                   value in ('a', 'A', 'i', 'I', 'd', 'D'):
-                    type = value.upper()
-            (fp, retrlen) = self.ftpcache[key].retrfile(file, type)
-            mtype = mimetypes.guess_type("ftp:" + url)[0]
-            headers = ""
-            if mtype:
-                headers += "Content-Type: %s\n" % mtype
-            if retrlen is not None and retrlen >= 0:
-                headers += "Content-Length: %d\n" % retrlen
-            headers = email.message_from_string(headers)
-            return addinfourl(fp, headers, "ftp:" + url)
-        except ftperrors() as msg:
-            raise IOError('ftp error', msg).with_traceback(sys.exc_info()[2])
-
-    def open_data(self, url, data=None):
-        """Use "data" URL."""
-        if not isinstance(url, str):
-            raise IOError('data error', 'proxy support for data protocol currently not implemented')
-        # ignore POSTed data
-        #
-        # syntax of data URLs:
-        # dataurl   := "data:" [ mediatype ] [ ";base64" ] "," data
-        # mediatype := [ type "/" subtype ] *( ";" parameter )
-        # data      := *urlchar
-        # parameter := attribute "=" value
-        from io import StringIO
-        try:
-            [type, data] = url.split(',', 1)
-        except ValueError:
-            raise IOError('data error', 'bad data URL')
-        if not type:
-            type = 'text/plain;charset=US-ASCII'
-        semi = type.rfind(';')
-        if semi >= 0 and '=' not in type[semi:]:
-            encoding = type[semi+1:]
-            type = type[:semi]
-        else:
-            encoding = ''
-        msg = []
-        msg.append('Date: %s'%time.strftime('%a, %d %b %Y %T GMT',
-                                            time.gmtime(time.time())))
-        msg.append('Content-type: %s' % type)
-        if encoding == 'base64':
-            import base64
-            data = base64.decodestring(data)
-        else:
-            data = unquote(data)
-        msg.append('Content-Length: %d' % len(data))
-        msg.append('')
-        msg.append(data)
-        msg = '\n'.join(msg)
-        headers = email.message_from_string(msg)
-        f = StringIO(msg)
-        #f.fileno = None     # needed for addinfourl
-        return addinfourl(f, headers, url)
-
-
-class FancyURLopener(URLopener):
-    """Derived class with handlers for errors we can handle (perhaps)."""
-
-    def __init__(self, *args, **kwargs):
-        URLopener.__init__(self, *args, **kwargs)
-        self.auth_cache = {}
-        self.tries = 0
-        self.maxtries = 10
-
-    def http_error_default(self, url, fp, errcode, errmsg, headers):
-        """Default error handling -- don't raise an exception."""
-        return addinfourl(fp, headers, "http:" + url, errcode)
-
-    def http_error_302(self, url, fp, errcode, errmsg, headers, data=None):
-        """Error 302 -- relocated (temporarily)."""
-        self.tries += 1
-        if self.maxtries and self.tries >= self.maxtries:
-            if hasattr(self, "http_error_500"):
-                meth = self.http_error_500
-            else:
-                meth = self.http_error_default
-            self.tries = 0
-            return meth(url, fp, 500,
-                        "Internal Server Error: Redirect Recursion", headers)
-        result = self.redirect_internal(url, fp, errcode, errmsg, headers,
-                                        data)
-        self.tries = 0
-        return result
-
-    def redirect_internal(self, url, fp, errcode, errmsg, headers, data):
-        if 'location' in headers:
-            newurl = headers['location']
-        elif 'uri' in headers:
-            newurl = headers['uri']
-        else:
-            return
-        void = fp.read()
-        fp.close()
-        # In case the server sent a relative URL, join with original:
-        newurl = basejoin(self.type + ":" + url, newurl)
-        return self.open(newurl)
-
-    def http_error_301(self, url, fp, errcode, errmsg, headers, data=None):
-        """Error 301 -- also relocated (permanently)."""
-        return self.http_error_302(url, fp, errcode, errmsg, headers, data)
-
-    def http_error_303(self, url, fp, errcode, errmsg, headers, data=None):
-        """Error 303 -- also relocated (essentially identical to 302)."""
-        return self.http_error_302(url, fp, errcode, errmsg, headers, data)
-
-    def http_error_307(self, url, fp, errcode, errmsg, headers, data=None):
-        """Error 307 -- relocated, but turn POST into error."""
-        if data is None:
-            return self.http_error_302(url, fp, errcode, errmsg, headers, data)
-        else:
-            return self.http_error_default(url, fp, errcode, errmsg, headers)
-
-    def http_error_401(self, url, fp, errcode, errmsg, headers, data=None):
-        """Error 401 -- authentication required.
-        This function supports Basic authentication only."""
-        if not 'www-authenticate' in headers:
-            URLopener.http_error_default(self, url, fp,
-                                         errcode, errmsg, headers)
-        stuff = headers['www-authenticate']
-        import re
-        match = re.match('[ \t]*([^ \t]+)[ \t]+realm="([^"]*)"', stuff)
-        if not match:
-            URLopener.http_error_default(self, url, fp,
-                                         errcode, errmsg, headers)
-        scheme, realm = match.groups()
-        if scheme.lower() != 'basic':
-            URLopener.http_error_default(self, url, fp,
-                                         errcode, errmsg, headers)
-        name = 'retry_' + self.type + '_basic_auth'
-        if data is None:
-            return getattr(self,name)(url, realm)
-        else:
-            return getattr(self,name)(url, realm, data)
-
-    def http_error_407(self, url, fp, errcode, errmsg, headers, data=None):
-        """Error 407 -- proxy authentication required.
-        This function supports Basic authentication only."""
-        if not 'proxy-authenticate' in headers:
-            URLopener.http_error_default(self, url, fp,
-                                         errcode, errmsg, headers)
-        stuff = headers['proxy-authenticate']
-        import re
-        match = re.match('[ \t]*([^ \t]+)[ \t]+realm="([^"]*)"', stuff)
-        if not match:
-            URLopener.http_error_default(self, url, fp,
-                                         errcode, errmsg, headers)
-        scheme, realm = match.groups()
-        if scheme.lower() != 'basic':
-            URLopener.http_error_default(self, url, fp,
-                                         errcode, errmsg, headers)
-        name = 'retry_proxy_' + self.type + '_basic_auth'
-        if data is None:
-            return getattr(self,name)(url, realm)
-        else:
-            return getattr(self,name)(url, realm, data)
-
-    def retry_proxy_http_basic_auth(self, url, realm, data=None):
-        host, selector = splithost(url)
-        newurl = 'http://' + host + selector
-        proxy = self.proxies['http']
-        urltype, proxyhost = splittype(proxy)
-        proxyhost, proxyselector = splithost(proxyhost)
-        i = proxyhost.find('@') + 1
-        proxyhost = proxyhost[i:]
-        user, passwd = self.get_user_passwd(proxyhost, realm, i)
-        if not (user or passwd): return None
-        proxyhost = quote(user, safe='') + ':' + quote(passwd, safe='') + '@' + proxyhost
-        self.proxies['http'] = 'http://' + proxyhost + proxyselector
-        if data is None:
-            return self.open(newurl)
-        else:
-            return self.open(newurl, data)
-
-    def retry_proxy_https_basic_auth(self, url, realm, data=None):
-        host, selector = splithost(url)
-        newurl = 'https://' + host + selector
-        proxy = self.proxies['https']
-        urltype, proxyhost = splittype(proxy)
-        proxyhost, proxyselector = splithost(proxyhost)
-        i = proxyhost.find('@') + 1
-        proxyhost = proxyhost[i:]
-        user, passwd = self.get_user_passwd(proxyhost, realm, i)
-        if not (user or passwd): return None
-        proxyhost = quote(user, safe='') + ':' + quote(passwd, safe='') + '@' + proxyhost
-        self.proxies['https'] = 'https://' + proxyhost + proxyselector
-        if data is None:
-            return self.open(newurl)
-        else:
-            return self.open(newurl, data)
-
-    def retry_http_basic_auth(self, url, realm, data=None):
-        host, selector = splithost(url)
-        i = host.find('@') + 1
-        host = host[i:]
-        user, passwd = self.get_user_passwd(host, realm, i)
-        if not (user or passwd): return None
-        host = quote(user, safe='') + ':' + quote(passwd, safe='') + '@' + host
-        newurl = 'http://' + host + selector
-        if data is None:
-            return self.open(newurl)
-        else:
-            return self.open(newurl, data)
-
-    def retry_https_basic_auth(self, url, realm, data=None):
-        host, selector = splithost(url)
-        i = host.find('@') + 1
-        host = host[i:]
-        user, passwd = self.get_user_passwd(host, realm, i)
-        if not (user or passwd): return None
-        host = quote(user, safe='') + ':' + quote(passwd, safe='') + '@' + host
-        newurl = 'https://' + host + selector
-        if data is None:
-            return self.open(newurl)
-        else:
-            return self.open(newurl, data)
-
-    def get_user_passwd(self, host, realm, clear_cache = 0):
-        key = realm + '@' + host.lower()
-        if key in self.auth_cache:
-            if clear_cache:
-                del self.auth_cache[key]
-            else:
-                return self.auth_cache[key]
-        user, passwd = self.prompt_user_passwd(host, realm)
-        if user or passwd: self.auth_cache[key] = (user, passwd)
-        return user, passwd
-
-    def prompt_user_passwd(self, host, realm):
-        """Override this in a GUI environment!"""
-        import getpass
-        try:
-            user = input("Enter username for %s at %s: " % (realm, host))
-            passwd = getpass.getpass("Enter password for %s in %s at %s: " %
-                (user, realm, host))
-            return user, passwd
-        except KeyboardInterrupt:
-            print()
-            return None, None
-
-
-# Utility functions
-
-_localhost = None
-def localhost():
-    """Return the IP address of the magic hostname 'localhost'."""
-    global _localhost
-    if _localhost is None:
-        _localhost = socket.gethostbyname('localhost')
-    return _localhost
-
-_thishost = None
-def thishost():
-    """Return the IP address of the current host."""
-    global _thishost
-    if _thishost is None:
-        _thishost = socket.gethostbyname(socket.gethostname())
-    return _thishost
-
-_ftperrors = None
-def ftperrors():
-    """Return the set of errors raised by the FTP class."""
-    global _ftperrors
-    if _ftperrors is None:
-        import ftplib
-        _ftperrors = ftplib.all_errors
-    return _ftperrors
-
-_noheaders = None
-def noheaders():
-    """Return an empty email.message.Message object."""
-    global _noheaders
-    if _noheaders is None:
-        _noheaders = email.message.Message()
-    return _noheaders
-
-
-# Utility classes
-
-class ftpwrapper:
-    """Class used by open_ftp() for cache of open FTP connections."""
-
-    def __init__(self, user, passwd, host, port, dirs,
-                 timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
-        self.user = user
-        self.passwd = passwd
-        self.host = host
-        self.port = port
-        self.dirs = dirs
-        self.timeout = timeout
-        self.init()
-
-    def init(self):
-        import ftplib
-        self.busy = 0
-        self.ftp = ftplib.FTP()
-        self.ftp.connect(self.host, self.port, self.timeout)
-        self.ftp.login(self.user, self.passwd)
-        for dir in self.dirs:
-            self.ftp.cwd(dir)
-
-    def retrfile(self, file, type):
-        import ftplib
-        self.endtransfer()
-        if type in ('d', 'D'): cmd = 'TYPE A'; isdir = 1
-        else: cmd = 'TYPE ' + type; isdir = 0
-        try:
-            self.ftp.voidcmd(cmd)
-        except ftplib.all_errors:
-            self.init()
-            self.ftp.voidcmd(cmd)
-        conn = None
-        if file and not isdir:
-            # Try to retrieve as a file
-            try:
-                cmd = 'RETR ' + file
-                conn = self.ftp.ntransfercmd(cmd)
-            except ftplib.error_perm as reason:
-                if str(reason)[:3] != '550':
-                    raise IOError('ftp error', reason).with_traceback(sys.exc_info()[2])
-        if not conn:
-            # Set transfer mode to ASCII!
-            self.ftp.voidcmd('TYPE A')
-            # Try a directory listing. Verify that directory exists.
-            if file:
-                pwd = self.ftp.pwd()
-                try:
-                    try:
-                        self.ftp.cwd(file)
-                    except ftplib.error_perm as reason:
-                        raise IOError('ftp error', reason) from reason
-                finally:
-                    self.ftp.cwd(pwd)
-                cmd = 'LIST ' + file
-            else:
-                cmd = 'LIST'
-            conn = self.ftp.ntransfercmd(cmd)
-        self.busy = 1
-        # Pass back both a suitably decorated object and a retrieval length
-        return (addclosehook(conn[0].makefile('rb'),
-                             self.endtransfer), conn[1])
-    def endtransfer(self):
-        if not self.busy:
-            return
-        self.busy = 0
-        try:
-            self.ftp.voidresp()
-        except ftperrors():
-            pass
-
-    def close(self):
-        self.endtransfer()
-        try:
-            self.ftp.close()
-        except ftperrors():
-            pass
-
-class addbase:
-    """Base class for addinfo and addclosehook."""
-
-    # XXX Add a method to expose the timeout on the underlying socket?
-
-    def __init__(self, fp):
-        self.fp = fp
-        self.read = self.fp.read
-        self.readline = self.fp.readline
-        if hasattr(self.fp, "readlines"): self.readlines = self.fp.readlines
-        if hasattr(self.fp, "fileno"):
-            self.fileno = self.fp.fileno
-        else:
-            self.fileno = lambda: None
-        if hasattr(self.fp, "__iter__"):
-            self.__iter__ = self.fp.__iter__
-            if hasattr(self.fp, "__next__"):
-                self.__next__ = self.fp.__next__
-
-    def __repr__(self):
-        return '<%s at %r whose fp = %r>' % (self.__class__.__name__,
-                                             id(self), self.fp)
-
-    def close(self):
-        self.read = None
-        self.readline = None
-        self.readlines = None
-        self.fileno = None
-        if self.fp: self.fp.close()
-        self.fp = None
-
-class addclosehook(addbase):
-    """Class to add a close hook to an open file."""
-
-    def __init__(self, fp, closehook, *hookargs):
-        addbase.__init__(self, fp)
-        self.closehook = closehook
-        self.hookargs = hookargs
-
-    def close(self):
-        addbase.close(self)
-        if self.closehook:
-            self.closehook(*self.hookargs)
-            self.closehook = None
-            self.hookargs = None
-
-class addinfo(addbase):
-    """class to add an info() method to an open file."""
-
-    def __init__(self, fp, headers):
-        addbase.__init__(self, fp)
-        self.headers = headers
-
-    def info(self):
-        return self.headers
-
-class addinfourl(addbase):
-    """class to add info() and geturl() methods to an open file."""
-
-    def __init__(self, fp, headers, url, code=None):
-        addbase.__init__(self, fp)
-        self.headers = headers
-        self.url = url
-        self.code = code
-
-    def info(self):
-        return self.headers
-
-    def getcode(self):
-        return self.code
-
-    def geturl(self):
-        return self.url
-
-
-# Utilities to parse URLs (most of these return None for missing parts):
-# unwrap('<URL:type://host/path>') --> 'type://host/path'
-# splittype('type:opaquestring') --> 'type', 'opaquestring'
-# splithost('//host[:port]/path') --> 'host[:port]', '/path'
-# splituser('user[:passwd]@host[:port]') --> 'user[:passwd]', 'host[:port]'
-# splitpasswd('user:passwd') -> 'user', 'passwd'
-# splitport('host:port') --> 'host', 'port'
-# splitquery('/path?query') --> '/path', 'query'
-# splittag('/path#tag') --> '/path', 'tag'
-# splitattr('/path;attr1=value1;attr2=value2;...') ->
-#   '/path', ['attr1=value1', 'attr2=value2', ...]
-# splitvalue('attr=value') --> 'attr', 'value'
-# unquote('abc%20def') -> 'abc def'
-# quote('abc def') -> 'abc%20def')
-
-def toBytes(url):
-    """toBytes(u"URL") --> 'URL'."""
-    # Most URL schemes require ASCII. If that changes, the conversion
-    # can be relaxed.
-    # XXX get rid of toBytes()
-    if isinstance(url, str):
-        try:
-            url = url.encode("ASCII").decode()
-        except UnicodeError:
-            raise UnicodeError("URL " + repr(url) +
-                               " contains non-ASCII characters")
-    return url
-
-def unwrap(url):
-    """unwrap('<URL:type://host/path>') --> 'type://host/path'."""
-    url = str(url).strip()
-    if url[:1] == '<' and url[-1:] == '>':
-        url = url[1:-1].strip()
-    if url[:4] == 'URL:': url = url[4:].strip()
-    return url
-
-_typeprog = None
-def splittype(url):
-    """splittype('type:opaquestring') --> 'type', 'opaquestring'."""
-    global _typeprog
-    if _typeprog is None:
-        import re
-        _typeprog = re.compile('^([^/:]+):')
-
-    match = _typeprog.match(url)
-    if match:
-        scheme = match.group(1)
-        return scheme.lower(), url[len(scheme) + 1:]
-    return None, url
-
-_hostprog = None
-def splithost(url):
-    """splithost('//host[:port]/path') --> 'host[:port]', '/path'."""
-    global _hostprog
-    if _hostprog is None:
-        import re
-        _hostprog = re.compile('^//([^/?]*)(.*)$')
-
-    match = _hostprog.match(url)
-    if match: return match.group(1, 2)
-    return None, url
-
-_userprog = None
-def splituser(host):
-    """splituser('user[:passwd]@host[:port]') --> 'user[:passwd]', 'host[:port]'."""
-    global _userprog
-    if _userprog is None:
-        import re
-        _userprog = re.compile('^(.*)@(.*)$')
-
-    match = _userprog.match(host)
-    if match: return map(unquote, match.group(1, 2))
-    return None, host
-
-_passwdprog = None
-def splitpasswd(user):
-    """splitpasswd('user:passwd') -> 'user', 'passwd'."""
-    global _passwdprog
-    if _passwdprog is None:
-        import re
-        _passwdprog = re.compile('^([^:]*):(.*)$')
-
-    match = _passwdprog.match(user)
-    if match: return match.group(1, 2)
-    return user, None
-
-# splittag('/path#tag') --> '/path', 'tag'
-_portprog = None
-def splitport(host):
-    """splitport('host:port') --> 'host', 'port'."""
-    global _portprog
-    if _portprog is None:
-        import re
-        _portprog = re.compile('^(.*):([0-9]+)$')
-
-    match = _portprog.match(host)
-    if match: return match.group(1, 2)
-    return host, None
-
-_nportprog = None
-def splitnport(host, defport=-1):
-    """Split host and port, returning numeric port.
-    Return given default port if no ':' found; defaults to -1.
-    Return numerical port if a valid number are found after ':'.
-    Return None if ':' but not a valid number."""
-    global _nportprog
-    if _nportprog is None:
-        import re
-        _nportprog = re.compile('^(.*):(.*)$')
-
-    match = _nportprog.match(host)
-    if match:
-        host, port = match.group(1, 2)
-        try:
-            if not port: raise ValueError("no digits")
-            nport = int(port)
-        except ValueError:
-            nport = None
-        return host, nport
-    return host, defport
-
-_queryprog = None
-def splitquery(url):
-    """splitquery('/path?query') --> '/path', 'query'."""
-    global _queryprog
-    if _queryprog is None:
-        import re
-        _queryprog = re.compile('^(.*)\?([^?]*)$')
-
-    match = _queryprog.match(url)
-    if match: return match.group(1, 2)
-    return url, None
-
-_tagprog = None
-def splittag(url):
-    """splittag('/path#tag') --> '/path', 'tag'."""
-    global _tagprog
-    if _tagprog is None:
-        import re
-        _tagprog = re.compile('^(.*)#([^#]*)$')
-
-    match = _tagprog.match(url)
-    if match: return match.group(1, 2)
-    return url, None
-
-def splitattr(url):
-    """splitattr('/path;attr1=value1;attr2=value2;...') ->
-        '/path', ['attr1=value1', 'attr2=value2', ...]."""
-    words = url.split(';')
-    return words[0], words[1:]
-
-_valueprog = None
-def splitvalue(attr):
-    """splitvalue('attr=value') --> 'attr', 'value'."""
-    global _valueprog
-    if _valueprog is None:
-        import re
-        _valueprog = re.compile('^([^=]*)=(.*)$')
-
-    match = _valueprog.match(attr)
-    if match: return match.group(1, 2)
-    return attr, None
-
-_hextochr = dict(('%02x' % i, chr(i)) for i in range(256))
-_hextochr.update(('%02X' % i, chr(i)) for i in range(256))
-
-def unquote(s):
-    """unquote('abc%20def') -> 'abc def'."""
-    res = s.split('%')
-    for i in range(1, len(res)):
-        item = res[i]
-        try:
-            res[i] = _hextochr[item[:2]] + item[2:]
-        except KeyError:
-            res[i] = '%' + item
-        except UnicodeDecodeError:
-            res[i] = chr(int(item[:2], 16)) + item[2:]
-    return "".join(res)
-
-def unquote_plus(s):
-    """unquote('%7e/abc+def') -> '~/abc def'"""
-    s = s.replace('+', ' ')
-    return unquote(s)
-
-always_safe = ('ABCDEFGHIJKLMNOPQRSTUVWXYZ'
-               'abcdefghijklmnopqrstuvwxyz'
-               '0123456789' '_.-')
-_safe_quoters= {}
-
-class Quoter:
-    def __init__(self, safe):
-        self.cache = {}
-        self.safe = safe + always_safe
-
-    def __call__(self, c):
-        try:
-            return self.cache[c]
-        except KeyError:
-            if ord(c) < 256:
-                res = (c in self.safe) and c or ('%%%02X' % ord(c))
-                self.cache[c] = res
-                return res
-            else:
-                return "".join(['%%%02X' % i for i in c.encode("utf-8")])
-
-def quote(s, safe = '/'):
-    """quote('abc def') -> 'abc%20def'
-
-    Each part of a URL, e.g. the path info, the query, etc., has a
-    different set of reserved characters that must be quoted.
-
-    RFC 2396 Uniform Resource Identifiers (URI): Generic Syntax lists
-    the following reserved characters.
-
-    reserved    = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" |
-                  "$" | ","
-
-    Each of these characters is reserved in some component of a URL,
-    but not necessarily in all of them.
-
-    By default, the quote function is intended for quoting the path
-    section of a URL.  Thus, it will not encode '/'.  This character
-    is reserved, but in typical usage the quote function is being
-    called on a path where the existing slash characters are used as
-    reserved characters.
-    """
-    cachekey = (safe, always_safe)
-    try:
-        quoter = _safe_quoters[cachekey]
-    except KeyError:
-        quoter = Quoter(safe)
-        _safe_quoters[cachekey] = quoter
-    res = map(quoter, s)
-    return ''.join(res)
-
-def quote_plus(s, safe = ''):
-    """Quote the query fragment of a URL; replacing ' ' with '+'"""
-    if ' ' in s:
-        s = quote(s, safe + ' ')
-        return s.replace(' ', '+')
-    return quote(s, safe)
-
-def urlencode(query,doseq=0):
-    """Encode a sequence of two-element tuples or dictionary into a URL query string.
-
-    If any values in the query arg are sequences and doseq is true, each
-    sequence element is converted to a separate parameter.
-
-    If the query arg is a sequence of two-element tuples, the order of the
-    parameters in the output will match the order of parameters in the
-    input.
-    """
-
-    if hasattr(query,"items"):
-        # mapping objects
-        query = query.items()
-    else:
-        # it's a bother at times that strings and string-like objects are
-        # sequences...
-        try:
-            # non-sequence items should not work with len()
-            # non-empty strings will fail this
-            if len(query) and not isinstance(query[0], tuple):
-                raise TypeError
-            # zero-length sequences of all types will get here and succeed,
-            # but that's a minor nit - since the original implementation
-            # allowed empty dicts that type of behavior probably should be
-            # preserved for consistency
-        except TypeError:
-            ty,va,tb = sys.exc_info()
-            raise TypeError("not a valid non-string sequence or mapping object").with_traceback(tb)
-
-    l = []
-    if not doseq:
-        # preserve old behavior
-        for k, v in query:
-            k = quote_plus(str(k))
-            v = quote_plus(str(v))
-            l.append(k + '=' + v)
-    else:
-        for k, v in query:
-            k = quote_plus(str(k))
-            if isinstance(v, str):
-                v = quote_plus(v)
-                l.append(k + '=' + v)
-            elif isinstance(v, str):
-                # is there a reasonable way to convert to ASCII?
-                # encode generates a string, but "replace" or "ignore"
-                # lose information and "strict" can raise UnicodeError
-                v = quote_plus(v.encode("ASCII","replace"))
-                l.append(k + '=' + v)
-            else:
-                try:
-                    # is this a sufficient test for sequence-ness?
-                    x = len(v)
-                except TypeError:
-                    # not a sequence
-                    v = quote_plus(str(v))
-                    l.append(k + '=' + v)
-                else:
-                    # loop over the sequence
-                    for elt in v:
-                        l.append(k + '=' + quote_plus(str(elt)))
-    return '&'.join(l)
-
-# Proxy handling
-def getproxies_environment():
-    """Return a dictionary of scheme -> proxy server URL mappings.
-
-    Scan the environment for variables named <scheme>_proxy;
-    this seems to be the standard convention.  If you need a
-    different way, you can pass a proxies dictionary to the
-    [Fancy]URLopener constructor.
-
-    """
-    proxies = {}
-    for name, value in os.environ.items():
-        name = name.lower()
-        if name == 'no_proxy':
-            # handled in proxy_bypass_environment
-            continue
-        if value and name[-6:] == '_proxy':
-            proxies[name[:-6]] = value
-    return proxies
-
-def proxy_bypass_environment(host):
-    """Test if proxies should not be used for a particular host.
-
-    Checks the environment for a variable named no_proxy, which should
-    be a list of DNS suffixes separated by commas, or '*' for all hosts.
-    """
-    no_proxy = os.environ.get('no_proxy', '') or os.environ.get('NO_PROXY', '')
-    # '*' is special case for always bypass
-    if no_proxy == '*':
-        return 1
-    # strip port off host
-    hostonly, port = splitport(host)
-    # check if the host ends with any of the DNS suffixes
-    for name in no_proxy.split(','):
-        if name and (hostonly.endswith(name) or host.endswith(name)):
-            return 1
-    # otherwise, don't bypass
-    return 0
-
-
-if sys.platform == 'darwin':
-
-    def _CFSetup(sc):
-        from ctypes import c_int32, c_void_p, c_char_p, c_int
-        sc.CFStringCreateWithCString.argtypes = [ c_void_p, c_char_p, c_int32 ]
-        sc.CFStringCreateWithCString.restype = c_void_p
-        sc.SCDynamicStoreCopyProxies.argtypes = [ c_void_p ]
-        sc.SCDynamicStoreCopyProxies.restype = c_void_p
-        sc.CFDictionaryGetValue.argtypes = [ c_void_p, c_void_p ]
-        sc.CFDictionaryGetValue.restype = c_void_p
-        sc.CFStringGetLength.argtypes = [ c_void_p ]
-        sc.CFStringGetLength.restype = c_int32
-        sc.CFStringGetCString.argtypes = [ c_void_p, c_char_p, c_int32, c_int32 ]
-        sc.CFStringGetCString.restype = c_int32
-        sc.CFNumberGetValue.argtypes = [ c_void_p, c_int, c_void_p ]
-        sc.CFNumberGetValue.restype = c_int32
-        sc.CFRelease.argtypes = [ c_void_p ]
-        sc.CFRelease.restype = None
-
-    def _CStringFromCFString(sc, value):
-        from ctypes import create_string_buffer
-        length = sc.CFStringGetLength(value) + 1
-        buff = create_string_buffer(length)
-        sc.CFStringGetCString(value, buff, length, 0)
-        return buff.value
-
-    def _CFNumberToInt32(sc, cfnum):
-        from ctypes import byref, c_int
-        val = c_int()
-        kCFNumberSInt32Type = 3
-        sc.CFNumberGetValue(cfnum, kCFNumberSInt32Type, byref(val))
-        return val.value
-
-
-    def proxy_bypass_macosx_sysconf(host):
-        """
-        Return True iff this host shouldn't be accessed using a proxy
-
-        This function uses the MacOSX framework SystemConfiguration
-        to fetch the proxy information.
-        """
-        from ctypes import cdll
-        from ctypes.util import find_library
-        import re
-        import socket
-        from fnmatch import fnmatch
-
-        def ip2num(ipAddr):
-            parts = ipAddr.split('.')
-            parts = map(int, parts)
-            if len(parts) != 4:
-                parts = (parts + [0, 0, 0, 0])[:4]
-            return (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8) | parts[3]
-
-        sc = cdll.LoadLibrary(find_library("SystemConfiguration"))
-        _CFSetup(sc)
-
-        hostIP = None
-
-        if not sc:
-            return False
-
-        kSCPropNetProxiesExceptionsList = sc.CFStringCreateWithCString(0, "ExceptionsList", 0)
-        kSCPropNetProxiesExcludeSimpleHostnames = sc.CFStringCreateWithCString(0,
-                "ExcludeSimpleHostnames", 0)
-
-
-        proxyDict = sc.SCDynamicStoreCopyProxies(None)
-        if proxyDict is None:
-            return False
-
-        try:
-            # Check for simple host names:
-            if '.' not in host:
-                exclude_simple = sc.CFDictionaryGetValue(proxyDict,
-                        kSCPropNetProxiesExcludeSimpleHostnames)
-                if exclude_simple and _CFNumberToInt32(sc, exclude_simple):
-                    return True
-
-
-            # Check the exceptions list:
-            exceptions = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesExceptionsList)
-            if exceptions:
-                # Items in the list are strings like these: *.local, 169.254/16
-                for index in xrange(sc.CFArrayGetCount(exceptions)):
-                    value = sc.CFArrayGetValueAtIndex(exceptions, index)
-                    if not value: continue
-                    value = _CStringFromCFString(sc, value)
-
-                    m = re.match(r"(\d+(?:\.\d+)*)(/\d+)?", value)
-                    if m is not None:
-                        if hostIP is None:
-                            hostIP = socket.gethostbyname(host)
-                            hostIP = ip2num(hostIP)
-
-                        base = ip2num(m.group(1))
-                        mask = int(m.group(2)[1:])
-                        mask = 32 - mask
-
-                        if (hostIP >> mask) == (base >> mask):
-                            return True
-
-                    elif fnmatch(host, value):
-                        return True
-
-            return False
-
-        finally:
-            sc.CFRelease(kSCPropNetProxiesExceptionsList)
-            sc.CFRelease(kSCPropNetProxiesExcludeSimpleHostnames)
-
-
-
-    def getproxies_macosx_sysconf():
-        """Return a dictionary of scheme -> proxy server URL mappings.
-
-        This function uses the MacOSX framework SystemConfiguration
-        to fetch the proxy information.
-        """
-        from ctypes import cdll
-        from ctypes.util import find_library
-
-        sc = cdll.LoadLibrary(find_library("SystemConfiguration"))
-        _CFSetup(sc)
-
-        if not sc:
-            return {}
-
-        kSCPropNetProxiesHTTPEnable = sc.CFStringCreateWithCString(0, b"HTTPEnable", 0)
-        kSCPropNetProxiesHTTPProxy = sc.CFStringCreateWithCString(0, b"HTTPProxy", 0)
-        kSCPropNetProxiesHTTPPort = sc.CFStringCreateWithCString(0, b"HTTPPort", 0)
-
-        kSCPropNetProxiesHTTPSEnable = sc.CFStringCreateWithCString(0, b"HTTPSEnable", 0)
-        kSCPropNetProxiesHTTPSProxy = sc.CFStringCreateWithCString(0, b"HTTPSProxy", 0)
-        kSCPropNetProxiesHTTPSPort = sc.CFStringCreateWithCString(0, b"HTTPSPort", 0)
-
-        kSCPropNetProxiesFTPEnable = sc.CFStringCreateWithCString(0, b"FTPEnable", 0)
-        kSCPropNetProxiesFTPPassive = sc.CFStringCreateWithCString(0, b"FTPPassive", 0)
-        kSCPropNetProxiesFTPPort = sc.CFStringCreateWithCString(0, b"FTPPort", 0)
-        kSCPropNetProxiesFTPProxy = sc.CFStringCreateWithCString(0, b"FTPProxy", 0)
-
-        kSCPropNetProxiesGopherEnable = sc.CFStringCreateWithCString(0, b"GopherEnable", 0)
-        kSCPropNetProxiesGopherPort = sc.CFStringCreateWithCString(0, b"GopherPort", 0)
-        kSCPropNetProxiesGopherProxy = sc.CFStringCreateWithCString(0, b"GopherProxy", 0)
-
-        proxies = {}
-        proxyDict = sc.SCDynamicStoreCopyProxies(None)
-
-        try:
-            # HTTP:
-            enabled = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesHTTPEnable)
-            if enabled and _CFNumberToInt32(sc, enabled):
-                proxy = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesHTTPProxy)
-                port = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesHTTPPort)
-
-                if proxy:
-                    proxy = _CStringFromCFString(sc, proxy)
-                    if port:
-                        port = _CFNumberToInt32(sc, port)
-                        proxies["http"] = "http://%s:%i" % (proxy, port)
-                    else:
-                        proxies["http"] = "http://%s" % (proxy, )
-
-            # HTTPS:
-            enabled = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesHTTPSEnable)
-            if enabled and _CFNumberToInt32(sc, enabled):
-                proxy = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesHTTPSProxy)
-                port = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesHTTPSPort)
-
-                if proxy:
-                    proxy = _CStringFromCFString(sc, proxy)
-                    if port:
-                        port = _CFNumberToInt32(sc, port)
-                        proxies["https"] = "http://%s:%i" % (proxy, port)
-                    else:
-                        proxies["https"] = "http://%s" % (proxy, )
-
-            # FTP:
-            enabled = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesFTPEnable)
-            if enabled and _CFNumberToInt32(sc, enabled):
-                proxy = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesFTPProxy)
-                port = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesFTPPort)
-
-                if proxy:
-                    proxy = _CStringFromCFString(sc, proxy)
-                    if port:
-                        port = _CFNumberToInt32(sc, port)
-                        proxies["ftp"] = "http://%s:%i" % (proxy, port)
-                    else:
-                        proxies["ftp"] = "http://%s" % (proxy, )
-
-            # Gopher:
-            enabled = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesGopherEnable)
-            if enabled and _CFNumberToInt32(sc, enabled):
-                proxy = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesGopherProxy)
-                port = sc.CFDictionaryGetValue(proxyDict, kSCPropNetProxiesGopherPort)
-
-                if proxy:
-                    proxy = _CStringFromCFString(sc, proxy)
-                    if port:
-                        port = _CFNumberToInt32(sc, port)
-                        proxies["gopher"] = "http://%s:%i" % (proxy, port)
-                    else:
-                        proxies["gopher"] = "http://%s" % (proxy, )
-        finally:
-            sc.CFRelease(proxyDict)
-
-        sc.CFRelease(kSCPropNetProxiesHTTPEnable)
-        sc.CFRelease(kSCPropNetProxiesHTTPProxy)
-        sc.CFRelease(kSCPropNetProxiesHTTPPort)
-        sc.CFRelease(kSCPropNetProxiesFTPEnable)
-        sc.CFRelease(kSCPropNetProxiesFTPPassive)
-        sc.CFRelease(kSCPropNetProxiesFTPPort)
-        sc.CFRelease(kSCPropNetProxiesFTPProxy)
-        sc.CFRelease(kSCPropNetProxiesGopherEnable)
-        sc.CFRelease(kSCPropNetProxiesGopherPort)
-        sc.CFRelease(kSCPropNetProxiesGopherProxy)
-
-        return proxies
-
-
-
-    def proxy_bypass(host):
-        if getproxies_environment():
-            return proxy_bypass_environment(host)
-        else:
-            return proxy_bypass_macosx_sysconf(host)
-
-    def getproxies():
-        return getproxies_environment() or getproxies_macosx_sysconf()
-
-elif os.name == 'nt':
-    def getproxies_registry():
-        """Return a dictionary of scheme -> proxy server URL mappings.
-
-        Win32 uses the registry to store proxies.
-
-        """
-        proxies = {}
-        try:
-            import winreg
-        except ImportError:
-            # Std module, so should be around - but you never know!
-            return proxies
-        try:
-            internetSettings = winreg.OpenKey(winreg.HKEY_CURRENT_USER,
-                r'Software\Microsoft\Windows\CurrentVersion\Internet Settings')
-            proxyEnable = winreg.QueryValueEx(internetSettings,
-                                              'ProxyEnable')[0]
-            if proxyEnable:
-                # Returned as Unicode but problems if not converted to ASCII
-                proxyServer = str(winreg.QueryValueEx(internetSettings,
-                                                      'ProxyServer')[0])
-                if '=' in proxyServer:
-                    # Per-protocol settings
-                    for p in proxyServer.split(';'):
-                        protocol, address = p.split('=', 1)
-                        # See if address has a type:// prefix
-                        import re
-                        if not re.match('^([^/:]+)://', address):
-                            address = '%s://%s' % (protocol, address)
-                        proxies[protocol] = address
-                else:
-                    # Use one setting for all protocols
-                    if proxyServer[:5] == 'http:':
-                        proxies['http'] = proxyServer
-                    else:
-                        proxies['http'] = 'http://%s' % proxyServer
-                        proxies['ftp'] = 'ftp://%s' % proxyServer
-            internetSettings.Close()
-        except (WindowsError, ValueError, TypeError):
-            # Either registry key not found etc, or the value in an
-            # unexpected format.
-            # proxies already set up to be empty so nothing to do
-            pass
-        return proxies
-
-    def getproxies():
-        """Return a dictionary of scheme -> proxy server URL mappings.
-
-        Returns settings gathered from the environment, if specified,
-        or the registry.
-
-        """
-        return getproxies_environment() or getproxies_registry()
-
-    def proxy_bypass_registry(host):
-        try:
-            import winreg
-            import re
-        except ImportError:
-            # Std modules, so should be around - but you never know!
-            return 0
-        try:
-            internetSettings = winreg.OpenKey(winreg.HKEY_CURRENT_USER,
-                r'Software\Microsoft\Windows\CurrentVersion\Internet Settings')
-            proxyEnable = winreg.QueryValueEx(internetSettings,
-                                              'ProxyEnable')[0]
-            proxyOverride = str(winreg.QueryValueEx(internetSettings,
-                                                    'ProxyOverride')[0])
-            # ^^^^ Returned as Unicode but problems if not converted to ASCII
-        except WindowsError:
-            return 0
-        if not proxyEnable or not proxyOverride:
-            return 0
-        # try to make a host list from name and IP address.
-        rawHost, port = splitport(host)
-        host = [rawHost]
-        try:
-            addr = socket.gethostbyname(rawHost)
-            if addr != rawHost:
-                host.append(addr)
-        except socket.error:
-            pass
-        try:
-            fqdn = socket.getfqdn(rawHost)
-            if fqdn != rawHost:
-                host.append(fqdn)
-        except socket.error:
-            pass
-        # make a check value list from the registry entry: replace the
-        # '<local>' string by the localhost entry and the corresponding
-        # canonical entry.
-        proxyOverride = proxyOverride.split(';')
-        i = 0
-        while i < len(proxyOverride):
-            if proxyOverride[i] == '<local>':
-                proxyOverride[i:i+1] = ['localhost',
-                                        '127.0.0.1',
-                                        socket.gethostname(),
-                                        socket.gethostbyname(
-                                            socket.gethostname())]
-            i += 1
-        # print proxyOverride
-        # now check if we match one of the registry values.
-        for test in proxyOverride:
-            test = test.replace(".", r"\.")     # mask dots
-            test = test.replace("*", r".*")     # change glob sequence
-            test = test.replace("?", r".")      # change glob char
-            for val in host:
-                # print "%s <--> %s" %( test, val )
-                if re.match(test, val, re.I):
-                    return 1
-        return 0
-
-    def proxy_bypass(host):
-        """Return a dictionary of scheme -> proxy server URL mappings.
-
-        Returns settings gathered from the environment, if specified,
-        or the registry.
-
-        """
-        if getproxies_environment():
-            return proxy_bypass_environment(host)
-        else:
-            return proxy_bypass_registry(host)
-
-else:
-    # By default use environment variables
-    getproxies = getproxies_environment
-    proxy_bypass = proxy_bypass_environment
-
-# Test and time quote() and unquote()
-def test1():
-    s = ''
-    for i in range(256): s = s + chr(i)
-    s = s*4
-    t0 = time.time()
-    qs = quote(s)
-    uqs = unquote(qs)
-    t1 = time.time()
-    if uqs != s:
-        print('Wrong!')
-    print(repr(s))
-    print(repr(qs))
-    print(repr(uqs))
-    print(round(t1 - t0, 3), 'sec')
-
-
-def reporthook(blocknum, blocksize, totalsize):
-    # Report during remote transfers
-    print("Block number: %d, Block size: %d, Total size: %d" % (
-        blocknum, blocksize, totalsize))
-
-# Test program
-def test(args=[]):
-    if not args:
-        args = [
-            '/etc/passwd',
-            'file:/etc/passwd',
-            'file://localhost/etc/passwd',
-            'ftp://ftp.gnu.org/pub/README',
-            'http://www.python.org/index.html',
-            ]
-        if hasattr(URLopener, "open_https"):
-            args.append('https://synergy.as.cmu.edu/~geek/')
-    try:
-        for url in args:
-            print('-'*10, url, '-'*10)
-            fn, h = urlretrieve(url, None, reporthook)
-            print(fn)
-            if h:
-                print('======')
-                for k in h.keys(): print(k + ':', h[k])
-                print('======')
-            fp = open(fn, 'rb')
-            data = fp.read()
-            del fp
-            data = data.replace("\r", "")
-            print(data)
-            fn, h = None, None
-        print('-'*40)
-    finally:
-        urlcleanup()
-
-def main():
-    import getopt, sys
-    try:
-        opts, args = getopt.getopt(sys.argv[1:], "th")
-    except getopt.error as msg:
-        print(msg)
-        print("Use -h for help")
-        return
-    t = 0
-    for o, a in opts:
-        if o == '-t':
-            t = t + 1
-        if o == '-h':
-            print("Usage: python urllib.py [-t] [url ...]")
-            print("-t runs self-test;", end=' ')
-            print("otherwise, contents of urls are printed")
-            return
-    if t:
-        if t > 1:
-            test1()
-        test(args)
-    else:
-        if not args:
-            print("Use -h for help")
-        for url in args:
-            print(urlopen(url).read(), end=' ')
-
-# Run test program when run as a script
-if __name__ == '__main__':
-    main()

Deleted: python/branches/py3k/Lib/urllib2.py
==============================================================================
--- python/branches/py3k/Lib/urllib2.py	Wed Jun 18 22:49:58 2008
+++ (empty file)
@@ -1,1351 +0,0 @@
-"""An extensible library for opening URLs using a variety of protocols
-
-The simplest way to use this module is to call the urlopen function,
-which accepts a string containing a URL or a Request object (described
-below).  It opens the URL and returns the results as file-like
-object; the returned object has some extra methods described below.
-
-The OpenerDirector manages a collection of Handler objects that do
-all the actual work.  Each Handler implements a particular protocol or
-option.  The OpenerDirector is a composite object that invokes the
-Handlers needed to open the requested URL.  For example, the
-HTTPHandler performs HTTP GET and POST requests and deals with
-non-error returns.  The HTTPRedirectHandler automatically deals with
-HTTP 301, 302, 303 and 307 redirect errors, and the HTTPDigestAuthHandler
-deals with digest authentication.
-
-urlopen(url, data=None) -- Basic usage is the same as original
-urllib.  pass the url and optionally data to post to an HTTP URL, and
-get a file-like object back.  One difference is that you can also pass
-a Request instance instead of URL.  Raises a URLError (subclass of
-IOError); for HTTP errors, raises an HTTPError, which can also be
-treated as a valid response.
-
-build_opener -- Function that creates a new OpenerDirector instance.
-Will install the default handlers.  Accepts one or more Handlers as
-arguments, either instances or Handler classes that it will
-instantiate.  If one of the argument is a subclass of the default
-handler, the argument will be installed instead of the default.
-
-install_opener -- Installs a new opener as the default opener.
-
-objects of interest:
-OpenerDirector --
-
-Request -- An object that encapsulates the state of a request.  The
-state can be as simple as the URL.  It can also include extra HTTP
-headers, e.g. a User-Agent.
-
-BaseHandler --
-
-exceptions:
-URLError -- A subclass of IOError, individual protocols have their own
-specific subclass.
-
-HTTPError -- Also a valid HTTP response, so you can treat an HTTP error
-as an exceptional event or valid response.
-
-internals:
-BaseHandler and parent
-_call_chain conventions
-
-Example usage:
-
-import urllib2
-
-# set up authentication info
-authinfo = urllib2.HTTPBasicAuthHandler()
-authinfo.add_password(realm='PDQ Application',
-                      uri='https://mahler:8092/site-updates.py',
-                      user='klem',
-                      passwd='geheim$parole')
-
-proxy_support = urllib2.ProxyHandler({"http" : "http://ahad-haam:3128"})
-
-# build a new opener that adds authentication and caching FTP handlers
-opener = urllib2.build_opener(proxy_support, authinfo, urllib2.CacheFTPHandler)
-
-# install it
-urllib2.install_opener(opener)
-
-f = urllib2.urlopen('http://www.python.org/')
-
-
-"""
-
-# XXX issues:
-# If an authentication error handler that tries to perform
-# authentication for some reason but fails, how should the error be
-# signalled?  The client needs to know the HTTP error code.  But if
-# the handler knows that the problem was, e.g., that it didn't know
-# that hash algo that requested in the challenge, it would be good to
-# pass that information along to the client, too.
-# ftp errors aren't handled cleanly
-# check digest against correct (i.e. non-apache) implementation
-
-# Possible extensions:
-# complex proxies  XXX not sure what exactly was meant by this
-# abstract factory for opener
-
-import base64
-import hashlib
-import http.client
-import io
-import email
-import os
-import posixpath
-import random
-import re
-import socket
-import sys
-import time
-import urlparse
-import bisect
-
-from io import StringIO
-
-from urllib import (unwrap, unquote, splittype, splithost, quote,
-     addinfourl, splitport, splitquery,
-     splitattr, ftpwrapper, noheaders, splituser, splitpasswd, splitvalue)
-
-# support for FileHandler, proxies via environment variables
-from urllib import localhost, url2pathname, getproxies
-
-# used in User-Agent header sent
-__version__ = sys.version[:3]
-
-_opener = None
-def urlopen(url, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
-    global _opener
-    if _opener is None:
-        _opener = build_opener()
-    return _opener.open(url, data, timeout)
-
-def install_opener(opener):
-    global _opener
-    _opener = opener
-
-# do these error classes make sense?
-# make sure all of the IOError stuff is overridden.  we just want to be
-# subtypes.
-
-class URLError(IOError):
-    # URLError is a sub-type of IOError, but it doesn't share any of
-    # the implementation.  need to override __init__ and __str__.
-    # It sets self.args for compatibility with other EnvironmentError
-    # subclasses, but args doesn't have the typical format with errno in
-    # slot 0 and strerror in slot 1.  This may be better than nothing.
-    def __init__(self, reason):
-        self.args = reason,
-        self.reason = reason
-
-    def __str__(self):
-        return '<urlopen error %s>' % self.reason
-
-class HTTPError(URLError, addinfourl):
-    """Raised when HTTP error occurs, but also acts like non-error return"""
-    __super_init = addinfourl.__init__
-
-    def __init__(self, url, code, msg, hdrs, fp):
-        self.code = code
-        self.msg = msg
-        self.hdrs = hdrs
-        self.fp = fp
-        self.filename = url
-        # The addinfourl classes depend on fp being a valid file
-        # object.  In some cases, the HTTPError may not have a valid
-        # file object.  If this happens, the simplest workaround is to
-        # not initialize the base classes.
-        if fp is not None:
-            self.__super_init(fp, hdrs, url, code)
-
-    def __str__(self):
-        return 'HTTP Error %s: %s' % (self.code, self.msg)
-
-# copied from cookielib.py
-_cut_port_re = re.compile(r":\d+$")
-def request_host(request):
-    """Return request-host, as defined by RFC 2965.
-
-    Variation from RFC: returned value is lowercased, for convenient
-    comparison.
-
-    """
-    url = request.get_full_url()
-    host = urlparse.urlparse(url)[1]
-    if host == "":
-        host = request.get_header("Host", "")
-
-    # remove port, if present
-    host = _cut_port_re.sub("", host, 1)
-    return host.lower()
-
-class Request:
-
-    def __init__(self, url, data=None, headers={},
-                 origin_req_host=None, unverifiable=False):
-        # unwrap('<URL:type://host/path>') --> 'type://host/path'
-        self.__original = unwrap(url)
-        self.type = None
-        # self.__r_type is what's left after doing the splittype
-        self.host = None
-        self.port = None
-        self.data = data
-        self.headers = {}
-        for key, value in headers.items():
-            self.add_header(key, value)
-        self.unredirected_hdrs = {}
-        if origin_req_host is None:
-            origin_req_host = request_host(self)
-        self.origin_req_host = origin_req_host
-        self.unverifiable = unverifiable
-
-    def __getattr__(self, attr):
-        # XXX this is a fallback mechanism to guard against these
-        # methods getting called in a non-standard order.  this may be
-        # too complicated and/or unnecessary.
-        # XXX should the __r_XXX attributes be public?
-        if attr[:12] == '_Request__r_':
-            name = attr[12:]
-            if hasattr(Request, 'get_' + name):
-                getattr(self, 'get_' + name)()
-                return getattr(self, attr)
-        raise AttributeError(attr)
-
-    def get_method(self):
-        if self.has_data():
-            return "POST"
-        else:
-            return "GET"
-
-    # XXX these helper methods are lame
-
-    def add_data(self, data):
-        self.data = data
-
-    def has_data(self):
-        return self.data is not None
-
-    def get_data(self):
-        return self.data
-
-    def get_full_url(self):
-        return self.__original
-
-    def get_type(self):
-        if self.type is None:
-            self.type, self.__r_type = splittype(self.__original)
-            if self.type is None:
-                raise ValueError("unknown url type: %s" % self.__original)
-        return self.type
-
-    def get_host(self):
-        if self.host is None:
-            self.host, self.__r_host = splithost(self.__r_type)
-            if self.host:
-                self.host = unquote(self.host)
-        return self.host
-
-    def get_selector(self):
-        return self.__r_host
-
-    def set_proxy(self, host, type):
-        self.host, self.type = host, type
-        self.__r_host = self.__original
-
-    def get_origin_req_host(self):
-        return self.origin_req_host
-
-    def is_unverifiable(self):
-        return self.unverifiable
-
-    def add_header(self, key, val):
-        # useful for something like authentication
-        self.headers[key.capitalize()] = val
-
-    def add_unredirected_header(self, key, val):
-        # will not be added to a redirected request
-        self.unredirected_hdrs[key.capitalize()] = val
-
-    def has_header(self, header_name):
-        return (header_name in self.headers or
-                header_name in self.unredirected_hdrs)
-
-    def get_header(self, header_name, default=None):
-        return self.headers.get(
-            header_name,
-            self.unredirected_hdrs.get(header_name, default))
-
-    def header_items(self):
-        hdrs = self.unredirected_hdrs.copy()
-        hdrs.update(self.headers)
-        return list(hdrs.items())
-
-class OpenerDirector:
-    def __init__(self):
-        client_version = "Python-urllib/%s" % __version__
-        self.addheaders = [('User-agent', client_version)]
-        # manage the individual handlers
-        self.handlers = []
-        self.handle_open = {}
-        self.handle_error = {}
-        self.process_response = {}
-        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"]:
-                # oops, coincidental match
-                continue
-
-            i = meth.find("_")
-            protocol = meth[:i]
-            condition = meth[i+1:]
-
-            if condition.startswith("error"):
-                j = condition.find("_") + i + 1
-                kind = meth[j+1:]
-                try:
-                    kind = int(kind)
-                except ValueError:
-                    pass
-                lookup = self.handle_error.get(protocol, {})
-                self.handle_error[protocol] = lookup
-            elif condition == "open":
-                kind = protocol
-                lookup = self.handle_open
-            elif condition == "response":
-                kind = protocol
-                lookup = self.process_response
-            elif condition == "request":
-                kind = protocol
-                lookup = self.process_request
-            else:
-                continue
-
-            handlers = lookup.setdefault(kind, [])
-            if handlers:
-                bisect.insort(handlers, handler)
-            else:
-                handlers.append(handler)
-            added = True
-
-        if added:
-            # the handlers must work in an specific order, the order
-            # is specified in a Handler attribute
-            bisect.insort(self.handlers, handler)
-            handler.add_parent(self)
-
-    def close(self):
-        # Only exists for backwards compatibility.
-        pass
-
-    def _call_chain(self, chain, kind, meth_name, *args):
-        # Handlers raise an exception if no one else should try to handle
-        # the request, or return None if they can't but another handler
-        # could.  Otherwise, they return the response.
-        handlers = chain.get(kind, ())
-        for handler in handlers:
-            func = getattr(handler, meth_name)
-
-            result = func(*args)
-            if result is not None:
-                return result
-
-    def open(self, fullurl, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
-        # accept a URL or a Request object
-        if isinstance(fullurl, str):
-            req = Request(fullurl, data)
-        else:
-            req = fullurl
-            if data is not None:
-                req.add_data(data)
-
-        req.timeout = timeout
-        protocol = req.get_type()
-
-        # pre-process request
-        meth_name = protocol+"_request"
-        for processor in self.process_request.get(protocol, []):
-            meth = getattr(processor, meth_name)
-            req = meth(req)
-
-        response = self._open(req, data)
-
-        # post-process response
-        meth_name = protocol+"_response"
-        for processor in self.process_response.get(protocol, []):
-            meth = getattr(processor, meth_name)
-            response = meth(req, response)
-
-        return response
-
-    def _open(self, req, data=None):
-        result = self._call_chain(self.handle_open, 'default',
-                                  'default_open', req)
-        if result:
-            return result
-
-        protocol = req.get_type()
-        result = self._call_chain(self.handle_open, protocol, protocol +
-                                  '_open', req)
-        if result:
-            return result
-
-        return self._call_chain(self.handle_open, 'unknown',
-                                'unknown_open', req)
-
-    def error(self, proto, *args):
-        if proto in ('http', 'https'):
-            # XXX http[s] protocols are special-cased
-            dict = self.handle_error['http'] # https is not different than http
-            proto = args[2]  # YUCK!
-            meth_name = 'http_error_%s' % proto
-            http_err = 1
-            orig_args = args
-        else:
-            dict = self.handle_error
-            meth_name = proto + '_error'
-            http_err = 0
-        args = (dict, proto, meth_name) + args
-        result = self._call_chain(*args)
-        if result:
-            return result
-
-        if http_err:
-            args = (dict, 'default', 'http_error_default') + orig_args
-            return self._call_chain(*args)
-
-# XXX probably also want an abstract factory that knows when it makes
-# sense to skip a superclass in favor of a subclass and when it might
-# make sense to include both
-
-def build_opener(*handlers):
-    """Create an opener object from a list of handlers.
-
-    The opener will use several default handlers, including support
-    for HTTP and FTP.
-
-    If any of the handlers passed as arguments are subclasses of the
-    default handlers, the default handlers will not be used.
-    """
-    def isclass(obj):
-        return isinstance(obj, type) or hasattr(obj, "__bases__")
-
-    opener = OpenerDirector()
-    default_classes = [ProxyHandler, UnknownHandler, HTTPHandler,
-                       HTTPDefaultErrorHandler, HTTPRedirectHandler,
-                       FTPHandler, FileHandler, HTTPErrorProcessor]
-    if hasattr(http.client, 'HTTPS'):
-        default_classes.append(HTTPSHandler)
-    skip = set()
-    for klass in default_classes:
-        for check in handlers:
-            if isclass(check):
-                if issubclass(check, klass):
-                    skip.add(klass)
-            elif isinstance(check, klass):
-                skip.add(klass)
-    for klass in skip:
-        default_classes.remove(klass)
-
-    for klass in default_classes:
-        opener.add_handler(klass())
-
-    for h in handlers:
-        if isclass(h):
-            h = h()
-        opener.add_handler(h)
-    return opener
-
-class BaseHandler:
-    handler_order = 500
-
-    def add_parent(self, parent):
-        self.parent = parent
-
-    def close(self):
-        # Only exists for backwards compatibility
-        pass
-
-    def __lt__(self, other):
-        if not hasattr(other, "handler_order"):
-            # Try to preserve the old behavior of having custom classes
-            # inserted after default ones (works only for custom user
-            # classes which are not aware of handler_order).
-            return True
-        return self.handler_order < other.handler_order
-
-
-class HTTPErrorProcessor(BaseHandler):
-    """Process HTTP error responses."""
-    handler_order = 1000  # after all other processing
-
-    def http_response(self, request, response):
-        code, msg, hdrs = response.code, response.msg, response.info()
-
-        # According to RFC 2616, "2xx" code indicates that the client's
-        # request was successfully received, understood, and accepted.
-        if not (200 <= code < 300):
-            response = self.parent.error(
-                'http', request, response, code, msg, hdrs)
-
-        return response
-
-    https_response = http_response
-
-class HTTPDefaultErrorHandler(BaseHandler):
-    def http_error_default(self, req, fp, code, msg, hdrs):
-        raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
-
-class HTTPRedirectHandler(BaseHandler):
-    # maximum number of redirections to any single URL
-    # this is needed because of the state that cookies introduce
-    max_repeats = 4
-    # maximum total number of redirections (regardless of URL) before
-    # assuming we're in a loop
-    max_redirections = 10
-
-    def redirect_request(self, req, fp, code, msg, headers, newurl):
-        """Return a Request or None in response to a redirect.
-
-        This is called by the http_error_30x methods when a
-        redirection response is received.  If a redirection should
-        take place, return a new Request to allow http_error_30x to
-        perform the redirect.  Otherwise, raise HTTPError if no-one
-        else should try to handle this url.  Return None if you can't
-        but another Handler might.
-        """
-        m = req.get_method()
-        if (code in (301, 302, 303, 307) and m in ("GET", "HEAD")
-            or code in (301, 302, 303) and m == "POST"):
-            # Strictly (according to RFC 2616), 301 or 302 in response
-            # to a POST MUST NOT cause a redirection without confirmation
-            # from the user (of urllib2, in this case).  In practice,
-            # essentially all clients do redirect in this case, so we
-            # do the same.
-            # be conciliant with URIs containing a space
-            newurl = newurl.replace(' ', '%20')
-            newheaders = dict((k,v) for k,v in req.headers.items()
-                              if k.lower() not in ("content-length", "content-type")
-                             )
-            return Request(newurl,
-                           headers=newheaders,
-                           origin_req_host=req.get_origin_req_host(),
-                           unverifiable=True)
-        else:
-            raise HTTPError(req.get_full_url(), code, msg, headers, fp)
-
-    # Implementation note: To avoid the server sending us into an
-    # infinite loop, the request object needs to track what URLs we
-    # have already seen.  Do this by adding a handler-specific
-    # attribute to the Request object.
-    def http_error_302(self, req, fp, code, msg, headers):
-        # Some servers (incorrectly) return multiple Location headers
-        # (so probably same goes for URI).  Use first header.
-        if 'location' in headers:
-            newurl = headers['location']
-        elif 'uri' in headers:
-            newurl = headers['uri']
-        else:
-            return
-        newurl = urlparse.urljoin(req.get_full_url(), newurl)
-
-        # XXX Probably want to forget about the state of the current
-        # request, although that might interact poorly with other
-        # handlers that also use handler-specific request attributes
-        new = self.redirect_request(req, fp, code, msg, headers, newurl)
-        if new is None:
-            return
-
-        # loop detection
-        # .redirect_dict has a key url if url was previously visited.
-        if hasattr(req, 'redirect_dict'):
-            visited = new.redirect_dict = req.redirect_dict
-            if (visited.get(newurl, 0) >= self.max_repeats or
-                len(visited) >= self.max_redirections):
-                raise HTTPError(req.get_full_url(), code,
-                                self.inf_msg + msg, headers, fp)
-        else:
-            visited = new.redirect_dict = req.redirect_dict = {}
-        visited[newurl] = visited.get(newurl, 0) + 1
-
-        # Don't close the fp until we are sure that we won't use it
-        # with HTTPError.
-        fp.read()
-        fp.close()
-
-        return self.parent.open(new)
-
-    http_error_301 = http_error_303 = http_error_307 = http_error_302
-
-    inf_msg = "The HTTP server returned a redirect error that would " \
-              "lead to an infinite loop.\n" \
-              "The last 30x error message was:\n"
-
-
-def _parse_proxy(proxy):
-    """Return (scheme, user, password, host/port) given a URL or an authority.
-
-    If a URL is supplied, it must have an authority (host:port) component.
-    According to RFC 3986, having an authority component means the URL must
-    have two slashes after the scheme:
-
-    >>> _parse_proxy('file:/ftp.example.com/')
-    Traceback (most recent call last):
-    ValueError: proxy URL with no authority: 'file:/ftp.example.com/'
-
-    The first three items of the returned tuple may be None.
-
-    Examples of authority parsing:
-
-    >>> _parse_proxy('proxy.example.com')
-    (None, None, None, 'proxy.example.com')
-    >>> _parse_proxy('proxy.example.com:3128')
-    (None, None, None, 'proxy.example.com:3128')
-
-    The authority component may optionally include userinfo (assumed to be
-    username:password):
-
-    >>> _parse_proxy('joe:password at proxy.example.com')
-    (None, 'joe', 'password', 'proxy.example.com')
-    >>> _parse_proxy('joe:password at proxy.example.com:3128')
-    (None, 'joe', 'password', 'proxy.example.com:3128')
-
-    Same examples, but with URLs instead:
-
-    >>> _parse_proxy('http://proxy.example.com/')
-    ('http', None, None, 'proxy.example.com')
-    >>> _parse_proxy('http://proxy.example.com:3128/')
-    ('http', None, None, 'proxy.example.com:3128')
-    >>> _parse_proxy('http://joe:password at proxy.example.com/')
-    ('http', 'joe', 'password', 'proxy.example.com')
-    >>> _parse_proxy('http://joe:password at proxy.example.com:3128')
-    ('http', 'joe', 'password', 'proxy.example.com:3128')
-
-    Everything after the authority is ignored:
-
-    >>> _parse_proxy('ftp://joe:password at proxy.example.com/rubbish:3128')
-    ('ftp', 'joe', 'password', 'proxy.example.com')
-
-    Test for no trailing '/' case:
-
-    >>> _parse_proxy('http://joe:password at proxy.example.com')
-    ('http', 'joe', 'password', 'proxy.example.com')
-
-    """
-    scheme, r_scheme = splittype(proxy)
-    if not r_scheme.startswith("/"):
-        # authority
-        scheme = None
-        authority = proxy
-    else:
-        # URL
-        if not r_scheme.startswith("//"):
-            raise ValueError("proxy URL with no authority: %r" % proxy)
-        # We have an authority, so for RFC 3986-compliant URLs (by ss 3.
-        # and 3.3.), path is empty or starts with '/'
-        end = r_scheme.find("/", 2)
-        if end == -1:
-            end = None
-        authority = r_scheme[2:end]
-    userinfo, hostport = splituser(authority)
-    if userinfo is not None:
-        user, password = splitpasswd(userinfo)
-    else:
-        user = password = None
-    return scheme, user, password, hostport
-
-class ProxyHandler(BaseHandler):
-    # Proxies must be in front
-    handler_order = 100
-
-    def __init__(self, proxies=None):
-        if proxies is None:
-            proxies = getproxies()
-        assert hasattr(proxies, 'keys'), "proxies must be a mapping"
-        self.proxies = proxies
-        for type, url in proxies.items():
-            setattr(self, '%s_open' % type,
-                    lambda r, proxy=url, type=type, meth=self.proxy_open: \
-                    meth(r, proxy, type))
-
-    def proxy_open(self, req, proxy, type):
-        orig_type = req.get_type()
-        proxy_type, user, password, hostport = _parse_proxy(proxy)
-        if proxy_type is None:
-            proxy_type = orig_type
-        if user and password:
-            user_pass = '%s:%s' % (unquote(user), unquote(password))
-            creds = base64.b64encode(user_pass.encode()).decode("ascii")
-            req.add_header('Proxy-authorization', 'Basic ' + creds)
-        hostport = unquote(hostport)
-        req.set_proxy(hostport, proxy_type)
-        if orig_type == proxy_type:
-            # let other handlers take care of it
-            return None
-        else:
-            # need to start over, because the other handlers don't
-            # grok the proxy's URL type
-            # e.g. if we have a constructor arg proxies like so:
-            # {'http': 'ftp://proxy.example.com'}, we may end up turning
-            # a request for http://acme.example.com/a into one for
-            # ftp://proxy.example.com/a
-            return self.parent.open(req)
-
-class HTTPPasswordMgr:
-
-    def __init__(self):
-        self.passwd = {}
-
-    def add_password(self, realm, uri, user, passwd):
-        # uri could be a single URI or a sequence
-        if isinstance(uri, str):
-            uri = [uri]
-        if not realm in self.passwd:
-            self.passwd[realm] = {}
-        for default_port in True, False:
-            reduced_uri = tuple(
-                [self.reduce_uri(u, default_port) for u in uri])
-            self.passwd[realm][reduced_uri] = (user, passwd)
-
-    def find_user_password(self, realm, authuri):
-        domains = self.passwd.get(realm, {})
-        for default_port in True, False:
-            reduced_authuri = self.reduce_uri(authuri, default_port)
-            for uris, authinfo in domains.items():
-                for uri in uris:
-                    if self.is_suburi(uri, reduced_authuri):
-                        return authinfo
-        return None, None
-
-    def reduce_uri(self, uri, default_port=True):
-        """Accept authority or URI and extract only the authority and path."""
-        # note HTTP URLs do not have a userinfo component
-        parts = urlparse.urlsplit(uri)
-        if parts[1]:
-            # URI
-            scheme = parts[0]
-            authority = parts[1]
-            path = parts[2] or '/'
-        else:
-            # host or host:port
-            scheme = None
-            authority = uri
-            path = '/'
-        host, port = splitport(authority)
-        if default_port and port is None and scheme is not None:
-            dport = {"http": 80,
-                     "https": 443,
-                     }.get(scheme)
-            if dport is not None:
-                authority = "%s:%d" % (host, dport)
-        return authority, path
-
-    def is_suburi(self, base, test):
-        """Check if test is below base in a URI tree
-
-        Both args must be URIs in reduced form.
-        """
-        if base == test:
-            return True
-        if base[0] != test[0]:
-            return False
-        common = posixpath.commonprefix((base[1], test[1]))
-        if len(common) == len(base[1]):
-            return True
-        return False
-
-
-class HTTPPasswordMgrWithDefaultRealm(HTTPPasswordMgr):
-
-    def find_user_password(self, realm, authuri):
-        user, password = HTTPPasswordMgr.find_user_password(self, realm,
-                                                            authuri)
-        if user is not None:
-            return user, password
-        return HTTPPasswordMgr.find_user_password(self, None, authuri)
-
-
-class AbstractBasicAuthHandler:
-
-    # XXX this allows for multiple auth-schemes, but will stupidly pick
-    # the last one with a realm specified.
-
-    # allow for double- and single-quoted realm values
-    # (single quotes are a violation of the RFC, but appear in the wild)
-    rx = re.compile('(?:.*,)*[ \t]*([^ \t]+)[ \t]+'
-                    'realm=(["\'])(.*?)\\2', re.I)
-
-    # XXX could pre-emptively send auth info already accepted (RFC 2617,
-    # end of section 2, and section 1.2 immediately after "credentials"
-    # production).
-
-    def __init__(self, password_mgr=None):
-        if password_mgr is None:
-            password_mgr = HTTPPasswordMgr()
-        self.passwd = password_mgr
-        self.add_password = self.passwd.add_password
-
-    def http_error_auth_reqed(self, authreq, host, req, headers):
-        # host may be an authority (without userinfo) or a URL with an
-        # authority
-        # XXX could be multiple headers
-        authreq = headers.get(authreq, None)
-        if authreq:
-            mo = AbstractBasicAuthHandler.rx.search(authreq)
-            if mo:
-                scheme, quote, realm = mo.groups()
-                if scheme.lower() == 'basic':
-                    return self.retry_http_basic_auth(host, req, realm)
-
-    def retry_http_basic_auth(self, host, req, realm):
-        user, pw = self.passwd.find_user_password(realm, host)
-        if pw is not None:
-            raw = "%s:%s" % (user, pw)
-            auth = "Basic " + base64.b64encode(raw.encode()).decode("ascii")
-            if req.headers.get(self.auth_header, None) == auth:
-                return None
-            req.add_header(self.auth_header, auth)
-            return self.parent.open(req)
-        else:
-            return None
-
-
-class HTTPBasicAuthHandler(AbstractBasicAuthHandler, BaseHandler):
-
-    auth_header = 'Authorization'
-
-    def http_error_401(self, req, fp, code, msg, headers):
-        url = req.get_full_url()
-        return self.http_error_auth_reqed('www-authenticate',
-                                          url, req, headers)
-
-
-class ProxyBasicAuthHandler(AbstractBasicAuthHandler, BaseHandler):
-
-    auth_header = 'Proxy-authorization'
-
-    def http_error_407(self, req, fp, code, msg, headers):
-        # http_error_auth_reqed requires that there is no userinfo component in
-        # authority.  Assume there isn't one, since urllib2 does not (and
-        # should not, RFC 3986 s. 3.2.1) support requests for URLs containing
-        # userinfo.
-        authority = req.get_host()
-        return self.http_error_auth_reqed('proxy-authenticate',
-                                          authority, req, headers)
-
-
-def randombytes(n):
-    """Return n random bytes."""
-    return os.urandom(n)
-
-class AbstractDigestAuthHandler:
-    # Digest authentication is specified in RFC 2617.
-
-    # XXX The client does not inspect the Authentication-Info header
-    # in a successful response.
-
-    # XXX It should be possible to test this implementation against
-    # a mock server that just generates a static set of challenges.
-
-    # XXX qop="auth-int" supports is shaky
-
-    def __init__(self, passwd=None):
-        if passwd is None:
-            passwd = HTTPPasswordMgr()
-        self.passwd = passwd
-        self.add_password = self.passwd.add_password
-        self.retried = 0
-        self.nonce_count = 0
-
-    def reset_retry_count(self):
-        self.retried = 0
-
-    def http_error_auth_reqed(self, auth_header, host, req, headers):
-        authreq = headers.get(auth_header, None)
-        if self.retried > 5:
-            # Don't fail endlessly - if we failed once, we'll probably
-            # fail a second time. Hm. Unless the Password Manager is
-            # prompting for the information. Crap. This isn't great
-            # but it's better than the current 'repeat until recursion
-            # depth exceeded' approach <wink>
-            raise HTTPError(req.get_full_url(), 401, "digest auth failed",
-                            headers, None)
-        else:
-            self.retried += 1
-        if authreq:
-            scheme = authreq.split()[0]
-            if scheme.lower() == 'digest':
-                return self.retry_http_digest_auth(req, authreq)
-
-    def retry_http_digest_auth(self, req, auth):
-        token, challenge = auth.split(' ', 1)
-        chal = parse_keqv_list(parse_http_list(challenge))
-        auth = self.get_authorization(req, chal)
-        if auth:
-            auth_val = 'Digest %s' % auth
-            if req.headers.get(self.auth_header, None) == auth_val:
-                return None
-            req.add_unredirected_header(self.auth_header, auth_val)
-            resp = self.parent.open(req)
-            return resp
-
-    def get_cnonce(self, nonce):
-        # The cnonce-value is an opaque
-        # quoted string value provided by the client and used by both client
-        # and server to avoid chosen plaintext attacks, to provide mutual
-        # authentication, and to provide some message integrity protection.
-        # This isn't a fabulous effort, but it's probably Good Enough.
-        s = "%s:%s:%s:" % (self.nonce_count, nonce, time.ctime())
-        b = s.encode("ascii") + randombytes(8)
-        dig = hashlib.sha1(b).hexdigest()
-        return dig[:16]
-
-    def get_authorization(self, req, chal):
-        try:
-            realm = chal['realm']
-            nonce = chal['nonce']
-            qop = chal.get('qop')
-            algorithm = chal.get('algorithm', 'MD5')
-            # mod_digest doesn't send an opaque, even though it isn't
-            # supposed to be optional
-            opaque = chal.get('opaque', None)
-        except KeyError:
-            return None
-
-        H, KD = self.get_algorithm_impls(algorithm)
-        if H is None:
-            return None
-
-        user, pw = self.passwd.find_user_password(realm, req.get_full_url())
-        if user is None:
-            return None
-
-        # XXX not implemented yet
-        if req.has_data():
-            entdig = self.get_entity_digest(req.get_data(), chal)
-        else:
-            entdig = None
-
-        A1 = "%s:%s:%s" % (user, realm, pw)
-        A2 = "%s:%s" % (req.get_method(),
-                        # XXX selector: what about proxies and full urls
-                        req.get_selector())
-        if qop == 'auth':
-            self.nonce_count += 1
-            ncvalue = '%08x' % self.nonce_count
-            cnonce = self.get_cnonce(nonce)
-            noncebit = "%s:%s:%s:%s:%s" % (nonce, ncvalue, cnonce, qop, H(A2))
-            respdig = KD(H(A1), noncebit)
-        elif qop is None:
-            respdig = KD(H(A1), "%s:%s" % (nonce, H(A2)))
-        else:
-            # XXX handle auth-int.
-            raise URLError("qop '%s' is not supported." % qop)
-
-        # XXX should the partial digests be encoded too?
-
-        base = 'username="%s", realm="%s", nonce="%s", uri="%s", ' \
-               'response="%s"' % (user, realm, nonce, req.get_selector(),
-                                  respdig)
-        if opaque:
-            base += ', opaque="%s"' % opaque
-        if entdig:
-            base += ', digest="%s"' % entdig
-        base += ', algorithm="%s"' % algorithm
-        if qop:
-            base += ', qop=auth, nc=%s, cnonce="%s"' % (ncvalue, cnonce)
-        return base
-
-    def get_algorithm_impls(self, algorithm):
-        # algorithm should be case-insensitive according to RFC2617
-        algorithm = algorithm.upper()
-        # lambdas assume digest modules are imported at the top level
-        if algorithm == 'MD5':
-            H = lambda x: hashlib.md5(x.encode("ascii")).hexdigest()
-        elif algorithm == 'SHA':
-            H = lambda x: hashlib.sha1(x.encode("ascii")).hexdigest()
-        # XXX MD5-sess
-        KD = lambda s, d: H("%s:%s" % (s, d))
-        return H, KD
-
-    def get_entity_digest(self, data, chal):
-        # XXX not implemented yet
-        return None
-
-
-class HTTPDigestAuthHandler(BaseHandler, AbstractDigestAuthHandler):
-    """An authentication protocol defined by RFC 2069
-
-    Digest authentication improves on basic authentication because it
-    does not transmit passwords in the clear.
-    """
-
-    auth_header = 'Authorization'
-    handler_order = 490  # before Basic auth
-
-    def http_error_401(self, req, fp, code, msg, headers):
-        host = urlparse.urlparse(req.get_full_url())[1]
-        retry = self.http_error_auth_reqed('www-authenticate',
-                                           host, req, headers)
-        self.reset_retry_count()
-        return retry
-
-
-class ProxyDigestAuthHandler(BaseHandler, AbstractDigestAuthHandler):
-
-    auth_header = 'Proxy-Authorization'
-    handler_order = 490  # before Basic auth
-
-    def http_error_407(self, req, fp, code, msg, headers):
-        host = req.get_host()
-        retry = self.http_error_auth_reqed('proxy-authenticate',
-                                           host, req, headers)
-        self.reset_retry_count()
-        return retry
-
-class AbstractHTTPHandler(BaseHandler):
-
-    def __init__(self, debuglevel=0):
-        self._debuglevel = debuglevel
-
-    def set_http_debuglevel(self, level):
-        self._debuglevel = level
-
-    def do_request_(self, request):
-        host = request.get_host()
-        if not host:
-            raise URLError('no host given')
-
-        if request.has_data():  # POST
-            data = request.get_data()
-            if not request.has_header('Content-type'):
-                request.add_unredirected_header(
-                    'Content-type',
-                    'application/x-www-form-urlencoded')
-            if not request.has_header('Content-length'):
-                request.add_unredirected_header(
-                    'Content-length', '%d' % len(data))
-
-        scheme, sel = splittype(request.get_selector())
-        sel_host, sel_path = splithost(sel)
-        if not request.has_header('Host'):
-            request.add_unredirected_header('Host', sel_host or host)
-        for name, value in self.parent.addheaders:
-            name = name.capitalize()
-            if not request.has_header(name):
-                request.add_unredirected_header(name, value)
-
-        return request
-
-    def do_open(self, http_class, req):
-        """Return an addinfourl object for the request, using http_class.
-
-        http_class must implement the HTTPConnection API from http.client.
-        The addinfourl return value is a file-like object.  It also
-        has methods and attributes including:
-            - info(): return a email.message.Message object for the headers
-            - geturl(): return the original request URL
-            - code: HTTP status code
-        """
-        host = req.get_host()
-        if not host:
-            raise URLError('no host given')
-
-        h = http_class(host, timeout=req.timeout) # will parse host:port
-        h.set_debuglevel(self._debuglevel)
-
-        headers = dict(req.headers)
-        headers.update(req.unredirected_hdrs)
-        # We want to make an HTTP/1.1 request, but the addinfourl
-        # class isn't prepared to deal with a persistent connection.
-        # It will try to read all remaining data from the socket,
-        # which will block while the server waits for the next request.
-        # So make sure the connection gets closed after the (only)
-        # request.
-        headers["Connection"] = "close"
-        headers = dict(
-            (name.title(), val) for name, val in headers.items())
-        try:
-            h.request(req.get_method(), req.get_selector(), req.data, headers)
-            r = h.getresponse()
-        except socket.error as err: # XXX what error?
-            raise URLError(err)
-
-        # Pick apart the HTTPResponse object to get the addinfourl
-        # object initialized properly.
-
-        # XXX Should an HTTPResponse object really be passed to
-        # BufferedReader?  If so, we should change http.client to support
-        # this use directly.
-
-        # Add some fake methods to the reader to satisfy BufferedReader.
-        r.readable = lambda: True
-        r.writable = r.seekable = lambda: False
-        r._checkReadable = lambda: True
-        r._checkWritable = lambda: False
-        fp = io.BufferedReader(r)
-
-        resp = addinfourl(fp, r.msg, req.get_full_url())
-        resp.code = r.status
-        resp.msg = r.reason
-        return resp
-
-
-class HTTPHandler(AbstractHTTPHandler):
-
-    def http_open(self, req):
-        return self.do_open(http.client.HTTPConnection, req)
-
-    http_request = AbstractHTTPHandler.do_request_
-
-if hasattr(http.client, 'HTTPS'):
-    class HTTPSHandler(AbstractHTTPHandler):
-
-        def https_open(self, req):
-            return self.do_open(http.client.HTTPSConnection, req)
-
-        https_request = AbstractHTTPHandler.do_request_
-
-class HTTPCookieProcessor(BaseHandler):
-    def __init__(self, cookiejar=None):
-        import http.cookiejar
-        if cookiejar is None:
-            cookiejar = http.cookiejar.CookieJar()
-        self.cookiejar = cookiejar
-
-    def http_request(self, request):
-        self.cookiejar.add_cookie_header(request)
-        return request
-
-    def http_response(self, request, response):
-        self.cookiejar.extract_cookies(response, request)
-        return response
-
-    https_request = http_request
-    https_response = http_response
-
-class UnknownHandler(BaseHandler):
-    def unknown_open(self, req):
-        type = req.get_type()
-        raise URLError('unknown url type: %s' % type)
-
-def parse_keqv_list(l):
-    """Parse list of key=value strings where keys are not duplicated."""
-    parsed = {}
-    for elt in l:
-        # Because of a trailing comma in the auth string, elt could be the
-        # empty string.
-        if not elt:
-            continue
-        k, v = elt.split('=', 1)
-        if v[0] == '"' and v[-1] == '"':
-            v = v[1:-1]
-        parsed[k] = v
-    return parsed
-
-def parse_http_list(s):
-    """Parse lists as described by RFC 2068 Section 2.
-
-    In particular, parse comma-separated lists where the elements of
-    the list may include quoted-strings.  A quoted-string could
-    contain a comma.  A non-quoted string could have quotes in the
-    middle.  Neither commas nor quotes count if they are escaped.
-    Only double-quotes count, not single-quotes.
-    """
-    res = []
-    part = ''
-
-    escape = quote = False
-    for cur in s:
-        if escape:
-            part += cur
-            escape = False
-            continue
-        if quote:
-            if cur == '\\':
-                escape = True
-                continue
-            elif cur == '"':
-                quote = False
-            part += cur
-            continue
-
-        if cur == ',':
-            res.append(part)
-            part = ''
-            continue
-
-        if cur == '"':
-            quote = True
-
-        part += cur
-
-    # append last part
-    if part:
-        res.append(part)
-
-    return [part.strip() for part in res]
-
-class FileHandler(BaseHandler):
-    # Use local file or FTP depending on form of URL
-    def file_open(self, req):
-        url = req.get_selector()
-        if url[:2] == '//' and url[2:3] != '/':
-            req.type = 'ftp'
-            return self.parent.open(req)
-        else:
-            return self.open_local_file(req)
-
-    # names for the localhost
-    names = None
-    def get_names(self):
-        if FileHandler.names is None:
-            try:
-                FileHandler.names = (socket.gethostbyname('localhost'),
-                                    socket.gethostbyname(socket.gethostname()))
-            except socket.gaierror:
-                FileHandler.names = (socket.gethostbyname('localhost'),)
-        return FileHandler.names
-
-    # not entirely sure what the rules are here
-    def open_local_file(self, req):
-        import email.utils
-        import mimetypes
-        host = req.get_host()
-        file = req.get_selector()
-        localfile = url2pathname(file)
-        try:
-            stats = os.stat(localfile)
-            size = stats.st_size
-            modified = email.utils.formatdate(stats.st_mtime, usegmt=True)
-            mtype = mimetypes.guess_type(file)[0]
-            headers = email.message_from_string(
-                'Content-type: %s\nContent-length: %d\nLast-modified: %s\n' %
-                (mtype or 'text/plain', size, modified))
-            if host:
-                host, port = splitport(host)
-            if not host or \
-                (not port and _safe_gethostbyname(host) in self.get_names()):
-                return addinfourl(open(localfile, 'rb'),
-                                  headers, 'file:'+file)
-        except OSError as msg:
-            # urllib2 users shouldn't expect OSErrors coming from urlopen()
-            raise URLError(msg)
-        raise URLError('file not on local host')
-
-def _safe_gethostbyname(host):
-    try:
-        return socket.gethostbyname(host)
-    except socket.gaierror:
-        return None
-
-class FTPHandler(BaseHandler):
-    def ftp_open(self, req):
-        import ftplib
-        import mimetypes
-        host = req.get_host()
-        if not host:
-            raise URLError('ftp error: no host given')
-        host, port = splitport(host)
-        if port is None:
-            port = ftplib.FTP_PORT
-        else:
-            port = int(port)
-
-        # username/password handling
-        user, host = splituser(host)
-        if user:
-            user, passwd = splitpasswd(user)
-        else:
-            passwd = None
-        host = unquote(host)
-        user = unquote(user or '')
-        passwd = unquote(passwd or '')
-
-        try:
-            host = socket.gethostbyname(host)
-        except socket.error as msg:
-            raise URLError(msg)
-        path, attrs = splitattr(req.get_selector())
-        dirs = path.split('/')
-        dirs = list(map(unquote, dirs))
-        dirs, file = dirs[:-1], dirs[-1]
-        if dirs and not dirs[0]:
-            dirs = dirs[1:]
-        try:
-            fw = self.connect_ftp(user, passwd, host, port, dirs, req.timeout)
-            type = file and 'I' or 'D'
-            for attr in attrs:
-                attr, value = splitvalue(attr)
-                if attr.lower() == 'type' and \
-                   value in ('a', 'A', 'i', 'I', 'd', 'D'):
-                    type = value.upper()
-            fp, retrlen = fw.retrfile(file, type)
-            headers = ""
-            mtype = mimetypes.guess_type(req.get_full_url())[0]
-            if mtype:
-                headers += "Content-type: %s\n" % mtype
-            if retrlen is not None and retrlen >= 0:
-                headers += "Content-length: %d\n" % retrlen
-            headers = email.message_from_string(headers)
-            sf = StringIO(str(headers))
-            return addinfourl(fp, headers, req.get_full_url())
-        except ftplib.all_errors as msg:
-            raise URLError('ftp error: %s' % msg).with_traceback(sys.exc_info()[2])
-
-    def connect_ftp(self, user, passwd, host, port, dirs, timeout):
-        fw = ftpwrapper(user, passwd, host, port, dirs, timeout)
-        return fw
-
-class CacheFTPHandler(FTPHandler):
-    # XXX would be nice to have pluggable cache strategies
-    # XXX this stuff is definitely not thread safe
-    def __init__(self):
-        self.cache = {}
-        self.timeout = {}
-        self.soonest = 0
-        self.delay = 60
-        self.max_conns = 16
-
-    def setTimeout(self, t):
-        self.delay = t
-
-    def setMaxConns(self, m):
-        self.max_conns = m
-
-    def connect_ftp(self, user, passwd, host, port, dirs, timeout):
-        key = user, host, port, '/'.join(dirs), timeout
-        if key in self.cache:
-            self.timeout[key] = time.time() + self.delay
-        else:
-            self.cache[key] = ftpwrapper(user, passwd, host, port, dirs, timeout)
-            self.timeout[key] = time.time() + self.delay
-        self.check_cache()
-        return self.cache[key]
-
-    def check_cache(self):
-        # first check for old ones
-        t = time.time()
-        if self.soonest <= t:
-            for k, v in list(self.timeout.items()):
-                if v < t:
-                    self.cache[k].close()
-                    del self.cache[k]
-                    del self.timeout[k]
-        self.soonest = min(list(self.timeout.values()))
-
-        # then check the size
-        if len(self.cache) == self.max_conns:
-            for k, v in list(self.timeout.items()):
-                if v == self.soonest:
-                    del self.cache[k]
-                    del self.timeout[k]
-                    break
-            self.soonest = min(list(self.timeout.values()))

Deleted: python/branches/py3k/Lib/urlparse.py
==============================================================================
--- python/branches/py3k/Lib/urlparse.py	Wed Jun 18 22:49:58 2008
+++ (empty file)
@@ -1,325 +0,0 @@
-"""Parse (absolute and relative) URLs.
-
-See RFC 1808: "Relative Uniform Resource Locators", by R. Fielding,
-UC Irvine, June 1995.
-"""
-
-__all__ = ["urlparse", "urlunparse", "urljoin", "urldefrag",
-           "urlsplit", "urlunsplit"]
-
-# A classification of schemes ('' means apply by default)
-uses_relative = ['ftp', 'http', 'gopher', 'nntp', 'imap',
-                 'wais', 'file', 'https', 'shttp', 'mms',
-                 'prospero', 'rtsp', 'rtspu', '', 'sftp']
-uses_netloc = ['ftp', 'http', 'gopher', 'nntp', 'telnet',
-               'imap', 'wais', 'file', 'mms', 'https', 'shttp',
-               'snews', 'prospero', 'rtsp', 'rtspu', 'rsync', '',
-               'svn', 'svn+ssh', 'sftp']
-non_hierarchical = ['gopher', 'hdl', 'mailto', 'news',
-                    'telnet', 'wais', 'imap', 'snews', 'sip', 'sips']
-uses_params = ['ftp', 'hdl', 'prospero', 'http', 'imap',
-               'https', 'shttp', 'rtsp', 'rtspu', 'sip', 'sips',
-               'mms', '', 'sftp']
-uses_query = ['http', 'wais', 'imap', 'https', 'shttp', 'mms',
-              'gopher', 'rtsp', 'rtspu', 'sip', 'sips', '']
-uses_fragment = ['ftp', 'hdl', 'http', 'gopher', 'news',
-                 'nntp', 'wais', 'https', 'shttp', 'snews',
-                 'file', 'prospero', '']
-
-# Characters valid in scheme names
-scheme_chars = ('abcdefghijklmnopqrstuvwxyz'
-                'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
-                '0123456789'
-                '+-.')
-
-MAX_CACHE_SIZE = 20
-_parse_cache = {}
-
-def clear_cache():
-    """Clear the parse cache."""
-    _parse_cache.clear()
-
-
-class ResultMixin(object):
-    """Shared methods for the parsed result objects."""
-
-    @property
-    def username(self):
-        netloc = self.netloc
-        if "@" in netloc:
-            userinfo = netloc.rsplit("@", 1)[0]
-            if ":" in userinfo:
-                userinfo = userinfo.split(":", 1)[0]
-            return userinfo
-        return None
-
-    @property
-    def password(self):
-        netloc = self.netloc
-        if "@" in netloc:
-            userinfo = netloc.rsplit("@", 1)[0]
-            if ":" in userinfo:
-                return userinfo.split(":", 1)[1]
-        return None
-
-    @property
-    def hostname(self):
-        netloc = self.netloc
-        if "@" in netloc:
-            netloc = netloc.rsplit("@", 1)[1]
-        if ":" in netloc:
-            netloc = netloc.split(":", 1)[0]
-        return netloc.lower() or None
-
-    @property
-    def port(self):
-        netloc = self.netloc
-        if "@" in netloc:
-            netloc = netloc.rsplit("@", 1)[1]
-        if ":" in netloc:
-            port = netloc.split(":", 1)[1]
-            return int(port, 10)
-        return None
-
-from collections import namedtuple
-
-class SplitResult(namedtuple('SplitResult', 'scheme netloc path query fragment'), ResultMixin):
-
-    __slots__ = ()
-
-    def geturl(self):
-        return urlunsplit(self)
-
-
-class ParseResult(namedtuple('ParseResult', 'scheme netloc path params query fragment'), ResultMixin):
-
-    __slots__ = ()
-
-    def geturl(self):
-        return urlunparse(self)
-
-
-def urlparse(url, scheme='', allow_fragments=True):
-    """Parse a URL into 6 components:
-    <scheme>://<netloc>/<path>;<params>?<query>#<fragment>
-    Return a 6-tuple: (scheme, netloc, path, params, query, fragment).
-    Note that we don't break the components up in smaller bits
-    (e.g. netloc is a single string) and we don't expand % escapes."""
-    tuple = urlsplit(url, scheme, allow_fragments)
-    scheme, netloc, url, query, fragment = tuple
-    if scheme in uses_params and ';' in url:
-        url, params = _splitparams(url)
-    else:
-        params = ''
-    return ParseResult(scheme, netloc, url, params, query, fragment)
-
-def _splitparams(url):
-    if '/'  in url:
-        i = url.find(';', url.rfind('/'))
-        if i < 0:
-            return url, ''
-    else:
-        i = url.find(';')
-    return url[:i], url[i+1:]
-
-def _splitnetloc(url, start=0):
-    delim = len(url)   # position of end of domain part of url, default is end
-    for c in '/?#':    # look for delimiters; the order is NOT important
-        wdelim = url.find(c, start)        # find first of this delim
-        if wdelim >= 0:                    # if found
-            delim = min(delim, wdelim)     # use earliest delim position
-    return url[start:delim], url[delim:]   # return (domain, rest)
-
-def urlsplit(url, scheme='', allow_fragments=True):
-    """Parse a URL into 5 components:
-    <scheme>://<netloc>/<path>?<query>#<fragment>
-    Return a 5-tuple: (scheme, netloc, path, query, fragment).
-    Note that we don't break the components up in smaller bits
-    (e.g. netloc is a single string) and we don't expand % escapes."""
-    allow_fragments = bool(allow_fragments)
-    key = url, scheme, allow_fragments, type(url), type(scheme)
-    cached = _parse_cache.get(key, None)
-    if cached:
-        return cached
-    if len(_parse_cache) >= MAX_CACHE_SIZE: # avoid runaway growth
-        clear_cache()
-    netloc = query = fragment = ''
-    i = url.find(':')
-    if i > 0:
-        if url[:i] == 'http': # optimize the common case
-            scheme = url[:i].lower()
-            url = url[i+1:]
-            if url[:2] == '//':
-                netloc, url = _splitnetloc(url, 2)
-            if allow_fragments and '#' in url:
-                url, fragment = url.split('#', 1)
-            if '?' in url:
-                url, query = url.split('?', 1)
-            v = SplitResult(scheme, netloc, url, query, fragment)
-            _parse_cache[key] = v
-            return v
-        for c in url[:i]:
-            if c not in scheme_chars:
-                break
-        else:
-            scheme, url = url[:i].lower(), url[i+1:]
-    if scheme in uses_netloc and url[:2] == '//':
-        netloc, url = _splitnetloc(url, 2)
-    if allow_fragments and scheme in uses_fragment and '#' in url:
-        url, fragment = url.split('#', 1)
-    if scheme in uses_query and '?' in url:
-        url, query = url.split('?', 1)
-    v = SplitResult(scheme, netloc, url, query, fragment)
-    _parse_cache[key] = v
-    return v
-
-def urlunparse(components):
-    """Put a parsed URL back together again.  This may result in a
-    slightly different, but equivalent URL, if the URL that was parsed
-    originally had redundant delimiters, e.g. a ? with an empty query
-    (the draft states that these are equivalent)."""
-    scheme, netloc, url, params, query, fragment = components
-    if params:
-        url = "%s;%s" % (url, params)
-    return urlunsplit((scheme, netloc, url, query, fragment))
-
-def urlunsplit(components):
-    scheme, netloc, url, query, fragment = components
-    if netloc or (scheme and scheme in uses_netloc and url[:2] != '//'):
-        if url and url[:1] != '/': url = '/' + url
-        url = '//' + (netloc or '') + url
-    if scheme:
-        url = scheme + ':' + url
-    if query:
-        url = url + '?' + query
-    if fragment:
-        url = url + '#' + fragment
-    return url
-
-def urljoin(base, url, allow_fragments=True):
-    """Join a base URL and a possibly relative URL to form an absolute
-    interpretation of the latter."""
-    if not base:
-        return url
-    if not url:
-        return base
-    bscheme, bnetloc, bpath, bparams, bquery, bfragment = \
-            urlparse(base, '', allow_fragments)
-    scheme, netloc, path, params, query, fragment = \
-            urlparse(url, bscheme, allow_fragments)
-    if scheme != bscheme or scheme not in uses_relative:
-        return url
-    if scheme in uses_netloc:
-        if netloc:
-            return urlunparse((scheme, netloc, path,
-                               params, query, fragment))
-        netloc = bnetloc
-    if path[:1] == '/':
-        return urlunparse((scheme, netloc, path,
-                           params, query, fragment))
-    if not (path or params or query):
-        return urlunparse((scheme, netloc, bpath,
-                           bparams, bquery, fragment))
-    segments = bpath.split('/')[:-1] + path.split('/')
-    # XXX The stuff below is bogus in various ways...
-    if segments[-1] == '.':
-        segments[-1] = ''
-    while '.' in segments:
-        segments.remove('.')
-    while 1:
-        i = 1
-        n = len(segments) - 1
-        while i < n:
-            if (segments[i] == '..'
-                and segments[i-1] not in ('', '..')):
-                del segments[i-1:i+1]
-                break
-            i = i+1
-        else:
-            break
-    if segments == ['', '..']:
-        segments[-1] = ''
-    elif len(segments) >= 2 and segments[-1] == '..':
-        segments[-2:] = ['']
-    return urlunparse((scheme, netloc, '/'.join(segments),
-                       params, query, fragment))
-
-def urldefrag(url):
-    """Removes any existing fragment from URL.
-
-    Returns a tuple of the defragmented URL and the fragment.  If
-    the URL contained no fragments, the second element is the
-    empty string.
-    """
-    if '#' in url:
-        s, n, p, a, q, frag = urlparse(url)
-        defrag = urlunparse((s, n, p, a, q, ''))
-        return defrag, frag
-    else:
-        return url, ''
-
-
-test_input = """
-      http://a/b/c/d
-
-      g:h        = <URL:g:h>
-      http:g     = <URL:http://a/b/c/g>
-      http:      = <URL:http://a/b/c/d>
-      g          = <URL:http://a/b/c/g>
-      ./g        = <URL:http://a/b/c/g>
-      g/         = <URL:http://a/b/c/g/>
-      /g         = <URL:http://a/g>
-      //g        = <URL:http://g>
-      ?y         = <URL:http://a/b/c/d?y>
-      g?y        = <URL:http://a/b/c/g?y>
-      g?y/./x    = <URL:http://a/b/c/g?y/./x>
-      .          = <URL:http://a/b/c/>
-      ./         = <URL:http://a/b/c/>
-      ..         = <URL:http://a/b/>
-      ../        = <URL:http://a/b/>
-      ../g       = <URL:http://a/b/g>
-      ../..      = <URL:http://a/>
-      ../../g    = <URL:http://a/g>
-      ../../../g = <URL:http://a/../g>
-      ./../g     = <URL:http://a/b/g>
-      ./g/.      = <URL:http://a/b/c/g/>
-      /./g       = <URL:http://a/./g>
-      g/./h      = <URL:http://a/b/c/g/h>
-      g/../h     = <URL:http://a/b/c/h>
-      http:g     = <URL:http://a/b/c/g>
-      http:      = <URL:http://a/b/c/d>
-      http:?y         = <URL:http://a/b/c/d?y>
-      http:g?y        = <URL:http://a/b/c/g?y>
-      http:g?y/./x    = <URL:http://a/b/c/g?y/./x>
-"""
-
-def test():
-    import sys
-    base = ''
-    if sys.argv[1:]:
-        fn = sys.argv[1]
-        if fn == '-':
-            fp = sys.stdin
-        else:
-            fp = open(fn)
-    else:
-        from io import StringIO
-        fp = StringIO(test_input)
-    for line in fp:
-        words = line.split()
-        if not words:
-            continue
-        url = words[0]
-        parts = urlparse(url)
-        print('%-10s : %s' % (url, parts))
-        abs = urljoin(base, url)
-        if not base:
-            base = abs
-        wrapped = '<URL:%s>' % abs
-        print('%-10s = %s' % (url, wrapped))
-        if len(words) == 3 and words[1] == '=':
-            if wrapped != words[2]:
-                print('EXPECTED', words[2], '!!!!!!!!!!')
-
-if __name__ == '__main__':
-    test()

Modified: python/branches/py3k/Lib/wsgiref/simple_server.py
==============================================================================
--- python/branches/py3k/Lib/wsgiref/simple_server.py	(original)
+++ python/branches/py3k/Lib/wsgiref/simple_server.py	Wed Jun 18 22:49:58 2008
@@ -11,7 +11,8 @@
 """
 
 from http.server import BaseHTTPRequestHandler, HTTPServer
-import urllib, sys
+import sys
+import urllib.parse
 from wsgiref.handlers import SimpleHandler
 
 __version__ = "0.1"
@@ -93,7 +94,7 @@
         else:
             path,query = self.path,''
 
-        env['PATH_INFO'] = urllib.unquote(path)
+        env['PATH_INFO'] = urllib.parse.unquote(path)
         env['QUERY_STRING'] = query
 
         host = self.address_string()

Modified: python/branches/py3k/Lib/wsgiref/util.py
==============================================================================
--- python/branches/py3k/Lib/wsgiref/util.py	(original)
+++ python/branches/py3k/Lib/wsgiref/util.py	Wed Jun 18 22:49:58 2008
@@ -50,7 +50,7 @@
 def application_uri(environ):
     """Return the application's base URI (no PATH_INFO or QUERY_STRING)"""
     url = environ['wsgi.url_scheme']+'://'
-    from urllib import quote
+    from urllib.parse import quote
 
     if environ.get('HTTP_HOST'):
         url += environ['HTTP_HOST']
@@ -70,7 +70,7 @@
 def request_uri(environ, include_query=1):
     """Return the full request URI, optionally including the query string"""
     url = application_uri(environ)
-    from urllib import quote
+    from urllib.parse import quote
     path_info = quote(environ.get('PATH_INFO',''))
     if not environ.get('SCRIPT_NAME'):
         url += path_info[1:]

Modified: python/branches/py3k/Lib/xml/dom/xmlbuilder.py
==============================================================================
--- python/branches/py3k/Lib/xml/dom/xmlbuilder.py	(original)
+++ python/branches/py3k/Lib/xml/dom/xmlbuilder.py	Wed Jun 18 22:49:58 2008
@@ -190,8 +190,8 @@
         options.errorHandler = self.errorHandler
         fp = input.byteStream
         if fp is None and options.systemId:
-            import urllib2
-            fp = urllib2.urlopen(input.systemId)
+            import urllib.request
+            fp = urllib.request.urlopen(input.systemId)
         return self._parse_bytestream(fp, options)
 
     def parseWithContext(self, input, cnode, action):
@@ -223,14 +223,14 @@
         source.encoding = self._guess_media_encoding(source)
 
         # determine the base URI is we can
-        import posixpath, urlparse
-        parts = urlparse.urlparse(systemId)
+        import posixpath, urllib.parse
+        parts = urllib.parse.urlparse(systemId)
         scheme, netloc, path, params, query, fragment = parts
         # XXX should we check the scheme here as well?
         if path and not path.endswith("/"):
             path = posixpath.dirname(path) + "/"
             parts = scheme, netloc, path, params, query, fragment
-            source.baseURI = urlparse.urlunparse(parts)
+            source.baseURI = urllib.parse.urlunparse(parts)
 
         return source
 
@@ -242,8 +242,8 @@
             return self._opener
 
     def _create_opener(self):
-        import urllib2
-        return urllib2.build_opener()
+        import urllib.request
+        return urllib.request.build_opener()
 
     def _guess_media_encoding(self, source):
         info = source.byteStream.info()

Modified: python/branches/py3k/Lib/xml/sax/saxutils.py
==============================================================================
--- python/branches/py3k/Lib/xml/sax/saxutils.py	(original)
+++ python/branches/py3k/Lib/xml/sax/saxutils.py	Wed Jun 18 22:49:58 2008
@@ -3,7 +3,7 @@
 convenience of application and driver writers.
 """
 
-import os, urlparse, urllib
+import os, urllib.parse, urllib.request
 from . import handler
 from . import xmlreader
 
@@ -289,8 +289,8 @@
             source.setSystemId(sysidfilename)
             f = open(sysidfilename, "rb")
         else:
-            source.setSystemId(urlparse.urljoin(base, sysid))
-            f = urllib.urlopen(source.getSystemId())
+            source.setSystemId(urllib.parse.urljoin(base, sysid))
+            f = urllib.request.urlopen(source.getSystemId())
 
         source.setByteStream(f)
 

Modified: python/branches/py3k/Lib/xmlrpc/client.py
==============================================================================
--- python/branches/py3k/Lib/xmlrpc/client.py	(original)
+++ python/branches/py3k/Lib/xmlrpc/client.py	Wed Jun 18 22:49:58 2008
@@ -1160,12 +1160,12 @@
         if isinstance(host, tuple):
             host, x509 = host
 
-        import urllib
-        auth, host = urllib.splituser(host)
+        import urllib.parse
+        auth, host = urllib.parse.splituser(host)
 
         if auth:
             import base64
-            auth = base64.encodestring(urllib.unquote(auth))
+            auth = base64.encodestring(urllib.parse.unquote(auth))
             auth = "".join(auth.split()) # get rid of whitespace
             extra_headers = [
                 ("Authorization", "Basic " + auth)
@@ -1321,11 +1321,11 @@
         # establish a "logical" server connection
 
         # get the url
-        import urllib
-        type, uri = urllib.splittype(uri)
+        import urllib.parse
+        type, uri = urllib.parse.splittype(uri)
         if type not in ("http", "https"):
             raise IOError("unsupported XML-RPC protocol")
-        self.__host, self.__handler = urllib.splithost(uri)
+        self.__host, self.__handler = urllib.parse.splithost(uri)
         if not self.__handler:
             self.__handler = "/RPC2"
 

Modified: python/branches/py3k/Makefile.pre.in
==============================================================================
--- python/branches/py3k/Makefile.pre.in	(original)
+++ python/branches/py3k/Makefile.pre.in	Wed Jun 18 22:49:58 2008
@@ -809,7 +809,7 @@
 		email email/mime email/test email/test/data \
 		html json json/tests http dbm xmlrpc \
 		sqlite3 sqlite3/test \
-		logging bsddb bsddb/test csv wsgiref \
+		logging bsddb bsddb/test csv wsgiref urllib \
 		lib2to3 lib2to3/fixes lib2to3/pgen2 lib2to3/tests \
 		ctypes ctypes/test ctypes/macholib idlelib idlelib/Icons \
 		distutils distutils/command distutils/tests $(XMLLIBSUBDIRS) \

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Wed Jun 18 22:49:58 2008
@@ -81,6 +81,15 @@
 Library
 -------
 
+- a new ``urllib`` package was created.  It consists of code from
+  ``urllib``, ``urllib2``, ``urlparse``, and ``robotparser``.  The old
+  modules have all been removed.  The new package has five submodules:
+  ``urllib.parse``, ``urllib.request``, ``urllib.response``,
+  ``urllib.error``, and ``urllib.robotparser``.  The
+  ``urllib.request.urlopen()`` function uses the url opener from
+  ``urllib2``.  (Note that the unittests have not been renamed for the
+  beta, but they will be renamed in the future.)
+
 - rfc822 has been removed in favor of the email package.
 
 - mimetools has been removed in favor of the email package.

From python-3000-checkins at python.org  Thu Jun 19 00:19:22 2008
From: python-3000-checkins at python.org (amaury.forgeotdarc)
Date: Thu, 19 Jun 2008 00:19:22 +0200 (CEST)
Subject: [Python-3000-checkins] r64389 - in python/branches/py3k:
	Lib/http/server.py Misc/NEWS
Message-ID: <20080618221922.747C01E4002@bag.python.org>

Author: amaury.forgeotdarc
Date: Thu Jun 19 00:19:22 2008
New Revision: 64389

Log:
Issue3113: tests for CGIHTTPRequestHandler failed on windows:
replace the now-invalid popen2 with a call to subprocess.Popen.


Modified:
   python/branches/py3k/Lib/http/server.py
   python/branches/py3k/Misc/NEWS

Modified: python/branches/py3k/Lib/http/server.py
==============================================================================
--- python/branches/py3k/Lib/http/server.py	(original)
+++ python/branches/py3k/Lib/http/server.py	Thu Jun 19 00:19:22 2008
@@ -13,9 +13,7 @@
 This class implements GET and POST requests to cgi-bin scripts.
 
 If the os.fork() function is not present (e.g. on Windows),
-os.popen2() is used as a fallback, with slightly altered semantics; if
-that function is not present either (e.g. on Macintosh), only Python
-scripts are supported, and they are executed by the current process.
+subprocess.Popen() is used as a fallback, with slightly altered semantics.
 
 In all cases, the implementation is intentionally naive -- all
 requests are executed synchronously.
@@ -826,8 +824,6 @@
 
     # Determine platform specifics
     have_fork = hasattr(os, 'fork')
-    have_popen2 = hasattr(os, 'popen2')
-    have_popen3 = hasattr(os, 'popen3')
 
     # Make rfile unbuffered -- we need to read one line and then pass
     # the rest to a subprocess, so we can't use buffered input.
@@ -929,10 +925,6 @@
             return
         ispy = self.is_python(scriptname)
         if not ispy:
-            if not (self.have_fork or self.have_popen2 or self.have_popen3):
-                self.send_error(403, "CGI script is not a Python script (%r)" %
-                                scriptname)
-                return
             if not self.is_executable(scriptfile):
                 self.send_error(403, "CGI script is not executable (%r)" %
                                 scriptname)
@@ -1041,13 +1033,9 @@
                 self.server.handle_error(self.request, self.client_address)
                 os._exit(127)
 
-        elif self.have_popen2 or self.have_popen3:
-            # Windows -- use popen2 or popen3 to create a subprocess
-            import shutil
-            if self.have_popen3:
-                popenx = os.popen3
-            else:
-                popenx = os.popen2
+        else:
+            # Non-Unix -- use subprocess
+            import subprocess
             cmdline = scriptfile
             if self.is_python(scriptfile):
                 interp = sys.executable
@@ -1062,54 +1050,26 @@
                 nbytes = int(length)
             except (TypeError, ValueError):
                 nbytes = 0
-            files = popenx(cmdline, 'b')
-            fi = files[0]
-            fo = files[1]
-            if self.have_popen3:
-                fe = files[2]
+            p = subprocess.Popen(cmdline,
+                                 stdin=subprocess.PIPE,
+                                 stdout=subprocess.PIPE,
+                                 stderr=subprocess.PIPE,
+                                 )
             if self.command.lower() == "post" and nbytes > 0:
                 data = self.rfile.read(nbytes)
-                fi.write(data)
+            else:
+                data = None
             # throw away additional data [see bug #427345]
             while select.select([self.rfile._sock], [], [], 0)[0]:
                 if not self.rfile._sock.recv(1):
                     break
-            fi.close()
-            shutil.copyfileobj(fo, self.wfile)
-            if self.have_popen3:
-                errors = fe.read()
-                fe.close()
-                if errors:
-                    self.log_error('%s', errors)
-            sts = fo.close()
-            if sts:
-                self.log_error("CGI script exit status %#x", sts)
-            else:
-                self.log_message("CGI script exited OK")
-
-        else:
-            # Other O.S. -- execute script in this process
-            save_argv = sys.argv
-            save_stdin = sys.stdin
-            save_stdout = sys.stdout
-            save_stderr = sys.stderr
-            try:
-                save_cwd = os.getcwd()
-                try:
-                    sys.argv = [scriptfile]
-                    if '=' not in decoded_query:
-                        sys.argv.append(decoded_query)
-                    sys.stdout = self.wfile
-                    sys.stdin = self.rfile
-                    exec(open(scriptfile).read(), {"__name__": "__main__"})
-                finally:
-                    sys.argv = save_argv
-                    sys.stdin = save_stdin
-                    sys.stdout = save_stdout
-                    sys.stderr = save_stderr
-                    os.chdir(save_cwd)
-            except SystemExit as sts:
-                self.log_error("CGI script exit status %s", str(sts))
+            stdout, stderr = p.communicate(data)
+            self.wfile.write(stdout)
+            if stderr:
+                self.log_error('%s', stderr)
+            status = p.returncode
+            if status:
+                self.log_error("CGI script exit status %#x", status)
             else:
                 self.log_message("CGI script exited OK")
 

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Thu Jun 19 00:19:22 2008
@@ -81,6 +81,8 @@
 Library
 -------
 
+- Patch #3133: http.server.CGIHTTPRequestHandler did not work on windows.
+
 - a new ``urllib`` package was created.  It consists of code from
   ``urllib``, ``urllib2``, ``urlparse``, and ``robotparser``.  The old
   modules have all been removed.  The new package has five submodules:

From python-3000-checkins at python.org  Thu Jun 19 00:38:24 2008
From: python-3000-checkins at python.org (amaury.forgeotdarc)
Date: Thu, 19 Jun 2008 00:38:24 +0200 (CEST)
Subject: [Python-3000-checkins] r64390 - in python/branches/py3k/Lib:
	nturl2path.py urllib/request.py
Message-ID: <20080618223824.800A51E4002@bag.python.org>

Author: amaury.forgeotdarc
Date: Thu Jun 19 00:38:24 2008
New Revision: 64390

Log:
follow-up of r64385: rename urllib.quote in nturl2path
and remove assertions & debugger when ssl is not present


Modified:
   python/branches/py3k/Lib/nturl2path.py
   python/branches/py3k/Lib/urllib/request.py

Modified: python/branches/py3k/Lib/nturl2path.py
==============================================================================
--- python/branches/py3k/Lib/nturl2path.py	(original)
+++ python/branches/py3k/Lib/nturl2path.py	Thu Jun 19 00:38:24 2008
@@ -7,7 +7,7 @@
     # ///C|/foo/bar/spam.foo
     # becomes
     # C:\foo\bar\spam.foo
-    import string, urllib
+    import string, urllib.parse
     # Windows itself uses ":" even in URLs.
     url = url.replace(':', '|')
     if not '|' in url:
@@ -19,7 +19,7 @@
             url = url[2:]
         components = url.split('/')
         # make sure not to convert quoted slashes :-)
-        return urllib.unquote('\\'.join(components))
+        return urllib.parse.unquote('\\'.join(components))
     comp = url.split('|')
     if len(comp) != 2 or comp[0][-1] not in string.ascii_letters:
         error = 'Bad URL: ' + url
@@ -29,7 +29,7 @@
     path = drive + ':'
     for  comp in components:
         if comp:
-            path = path + '\\' + urllib.unquote(comp)
+            path = path + '\\' + urllib.parse.unquote(comp)
     return path
 
 def pathname2url(p):
@@ -39,7 +39,7 @@
     # C:\foo\bar\spam.foo
     # becomes
     # ///C|/foo/bar/spam.foo
-    import urllib
+    import urllib.parse
     if not ':' in p:
         # No drive specifier, just convert slashes and quote the name
         if p[:2] == '\\\\':
@@ -48,16 +48,16 @@
         # (notice doubling of slashes at the start of the path)
             p = '\\\\' + p
         components = p.split('\\')
-        return urllib.quote('/'.join(components))
+        return urllib.parse.quote('/'.join(components))
     comp = p.split(':')
     if len(comp) != 2 or len(comp[0]) > 1:
         error = 'Bad path: ' + p
         raise IOError(error)
 
-    drive = urllib.quote(comp[0].upper())
+    drive = urllib.parse.quote(comp[0].upper())
     components = comp[1].split('\\')
     path = '///' + drive + '|'
     for comp in components:
         if comp:
-            path = path + '/' + urllib.quote(comp)
+            path = path + '/' + urllib.parse.quote(comp)
     return path

Modified: python/branches/py3k/Lib/urllib/request.py
==============================================================================
--- python/branches/py3k/Lib/urllib/request.py	(original)
+++ python/branches/py3k/Lib/urllib/request.py	Thu Jun 19 00:38:24 2008
@@ -105,7 +105,6 @@
     _have_ssl = False
 else:
     _have_ssl = True
-assert _have_ssl
 
 # used in User-Agent header sent
 __version__ = sys.version[:3]
@@ -417,8 +416,6 @@
                        FTPHandler, FileHandler, HTTPErrorProcessor]
     if hasattr(http.client, "HTTPSConnection"):
         default_classes.append(HTTPSHandler)
-    else:
-        import pdb; pdb.set_trace()
     skip = set()
     for klass in default_classes:
         for check in handlers:

From python-3000-checkins at python.org  Thu Jun 19 00:39:26 2008
From: python-3000-checkins at python.org (amaury.forgeotdarc)
Date: Thu, 19 Jun 2008 00:39:26 +0200 (CEST)
Subject: [Python-3000-checkins] r64391 - in python/branches/py3k:
	Tools/buildbot/external-amd64.bat
Message-ID: <20080618223926.432421E4002@bag.python.org>

Author: amaury.forgeotdarc
Date: Thu Jun 19 00:39:25 2008
New Revision: 64391

Log:
Merged revisions 64387 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/trunk

........
  r64387 | amaury.forgeotdarc | 2008-06-18 23:33:58 +0200 (mer., 18 juin 2008) | 2 lines
  
  Typo in a directory name. Should help the AMD64 buildbots
........


Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Tools/buildbot/external-amd64.bat

Modified: python/branches/py3k/Tools/buildbot/external-amd64.bat
==============================================================================
--- python/branches/py3k/Tools/buildbot/external-amd64.bat	(original)
+++ python/branches/py3k/Tools/buildbot/external-amd64.bat	Thu Jun 19 00:39:25 2008
@@ -12,7 +12,7 @@
 )
 
 if not exist tcltk64\bin\tk85g.dll (
-    cd tk-8.5.2.1\win    
+    cd tk-8.5.2.0\win    
     nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 OPTS=noxp DEBUG=1 MACHINE=AMD64 INSTALLDIR=..\..\tcltk64 TCLDIR=..\..\tcl-8.5.2.1 clean
     nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 OPTS=noxp DEBUG=1 MACHINE=AMD64 INSTALLDIR=..\..\tcltk64 TCLDIR=..\..\tcl-8.5.2.1 all
     nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 OPTS=noxp DEBUG=1 MACHINE=AMD64 INSTALLDIR=..\..\tcltk64 TCLDIR=..\..\tcl-8.5.2.1 install

From python-3000-checkins at python.org  Thu Jun 19 01:03:22 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Thu, 19 Jun 2008 01:03:22 +0200 (CEST)
Subject: [Python-3000-checkins] r64393 - python/branches/py3k
Message-ID: <20080618230322.A03CD1E4020@bag.python.org>

Author: benjamin.peterson
Date: Thu Jun 19 01:03:21 2008
New Revision: 64393

Log:
Blocked revisions 64386,64392 via svnmerge

........
  r64386 | amaury.forgeotdarc | 2008-06-18 16:18:27 -0500 (Wed, 18 Jun 2008) | 3 lines
  
  The ssl certificate at https://sf.net is not valid.
  Switch to https://sourceforge.net
........
  r64392 | benjamin.peterson | 2008-06-18 17:59:32 -0500 (Wed, 18 Jun 2008) | 2 lines
  
  Fix test_socket_ssl the easy way and remove it per #1489
........


Modified:
   python/branches/py3k/   (props changed)

From python-3000-checkins at python.org  Thu Jun 19 01:11:29 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Thu, 19 Jun 2008 01:11:29 +0200 (CEST)
Subject: [Python-3000-checkins] r64394 - python/branches/py3k
Message-ID: <20080618231129.F3ABA1E4002@bag.python.org>

Author: benjamin.peterson
Date: Thu Jun 19 01:11:29 2008
New Revision: 64394

Log:
Blocked revisions 64371 via svnmerge

........
  r64371 | georg.brandl | 2008-06-18 04:28:22 -0500 (Wed, 18 Jun 2008) | 2 lines
  
  Add versionadded tags to new math functions.
........


Modified:
   python/branches/py3k/   (props changed)

From jeremy at alum.mit.edu  Thu Jun 19 01:45:09 2008
From: jeremy at alum.mit.edu (Jeremy Hylton)
Date: Wed, 18 Jun 2008 19:45:09 -0400
Subject: [Python-3000-checkins] r64390 - in python/branches/py3k/Lib:
	nturl2path.py urllib/request.py
In-Reply-To: <20080618223824.800A51E4002@bag.python.org>
References: <20080618223824.800A51E4002@bag.python.org>
Message-ID: <e8bf7a530806181645t1e7ec633v9d3bde54c418e218@mail.gmail.com>

Thanks!

Jeremy

On Wed, Jun 18, 2008 at 6:38 PM, amaury.forgeotdarc <
python-3000-checkins at python.org> wrote:

> Author: amaury.forgeotdarc
> Date: Thu Jun 19 00:38:24 2008
> New Revision: 64390
>
> Log:
> follow-up of r64385: rename urllib.quote in nturl2path
> and remove assertions & debugger when ssl is not present
>
>
> Modified:
>   python/branches/py3k/Lib/nturl2path.py
>   python/branches/py3k/Lib/urllib/request.py
>
> Modified: python/branches/py3k/Lib/nturl2path.py
>
> ==============================================================================
> --- python/branches/py3k/Lib/nturl2path.py      (original)
> +++ python/branches/py3k/Lib/nturl2path.py      Thu Jun 19 00:38:24 2008
> @@ -7,7 +7,7 @@
>     # ///C|/foo/bar/spam.foo
>     # becomes
>     # C:\foo\bar\spam.foo
> -    import string, urllib
> +    import string, urllib.parse
>     # Windows itself uses ":" even in URLs.
>     url = url.replace(':', '|')
>     if not '|' in url:
> @@ -19,7 +19,7 @@
>             url = url[2:]
>         components = url.split('/')
>         # make sure not to convert quoted slashes :-)
> -        return urllib.unquote('\\'.join(components))
> +        return urllib.parse.unquote('\\'.join(components))
>     comp = url.split('|')
>     if len(comp) != 2 or comp[0][-1] not in string.ascii_letters:
>         error = 'Bad URL: ' + url
> @@ -29,7 +29,7 @@
>     path = drive + ':'
>     for  comp in components:
>         if comp:
> -            path = path + '\\' + urllib.unquote(comp)
> +            path = path + '\\' + urllib.parse.unquote(comp)
>     return path
>
>  def pathname2url(p):
> @@ -39,7 +39,7 @@
>     # C:\foo\bar\spam.foo
>     # becomes
>     # ///C|/foo/bar/spam.foo
> -    import urllib
> +    import urllib.parse
>     if not ':' in p:
>         # No drive specifier, just convert slashes and quote the name
>         if p[:2] == '\\\\':
> @@ -48,16 +48,16 @@
>         # (notice doubling of slashes at the start of the path)
>             p = '\\\\' + p
>         components = p.split('\\')
> -        return urllib.quote('/'.join(components))
> +        return urllib.parse.quote('/'.join(components))
>     comp = p.split(':')
>     if len(comp) != 2 or len(comp[0]) > 1:
>         error = 'Bad path: ' + p
>         raise IOError(error)
>
> -    drive = urllib.quote(comp[0].upper())
> +    drive = urllib.parse.quote(comp[0].upper())
>     components = comp[1].split('\\')
>     path = '///' + drive + '|'
>     for comp in components:
>         if comp:
> -            path = path + '/' + urllib.quote(comp)
> +            path = path + '/' + urllib.parse.quote(comp)
>     return path
>
> Modified: python/branches/py3k/Lib/urllib/request.py
>
> ==============================================================================
> --- python/branches/py3k/Lib/urllib/request.py  (original)
> +++ python/branches/py3k/Lib/urllib/request.py  Thu Jun 19 00:38:24 2008
> @@ -105,7 +105,6 @@
>     _have_ssl = False
>  else:
>     _have_ssl = True
> -assert _have_ssl
>
>  # used in User-Agent header sent
>  __version__ = sys.version[:3]
> @@ -417,8 +416,6 @@
>                        FTPHandler, FileHandler, HTTPErrorProcessor]
>     if hasattr(http.client, "HTTPSConnection"):
>         default_classes.append(HTTPSHandler)
> -    else:
> -        import pdb; pdb.set_trace()
>     skip = set()
>     for klass in default_classes:
>         for check in handlers:
> _______________________________________________
> Python-3000-checkins mailing list
> Python-3000-checkins at python.org
> http://mail.python.org/mailman/listinfo/python-3000-checkins
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-3000-checkins/attachments/20080618/c7be8844/attachment-0001.htm>

From python-3000-checkins at python.org  Thu Jun 19 02:35:43 2008
From: python-3000-checkins at python.org (barry.warsaw)
Date: Thu, 19 Jun 2008 02:35:43 +0200 (CEST)
Subject: [Python-3000-checkins] r64395 - in python/branches/py3k:
	Include/patchlevel.h Lib/distutils/__init__.py
	Lib/idlelib/idlever.py Misc/NEWS Misc/RPM/python-3.0.spec
	README RELNOTES
Message-ID: <20080619003543.D4F2E1E4002@bag.python.org>

Author: barry.warsaw
Date: Thu Jun 19 02:35:43 2008
New Revision: 64395

Log:
Bump to 3.0b1


Modified:
   python/branches/py3k/Include/patchlevel.h
   python/branches/py3k/Lib/distutils/__init__.py
   python/branches/py3k/Lib/idlelib/idlever.py
   python/branches/py3k/Misc/NEWS
   python/branches/py3k/Misc/RPM/python-3.0.spec
   python/branches/py3k/README
   python/branches/py3k/RELNOTES

Modified: python/branches/py3k/Include/patchlevel.h
==============================================================================
--- python/branches/py3k/Include/patchlevel.h	(original)
+++ python/branches/py3k/Include/patchlevel.h	Thu Jun 19 02:35:43 2008
@@ -19,11 +19,11 @@
 #define PY_MAJOR_VERSION	3
 #define PY_MINOR_VERSION	0
 #define PY_MICRO_VERSION	0
-#define PY_RELEASE_LEVEL	PY_RELEASE_LEVEL_ALPHA
-#define PY_RELEASE_SERIAL	5
+#define PY_RELEASE_LEVEL	PY_RELEASE_LEVEL_BETA
+#define PY_RELEASE_SERIAL	1
 
 /* Version as a string */
-#define PY_VERSION      	"3.0a5+"
+#define PY_VERSION      	"3.0b1"
 /*--end constants--*/
 
 /* Subversion Revision number of this file (not of the repository) */

Modified: python/branches/py3k/Lib/distutils/__init__.py
==============================================================================
--- python/branches/py3k/Lib/distutils/__init__.py	(original)
+++ python/branches/py3k/Lib/distutils/__init__.py	Thu Jun 19 02:35:43 2008
@@ -20,5 +20,5 @@
 #
 
 #--start constants--
-__version__ = "3.0a5"
+__version__ = "3.0b1"
 #--end constants--

Modified: python/branches/py3k/Lib/idlelib/idlever.py
==============================================================================
--- python/branches/py3k/Lib/idlelib/idlever.py	(original)
+++ python/branches/py3k/Lib/idlelib/idlever.py	Thu Jun 19 02:35:43 2008
@@ -1 +1 @@
-IDLE_VERSION = "3.0a5"
+IDLE_VERSION = "3.0b1"

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Thu Jun 19 02:35:43 2008
@@ -7,7 +7,7 @@
 What's new in Python 3.0b1?
 ===========================
 
-*Release date: XX-June-2008*
+*Release date: 18-Jun-2008*
 
 Core and Builtins
 -----------------

Modified: python/branches/py3k/Misc/RPM/python-3.0.spec
==============================================================================
--- python/branches/py3k/Misc/RPM/python-3.0.spec	(original)
+++ python/branches/py3k/Misc/RPM/python-3.0.spec	Thu Jun 19 02:35:43 2008
@@ -34,7 +34,7 @@
 
 %define name python
 #--start constants--
-%define version 3.0a5
+%define version 3.0b1
 %define libver 3.0
 #--end constants--
 %define release 1pydotorg

Modified: python/branches/py3k/README
==============================================================================
--- python/branches/py3k/README	(original)
+++ python/branches/py3k/README	Thu Jun 19 02:35:43 2008
@@ -1,5 +1,5 @@
-This is Python version 3.0 alpha 5
-==================================
+This is Python version 3.0 beta 1
+=================================
 
 For notes specific to this release, see RELNOTES in this directory.
 Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
@@ -22,7 +22,7 @@
 ----------------
 
 The release plan is to have a series of alpha releases in 2007 and 2008,
-beta releases in 2008, and a final release in August 2008.  The alpha
+beta releases in 2008, and a final release in September 2008.  The alpha
 releases are primarily aimed at developers who want a sneak peek at the
 new langauge, especially those folks who plan to port their code to
 Python 3000.  The hope is that by the time of the final release, many

Modified: python/branches/py3k/RELNOTES
==============================================================================
--- python/branches/py3k/RELNOTES	(original)
+++ python/branches/py3k/RELNOTES	Thu Jun 19 02:35:43 2008
@@ -6,6 +6,12 @@
 Please report bugs to http://bugs.python.org/.
 
 
+Version 3.0b1 - Release Date 18-Jun-2008
+----------------------------------------
+
+Please search the bug tracker for critical issues in Python 3.0.
+
+
 Version 3.0a5 - Release Date 08-May-2008
 ----------------------------------------
 

From python-3000-checkins at python.org  Thu Jun 19 03:45:11 2008
From: python-3000-checkins at python.org (barry.warsaw)
Date: Thu, 19 Jun 2008 03:45:11 +0200 (CEST)
Subject: [Python-3000-checkins] r64397 -
	python/branches/py3k/Include/patchlevel.h
Message-ID: <20080619014511.A0E7C1E4004@bag.python.org>

Author: barry.warsaw
Date: Thu Jun 19 03:45:11 2008
New Revision: 64397

Log:
Post 3.0b1 release

Modified:
   python/branches/py3k/Include/patchlevel.h

Modified: python/branches/py3k/Include/patchlevel.h
==============================================================================
--- python/branches/py3k/Include/patchlevel.h	(original)
+++ python/branches/py3k/Include/patchlevel.h	Thu Jun 19 03:45:11 2008
@@ -23,7 +23,7 @@
 #define PY_RELEASE_SERIAL	1
 
 /* Version as a string */
-#define PY_VERSION      	"3.0b1"
+#define PY_VERSION      	"3.0b1+"
 /*--end constants--*/
 
 /* Subversion Revision number of this file (not of the repository) */

From python-3000-checkins at python.org  Thu Jun 19 15:21:49 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Thu, 19 Jun 2008 15:21:49 +0200 (CEST)
Subject: [Python-3000-checkins] r64405 - python/branches/py3k/setup.py
Message-ID: <20080619132149.12C621E4023@bag.python.org>

Author: benjamin.peterson
Date: Thu Jun 19 15:21:48 2008
New Revision: 64405

Log:
_getstalt doesn't need to be built on non-darwin systems #3141

Modified:
   python/branches/py3k/setup.py

Modified: python/branches/py3k/setup.py
==============================================================================
--- python/branches/py3k/setup.py	(original)
+++ python/branches/py3k/setup.py	Thu Jun 19 15:21:48 2008
@@ -1176,8 +1176,6 @@
                        Extension('_gestalt', ['_gestalt.c'],
                        extra_link_args=['-framework', 'Carbon'])
                        )
-        else:
-            missing.append('_gestalt')
 
         self.extensions.extend(exts)
 

From python-3000-checkins at python.org  Thu Jun 19 22:54:33 2008
From: python-3000-checkins at python.org (amaury.forgeotdarc)
Date: Thu, 19 Jun 2008 22:54:33 +0200 (CEST)
Subject: [Python-3000-checkins] r64411 - in python/branches/py3k:
	Lib/pydoc.py Misc/NEWS
Message-ID: <20080619205433.37D4C1E4002@bag.python.org>

Author: amaury.forgeotdarc
Date: Thu Jun 19 22:54:32 2008
New Revision: 64411

Log:
Issue 3145: help("modules xxx") failed when scanning test.badsyntax_pep3120...
now it silently ignores modules it cannot scan or import.


Modified:
   python/branches/py3k/Lib/pydoc.py
   python/branches/py3k/Misc/NEWS

Modified: python/branches/py3k/Lib/pydoc.py
==============================================================================
--- python/branches/py3k/Lib/pydoc.py	(original)
+++ python/branches/py3k/Lib/pydoc.py	Thu Jun 19 22:54:32 2008
@@ -1870,16 +1870,25 @@
             else:
                 loader = importer.find_module(modname)
                 if hasattr(loader,'get_source'):
+                    try:
+                        source = loader.get_source(modname)
+                    except UnicodeDecodeError:
+                        if onerror:
+                            onerror(modname)
+                        continue
                     import io
-                    desc = source_synopsis(
-                        io.StringIO(loader.get_source(modname))
-                    ) or ''
+                    desc = source_synopsis(io.StringIO(source)) or ''
                     if hasattr(loader,'get_filename'):
                         path = loader.get_filename(modname)
                     else:
                         path = None
                 else:
-                    module = loader.load_module(modname)
+                    try:
+                        module = loader.load_module(modname)
+                    except ImportError:
+                        if onerror:
+                            onerror(modname)
+                        continue
                     desc = (module.__doc__ or '').splitlines()[0]
                     path = getattr(module,'__file__',None)
                 name = modname + ' - ' + desc
@@ -1895,10 +1904,12 @@
         if modname[-9:] == '.__init__':
             modname = modname[:-9] + ' (package)'
         print(modname, desc and '- ' + desc)
+    def onerror(modname):
+        pass
     try: import warnings
     except ImportError: pass
     else: warnings.filterwarnings('ignore') # ignore problems during import
-    ModuleScanner().run(callback, key)
+    ModuleScanner().run(callback, key, onerror=onerror)
 
 # --------------------------------------------------- web browser interface
 

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Thu Jun 19 22:54:32 2008
@@ -4,6 +4,21 @@
 
 (editors: check NEWS.help for information about editing NEWS using ReST.)
 
+What's new in Python 3.0b2?
+===========================
+
+*Release date: XX-XXX-2008*
+
+Core and Builtins
+-----------------
+
+Library
+-------
+
+- Issue #3145: help("modules whatever") failed when trying to load the source
+  code of every single module of the standard library, including invalid files
+  used in the test suite.
+
 What's new in Python 3.0b1?
 ===========================
 

From python-3000-checkins at python.org  Fri Jun 20 00:03:50 2008
From: python-3000-checkins at python.org (amaury.forgeotdarc)
Date: Fri, 20 Jun 2008 00:03:50 +0200 (CEST)
Subject: [Python-3000-checkins] r64414 -
	python/branches/py3k/Lib/test/test_multiprocessing.py
Message-ID: <20080619220350.8D48D1E4002@bag.python.org>

Author: amaury.forgeotdarc
Date: Fri Jun 20 00:03:50 2008
New Revision: 64414

Log:
merge error: test.test_support is now test.support


Modified:
   python/branches/py3k/Lib/test/test_multiprocessing.py

Modified: python/branches/py3k/Lib/test/test_multiprocessing.py
==============================================================================
--- python/branches/py3k/Lib/test/test_multiprocessing.py	(original)
+++ python/branches/py3k/Lib/test/test_multiprocessing.py	Fri Jun 20 00:03:50 2008
@@ -1759,7 +1759,7 @@
         try:
             lock = multiprocessing.RLock()
         except OSError:
-            from test.test_support import TestSkipped
+            from test.support import TestSkipped
             raise TestSkipped("OSError raises on RLock creation, see issue 3111!")
 
     if run is None:

From python-3000-checkins at python.org  Fri Jun 20 00:16:54 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Fri, 20 Jun 2008 00:16:54 +0200 (CEST)
Subject: [Python-3000-checkins] r64415 - python/branches/py3k
Message-ID: <20080619221654.6A5AC1E400C@bag.python.org>

Author: benjamin.peterson
Date: Fri Jun 20 00:16:54 2008
New Revision: 64415

Log:
Blocked revisions 64413 via svnmerge

........
  r64413 | benjamin.peterson | 2008-06-19 16:39:06 -0500 (Thu, 19 Jun 2008) | 1 line
  
  skip test_macostools when UCS4 is enabled
........


Modified:
   python/branches/py3k/   (props changed)

From python-3000-checkins at python.org  Fri Jun 20 01:34:35 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Fri, 20 Jun 2008 01:34:35 +0200 (CEST)
Subject: [Python-3000-checkins] r64418 -
	python/branches/py3k/Lib/test/regrtest.py
Message-ID: <20080619233435.04E801E4002@bag.python.org>

Author: benjamin.peterson
Date: Fri Jun 20 01:34:34 2008
New Revision: 64418

Log:
don't bother expecting to skip tests that don't exist

Modified:
   python/branches/py3k/Lib/test/regrtest.py

Modified: python/branches/py3k/Lib/test/regrtest.py
==============================================================================
--- python/branches/py3k/Lib/test/regrtest.py	(original)
+++ python/branches/py3k/Lib/test/regrtest.py	Fri Jun 20 01:34:34 2008
@@ -870,7 +870,6 @@
         test_crypt
         test_curses
         test_dbm
-        test_dl
         test_fcntl
         test_fork1
         test_epoll
@@ -879,7 +878,6 @@
         test_ioctl
         test_largefile
         test_kqueue
-        test_mhlib
         test_openpty
         test_ossaudiodev
         test_pipes
@@ -897,7 +895,6 @@
     'linux2':
         """
         test_curses
-        test_dl
         test_largefile
         test_kqueue
         test_ossaudiodev
@@ -911,7 +908,6 @@
         test_crypt
         test_curses
         test_dbm
-        test_dl
         test_fcntl
         test_fork1
         test_epoll
@@ -936,7 +932,6 @@
     'unixware7':
         """
         test_bsddb
-        test_dl
         test_epoll
         test_largefile
         test_kqueue
@@ -949,7 +944,6 @@
     'openunix8':
         """
         test_bsddb
-        test_dl
         test_epoll
         test_largefile
         test_kqueue
@@ -963,7 +957,6 @@
         """
         test_asynchat
         test_bsddb
-        test_dl
         test_fork1
         test_epoll
         test_gettext
@@ -1012,7 +1005,6 @@
         """
         test_bsddb
         test_curses
-        test_dl
         test_epoll
         test_dbm_gnu
         test_gzip
@@ -1029,7 +1021,6 @@
     'atheos':
         """
         test_curses
-        test_dl
         test_dbm_gnu
         test_epoll
         test_largefile
@@ -1058,11 +1049,9 @@
         test_audioop
         test_bsddb3
         test_curses
-        test_dl
         test_epoll
         test_kqueue
         test_largefile
-        test_mhlib
         test_mmap
         test_openpty
         test_ossaudiodev
@@ -1090,7 +1079,6 @@
         test_bsddb
         test_bsddb3
         test_bz2
-        test_dl
         test_epoll
         test_dbm_gnu
         test_gzip
@@ -1105,7 +1093,6 @@
         test_bsddb
         test_bsddb3
         test_ctypes
-        test_dl
         test_epoll
         test_dbm_gnu
         test_locale
@@ -1120,7 +1107,6 @@
         test_bsddb3
         test_ctypes
         test_curses
-        test_dl
         test_epoll
         test_dbm_gnu
         test_locale
@@ -1164,13 +1150,6 @@
             if test_timeout.skip_expected:
                 self.expected.add('test_timeout')
 
-            if not sys.platform in ("mac", "darwin"):
-                MAC_ONLY = ["test_macostools", "test_aepack",
-                            "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

From python-3000-checkins at python.org  Fri Jun 20 04:54:42 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Fri, 20 Jun 2008 04:54:42 +0200 (CEST)
Subject: [Python-3000-checkins] r64423 - in python/branches/py3k:
	Makefile.pre.in
Message-ID: <20080620025442.7015C1E4002@bag.python.org>

Author: benjamin.peterson
Date: Fri Jun 20 04:54:41 2008
New Revision: 64423

Log:
Merged revisions 64422 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/trunk

........
  r64422 | benjamin.peterson | 2008-06-19 21:47:03 -0500 (Thu, 19 Jun 2008) | 1 line
  
  add multiprocessing to the Makefile
........


Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Makefile.pre.in

Modified: python/branches/py3k/Makefile.pre.in
==============================================================================
--- python/branches/py3k/Makefile.pre.in	(original)
+++ python/branches/py3k/Makefile.pre.in	Fri Jun 20 04:54:41 2008
@@ -814,6 +814,7 @@
 		ctypes ctypes/test ctypes/macholib idlelib idlelib/Icons \
 		distutils distutils/command distutils/tests $(XMLLIBSUBDIRS) \
 		setuptools setuptools/command setuptools/tests setuptools.egg-info \
+		multiprocessing multiprocessing/dummy \
 		curses $(MACHDEPS)
 libinstall:	build_all $(srcdir)/Lib/$(PLATDIR)
 	@for i in $(SCRIPTDIR) $(LIBDEST); \

From python-3000-checkins at python.org  Fri Jun 20 22:35:48 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Fri, 20 Jun 2008 22:35:48 +0200 (CEST)
Subject: [Python-3000-checkins] r64432 - python/branches/py3k
Message-ID: <20080620203549.0502E1E400C@bag.python.org>

Author: benjamin.peterson
Date: Fri Jun 20 22:35:48 2008
New Revision: 64432

Log:
Blocked revisions 64431 via svnmerge

........
  r64431 | benjamin.peterson | 2008-06-20 15:33:33 -0500 (Fri, 20 Jun 2008) | 1 line
  
  rephrase
........


Modified:
   python/branches/py3k/   (props changed)

From python-3000-checkins at python.org  Fri Jun 20 23:03:22 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Fri, 20 Jun 2008 23:03:22 +0200 (CEST)
Subject: [Python-3000-checkins] r64433 -
	python/branches/py3k/Doc/library/pickle.rst
Message-ID: <20080620210322.D55241E4003@bag.python.org>

Author: benjamin.peterson
Date: Fri Jun 20 23:03:22 2008
New Revision: 64433

Log:
remove references of cPickle in the pickle docs (uhh. unlabeled footnotes)

Modified:
   python/branches/py3k/Doc/library/pickle.rst

Modified: python/branches/py3k/Doc/library/pickle.rst
==============================================================================
--- python/branches/py3k/Doc/library/pickle.rst	(original)
+++ python/branches/py3k/Doc/library/pickle.rst	Fri Jun 20 23:03:22 2008
@@ -20,27 +20,15 @@
 "unpickling" is the inverse operation, whereby a byte stream is converted back
 into an object hierarchy.  Pickling (and unpickling) is alternatively known as
 "serialization", "marshalling," [#]_ or "flattening", however, to avoid
-confusion, the terms used here are "pickling" and "unpickling".
-
-This documentation describes both the :mod:`pickle` module and the
-:mod:`cPickle` module.
+confusion, the terms used here are "pickling" and "unpickling"..
 
 
 Relationship to other Python modules
 ------------------------------------
 
-The :mod:`pickle` module has an optimized cousin called the :mod:`cPickle`
-module.  As its name implies, :mod:`cPickle` is written in C, so it can be up to
-1000 times faster than :mod:`pickle`.  However it does not support subclassing
-of the :func:`Pickler` and :func:`Unpickler` classes, because in :mod:`cPickle`
-these are functions, not classes.  Most applications have no need for this
-functionality, and can benefit from the improved performance of :mod:`cPickle`.
-Other than that, the interfaces of the two modules are nearly identical; the
-common interface is described in this manual and differences are pointed out
-where necessary.  In the following discussions, we use the term "pickle" to
-collectively describe the :mod:`pickle` and :mod:`cPickle` modules.
-
-The data streams the two modules produce are guaranteed to be interchangeable.
+The :mod:`pickle` module has an transparent optimizer (:mod:`_pickle`) written
+in C. It is used whenever available. Otherwise the pure Python implementation is
+used.
 
 Python has a more primitive serialization module called :mod:`marshal`, but in
 general :mod:`pickle` should always be the preferred way to serialize Python
@@ -229,7 +217,7 @@
    necessarily limited to) :exc:`AttributeError`, :exc:`EOFError`,
    :exc:`ImportError`, and :exc:`IndexError`.
 
-The :mod:`pickle` module also exports two callables [#]_, :class:`Pickler` and
+The :mod:`pickle` module also exports two callables, :class:`Pickler` and
 :class:`Unpickler`:
 
 
@@ -305,11 +293,6 @@
       ids" that may be referenced in a pickle data stream.  See section
       :ref:`pickle-protocol` below for more details.
 
-      **Note:** the :meth:`noload` method is currently only available on
-      :class:`Unpickler` objects created with the :mod:`cPickle` module.
-      :mod:`pickle` module :class:`Unpickler`\ s do not have the :meth:`noload`
-      method.
-
 
 What can be pickled and unpickled?
 ----------------------------------
@@ -535,7 +518,7 @@
 objects are referenced by a "persistent id", which is just an arbitrary string
 of printable ASCII characters. The resolution of such names is not defined by
 the :mod:`pickle` module; it will delegate this resolution to user defined
-functions on the pickler and unpickler. [#]_
+functions on the pickler and unpickler.
 
 To define external persistent id resolution, you need to set the
 :attr:`persistent_id` attribute of the pickler object and the
@@ -600,15 +583,8 @@
    j = up.load()
    print(j)
 
-In the :mod:`cPickle` module, the unpickler's :attr:`persistent_load` attribute
-can also be set to a Python list, in which case, when the unpickler reaches a
-persistent id, the persistent id string will simply be appended to this list.
-This functionality exists so that a pickle data stream can be "sniffed" for
-object references without actually instantiating all the objects in a pickle.
-[#]_  Setting :attr:`persistent_load` to a list is usually used in conjunction
-with the :meth:`noload` method on the Unpickler.
 
-.. BAW: Both pickle and cPickle support something called inst_persistent_id()
+.. BAW: pickle supports something called inst_persistent_id()
    which appears to give unknown types a second shot at producing a persistent
    id.  Since Jim Fulton can't remember why it was added or what it's for, I'm
    leaving it undocumented.
@@ -625,32 +601,22 @@
 
 By default, unpickling will import any class that it finds in the pickle data.
 You can control exactly what gets unpickled and what gets called by customizing
-your unpickler.  Unfortunately, exactly how you do this is different depending
-on whether you're using :mod:`pickle` or :mod:`cPickle`. [#]_
+your unpickler.
 
-In the :mod:`pickle` module, you need to derive a subclass from
-:class:`Unpickler`, overriding the :meth:`load_global` method.
-:meth:`load_global` should read two lines from the pickle data stream where the
-first line will the name of the module containing the class and the second line
-will be the name of the instance's class.  It then looks up the class, possibly
-importing the module and digging out the attribute, then it appends what it
-finds to the unpickler's stack.  Later on, this class will be assigned to the
-:attr:`__class__` attribute of an empty class, as a way of magically creating an
-instance without calling its class's :meth:`__init__`. Your job (should you
-choose to accept it), would be to have :meth:`load_global` push onto the
-unpickler's stack, a known safe version of any class you deem safe to unpickle.
-It is up to you to produce such a class.  Or you could raise an error if you
-want to disallow all unpickling of instances.  If this sounds like a hack,
-you're right.  Refer to the source code to make this work.
-
-Things are a little cleaner with :mod:`cPickle`, but not by much. To control
-what gets unpickled, you can set the unpickler's :attr:`find_global` attribute
-to a function or ``None``.  If it is ``None`` then any attempts to unpickle
-instances will raise an :exc:`UnpicklingError`.  If it is a function, then it
-should accept a module name and a class name, and return the corresponding class
-object.  It is responsible for looking up the class and performing any necessary
-imports, and it may raise an error to prevent instances of the class from being
-unpickled.
+You need to derive a subclass from :class:`Unpickler`, overriding the
+:meth:`load_global` method.  :meth:`load_global` should read two lines from the
+pickle data stream where the first line will the name of the module containing
+the class and the second line will be the name of the instance's class.  It then
+looks up the class, possibly importing the module and digging out the attribute,
+then it appends what it finds to the unpickler's stack.  Later on, this class
+will be assigned to the :attr:`__class__` attribute of an empty class, as a way
+of magically creating an instance without calling its class's
+:meth:`__init__`. Your job (should you choose to accept it), would be to have
+:meth:`load_global` push onto the unpickler's stack, a known safe version of any
+class you deem safe to unpickle.  It is up to you to produce such a class.  Or
+you could raise an error if you want to disallow all unpickling of instances.
+If this sounds like a hack, you're right.  Refer to the source code to make this
+work.
 
 The moral of the story is that you should be really careful about the source of
 the strings your application unpickles.
@@ -777,48 +743,10 @@
       High-performance serialization of built-in types.
 
 
-:mod:`cPickle` --- A faster :mod:`pickle`
-=========================================
-
-.. module:: cPickle
-   :synopsis: Faster version of pickle, but not subclassable.
-.. moduleauthor:: Jim Fulton <jim at zope.com>
-.. sectionauthor:: Fred L. Drake, Jr. <fdrake at acm.org>
-
-
-.. index:: module: pickle
-
-The :mod:`cPickle` module supports serialization and de-serialization of Python
-objects, providing an interface and functionality nearly identical to the
-:mod:`pickle` module.  There are several differences, the most important being
-performance and subclassability.
-
-First, :mod:`cPickle` can be up to 1000 times faster than :mod:`pickle` because
-the former is implemented in C.  Second, in the :mod:`cPickle` module the
-callables :func:`Pickler` and :func:`Unpickler` are functions, not classes.
-This means that you cannot use them to derive custom pickling and unpickling
-subclasses.  Most applications have no need for this functionality and should
-benefit from the greatly improved performance of the :mod:`cPickle` module.
-
-The pickle data stream produced by :mod:`pickle` and :mod:`cPickle` are
-identical, so it is possible to use :mod:`pickle` and :mod:`cPickle`
-interchangeably with existing pickles. [#]_
-
-There are additional minor differences in API between :mod:`cPickle` and
-:mod:`pickle`, however for most applications, they are interchangeable.  More
-documentation is provided in the :mod:`pickle` module documentation, which
-includes a list of the documented differences.
-
 .. rubric:: Footnotes
 
 .. [#] Don't confuse this with the :mod:`marshal` module
 
-.. [#] In the :mod:`pickle` module these callables are classes, which you could
-   subclass to customize the behavior.  However, in the :mod:`cPickle` module these
-   callables are factory functions and so cannot be subclassed.  One common reason
-   to subclass is to control what objects can actually be unpickled.  See section
-   :ref:`pickle-sub` for more details.
-
 .. [#] *Warning*: this is intended for pickling multiple objects without intervening
    modifications to the objects or their parts.  If you modify an object and then
    pickle it again using the same :class:`Pickler` instance, the object is not
@@ -834,25 +762,3 @@
 
 .. [#] This protocol is also used by the shallow and deep copying operations defined in
    the :mod:`copy` module.
-
-.. [#] The actual mechanism for associating these user defined functions is slightly
-   different for :mod:`pickle` and :mod:`cPickle`.  The description given here
-   works the same for both implementations.  Users of the :mod:`pickle` module
-   could also use subclassing to effect the same results, overriding the
-   :meth:`persistent_id` and :meth:`persistent_load` methods in the derived
-   classes.
-
-.. [#] We'll leave you with the image of Guido and Jim sitting around sniffing pickles
-   in their living rooms.
-
-.. [#] A word of caution: the mechanisms described here use internal attributes and
-   methods, which are subject to change in future versions of Python.  We intend to
-   someday provide a common interface for controlling this behavior, which will
-   work in either :mod:`pickle` or :mod:`cPickle`.
-
-.. [#] Since the pickle data format is actually a tiny stack-oriented programming
-   language, and some freedom is taken in the encodings of certain objects, it is
-   possible that the two modules produce different data streams for the same input
-   objects.  However it is guaranteed that they will always be able to read each
-   other's data streams.
-

From python-3000-checkins at python.org  Sat Jun 21 19:29:41 2008
From: python-3000-checkins at python.org (facundo.batista)
Date: Sat, 21 Jun 2008 19:29:41 +0200 (CEST)
Subject: [Python-3000-checkins] r64444 -
	python/branches/py3k/Doc/library/decimal.rst
Message-ID: <20080621172941.D78B51E4016@bag.python.org>

Author: facundo.batista
Date: Sat Jun 21 19:29:41 2008
New Revision: 64444

Log:

Reviewed and updated the documentation. Fixes #3017.


Modified:
   python/branches/py3k/Doc/library/decimal.rst

Modified: python/branches/py3k/Doc/library/decimal.rst
==============================================================================
--- python/branches/py3k/Doc/library/decimal.rst	(original)
+++ python/branches/py3k/Doc/library/decimal.rst	Sat Jun 21 19:29:41 2008
@@ -135,6 +135,7 @@
 :const:`NaN` which stands for "Not a number", positive and negative
 :const:`Infinity`, and :const:`-0`.
 
+   >>> getcontext().prec = 28
    >>> Decimal(10)
    Decimal('10')
    >>> Decimal('3.14')
@@ -173,7 +174,7 @@
 .. doctest::
    :options: +NORMALIZE_WHITESPACE
 
-   >>> data = map(Decimal, '1.34 1.87 3.45 2.35 1.00 0.03 9.25'.split())
+   >>> data = list(map(Decimal, '1.34 1.87 3.45 2.35 1.00 0.03 9.25'.split()))
    >>> max(data)
    Decimal('9.25')
    >>> min(data)
@@ -201,6 +202,7 @@
 
 And some mathematical functions are also available to Decimal:
 
+   >>> getcontext().prec = 28
    >>> Decimal(2).sqrt()
    Decimal('1.414213562373095048801688724')
    >>> Decimal(1).exp()
@@ -267,7 +269,7 @@
    Decimal('3.14159292')
    >>> getcontext()
    Context(prec=9, rounding=ROUND_HALF_EVEN, Emin=-999999999, Emax=999999999,
-           capitals=1, flags=[Rounded, Inexact], traps=[])
+           capitals=1, flags=[Inexact, Rounded], traps=[])
 
 The *flags* entry shows that the rational approximation to :const:`Pi` was
 rounded (digits beyond the context precision were thrown away) and that the
@@ -414,6 +416,11 @@
       ``x.compare_total_mag(y)`` is equivalent to
       ``x.copy_abs().compare_total(y.copy_abs())``.
 
+   .. method:: conjugate()
+
+      Just returns itself, this method is only to comply with the Decimal
+      Specification.
+
    .. method:: copy_abs()
 
       Return the absolute value of the argument.  This operation is unaffected
@@ -722,13 +729,6 @@
       :const:`Rounded`.  If given, applies *rounding*; otherwise, uses the
       rounding method in either the supplied *context* or the current context.
 
-   .. method:: trim()
-
-      Return the decimal with *insignificant* trailing zeros removed.  Here, a
-      trailing zero is considered insignificant either if it follows the decimal
-      point, or if the exponent of the argument (that is, the last element of
-      the :meth:`as_tuple` representation) is positive.
-
 
 .. _logical_operands_label:
 
@@ -940,6 +940,46 @@
       Return the sum of *x* and *y*.
 
 
+   .. method:: canonical(x)
+
+      Returns the same Decimal object *x*.
+
+
+   .. method:: compare(x, y)
+
+      Compares *x* and *y* numerically.
+
+
+   .. method:: compare_signal(x, y)
+
+      Compares the values of the two operands numerically.
+
+
+   .. method:: compare_total(x, y)
+
+      Compares two operands using their abstract representation.
+
+
+   .. method:: compare_total_mag(x, y)
+
+      Compares two operands using their abstract representation, ignoring sign.
+
+
+   .. method:: copy_abs(x)
+
+      Returns a copy of *x* with the sign set to 0.
+
+
+   .. method:: copy_negate(x)
+
+      Returns a copy of *x* with the sign inverted.
+
+
+   .. method:: copy_sign(x, y)
+
+      Copies the sign from *y* to *x*.
+
+
    .. method:: divide(x, y)
 
       Return *x* divided by *y*.
@@ -955,6 +995,121 @@
       Divides two numbers and returns the integer part of the result.
 
 
+   .. method:: exp(x)
+
+      Returns `e ** x`.
+
+
+   .. method:: fma(x, y, z)
+
+      Returns *x* multiplied by *y*, plus *z*.
+
+
+   .. method:: is_canonical(x)
+
+      Returns True if *x* is canonical; otherwise returns False.
+
+
+   .. method:: is_finite(x)
+
+      Returns True if *x* is finite; otherwise returns False.
+
+
+   .. method:: is_infinite(x)
+
+      Returns True if *x* is infinite; otherwise returns False.
+
+
+   .. method:: is_nan(x)
+
+      Returns True if *x* is a qNaN or sNaN; otherwise returns False.
+
+
+   .. method:: is_normal(x)
+
+      Returns True if *x* is a normal number; otherwise returns False.
+
+
+   .. method:: is_qnan(x)
+
+      Returns True if *x* is a quiet NaN; otherwise returns False.
+
+
+   .. method:: is_signed(x)
+
+      Returns True if *x* is negative; otherwise returns False.
+
+
+   .. method:: is_snan(x)
+
+      Returns True if *x* is a signaling NaN; otherwise returns False.
+
+
+   .. method:: is_subnormal(x)
+
+      Returns True if *x* is subnormal; otherwise returns False.
+
+
+   .. method:: is_zero(x)
+
+      Returns True if *x* is a zero; otherwise returns False.
+
+
+   .. method:: ln(x)
+
+      Returns the natural (base e) logarithm of *x*.
+
+
+   .. method:: log10(x)
+
+      Returns the base 10 logarithm of *x*.
+
+
+   .. method:: logb(x)
+
+       Returns the exponent of the magnitude of the operand's MSD.
+
+
+   .. method:: logical_and(x, y)
+
+      Applies the logical operation `and` between each operand's digits.
+
+
+   .. method:: logical_invert(x)
+
+      Invert all the digits in *x*.
+
+
+   .. method:: logical_or(x, y)
+
+      Applies the logical operation `or` between each operand's digits.
+
+
+   .. method:: logical_xor(x, y)
+
+      Applies the logical operation `xor` between each operand's digits.
+
+
+   .. method:: max(x, y)
+
+      Compares two values numerically and returns the maximum.
+
+
+   .. method:: max_mag(x, y)
+
+      Compares the values numerically with their sign ignored.
+
+
+   .. method:: min(x, y)
+
+      Compares two values numerically and returns the minimum.
+
+
+   .. method:: min_mag(x, y)
+
+      Compares the values numerically with their sign ignored.
+
+
    .. method:: minus(x)
 
       Minus corresponds to the unary prefix minus operator in Python.
@@ -965,6 +1120,31 @@
       Return the product of *x* and *y*.
 
 
+   .. method:: next_minus(x)
+
+      Returns the largest representable number smaller than *x*.
+
+
+   .. method:: next_plus(x)
+
+      Returns the smallest representable number larger than *x*.
+
+
+   .. method:: next_toward(x, y)
+
+      Returns the number closest to *x*, in direction towards *y*.
+
+
+   .. method:: normalize(x)
+
+      Reduces *x* to its simplest form.
+
+
+   .. method:: number_class(x)
+
+      Returns an indication of the class of *x*.
+
+
    .. method:: plus(x)
 
       Plus corresponds to the unary prefix plus operator in Python.  This
@@ -994,6 +1174,17 @@
       that would be obtained by computing ``(x**y) % modulo`` with unbounded
       precision, but is computed more efficiently.  It is always exact.
 
+
+   .. method:: quantize(x, y)
+
+      Returns a value equal to *x* (rounded), having the exponent of *y*.
+
+
+   .. method:: radix()
+
+      Just returns 10, as this is Decimal, :)
+
+
    .. method:: remainder(x, y)
 
       Returns the remainder from integer division.
@@ -1001,10 +1192,52 @@
       The sign of the result, if non-zero, is the same as that of the original
       dividend.
 
+   .. method:: remainder_near(x, y)
+
+      Returns `x - y * n`, where *n* is the integer nearest the exact value 
+      of `x / y` (if the result is `0` then its sign will be the sign of *x*).
+
+
+   .. method:: rotate(x, y)
+
+      Returns a rotated copy of *x*, *y* times.
+
+
+   .. method:: same_quantum(x, y)
+
+      Returns True if the two operands have the same exponent.
+
+
+   .. method:: scaleb (x, y)
+
+      Returns the first operand after adding the second value its exp.
+
+
+   .. method:: shift(x, y)
+
+      Returns a shifted copy of *x*, *y* times.
+
+
+   .. method:: sqrt(x)
+
+      Square root of a non-negative number to context precision.
+
+
    .. method:: subtract(x, y)
 
       Return the difference between *x* and *y*.
 
+
+   .. method:: to_eng_string(x)
+
+      Converts a number to a string, using scientific notation.
+
+
+   .. method:: to_integral_exact(x)
+
+      Rounds to an integer.
+
+
    .. method:: to_sci_string(x)
 
       Converts a number to a string using scientific notation.
@@ -1323,7 +1556,7 @@
        q = Decimal(10) ** -places      # 2 places --> '0.01'
        sign, digits, exp = value.quantize(q).as_tuple()  
        result = []
-       digits = map(str, digits)
+       digits = list(map(str, digits))
        build, next = result.append, digits.pop
        if sign:
            build(trailneg)

From python-3000-checkins at python.org  Sat Jun 21 22:51:10 2008
From: python-3000-checkins at python.org (guido.van.rossum)
Date: Sat, 21 Jun 2008 22:51:10 +0200 (CEST)
Subject: [Python-3000-checkins] r64449 -
	python/branches/py3k/Lib/multiprocessing/dummy
Message-ID: <20080621205110.675041E4011@bag.python.org>

Author: guido.van.rossum
Date: Sat Jun 21 22:51:10 2008
New Revision: 64449

Log:
Ignore .py[co] files here.


Modified:
   python/branches/py3k/Lib/multiprocessing/dummy/   (props changed)

From python-3000-checkins at python.org  Sun Jun 22 13:39:13 2008
From: python-3000-checkins at python.org (raymond.hettinger)
Date: Sun, 22 Jun 2008 13:39:13 +0200 (CEST)
Subject: [Python-3000-checkins] r64451 - in python/branches/py3k:
	Include/floatobject.h Lib/test/test_builtin.py
	Objects/abstract.c Objects/floatobject.c
Message-ID: <20080622113913.97EB31E4005@bag.python.org>

Author: raymond.hettinger
Date: Sun Jun 22 13:39:13 2008
New Revision: 64451

Log:
Merge 64438: hex/oct/bin can show floats exactly.

Modified:
   python/branches/py3k/Include/floatobject.h
   python/branches/py3k/Lib/test/test_builtin.py
   python/branches/py3k/Objects/abstract.c
   python/branches/py3k/Objects/floatobject.c

Modified: python/branches/py3k/Include/floatobject.h
==============================================================================
--- python/branches/py3k/Include/floatobject.h	(original)
+++ python/branches/py3k/Include/floatobject.h	Sun Jun 22 13:39:13 2008
@@ -111,6 +111,8 @@
 					       Py_UNICODE *format_spec,
 					       Py_ssize_t format_spec_len);
 
+PyAPI_FUNC(PyObject *) _float_to_base(PyObject *v, int base);
+
 #ifdef __cplusplus
 }
 #endif

Modified: python/branches/py3k/Lib/test/test_builtin.py
==============================================================================
--- python/branches/py3k/Lib/test/test_builtin.py	(original)
+++ python/branches/py3k/Lib/test/test_builtin.py	Sun Jun 22 13:39:13 2008
@@ -553,6 +553,15 @@
         self.assertEqual(hex(-16), '-0x10')
         self.assertEqual(hex(-16), '-0x10')
         self.assertRaises(TypeError, hex, {})
+        self.assertEqual(hex(3.125), '0x19 * 2.0 ** -3')
+        self.assertEqual(hex(0.0), '0x0 * 2.0 ** 0')
+        for sv in float('nan'), float('inf'), float('-inf'):
+            self.assertEqual(hex(sv), repr(sv))
+        for i in range(100):
+            x = random.expovariate(.05)
+            self.assertEqual(eval(hex(x)), x, (x, hex(x), eval(hex(x))))
+            self.assertEqual(eval(hex(-x)), -x)
+            self.assertEqual(hex(-x), ('-' + hex(x)))
 
     def test_id(self):
         id(None)
@@ -796,6 +805,15 @@
         self.assertEqual(oct(-100), '-0o144')
         self.assertEqual(oct(-100), '-0o144')
         self.assertRaises(TypeError, oct, ())
+        self.assertEqual(oct(3.125), '0o31 * 2.0 ** -3')
+        self.assertEqual(oct(0.0), '0o0 * 2.0 ** 0')
+        for sv in float('nan'), float('inf'), float('-inf'):
+            self.assertEqual(oct(sv), repr(sv))
+        for i in range(100):
+            x = random.expovariate(.05)
+            self.assertEqual(eval(oct(x)), x)
+            self.assertEqual(eval(oct(-x)), -x)
+            self.assertEqual(oct(-x), ('-' + oct(x)))
 
     def write_testfile(self):
         # NB the first 4 lines are also used to test input, below
@@ -1213,6 +1231,15 @@
         self.assertEqual(bin(2**65-1), '0b' + '1' * 65)
         self.assertEqual(bin(-(2**65)), '-0b1' + '0' * 65)
         self.assertEqual(bin(-(2**65-1)), '-0b' + '1' * 65)
+        self.assertEqual(bin(3.125), '0b11001 * 2.0 ** -3')
+        self.assertEqual(bin(0.0), '0b0 * 2.0 ** 0')
+        for sv in float('nan'), float('inf'), float('-inf'):
+            self.assertEqual(bin(sv), repr(sv))
+        for i in range(100):
+            x = random.expovariate(.05)
+            self.assertEqual(eval(bin(x)), x)
+            self.assertEqual(eval(bin(-x)), -x)
+            self.assertEqual(bin(-x), ('-' + bin(x)))
 
 class TestSorted(unittest.TestCase):
 

Modified: python/branches/py3k/Objects/abstract.c
==============================================================================
--- python/branches/py3k/Objects/abstract.c	(original)
+++ python/branches/py3k/Objects/abstract.c	Sun Jun 22 13:39:13 2008
@@ -1451,8 +1451,11 @@
 PyNumber_ToBase(PyObject *n, int base)
 {
 	PyObject *res = NULL;
-	PyObject *index = PyNumber_Index(n);
+	PyObject *index;
 
+	if (PyFloat_Check(n))
+		return _float_to_base(n, base);
+	index = PyNumber_Index(n);
 	if (!index)
 		return NULL;
 	if (PyLong_Check(index))

Modified: python/branches/py3k/Objects/floatobject.c
==============================================================================
--- python/branches/py3k/Objects/floatobject.c	(original)
+++ python/branches/py3k/Objects/floatobject.c	Sun Jun 22 13:39:13 2008
@@ -1113,6 +1113,36 @@
 ">>> (-.25).as_integer_ratio()\n"
 "(-1, 4)");
 
+PyObject *
+_float_to_base(PyObject *v, int base)
+{
+	PyObject *mant, *conv, *result;
+	double x, fr;
+	int i, exp;
+
+	if (!PyFloat_Check(v)) {
+		PyErr_BadInternalCall();
+		return NULL;
+	}
+	CONVERT_TO_DOUBLE(v, x);
+	if (!Py_IS_FINITE(x))
+		return PyObject_Repr(v);
+	fr = frexp(x, &exp);
+	for (i=0; i<300 && fr != floor(fr) ; i++) {
+		fr *= 2.0;
+		exp--;
+	}
+	mant = PyLong_FromDouble(floor(fr));
+	if (mant == NULL)
+		return NULL;
+	conv = PyNumber_ToBase(mant, base);
+	Py_DECREF(mant);
+	if (conv == NULL)
+		return NULL;
+	result = PyUnicode_FromFormat("%U * 2.0 ** %d", conv, exp);
+	Py_DECREF(conv);
+	return result;
+}
 
 static PyObject *
 float_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds);

From python-3000-checkins at python.org  Mon Jun 23 04:31:25 2008
From: python-3000-checkins at python.org (senthil.kumaran)
Date: Mon, 23 Jun 2008 04:31:25 +0200 (CEST)
Subject: [Python-3000-checkins] r64472 - in python/branches/py3k-urllib/Doc:
	library/fileformats.rst library/internet.rst tutorial/stdlib.rst
Message-ID: <20080623023125.06C971E4007@bag.python.org>

Author: senthil.kumaran
Date: Mon Jun 23 04:31:24 2008
New Revision: 64472

Log:
Documentation updates for urllib package. Restructured the documentation of the
urllib,urllib2 -> urllib.request,urllib.error
urlparse -> urllib.parse
RobotParser -> urllib.robotparser

Updated Tutorial References:

TODO: Diveinto other sections in Library Reference for the former urllib,
urllib2 references and update those sections to the new urllib usages.
1) howtos shipped include a urllib2 howto. Needs to be updated, if it is to be
maintained at svn.python.org



Modified:
   python/branches/py3k-urllib/Doc/library/fileformats.rst
   python/branches/py3k-urllib/Doc/library/internet.rst
   python/branches/py3k-urllib/Doc/tutorial/stdlib.rst

Modified: python/branches/py3k-urllib/Doc/library/fileformats.rst
==============================================================================
--- python/branches/py3k-urllib/Doc/library/fileformats.rst	(original)
+++ python/branches/py3k-urllib/Doc/library/fileformats.rst	Mon Jun 23 04:31:24 2008
@@ -13,7 +13,6 @@
 
    csv.rst
    configparser.rst
-   robotparser.rst
    netrc.rst
    xdrlib.rst
    plistlib.rst

Modified: python/branches/py3k-urllib/Doc/library/internet.rst
==============================================================================
--- python/branches/py3k-urllib/Doc/library/internet.rst	(original)
+++ python/branches/py3k-urllib/Doc/library/internet.rst	Mon Jun 23 04:31:24 2008
@@ -24,8 +24,10 @@
    cgi.rst
    cgitb.rst
    wsgiref.rst
-   urllib.rst
-   urllib2.rst
+   urllib.request.rst
+   urllib.robotparser.rst
+   urllib.error.rst
+   urllib.parse.rst
    http.client.rst
    ftplib.rst
    poplib.rst
@@ -35,7 +37,6 @@
    smtpd.rst
    telnetlib.rst
    uuid.rst
-   urlparse.rst
    socketserver.rst
    http.server.rst
    http.cookies.rst

Modified: python/branches/py3k-urllib/Doc/tutorial/stdlib.rst
==============================================================================
--- python/branches/py3k-urllib/Doc/tutorial/stdlib.rst	(original)
+++ python/branches/py3k-urllib/Doc/tutorial/stdlib.rst	Mon Jun 23 04:31:24 2008
@@ -147,11 +147,11 @@
 ===============
 
 There are a number of modules for accessing the internet and processing internet
-protocols. Two of the simplest are :mod:`urllib2` for retrieving data from urls
+protocols. Two of the simplest are :mod:`urllib.request` for retrieving data from urls
 and :mod:`smtplib` for sending mail::
 
-   >>> import urllib2
-   >>> for line in urllib2.urlopen('http://tycho.usno.navy.mil/cgi-bin/timer.pl'):
+   >>> import urllib.request
+   >>> for line in urllib.request.urlopen('http://tycho.usno.navy.mil/cgi-bin/timer.pl'):
    ...     if 'EST' in line or 'EDT' in line:  # look for Eastern Time
    ...         print(line)
 

From python-3000-checkins at python.org  Mon Jun 23 04:33:01 2008
From: python-3000-checkins at python.org (senthil.kumaran)
Date: Mon, 23 Jun 2008 04:33:01 +0200 (CEST)
Subject: [Python-3000-checkins] r64473 - in
	python/branches/py3k-urllib/Doc/library: urllib.error.rst
	urllib.parse.rst urllib.request.rst urllib.robotparser.rst
Message-ID: <20080623023301.D345A1E4007@bag.python.org>

Author: senthil.kumaran
Date: Mon Jun 23 04:33:01 2008
New Revision: 64473

Log:
urllib package documentation.



Added:
   python/branches/py3k-urllib/Doc/library/urllib.error.rst   (contents, props changed)
   python/branches/py3k-urllib/Doc/library/urllib.parse.rst   (contents, props changed)
   python/branches/py3k-urllib/Doc/library/urllib.request.rst   (contents, props changed)
   python/branches/py3k-urllib/Doc/library/urllib.robotparser.rst   (contents, props changed)

Added: python/branches/py3k-urllib/Doc/library/urllib.error.rst
==============================================================================
--- (empty file)
+++ python/branches/py3k-urllib/Doc/library/urllib.error.rst	Mon Jun 23 04:33:01 2008
@@ -0,0 +1,48 @@
+:mod:`urllib.error` --- Exception classes raised by urllib.request
+==================================================================
+
+.. module:: urllib.error
+   :synopsis: Next generation URL opening library.
+.. moduleauthor:: Jeremy Hylton <jhylton at users.sourceforge.net>
+.. sectionauthor:: Senthil Kumaran <orsenthil at gmail.com>
+
+
+The :mod:`urllib.error` module defines exception classes raise by
+urllib.request. The base exception class is URLError, which inherits from
+IOError.
+
+The following exceptions are raised by :mod:`urllib.error` as appropriate:
+
+
+.. exception:: URLError
+
+   The handlers raise this exception (or derived exceptions) when they run into a
+   problem.  It is a subclass of :exc:`IOError`.
+
+   .. attribute:: reason
+
+      The reason for this error.  It can be a message string or another exception
+      instance (:exc:`socket.error` for remote URLs, :exc:`OSError` for local
+      URLs).
+
+
+.. exception:: HTTPError
+
+   Though being an exception (a subclass of :exc:`URLError`), an :exc:`HTTPError`
+   can also function as a non-exceptional file-like return value (the same thing
+   that :func:`urlopen` returns).  This is useful when handling exotic HTTP
+   errors, such as requests for authentication.
+
+   .. attribute:: code
+
+      An HTTP status code as defined in `RFC 2616 <http://www.faqs.org/rfcs/rfc2616.html>`_. 
+      This numeric value corresponds to a value found in the dictionary of
+      codes as found in :attr:`http.server.BaseHTTPRequestHandler.responses`.
+
+.. exception:: ContentTooShortError(msg[, content])
+
+   This exception is raised when the :func:`urlretrieve` function detects that the
+   amount of the downloaded data is less than the  expected amount (given by the
+   *Content-Length* header). The :attr:`content` attribute stores the downloaded
+   (and supposedly truncated) data.
+

Added: python/branches/py3k-urllib/Doc/library/urllib.parse.rst
==============================================================================
--- (empty file)
+++ python/branches/py3k-urllib/Doc/library/urllib.parse.rst	Mon Jun 23 04:33:01 2008
@@ -0,0 +1,301 @@
+:mod:`urllib.parse` --- Parse URLs into components
+==================================================
+
+.. module:: urllib.parse
+   :synopsis: Parse URLs into or assemble them from components.
+
+
+.. index::
+   single: WWW
+   single: World Wide Web
+   single: URL
+   pair: URL; parsing
+   pair: relative; URL
+
+This module defines a standard interface to break Uniform Resource Locator (URL)
+strings up in components (addressing scheme, network location, path etc.), to
+combine the components back into a URL string, and to convert a "relative URL"
+to an absolute URL given a "base URL."
+
+The module has been designed to match the Internet RFC on Relative Uniform
+Resource Locators (and discovered a bug in an earlier draft!). It supports the
+following URL schemes: ``file``, ``ftp``, ``gopher``, ``hdl``, ``http``,
+``https``, ``imap``, ``mailto``, ``mms``, ``news``,  ``nntp``, ``prospero``,
+``rsync``, ``rtsp``, ``rtspu``,  ``sftp``, ``shttp``, ``sip``, ``sips``,
+``snews``, ``svn``,  ``svn+ssh``, ``telnet``, ``wais``.
+
+The :mod:`urllib.parse` module defines the following functions:
+
+
+.. function:: urlparse(urlstring[, default_scheme[, allow_fragments]])
+
+   Parse a URL into six components, returning a 6-tuple.  This corresponds to the
+   general structure of a URL: ``scheme://netloc/path;parameters?query#fragment``.
+   Each tuple item is a string, possibly empty. The components are not broken up in
+   smaller parts (for example, the network location is a single string), and %
+   escapes are not expanded. The delimiters as shown above are not part of the
+   result, except for a leading slash in the *path* component, which is retained if
+   present.  For example:
+
+      >>> from urllib.parse import urlparse
+      >>> o = urlparse('http://www.cwi.nl:80/%7Eguido/Python.html')
+      >>> o   # doctest: +NORMALIZE_WHITESPACE
+      ParseResult(scheme='http', netloc='www.cwi.nl:80', path='/%7Eguido/Python.html',
+                  params='', query='', fragment='')
+      >>> o.scheme
+      'http'
+      >>> o.port
+      80
+      >>> o.geturl()
+      'http://www.cwi.nl:80/%7Eguido/Python.html'
+
+   If the *default_scheme* argument is specified, it gives the default addressing
+   scheme, to be used only if the URL does not specify one.  The default value for
+   this argument is the empty string.
+
+   If the *allow_fragments* argument is false, fragment identifiers are not
+   allowed, even if the URL's addressing scheme normally does support them.  The
+   default value for this argument is :const:`True`.
+
+   The return value is actually an instance of a subclass of :class:`tuple`.  This
+   class has the following additional read-only convenience attributes:
+
+   +------------------+-------+--------------------------+----------------------+
+   | Attribute        | Index | Value                    | Value if not present |
+   +==================+=======+==========================+======================+
+   | :attr:`scheme`   | 0     | URL scheme specifier     | empty string         |
+   +------------------+-------+--------------------------+----------------------+
+   | :attr:`netloc`   | 1     | Network location part    | empty string         |
+   +------------------+-------+--------------------------+----------------------+
+   | :attr:`path`     | 2     | Hierarchical path        | empty string         |
+   +------------------+-------+--------------------------+----------------------+
+   | :attr:`params`   | 3     | Parameters for last path | empty string         |
+   |                  |       | element                  |                      |
+   +------------------+-------+--------------------------+----------------------+
+   | :attr:`query`    | 4     | Query component          | empty string         |
+   +------------------+-------+--------------------------+----------------------+
+   | :attr:`fragment` | 5     | Fragment identifier      | empty string         |
+   +------------------+-------+--------------------------+----------------------+
+   | :attr:`username` |       | User name                | :const:`None`        |
+   +------------------+-------+--------------------------+----------------------+
+   | :attr:`password` |       | Password                 | :const:`None`        |
+   +------------------+-------+--------------------------+----------------------+
+   | :attr:`hostname` |       | Host name (lower case)   | :const:`None`        |
+   +------------------+-------+--------------------------+----------------------+
+   | :attr:`port`     |       | Port number as integer,  | :const:`None`        |
+   |                  |       | if present               |                      |
+   +------------------+-------+--------------------------+----------------------+
+
+   See section :ref:`urlparse-result-object` for more information on the result
+   object.
+
+
+.. function:: urlunparse(parts)
+
+   Construct a URL from a tuple as returned by ``urlparse()``. The *parts* argument
+   can be any six-item iterable. This may result in a slightly different, but
+   equivalent URL, if the URL that was parsed originally had unnecessary delimiters
+   (for example, a ? with an empty query; the RFC states that these are
+   equivalent).
+
+
+.. function:: urlsplit(urlstring[, default_scheme[, allow_fragments]])
+
+   This is similar to :func:`urlparse`, but does not split the params from the URL.
+   This should generally be used instead of :func:`urlparse` if the more recent URL
+   syntax allowing parameters to be applied to each segment of the *path* portion
+   of the URL (see :rfc:`2396`) is wanted.  A separate function is needed to
+   separate the path segments and parameters.  This function returns a 5-tuple:
+   (addressing scheme, network location, path, query, fragment identifier).
+
+   The return value is actually an instance of a subclass of :class:`tuple`.  This
+   class has the following additional read-only convenience attributes:
+
+   +------------------+-------+-------------------------+----------------------+
+   | Attribute        | Index | Value                   | Value if not present |
+   +==================+=======+=========================+======================+
+   | :attr:`scheme`   | 0     | URL scheme specifier    | empty string         |
+   +------------------+-------+-------------------------+----------------------+
+   | :attr:`netloc`   | 1     | Network location part   | empty string         |
+   +------------------+-------+-------------------------+----------------------+
+   | :attr:`path`     | 2     | Hierarchical path       | empty string         |
+   +------------------+-------+-------------------------+----------------------+
+   | :attr:`query`    | 3     | Query component         | empty string         |
+   +------------------+-------+-------------------------+----------------------+
+   | :attr:`fragment` | 4     | Fragment identifier     | empty string         |
+   +------------------+-------+-------------------------+----------------------+
+   | :attr:`username` |       | User name               | :const:`None`        |
+   +------------------+-------+-------------------------+----------------------+
+   | :attr:`password` |       | Password                | :const:`None`        |
+   +------------------+-------+-------------------------+----------------------+
+   | :attr:`hostname` |       | Host name (lower case)  | :const:`None`        |
+   +------------------+-------+-------------------------+----------------------+
+   | :attr:`port`     |       | Port number as integer, | :const:`None`        |
+   |                  |       | if present              |                      |
+   +------------------+-------+-------------------------+----------------------+
+
+   See section :ref:`urlparse-result-object` for more information on the result
+   object.
+
+
+.. function:: urlunsplit(parts)
+
+   Combine the elements of a tuple as returned by :func:`urlsplit` into a complete
+   URL as a string. The *parts* argument can be any five-item iterable. This may
+   result in a slightly different, but equivalent URL, if the URL that was parsed
+   originally had unnecessary delimiters (for example, a ? with an empty query; the
+   RFC states that these are equivalent).
+
+
+.. function:: urljoin(base, url[, allow_fragments])
+
+   Construct a full ("absolute") URL by combining a "base URL" (*base*) with
+   another URL (*url*).  Informally, this uses components of the base URL, in
+   particular the addressing scheme, the network location and (part of) the path,
+   to provide missing components in the relative URL.  For example:
+
+      >>> from urllib.parse import urljoin
+      >>> urljoin('http://www.cwi.nl/%7Eguido/Python.html', 'FAQ.html')
+      'http://www.cwi.nl/%7Eguido/FAQ.html'
+
+   The *allow_fragments* argument has the same meaning and default as for
+   :func:`urlparse`.
+
+   .. note::
+
+      If *url* is an absolute URL (that is, starting with ``//`` or ``scheme://``),
+      the *url*'s host name and/or scheme will be present in the result.  For example:
+
+   .. doctest::
+
+      >>> urljoin('http://www.cwi.nl/%7Eguido/Python.html',
+      ...         '//www.python.org/%7Eguido')
+      'http://www.python.org/%7Eguido'
+
+   If you do not want that behavior, preprocess the *url* with :func:`urlsplit` and
+   :func:`urlunsplit`, removing possible *scheme* and *netloc* parts.
+
+
+.. function:: urldefrag(url)
+
+   If *url* contains a fragment identifier, returns a modified version of *url*
+   with no fragment identifier, and the fragment identifier as a separate string.
+   If there is no fragment identifier in *url*, returns *url* unmodified and an
+   empty string.
+
+.. function:: quote(string[, safe])
+
+   Replace special characters in *string* using the ``%xx`` escape. Letters,
+   digits, and the characters ``'_.-'`` are never quoted. The optional *safe*
+   parameter specifies additional characters that should not be quoted --- its
+   default value is ``'/'``.
+
+   Example: ``quote('/~connolly/')`` yields ``'/%7econnolly/'``.
+
+
+.. function:: quote_plus(string[, safe])
+
+   Like :func:`quote`, but also replaces spaces by plus signs, as required for
+   quoting HTML form values.  Plus signs in the original string are escaped unless
+   they are included in *safe*.  It also does not have *safe* default to ``'/'``.
+
+
+.. function:: unquote(string)
+
+   Replace ``%xx`` escapes by their single-character equivalent.
+
+   Example: ``unquote('/%7Econnolly/')`` yields ``'/~connolly/'``.
+
+
+.. function:: unquote_plus(string)
+
+   Like :func:`unquote`, but also replaces plus signs by spaces, as required for
+   unquoting HTML form values.
+
+
+.. function:: urlencode(query[, doseq])
+
+   Convert a mapping object or a sequence of two-element tuples  to a "url-encoded"
+   string, suitable to pass to :func:`urlopen` above as the optional *data*
+   argument.  This is useful to pass a dictionary of form fields to a ``POST``
+   request.  The resulting string is a series of ``key=value`` pairs separated by
+   ``'&'`` characters, where both *key* and *value* are quoted using
+   :func:`quote_plus` above.  If the optional parameter *doseq* is present and
+   evaluates to true, individual ``key=value`` pairs are generated for each element
+   of the sequence. When a sequence of two-element tuples is used as the *query*
+   argument, the first element of each tuple is a key and the second is a value.
+   The order of parameters in the encoded string will match the order of parameter
+   tuples in the sequence. The :mod:`cgi` module provides the functions
+   :func:`parse_qs` and :func:`parse_qsl` which are used to parse query strings
+   into Python data structures.
+
+
+.. seealso::
+
+   :rfc:`1738` - Uniform Resource Locators (URL)
+      This specifies the formal syntax and semantics of absolute URLs.
+
+   :rfc:`1808` - Relative Uniform Resource Locators
+      This Request For Comments includes the rules for joining an absolute and a
+      relative URL, including a fair number of "Abnormal Examples" which govern the
+      treatment of border cases.
+
+   :rfc:`2396` - Uniform Resource Identifiers (URI): Generic Syntax
+      Document describing the generic syntactic requirements for both Uniform Resource
+      Names (URNs) and Uniform Resource Locators (URLs).
+
+
+.. _urlparse-result-object:
+
+Results of :func:`urlparse` and :func:`urlsplit`
+------------------------------------------------
+
+The result objects from the :func:`urlparse` and :func:`urlsplit` functions are
+subclasses of the :class:`tuple` type.  These subclasses add the attributes
+described in those functions, as well as provide an additional method:
+
+
+.. method:: ParseResult.geturl()
+
+   Return the re-combined version of the original URL as a string. This may differ
+   from the original URL in that the scheme will always be normalized to lower case
+   and empty components may be dropped. Specifically, empty parameters, queries,
+   and fragment identifiers will be removed.
+
+   The result of this method is a fixpoint if passed back through the original
+   parsing function:
+
+      >>> import urllib.parse
+      >>> url = 'HTTP://www.Python.org/doc/#'
+
+      >>> r1 = urllib.parse.urlsplit(url)
+      >>> r1.geturl()
+      'http://www.Python.org/doc/'
+
+      >>> r2 = urllib.parse.urlsplit(r1.geturl())
+      >>> r2.geturl()
+      'http://www.Python.org/doc/'
+
+
+The following classes provide the implementations of the parse results::
+
+
+.. class:: BaseResult
+
+   Base class for the concrete result classes.  This provides most of the attribute
+   definitions.  It does not provide a :meth:`geturl` method.  It is derived from
+   :class:`tuple`, but does not override the :meth:`__init__` or :meth:`__new__`
+   methods.
+
+
+.. class:: ParseResult(scheme, netloc, path, params, query, fragment)
+
+   Concrete class for :func:`urlparse` results.  The :meth:`__new__` method is
+   overridden to support checking that the right number of arguments are passed.
+
+
+.. class:: SplitResult(scheme, netloc, path, query, fragment)
+
+   Concrete class for :func:`urlsplit` results.  The :meth:`__new__` method is
+   overridden to support checking that the right number of arguments are passed.
+

Added: python/branches/py3k-urllib/Doc/library/urllib.request.rst
==============================================================================
--- (empty file)
+++ python/branches/py3k-urllib/Doc/library/urllib.request.rst	Mon Jun 23 04:33:01 2008
@@ -0,0 +1,1194 @@
+:mod:`urllib.request` --- extensible library for opening URLs
+=============================================================
+
+.. module:: urllib.request
+   :synopsis: Next generation URL opening library.
+.. moduleauthor:: Jeremy Hylton <jhylton at users.sourceforge.net>
+.. sectionauthor:: Moshe Zadka <moshez at users.sourceforge.net>
+
+
+The :mod:`urllib.request` module defines functions and classes which help in opening
+URLs (mostly HTTP) in a complex world --- basic and digest authentication,
+redirections, cookies and more.
+
+The :mod:`urllib.request` module defines the following functions:
+
+
+.. function:: urlopen(url[, data][, timeout])
+
+   Open the URL *url*, which can be either a string or a :class:`Request` object.
+
+   *data* may be a string specifying additional data to send to the server, or
+   ``None`` if no such data is needed.  Currently HTTP requests are the only ones
+   that use *data*; the HTTP request will be a POST instead of a GET when the
+   *data* parameter is provided.  *data* should be a buffer in the standard
+   :mimetype:`application/x-www-form-urlencoded` format.  The
+   :func:`urllib.urlencode` function takes a mapping or sequence of 2-tuples and
+   returns a string in this format.
+
+   The optional *timeout* parameter specifies a timeout in seconds for blocking
+   operations like the connection attempt (if not specified, the global default
+   timeout setting will be used).  This actually only works for HTTP, HTTPS,
+   FTP and FTPS connections.
+
+   This function returns a file-like object with two additional methods from
+   the :mod:`urllib.response` module
+
+   * :meth:`geturl` --- return the URL of the resource retrieved, commonly used to
+     determine if a redirect was followed
+
+   * :meth:`info` --- return the meta-information of the page, such as headers, in
+     the form of an ``http.client.HTTPMessage`` instance
+     (see `Quick Reference to HTTP Headers <http://www.cs.tut.fi/~jkorpela/http.html>`_)
+
+   Raises :exc:`URLError` on errors.
+
+   Note that ``None`` may be returned if no handler handles the request (though the
+   default installed global :class:`OpenerDirector` uses :class:`UnknownHandler` to
+   ensure this never happens).
+   The urlopen function from the previous version, Python 2.6 and earlier,  of
+   the module  urllib has been discontinued as urlopen can return the
+   file-object as the previous. The proxy handling, which in earlier was passed
+   as a dict parameter to urlopen can be availed by the use of `ProxyHandler`
+   objects.
+
+
+.. function:: install_opener(opener)
+
+   Install an :class:`OpenerDirector` instance as the default global opener.
+   Installing an opener is only necessary if you want urlopen to use that opener;
+   otherwise, simply call :meth:`OpenerDirector.open` instead of :func:`urlopen`.
+   The code does not check for a real :class:`OpenerDirector`, and any class with
+   the appropriate interface will work.
+
+
+.. function:: build_opener([handler, ...])
+
+   Return an :class:`OpenerDirector` instance, which chains the handlers in the
+   order given. *handler*\s can be either instances of :class:`BaseHandler`, or
+   subclasses of :class:`BaseHandler` (in which case it must be possible to call
+   the constructor without any parameters).  Instances of the following classes
+   will be in front of the *handler*\s, unless the *handler*\s contain them,
+   instances of them or subclasses of them: :class:`ProxyHandler`,
+   :class:`UnknownHandler`, :class:`HTTPHandler`, :class:`HTTPDefaultErrorHandler`,
+   :class:`HTTPRedirectHandler`, :class:`FTPHandler`, :class:`FileHandler`,
+   :class:`HTTPErrorProcessor`.
+
+   If the Python installation has SSL support (i.e., if the :mod:`ssl` module can be imported),
+   :class:`HTTPSHandler` will also be added.
+
+   A :class:`BaseHandler` subclass may also change its :attr:`handler_order`
+   member variable to modify its position in the handlers list.
+
+.. function:: urlretrieve(url[, filename[, reporthook[, data]]])
+
+   Copy a network object denoted by a URL to a local file, if necessary. If the URL
+   points to a local file, or a valid cached copy of the object exists, the object
+   is not copied.  Return a tuple ``(filename, headers)`` where *filename* is the
+   local file name under which the object can be found, and *headers* is whatever
+   the :meth:`info` method of the object returned by :func:`urlopen` returned (for
+   a remote object, possibly cached). Exceptions are the same as for
+   :func:`urlopen`.
+
+   The second argument, if present, specifies the file location to copy to (if
+   absent, the location will be a tempfile with a generated name). The third
+   argument, if present, is a hook function that will be called once on
+   establishment of the network connection and once after each block read
+   thereafter.  The hook will be passed three arguments; a count of blocks
+   transferred so far, a block size in bytes, and the total size of the file.  The
+   third argument may be ``-1`` on older FTP servers which do not return a file
+   size in response to a retrieval request.
+
+   If the *url* uses the :file:`http:` scheme identifier, the optional *data*
+   argument may be given to specify a ``POST`` request (normally the request type
+   is ``GET``).  The *data* argument must in standard
+   :mimetype:`application/x-www-form-urlencoded` format; see the :func:`urlencode`
+   function below.
+
+   :func:`urlretrieve` will raise :exc:`ContentTooShortError` when it detects that
+   the amount of data available  was less than the expected amount (which is the
+   size reported by a  *Content-Length* header). This can occur, for example, when
+   the  download is interrupted.
+
+   The *Content-Length* is treated as a lower bound: if there's more data  to read,
+   urlretrieve reads more data, but if less data is available,  it raises the
+   exception.
+
+   You can still retrieve the downloaded data in this case, it is stored  in the
+   :attr:`content` attribute of the exception instance.
+
+   If no *Content-Length* header was supplied, urlretrieve can not check the size
+   of the data it has downloaded, and just returns it.  In this case you just have
+   to assume that the download was successful.
+
+
+.. data:: _urlopener
+
+   The public functions :func:`urlopen` and :func:`urlretrieve` create an instance
+   of the :class:`FancyURLopener` class and use it to perform their requested
+   actions.  To override this functionality, programmers can create a subclass of
+   :class:`URLopener` or :class:`FancyURLopener`, then assign an instance of that
+   class to the ``urllib._urlopener`` variable before calling the desired function.
+   For example, applications may want to specify a different
+   :mailheader:`User-Agent` header than :class:`URLopener` defines.  This can be
+   accomplished with the following code::
+
+      import urllib.request
+
+      class AppURLopener(urllib.request.FancyURLopener):
+          version = "App/1.7"
+
+      urllib._urlopener = AppURLopener()
+
+
+.. function:: urlcleanup()
+
+   Clear the cache that may have been built up by previous calls to
+   :func:`urlretrieve`.
+
+.. function:: pathname2url(path)
+
+   Convert the pathname *path* from the local syntax for a path to the form used in
+   the path component of a URL.  This does not produce a complete URL.  The return
+   value will already be quoted using the :func:`quote` function.
+
+
+.. function:: url2pathname(path)
+
+   Convert the path component *path* from an encoded URL to the local syntax for a
+   path.  This does not accept a complete URL.  This function uses :func:`unquote`
+   to decode *path*.
+
+The following classes are provided:
+
+.. class:: Request(url[, data][, headers][, origin_req_host][, unverifiable])
+
+   This class is an abstraction of a URL request.
+
+   *url* should be a string containing a valid URL.
+
+   *data* may be a string specifying additional data to send to the server, or
+   ``None`` if no such data is needed.  Currently HTTP requests are the only ones
+   that use *data*; the HTTP request will be a POST instead of a GET when the
+   *data* parameter is provided.  *data* should be a buffer in the standard
+   :mimetype:`application/x-www-form-urlencoded` format.  The
+   :func:`urllib.urlencode` function takes a mapping or sequence of 2-tuples and
+   returns a string in this format.
+
+   *headers* should be a dictionary, and will be treated as if :meth:`add_header`
+   was called with each key and value as arguments.  This is often used to "spoof"
+   the ``User-Agent`` header, which is used by a browser to identify itself --
+   some HTTP servers only allow requests coming from common browsers as opposed
+   to scripts.  For example, Mozilla Firefox may identify itself as ``"Mozilla/5.0
+   (X11; U; Linux i686) Gecko/20071127 Firefox/2.0.0.11"``, while :mod:`urllib2`'s
+   default user agent string is ``"Python-urllib/2.6"`` (on Python 2.6).
+
+   The final two arguments are only of interest for correct handling of third-party
+   HTTP cookies:
+
+   *origin_req_host* should be the request-host of the origin transaction, as
+   defined by :rfc:`2965`.  It defaults to ``http.cookiejar.request_host(self)``.
+   This is the host name or IP address of the original request that was
+   initiated by the user.  For example, if the request is for an image in an
+   HTML document, this should be the request-host of the request for the page
+   containing the image.
+
+   *unverifiable* should indicate whether the request is unverifiable, as defined
+   by RFC 2965.  It defaults to False.  An unverifiable request is one whose URL
+   the user did not have the option to approve.  For example, if the request is for
+   an image in an HTML document, and the user had no option to approve the
+   automatic fetching of the image, this should be true.
+
+.. class:: URLopener([proxies[, **x509]])
+
+   Base class for opening and reading URLs.  Unless you need to support opening
+   objects using schemes other than :file:`http:`, :file:`ftp:`, or :file:`file:`,
+   you probably want to use :class:`FancyURLopener`.
+
+   By default, the :class:`URLopener` class sends a :mailheader:`User-Agent` header
+   of ``urllib/VVV``, where *VVV* is the :mod:`urllib` version number.
+   Applications can define their own :mailheader:`User-Agent` header by subclassing
+   :class:`URLopener` or :class:`FancyURLopener` and setting the class attribute
+   :attr:`version` to an appropriate string value in the subclass definition.
+
+   The optional *proxies* parameter should be a dictionary mapping scheme names to
+   proxy URLs, where an empty dictionary turns proxies off completely.  Its default
+   value is ``None``, in which case environmental proxy settings will be used if
+   present, as discussed in the definition of :func:`urlopen`, above.
+
+   Additional keyword parameters, collected in *x509*, may be used for
+   authentication of the client when using the :file:`https:` scheme.  The keywords
+   *key_file* and *cert_file* are supported to provide an  SSL key and certificate;
+   both are needed to support client authentication.
+
+   :class:`URLopener` objects will raise an :exc:`IOError` exception if the server
+   returns an error code.
+
+    .. method:: open(fullurl[, data])
+
+       Open *fullurl* using the appropriate protocol.  This method sets up cache and
+       proxy information, then calls the appropriate open method with its input
+       arguments.  If the scheme is not recognized, :meth:`open_unknown` is called.
+       The *data* argument has the same meaning as the *data* argument of
+       :func:`urlopen`.
+
+
+    .. method:: open_unknown(fullurl[, data])
+
+       Overridable interface to open unknown URL types.
+
+
+    .. method:: retrieve(url[, filename[, reporthook[, data]]])
+
+       Retrieves the contents of *url* and places it in *filename*.  The return value
+       is a tuple consisting of a local filename and either a
+       :class:`email.message.Message` object containing the response headers (for remote
+       URLs) or ``None`` (for local URLs).  The caller must then open and read the
+       contents of *filename*.  If *filename* is not given and the URL refers to a
+       local file, the input filename is returned.  If the URL is non-local and
+       *filename* is not given, the filename is the output of :func:`tempfile.mktemp`
+       with a suffix that matches the suffix of the last path component of the input
+       URL.  If *reporthook* is given, it must be a function accepting three numeric
+       parameters.  It will be called after each chunk of data is read from the
+       network.  *reporthook* is ignored for local URLs.
+
+       If the *url* uses the :file:`http:` scheme identifier, the optional *data*
+       argument may be given to specify a ``POST`` request (normally the request type
+       is ``GET``).  The *data* argument must in standard
+       :mimetype:`application/x-www-form-urlencoded` format; see the :func:`urlencode`
+       function below.
+
+
+    .. attribute:: version
+
+       Variable that specifies the user agent of the opener object.  To get
+       :mod:`urllib` to tell servers that it is a particular user agent, set this in a
+       subclass as a class variable or in the constructor before calling the base
+       constructor.
+
+
+.. class:: FancyURLopener(...)
+
+   :class:`FancyURLopener` subclasses :class:`URLopener` providing default handling
+   for the following HTTP response codes: 301, 302, 303, 307 and 401.  For the 30x
+   response codes listed above, the :mailheader:`Location` header is used to fetch
+   the actual URL.  For 401 response codes (authentication required), basic HTTP
+   authentication is performed.  For the 30x response codes, recursion is bounded
+   by the value of the *maxtries* attribute, which defaults to 10.
+
+   For all other response codes, the method :meth:`http_error_default` is called
+   which you can override in subclasses to handle the error appropriately.
+
+   .. note::
+
+      According to the letter of :rfc:`2616`, 301 and 302 responses to POST requests
+      must not be automatically redirected without confirmation by the user.  In
+      reality, browsers do allow automatic redirection of these responses, changing
+      the POST to a GET, and :mod:`urllib` reproduces this behaviour.
+
+   The parameters to the constructor are the same as those for :class:`URLopener`.
+
+   .. note::
+
+      When performing basic authentication, a :class:`FancyURLopener` instance calls
+      its :meth:`prompt_user_passwd` method.  The default implementation asks the
+      users for the required information on the controlling terminal.  A subclass may
+      override this method to support more appropriate behavior if needed.
+
+    The :class:`FancyURLopener` class offers one additional method that should be
+    overloaded to provide the appropriate behavior:
+
+    .. method:: prompt_user_passwd(host, realm)
+
+       Return information needed to authenticate the user at the given host in the
+       specified security realm.  The return value should be a tuple, ``(user,
+       password)``, which can be used for basic authentication.
+
+       The implementation prompts for this information on the terminal; an application
+       should override this method to use an appropriate interaction model in the local
+       environment.
+
+.. class:: OpenerDirector()
+
+   The :class:`OpenerDirector` class opens URLs via :class:`BaseHandler`\ s chained
+   together. It manages the chaining of handlers, and recovery from errors.
+
+
+.. class:: BaseHandler()
+
+   This is the base class for all registered handlers --- and handles only the
+   simple mechanics of registration.
+
+
+.. class:: HTTPDefaultErrorHandler()
+
+   A class which defines a default handler for HTTP error responses; all responses
+   are turned into :exc:`HTTPError` exceptions.
+
+
+.. class:: HTTPRedirectHandler()
+
+   A class to handle redirections.
+
+
+.. class:: HTTPCookieProcessor([cookiejar])
+
+   A class to handle HTTP Cookies.
+
+
+.. class:: ProxyHandler([proxies])
+
+   Cause requests to go through a proxy. If *proxies* is given, it must be a
+   dictionary mapping protocol names to URLs of proxies. The default is to read the
+   list of proxies from the environment variables :envvar:`<protocol>_proxy`.
+   To disable autodetected proxy pass an empty dictionary.
+
+
+.. class:: HTTPPasswordMgr()
+
+   Keep a database of  ``(realm, uri) -> (user, password)`` mappings.
+
+
+.. class:: HTTPPasswordMgrWithDefaultRealm()
+
+   Keep a database of  ``(realm, uri) -> (user, password)`` mappings. A realm of
+   ``None`` is considered a catch-all realm, which is searched if no other realm
+   fits.
+
+
+.. class:: AbstractBasicAuthHandler([password_mgr])
+
+   This is a mixin class that helps with HTTP authentication, both to the remote
+   host and to a proxy. *password_mgr*, if given, should be something that is
+   compatible with :class:`HTTPPasswordMgr`; refer to section
+   :ref:`http-password-mgr` for information on the interface that must be
+   supported.
+
+
+.. class:: HTTPBasicAuthHandler([password_mgr])
+
+   Handle authentication with the remote host. *password_mgr*, if given, should be
+   something that is compatible with :class:`HTTPPasswordMgr`; refer to section
+   :ref:`http-password-mgr` for information on the interface that must be
+   supported.
+
+
+.. class:: ProxyBasicAuthHandler([password_mgr])
+
+   Handle authentication with the proxy. *password_mgr*, if given, should be
+   something that is compatible with :class:`HTTPPasswordMgr`; refer to section
+   :ref:`http-password-mgr` for information on the interface that must be
+   supported.
+
+
+.. class:: AbstractDigestAuthHandler([password_mgr])
+
+   This is a mixin class that helps with HTTP authentication, both to the remote
+   host and to a proxy. *password_mgr*, if given, should be something that is
+   compatible with :class:`HTTPPasswordMgr`; refer to section
+   :ref:`http-password-mgr` for information on the interface that must be
+   supported.
+
+
+.. class:: HTTPDigestAuthHandler([password_mgr])
+
+   Handle authentication with the remote host. *password_mgr*, if given, should be
+   something that is compatible with :class:`HTTPPasswordMgr`; refer to section
+   :ref:`http-password-mgr` for information on the interface that must be
+   supported.
+
+
+.. class:: ProxyDigestAuthHandler([password_mgr])
+
+   Handle authentication with the proxy. *password_mgr*, if given, should be
+   something that is compatible with :class:`HTTPPasswordMgr`; refer to section
+   :ref:`http-password-mgr` for information on the interface that must be
+   supported.
+
+
+.. class:: HTTPHandler()
+
+   A class to handle opening of HTTP URLs.
+
+
+.. class:: HTTPSHandler()
+
+   A class to handle opening of HTTPS URLs.
+
+
+.. class:: FileHandler()
+
+   Open local files.
+
+
+.. class:: FTPHandler()
+
+   Open FTP URLs.
+
+
+.. class:: CacheFTPHandler()
+
+   Open FTP URLs, keeping a cache of open FTP connections to minimize delays.
+
+
+.. class:: UnknownHandler()
+
+   A catch-all class to handle unknown URLs.
+
+
+.. _request-objects:
+
+Request Objects
+---------------
+
+The following methods describe all of :class:`Request`'s public interface, and
+so all must be overridden in subclasses.
+
+
+.. method:: Request.add_data(data)
+
+   Set the :class:`Request` data to *data*.  This is ignored by all handlers except
+   HTTP handlers --- and there it should be a byte string, and will change the
+   request to be ``POST`` rather than ``GET``.
+
+
+.. method:: Request.get_method()
+
+   Return a string indicating the HTTP request method.  This is only meaningful for
+   HTTP requests, and currently always returns ``'GET'`` or ``'POST'``.
+
+
+.. method:: Request.has_data()
+
+   Return whether the instance has a non-\ ``None`` data.
+
+
+.. method:: Request.get_data()
+
+   Return the instance's data.
+
+
+.. method:: Request.add_header(key, val)
+
+   Add another header to the request.  Headers are currently ignored by all
+   handlers except HTTP handlers, where they are added to the list of headers sent
+   to the server.  Note that there cannot be more than one header with the same
+   name, and later calls will overwrite previous calls in case the *key* collides.
+   Currently, this is no loss of HTTP functionality, since all headers which have
+   meaning when used more than once have a (header-specific) way of gaining the
+   same functionality using only one header.
+
+
+.. method:: Request.add_unredirected_header(key, header)
+
+   Add a header that will not be added to a redirected request.
+
+
+.. method:: Request.has_header(header)
+
+   Return whether the instance has the named header (checks both regular and
+   unredirected).
+
+
+.. method:: Request.get_full_url()
+
+   Return the URL given in the constructor.
+
+
+.. method:: Request.get_type()
+
+   Return the type of the URL --- also known as the scheme.
+
+
+.. method:: Request.get_host()
+
+   Return the host to which a connection will be made.
+
+
+.. method:: Request.get_selector()
+
+   Return the selector --- the part of the URL that is sent to the server.
+
+
+.. method:: Request.set_proxy(host, type)
+
+   Prepare the request by connecting to a proxy server. The *host* and *type* will
+   replace those of the instance, and the instance's selector will be the original
+   URL given in the constructor.
+
+
+.. method:: Request.get_origin_req_host()
+
+   Return the request-host of the origin transaction, as defined by :rfc:`2965`.
+   See the documentation for the :class:`Request` constructor.
+
+
+.. method:: Request.is_unverifiable()
+
+   Return whether the request is unverifiable, as defined by RFC 2965. See the
+   documentation for the :class:`Request` constructor.
+
+
+.. _opener-director-objects:
+
+OpenerDirector Objects
+----------------------
+
+:class:`OpenerDirector` instances have the following methods:
+
+
+.. method:: OpenerDirector.add_handler(handler)
+
+   *handler* should be an instance of :class:`BaseHandler`.  The following methods
+   are searched, and added to the possible chains (note that HTTP errors are a
+   special case).
+
+   * :meth:`protocol_open` --- signal that the handler knows how to open *protocol*
+     URLs.
+
+   * :meth:`http_error_type` --- signal that the handler knows how to handle HTTP
+     errors with HTTP error code *type*.
+
+   * :meth:`protocol_error` --- signal that the handler knows how to handle errors
+     from (non-\ ``http``) *protocol*.
+
+   * :meth:`protocol_request` --- signal that the handler knows how to pre-process
+     *protocol* requests.
+
+   * :meth:`protocol_response` --- signal that the handler knows how to
+     post-process *protocol* responses.
+
+
+.. method:: OpenerDirector.open(url[, data][, timeout])
+
+   Open the given *url* (which can be a request object or a string), optionally
+   passing the given *data*. Arguments, return values and exceptions raised are
+   the same as those of :func:`urlopen` (which simply calls the :meth:`open`
+   method on the currently installed global :class:`OpenerDirector`).  The
+   optional *timeout* parameter specifies a timeout in seconds for blocking
+   operations like the connection attempt (if not specified, the global default
+   timeout setting will be usedi). The timeout feature actually works only for
+   HTTP, HTTPS, FTP and FTPS connections).
+
+
+.. method:: OpenerDirector.error(proto[, arg[, ...]])
+
+   Handle an error of the given protocol.  This will call the registered error
+   handlers for the given protocol with the given arguments (which are protocol
+   specific).  The HTTP protocol is a special case which uses the HTTP response
+   code to determine the specific error handler; refer to the :meth:`http_error_\*`
+   methods of the handler classes.
+
+   Return values and exceptions raised are the same as those of :func:`urlopen`.
+
+OpenerDirector objects open URLs in three stages:
+
+The order in which these methods are called within each stage is determined by
+sorting the handler instances.
+
+#. Every handler with a method named like :meth:`protocol_request` has that
+   method called to pre-process the request.
+
+#. Handlers with a method named like :meth:`protocol_open` are called to handle
+   the request. This stage ends when a handler either returns a non-\ :const:`None`
+   value (ie. a response), or raises an exception (usually :exc:`URLError`).
+   Exceptions are allowed to propagate.
+
+   In fact, the above algorithm is first tried for methods named
+   :meth:`default_open`.  If all such methods return :const:`None`, the algorithm
+   is repeated for methods named like :meth:`protocol_open`.  If all such methods
+   return :const:`None`, the algorithm is repeated for methods named
+   :meth:`unknown_open`.
+
+   Note that the implementation of these methods may involve calls of the parent
+   :class:`OpenerDirector` instance's :meth:`.open` and :meth:`.error` methods.
+
+#. Every handler with a method named like :meth:`protocol_response` has that
+   method called to post-process the response.
+
+
+.. _base-handler-objects:
+
+BaseHandler Objects
+-------------------
+
+:class:`BaseHandler` objects provide a couple of methods that are directly
+useful, and others that are meant to be used by derived classes.  These are
+intended for direct use:
+
+
+.. method:: BaseHandler.add_parent(director)
+
+   Add a director as parent.
+
+
+.. method:: BaseHandler.close()
+
+   Remove any parents.
+
+The following members and methods should only be used by classes derived from
+:class:`BaseHandler`.
+
+.. note::
+
+   The convention has been adopted that subclasses defining
+   :meth:`protocol_request` or :meth:`protocol_response` methods are named
+   :class:`\*Processor`; all others are named :class:`\*Handler`.
+
+
+.. attribute:: BaseHandler.parent
+
+   A valid :class:`OpenerDirector`, which can be used to open using a different
+   protocol, or handle errors.
+
+
+.. method:: BaseHandler.default_open(req)
+
+   This method is *not* defined in :class:`BaseHandler`, but subclasses should
+   define it if they want to catch all URLs.
+
+   This method, if implemented, will be called by the parent
+   :class:`OpenerDirector`.  It should return a file-like object as described in
+   the return value of the :meth:`open` of :class:`OpenerDirector`, or ``None``.
+   It should raise :exc:`URLError`, unless a truly exceptional thing happens (for
+   example, :exc:`MemoryError` should not be mapped to :exc:`URLError`).
+
+   This method will be called before any protocol-specific open method.
+
+
+.. method:: BaseHandler.protocol_open(req)
+   :noindex:
+
+   This method is *not* defined in :class:`BaseHandler`, but subclasses should
+   define it if they want to handle URLs with the given protocol.
+
+   This method, if defined, will be called by the parent :class:`OpenerDirector`.
+   Return values should be the same as for  :meth:`default_open`.
+
+
+.. method:: BaseHandler.unknown_open(req)
+
+   This method is *not* defined in :class:`BaseHandler`, but subclasses should
+   define it if they want to catch all URLs with no specific registered handler to
+   open it.
+
+   This method, if implemented, will be called by the :attr:`parent`
+   :class:`OpenerDirector`.  Return values should be the same as for
+   :meth:`default_open`.
+
+
+.. method:: BaseHandler.http_error_default(req, fp, code, msg, hdrs)
+
+   This method is *not* defined in :class:`BaseHandler`, but subclasses should
+   override it if they intend to provide a catch-all for otherwise unhandled HTTP
+   errors.  It will be called automatically by the  :class:`OpenerDirector` getting
+   the error, and should not normally be called in other circumstances.
+
+   *req* will be a :class:`Request` object, *fp* will be a file-like object with
+   the HTTP error body, *code* will be the three-digit code of the error, *msg*
+   will be the user-visible explanation of the code and *hdrs* will be a mapping
+   object with the headers of the error.
+
+   Return values and exceptions raised should be the same as those of
+   :func:`urlopen`.
+
+
+.. method:: BaseHandler.http_error_nnn(req, fp, code, msg, hdrs)
+
+   *nnn* should be a three-digit HTTP error code.  This method is also not defined
+   in :class:`BaseHandler`, but will be called, if it exists, on an instance of a
+   subclass, when an HTTP error with code *nnn* occurs.
+
+   Subclasses should override this method to handle specific HTTP errors.
+
+   Arguments, return values and exceptions raised should be the same as for
+   :meth:`http_error_default`.
+
+
+.. method:: BaseHandler.protocol_request(req)
+   :noindex:
+
+   This method is *not* defined in :class:`BaseHandler`, but subclasses should
+   define it if they want to pre-process requests of the given protocol.
+
+   This method, if defined, will be called by the parent :class:`OpenerDirector`.
+   *req* will be a :class:`Request` object. The return value should be a
+   :class:`Request` object.
+
+
+.. method:: BaseHandler.protocol_response(req, response)
+   :noindex:
+
+   This method is *not* defined in :class:`BaseHandler`, but subclasses should
+   define it if they want to post-process responses of the given protocol.
+
+   This method, if defined, will be called by the parent :class:`OpenerDirector`.
+   *req* will be a :class:`Request` object. *response* will be an object
+   implementing the same interface as the return value of :func:`urlopen`.  The
+   return value should implement the same interface as the return value of
+   :func:`urlopen`.
+
+
+.. _http-redirect-handler:
+
+HTTPRedirectHandler Objects
+---------------------------
+
+.. note::
+
+   Some HTTP redirections require action from this module's client code.  If this
+   is the case, :exc:`HTTPError` is raised.  See :rfc:`2616` for details of the
+   precise meanings of the various redirection codes.
+
+
+.. method:: HTTPRedirectHandler.redirect_request(req, fp, code, msg, hdrs)
+
+   Return a :class:`Request` or ``None`` in response to a redirect. This is called
+   by the default implementations of the :meth:`http_error_30\*` methods when a
+   redirection is received from the server.  If a redirection should take place,
+   return a new :class:`Request` to allow :meth:`http_error_30\*` to perform the
+   redirect.  Otherwise, raise :exc:`HTTPError` if no other handler should try to
+   handle this URL, or return ``None`` if you can't but another handler might.
+
+   .. note::
+
+      The default implementation of this method does not strictly follow :rfc:`2616`,
+      which says that 301 and 302 responses to ``POST`` requests must not be
+      automatically redirected without confirmation by the user.  In reality, browsers
+      do allow automatic redirection of these responses, changing the POST to a
+      ``GET``, and the default implementation reproduces this behavior.
+
+
+.. method:: HTTPRedirectHandler.http_error_301(req, fp, code, msg, hdrs)
+
+   Redirect to the ``Location:`` URL.  This method is called by the parent
+   :class:`OpenerDirector` when getting an HTTP 'moved permanently' response.
+
+
+.. method:: HTTPRedirectHandler.http_error_302(req, fp, code, msg, hdrs)
+
+   The same as :meth:`http_error_301`, but called for the 'found' response.
+
+
+.. method:: HTTPRedirectHandler.http_error_303(req, fp, code, msg, hdrs)
+
+   The same as :meth:`http_error_301`, but called for the 'see other' response.
+
+
+.. method:: HTTPRedirectHandler.http_error_307(req, fp, code, msg, hdrs)
+
+   The same as :meth:`http_error_301`, but called for the 'temporary redirect'
+   response.
+
+
+.. _http-cookie-processor:
+
+HTTPCookieProcessor Objects
+---------------------------
+
+:class:`HTTPCookieProcessor` instances have one attribute:
+
+.. attribute:: HTTPCookieProcessor.cookiejar
+
+   The :class:`http.cookiejar.CookieJar` in which cookies are stored.
+
+
+.. _proxy-handler:
+
+ProxyHandler Objects
+--------------------
+
+
+.. method:: ProxyHandler.protocol_open(request)
+   :noindex:
+
+   The :class:`ProxyHandler` will have a method :meth:`protocol_open` for every
+   *protocol* which has a proxy in the *proxies* dictionary given in the
+   constructor.  The method will modify requests to go through the proxy, by
+   calling ``request.set_proxy()``, and call the next handler in the chain to
+   actually execute the protocol.
+
+
+.. _http-password-mgr:
+
+HTTPPasswordMgr Objects
+-----------------------
+
+These methods are available on :class:`HTTPPasswordMgr` and
+:class:`HTTPPasswordMgrWithDefaultRealm` objects.
+
+
+.. method:: HTTPPasswordMgr.add_password(realm, uri, user, passwd)
+
+   *uri* can be either a single URI, or a sequence of URIs. *realm*, *user* and
+   *passwd* must be strings. This causes ``(user, passwd)`` to be used as
+   authentication tokens when authentication for *realm* and a super-URI of any of
+   the given URIs is given.
+
+
+.. method:: HTTPPasswordMgr.find_user_password(realm, authuri)
+
+   Get user/password for given realm and URI, if any.  This method will return
+   ``(None, None)`` if there is no matching user/password.
+
+   For :class:`HTTPPasswordMgrWithDefaultRealm` objects, the realm ``None`` will be
+   searched if the given *realm* has no matching user/password.
+
+
+.. _abstract-basic-auth-handler:
+
+AbstractBasicAuthHandler Objects
+--------------------------------
+
+
+.. method:: AbstractBasicAuthHandler.http_error_auth_reqed(authreq, host, req, headers)
+
+   Handle an authentication request by getting a user/password pair, and re-trying
+   the request.  *authreq* should be the name of the header where the information
+   about the realm is included in the request, *host* specifies the URL and path to
+   authenticate for, *req* should be the (failed) :class:`Request` object, and
+   *headers* should be the error headers.
+
+   *host* is either an authority (e.g. ``"python.org"``) or a URL containing an
+   authority component (e.g. ``"http://python.org/"``). In either case, the
+   authority must not contain a userinfo component (so, ``"python.org"`` and
+   ``"python.org:80"`` are fine, ``"joe:password at python.org"`` is not).
+
+
+.. _http-basic-auth-handler:
+
+HTTPBasicAuthHandler Objects
+----------------------------
+
+
+.. method:: HTTPBasicAuthHandler.http_error_401(req, fp, code,  msg, hdrs)
+
+   Retry the request with authentication information, if available.
+
+
+.. _proxy-basic-auth-handler:
+
+ProxyBasicAuthHandler Objects
+-----------------------------
+
+
+.. method:: ProxyBasicAuthHandler.http_error_407(req, fp, code,  msg, hdrs)
+
+   Retry the request with authentication information, if available.
+
+
+.. _abstract-digest-auth-handler:
+
+AbstractDigestAuthHandler Objects
+---------------------------------
+
+
+.. method:: AbstractDigestAuthHandler.http_error_auth_reqed(authreq, host, req, headers)
+
+   *authreq* should be the name of the header where the information about the realm
+   is included in the request, *host* should be the host to authenticate to, *req*
+   should be the (failed) :class:`Request` object, and *headers* should be the
+   error headers.
+
+
+.. _http-digest-auth-handler:
+
+HTTPDigestAuthHandler Objects
+-----------------------------
+
+
+.. method:: HTTPDigestAuthHandler.http_error_401(req, fp, code,  msg, hdrs)
+
+   Retry the request with authentication information, if available.
+
+
+.. _proxy-digest-auth-handler:
+
+ProxyDigestAuthHandler Objects
+------------------------------
+
+
+.. method:: ProxyDigestAuthHandler.http_error_407(req, fp, code,  msg, hdrs)
+
+   Retry the request with authentication information, if available.
+
+
+.. _http-handler-objects:
+
+HTTPHandler Objects
+-------------------
+
+
+.. method:: HTTPHandler.http_open(req)
+
+   Send an HTTP request, which can be either GET or POST, depending on
+   ``req.has_data()``.
+
+
+.. _https-handler-objects:
+
+HTTPSHandler Objects
+--------------------
+
+
+.. method:: HTTPSHandler.https_open(req)
+
+   Send an HTTPS request, which can be either GET or POST, depending on
+   ``req.has_data()``.
+
+
+.. _file-handler-objects:
+
+FileHandler Objects
+-------------------
+
+
+.. method:: FileHandler.file_open(req)
+
+   Open the file locally, if there is no host name, or the host name is
+   ``'localhost'``. Change the protocol to ``ftp`` otherwise, and retry opening it
+   using :attr:`parent`.
+
+
+.. _ftp-handler-objects:
+
+FTPHandler Objects
+------------------
+
+
+.. method:: FTPHandler.ftp_open(req)
+
+   Open the FTP file indicated by *req*. The login is always done with empty
+   username and password.
+
+
+.. _cacheftp-handler-objects:
+
+CacheFTPHandler Objects
+-----------------------
+
+:class:`CacheFTPHandler` objects are :class:`FTPHandler` objects with the
+following additional methods:
+
+
+.. method:: CacheFTPHandler.setTimeout(t)
+
+   Set timeout of connections to *t* seconds.
+
+
+.. method:: CacheFTPHandler.setMaxConns(m)
+
+   Set maximum number of cached connections to *m*.
+
+
+.. _unknown-handler-objects:
+
+UnknownHandler Objects
+----------------------
+
+
+.. method:: UnknownHandler.unknown_open()
+
+   Raise a :exc:`URLError` exception.
+
+
+.. _http-error-processor-objects:
+
+HTTPErrorProcessor Objects
+--------------------------
+
+.. method:: HTTPErrorProcessor.unknown_open()
+
+   Process HTTP error responses.
+
+   For 200 error codes, the response object is returned immediately.
+
+   For non-200 error codes, this simply passes the job on to the
+   :meth:`protocol_error_code` handler methods, via :meth:`OpenerDirector.error`.
+   Eventually, :class:`urllib2.HTTPDefaultErrorHandler` will raise an
+   :exc:`HTTPError` if no other handler handles the error.
+
+.. _urllib2-examples:
+
+Examples
+--------
+
+This example gets the python.org main page and displays the first 100 bytes of
+it::
+
+   >>> import urllib.request
+   >>> f = urllib.request.urlopen('http://www.python.org/')
+   >>> print(f.read(100))
+   <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+   <?xml-stylesheet href="./css/ht2html
+
+Here we are sending a data-stream to the stdin of a CGI and reading the data it
+returns to us. Note that this example will only work when the Python
+installation supports SSL. ::
+
+   >>> import urllib.request
+   >>> req = urllib.request.Request(url='https://localhost/cgi-bin/test.cgi',
+   ...                       data='This data is passed to stdin of the CGI')
+   >>> f = urllib.request.urlopen(req)
+   >>> print(f.read())
+   Got Data: "This data is passed to stdin of the CGI"
+
+The code for the sample CGI used in the above example is::
+
+   #!/usr/bin/env python
+   import sys
+   data = sys.stdin.read()
+   print('Content-type: text-plain\n\nGot Data: "%s"' % data)
+
+Use of Basic HTTP Authentication::
+
+   import urllib.request
+   # Create an OpenerDirector with support for Basic HTTP Authentication...
+   auth_handler = urllib.request.HTTPBasicAuthHandler()
+   auth_handler.add_password(realm='PDQ Application',
+                             uri='https://mahler:8092/site-updates.py',
+                             user='klem',
+                             passwd='kadidd!ehopper')
+   opener = urllib.request.build_opener(auth_handler)
+   # ...and install it globally so it can be used with urlopen.
+   urllib.request.install_opener(opener)
+   urllib.request.urlopen('http://www.example.com/login.html')
+
+:func:`build_opener` provides many handlers by default, including a
+:class:`ProxyHandler`.  By default, :class:`ProxyHandler` uses the environment
+variables named ``<scheme>_proxy``, where ``<scheme>`` is the URL scheme
+involved.  For example, the :envvar:`http_proxy` environment variable is read to
+obtain the HTTP proxy's URL.
+
+This example replaces the default :class:`ProxyHandler` with one that uses
+programatically-supplied proxy URLs, and adds proxy authorization support with
+:class:`ProxyBasicAuthHandler`. ::
+
+   proxy_handler = urllib.request.ProxyHandler({'http': 'http://www.example.com:3128/'})
+   proxy_auth_handler = urllib.request.HTTPBasicAuthHandler()
+   proxy_auth_handler.add_password('realm', 'host', 'username', 'password')
+
+   opener = build_opener(proxy_handler, proxy_auth_handler)
+   # This time, rather than install the OpenerDirector, we use it directly:
+   opener.open('http://www.example.com/login.html')
+
+Adding HTTP headers:
+
+Use the *headers* argument to the :class:`Request` constructor, or::
+
+   import urllib
+   req = urllib.request.Request('http://www.example.com/')
+   req.add_header('Referer', 'http://www.python.org/')
+   r = urllib.request.urlopen(req)
+
+:class:`OpenerDirector` automatically adds a :mailheader:`User-Agent` header to
+every :class:`Request`.  To change this::
+
+   import urllib
+   opener = urllib.request.build_opener()
+   opener.addheaders = [('User-agent', 'Mozilla/5.0')]
+   opener.open('http://www.example.com/')
+
+Also, remember that a few standard headers (:mailheader:`Content-Length`,
+:mailheader:`Content-Type` and :mailheader:`Host`) are added when the
+:class:`Request` is passed to :func:`urlopen` (or :meth:`OpenerDirector.open`).
+
+.. _urllib-examples:
+
+Here is an example session that uses the ``GET`` method to retrieve a URL
+containing parameters::
+
+   >>> import urllib.request
+   >>> import urllib.parse
+   >>> params = urllib.parse.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0})
+   >>> f = urllib.request.urlopen("http://www.musi-cal.com/cgi-bin/query?%s" % params)
+   >>> print(f.read())
+
+The following example uses the ``POST`` method instead::
+
+   >>> import urllib.request
+   >>> import urllib.parse
+   >>> params = urllib.parse.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0})
+   >>> f = urllib.request.urlopen("http://www.musi-cal.com/cgi-bin/query", params)
+   >>> print(f.read())
+
+The following example uses an explicitly specified HTTP proxy, overriding
+environment settings::
+
+   >>> import urllib.request
+   >>> proxies = {'http': 'http://proxy.example.com:8080/'}
+   >>> opener = urllib.request.FancyURLopener(proxies)
+   >>> f = opener.open("http://www.python.org")
+   >>> f.read()
+
+The following example uses no proxies at all, overriding environment settings::
+
+   >>> import urllib.request
+   >>> opener = urllib.request.FancyURLopener({})
+   >>> f = opener.open("http://www.python.org/")
+   >>> f.read()
+
+
+:mod:`urllib.request` Restrictions
+----------------------------------
+
+  .. index::
+     pair: HTTP; protocol
+     pair: FTP; protocol
+
+* Currently, only the following protocols are supported: HTTP, (versions 0.9 and
+  1.0),  FTP, and local files.
+
+* The caching feature of :func:`urlretrieve` has been disabled until I find the
+  time to hack proper processing of Expiration time headers.
+
+* There should be a function to query whether a particular URL is in the cache.
+
+* For backward compatibility, if a URL appears to point to a local file but the
+  file can't be opened, the URL is re-interpreted using the FTP protocol.  This
+  can sometimes cause confusing error messages.
+
+* The :func:`urlopen` and :func:`urlretrieve` functions can cause arbitrarily
+  long delays while waiting for a network connection to be set up.  This means
+  that it is difficult to build an interactive Web client using these functions
+  without using threads.
+
+  .. index::
+     single: HTML
+     pair: HTTP; protocol
+
+* The data returned by :func:`urlopen` or :func:`urlretrieve` is the raw data
+  returned by the server.  This may be binary data (such as an image), plain text
+  or (for example) HTML.  The HTTP protocol provides type information in the reply
+  header, which can be inspected by looking at the :mailheader:`Content-Type`
+  header.  If the returned data is HTML, you can use the module
+  :mod:`html.parser` to parse it.
+
+  .. index:: single: FTP
+
+* The code handling the FTP protocol cannot differentiate between a file and a
+  directory.  This can lead to unexpected behavior when attempting to read a URL
+  that points to a file that is not accessible.  If the URL ends in a ``/``, it is
+  assumed to refer to a directory and will be handled accordingly.  But if an
+  attempt to read a file leads to a 550 error (meaning the URL cannot be found or
+  is not accessible, often for permission reasons), then the path is treated as a
+  directory in order to handle the case when a directory is specified by a URL but
+  the trailing ``/`` has been left off.  This can cause misleading results when
+  you try to fetch a file whose read permissions make it inaccessible; the FTP
+  code will try to read it, fail with a 550 error, and then perform a directory
+  listing for the unreadable file. If fine-grained control is needed, consider
+  using the :mod:`ftplib` module, subclassing :class:`FancyURLOpener`, or changing
+  *_urlopener* to meet your needs.
+
+:mod:`urllib.response` --- Response classes used by urllib.
+===========================================================
+.. module:: urllib.response
+   :synopsis: Response classes used by urllib.
+
+The :mod:`urllib.response` module defines functions and classes which define a
+minimal file like interface, including read() and readline(). The typical
+response object is an addinfourl instance, which defines and info() method and
+that returns headers and a geturl() method that returns the url. 
+Functions defined by this module are used internally by the
+:mod:`urllib.request` module.
+

Added: python/branches/py3k-urllib/Doc/library/urllib.robotparser.rst
==============================================================================
--- (empty file)
+++ python/branches/py3k-urllib/Doc/library/urllib.robotparser.rst	Mon Jun 23 04:33:01 2008
@@ -0,0 +1,73 @@
+
+:mod:`urllib.robotparser` ---  Parser for robots.txt
+====================================================
+
+.. module:: urllib.robotparser
+   :synopsis: Loads a robots.txt file and answers questions about
+              fetchability of other URLs.
+.. sectionauthor:: Skip Montanaro <skip at pobox.com>
+
+
+.. index::
+   single: WWW
+   single: World Wide Web
+   single: URL
+   single: robots.txt
+
+This module provides a single class, :class:`RobotFileParser`, which answers
+questions about whether or not a particular user agent can fetch a URL on the
+Web site that published the :file:`robots.txt` file.  For more details on the
+structure of :file:`robots.txt` files, see http://www.robotstxt.org/orig.html.
+
+
+.. class:: RobotFileParser()
+
+   This class provides a set of methods to read, parse and answer questions
+   about a single :file:`robots.txt` file.
+
+
+   .. method:: set_url(url)
+
+      Sets the URL referring to a :file:`robots.txt` file.
+
+
+   .. method:: read()
+
+      Reads the :file:`robots.txt` URL and feeds it to the parser.
+
+
+   .. method:: parse(lines)
+
+      Parses the lines argument.
+
+
+   .. method:: can_fetch(useragent, url)
+
+      Returns ``True`` if the *useragent* is allowed to fetch the *url*
+      according to the rules contained in the parsed :file:`robots.txt`
+      file.
+
+
+   .. method:: mtime()
+
+      Returns the time the ``robots.txt`` file was last fetched.  This is
+      useful for long-running web spiders that need to check for new
+      ``robots.txt`` files periodically.
+
+
+   .. method:: modified()
+
+      Sets the time the ``robots.txt`` file was last fetched to the current
+      time.
+
+The following example demonstrates basic use of the RobotFileParser class. ::
+
+   >>> import urllib.robotparser
+   >>> rp = urllib.robotparser.RobotFileParser()
+   >>> rp.set_url("http://www.musi-cal.com/robots.txt")
+   >>> rp.read()
+   >>> rp.can_fetch("*", "http://www.musi-cal.com/cgi-bin/search?city=San+Francisco")
+   False
+   >>> rp.can_fetch("*", "http://www.musi-cal.com/")
+   True
+

From python-3000-checkins at python.org  Mon Jun 23 04:34:42 2008
From: python-3000-checkins at python.org (senthil.kumaran)
Date: Mon, 23 Jun 2008 04:34:42 +0200 (CEST)
Subject: [Python-3000-checkins] r64474 - in
	python/branches/py3k-urllib/Doc/library: robotparser.rst
	urllib.rst urllib2.rst urlparse.rst
Message-ID: <20080623023442.CB3BB1E4013@bag.python.org>

Author: senthil.kumaran
Date: Mon Jun 23 04:34:41 2008
New Revision: 64474

Log:

Remove the old module documentation.



Removed:
   python/branches/py3k-urllib/Doc/library/robotparser.rst
   python/branches/py3k-urllib/Doc/library/urllib.rst
   python/branches/py3k-urllib/Doc/library/urllib2.rst
   python/branches/py3k-urllib/Doc/library/urlparse.rst

Deleted: python/branches/py3k-urllib/Doc/library/robotparser.rst
==============================================================================
--- python/branches/py3k-urllib/Doc/library/robotparser.rst	Mon Jun 23 04:34:41 2008
+++ (empty file)
@@ -1,73 +0,0 @@
-
-:mod:`robotparser` ---  Parser for robots.txt
-=============================================
-
-.. module:: robotparser
-   :synopsis: Loads a robots.txt file and answers questions about
-              fetchability of other URLs.
-.. sectionauthor:: Skip Montanaro <skip at pobox.com>
-
-
-.. index::
-   single: WWW
-   single: World Wide Web
-   single: URL
-   single: robots.txt
-
-This module provides a single class, :class:`RobotFileParser`, which answers
-questions about whether or not a particular user agent can fetch a URL on the
-Web site that published the :file:`robots.txt` file.  For more details on the
-structure of :file:`robots.txt` files, see http://www.robotstxt.org/orig.html.
-
-
-.. class:: RobotFileParser()
-
-   This class provides a set of methods to read, parse and answer questions
-   about a single :file:`robots.txt` file.
-
-
-   .. method:: set_url(url)
-
-      Sets the URL referring to a :file:`robots.txt` file.
-
-
-   .. method:: read()
-
-      Reads the :file:`robots.txt` URL and feeds it to the parser.
-
-
-   .. method:: parse(lines)
-
-      Parses the lines argument.
-
-
-   .. method:: can_fetch(useragent, url)
-
-      Returns ``True`` if the *useragent* is allowed to fetch the *url*
-      according to the rules contained in the parsed :file:`robots.txt`
-      file.
-
-
-   .. method:: mtime()
-
-      Returns the time the ``robots.txt`` file was last fetched.  This is
-      useful for long-running web spiders that need to check for new
-      ``robots.txt`` files periodically.
-
-
-   .. method:: modified()
-
-      Sets the time the ``robots.txt`` file was last fetched to the current
-      time.
-
-The following example demonstrates basic use of the RobotFileParser class. ::
-
-   >>> import robotparser
-   >>> rp = robotparser.RobotFileParser()
-   >>> rp.set_url("http://www.musi-cal.com/robots.txt")
-   >>> rp.read()
-   >>> rp.can_fetch("*", "http://www.musi-cal.com/cgi-bin/search?city=San+Francisco")
-   False
-   >>> rp.can_fetch("*", "http://www.musi-cal.com/")
-   True
-

Deleted: python/branches/py3k-urllib/Doc/library/urllib.rst
==============================================================================
--- python/branches/py3k-urllib/Doc/library/urllib.rst	Mon Jun 23 04:34:41 2008
+++ (empty file)
@@ -1,459 +0,0 @@
-:mod:`urllib` --- Open arbitrary resources by URL
-=================================================
-
-.. module:: urllib
-   :synopsis: Open an arbitrary network resource by URL (requires sockets).
-
-
-.. index::
-   single: WWW
-   single: World Wide Web
-   single: URL
-
-This module provides a high-level interface for fetching data across the World
-Wide Web.  In particular, the :func:`urlopen` function is similar to the
-built-in function :func:`open`, but accepts Universal Resource Locators (URLs)
-instead of filenames.  Some restrictions apply --- it can only open URLs for
-reading, and no seek operations are available.
-
-High-level interface
---------------------
-
-.. function:: urlopen(url[, data[, proxies]])
-
-   Open a network object denoted by a URL for reading.  If the URL does not have a
-   scheme identifier, or if it has :file:`file:` as its scheme identifier, this
-   opens a local file (without universal newlines); otherwise it opens a socket to
-   a server somewhere on the network.  If the connection cannot be made the
-   :exc:`IOError` exception is raised.  If all went well, a file-like object is
-   returned.  This supports the following methods: :meth:`read`, :meth:`readline`,
-   :meth:`readlines`, :meth:`fileno`, :meth:`close`, :meth:`info`, :meth:`getcode` and
-   :meth:`geturl`.  It also has proper support for the :term:`iterator` protocol. One
-   caveat: the :meth:`read` method, if the size argument is omitted or negative,
-   may not read until the end of the data stream; there is no good way to determine
-   that the entire stream from a socket has been read in the general case.
-
-   Except for the :meth:`info`, :meth:`getcode` and :meth:`geturl` methods,
-   these methods have the same interface as for file objects --- see section
-   :ref:`bltin-file-objects` in this manual.  (It is not a built-in file object,
-   however, so it can't be used at those few places where a true built-in file
-   object is required.)
-
-   The :meth:`info` method returns an instance of the class
-   :class:`email.message.Message` containing meta-information associated with
-   the URL.  When the method is HTTP, these headers are those returned by the
-   server at the head of the retrieved HTML page (including Content-Length and
-   Content-Type).  When the method is FTP, a Content-Length header will be
-   present if (as is now usual) the server passed back a file length in response
-   to the FTP retrieval request. A Content-Type header will be present if the
-   MIME type can be guessed.  When the method is local-file, returned headers
-   will include a Date representing the file's last-modified time, a
-   Content-Length giving file size, and a Content-Type containing a guess at the
-   file's type.
-
-   The :meth:`geturl` method returns the real URL of the page.  In some cases, the
-   HTTP server redirects a client to another URL.  The :func:`urlopen` function
-   handles this transparently, but in some cases the caller needs to know which URL
-   the client was redirected to.  The :meth:`geturl` method can be used to get at
-   this redirected URL.
-
-   The :meth:`getcode` method returns the HTTP status code that was sent with the
-   response, or ``None`` if the URL is no HTTP URL.
-
-   If the *url* uses the :file:`http:` scheme identifier, the optional *data*
-   argument may be given to specify a ``POST`` request (normally the request type
-   is ``GET``).  The *data* argument must be in standard
-   :mimetype:`application/x-www-form-urlencoded` format; see the :func:`urlencode`
-   function below.
-
-   The :func:`urlopen` function works transparently with proxies which do not
-   require authentication.  In a Unix or Windows environment, set the
-   :envvar:`http_proxy`, or :envvar:`ftp_proxy` environment variables to a URL that
-   identifies the proxy server before starting the Python interpreter.  For example
-   (the ``'%'`` is the command prompt)::
-
-      % http_proxy="http://www.someproxy.com:3128"
-      % export http_proxy
-      % python
-      ...
-
-   The :envvar:`no_proxy` environment variable can be used to specify hosts which
-   shouldn't be reached via proxy; if set, it should be a comma-separated list
-   of hostname suffixes, optionally with ``:port`` appended, for example
-   ``cern.ch,ncsa.uiuc.edu,some.host:8080``.
-
-   In a Windows environment, if no proxy environment variables are set, proxy
-   settings are obtained from the registry's Internet Settings section.
-
-   .. index:: single: Internet Config
-
-   In a Macintosh environment, :func:`urlopen` will retrieve proxy information from
-   Internet Config.
-
-   Alternatively, the optional *proxies* argument may be used to explicitly specify
-   proxies.  It must be a dictionary mapping scheme names to proxy URLs, where an
-   empty dictionary causes no proxies to be used, and ``None`` (the default value)
-   causes environmental proxy settings to be used as discussed above.  For
-   example::
-
-      # Use http://www.someproxy.com:3128 for http proxying
-      proxies = {'http': 'http://www.someproxy.com:3128'}
-      filehandle = urllib.urlopen(some_url, proxies=proxies)
-      # Don't use any proxies
-      filehandle = urllib.urlopen(some_url, proxies={})
-      # Use proxies from environment - both versions are equivalent
-      filehandle = urllib.urlopen(some_url, proxies=None)
-      filehandle = urllib.urlopen(some_url)
-
-   Proxies which require authentication for use are not currently supported; this
-   is considered an implementation limitation.
-
-
-.. function:: urlretrieve(url[, filename[, reporthook[, data]]])
-
-   Copy a network object denoted by a URL to a local file, if necessary. If the URL
-   points to a local file, or a valid cached copy of the object exists, the object
-   is not copied.  Return a tuple ``(filename, headers)`` where *filename* is the
-   local file name under which the object can be found, and *headers* is whatever
-   the :meth:`info` method of the object returned by :func:`urlopen` returned (for
-   a remote object, possibly cached). Exceptions are the same as for
-   :func:`urlopen`.
-
-   The second argument, if present, specifies the file location to copy to (if
-   absent, the location will be a tempfile with a generated name). The third
-   argument, if present, is a hook function that will be called once on
-   establishment of the network connection and once after each block read
-   thereafter.  The hook will be passed three arguments; a count of blocks
-   transferred so far, a block size in bytes, and the total size of the file.  The
-   third argument may be ``-1`` on older FTP servers which do not return a file
-   size in response to a retrieval request.
-
-   If the *url* uses the :file:`http:` scheme identifier, the optional *data*
-   argument may be given to specify a ``POST`` request (normally the request type
-   is ``GET``).  The *data* argument must in standard
-   :mimetype:`application/x-www-form-urlencoded` format; see the :func:`urlencode`
-   function below.
-
-   :func:`urlretrieve` will raise :exc:`ContentTooShortError` when it detects that
-   the amount of data available  was less than the expected amount (which is the
-   size reported by a  *Content-Length* header). This can occur, for example, when
-   the  download is interrupted.
-
-   The *Content-Length* is treated as a lower bound: if there's more data  to read,
-   urlretrieve reads more data, but if less data is available,  it raises the
-   exception.
-
-   You can still retrieve the downloaded data in this case, it is stored  in the
-   :attr:`content` attribute of the exception instance.
-
-   If no *Content-Length* header was supplied, urlretrieve can not check the size
-   of the data it has downloaded, and just returns it.  In this case you just have
-   to assume that the download was successful.
-
-
-.. data:: _urlopener
-
-   The public functions :func:`urlopen` and :func:`urlretrieve` create an instance
-   of the :class:`FancyURLopener` class and use it to perform their requested
-   actions.  To override this functionality, programmers can create a subclass of
-   :class:`URLopener` or :class:`FancyURLopener`, then assign an instance of that
-   class to the ``urllib._urlopener`` variable before calling the desired function.
-   For example, applications may want to specify a different
-   :mailheader:`User-Agent` header than :class:`URLopener` defines.  This can be
-   accomplished with the following code::
-
-      import urllib
-
-      class AppURLopener(urllib.FancyURLopener):
-          version = "App/1.7"
-
-      urllib._urlopener = AppURLopener()
-
-
-.. function:: urlcleanup()
-
-   Clear the cache that may have been built up by previous calls to
-   :func:`urlretrieve`.
-
-
-Utility functions
------------------
-
-.. function:: quote(string[, safe])
-
-   Replace special characters in *string* using the ``%xx`` escape. Letters,
-   digits, and the characters ``'_.-'`` are never quoted. The optional *safe*
-   parameter specifies additional characters that should not be quoted --- its
-   default value is ``'/'``.
-
-   Example: ``quote('/~connolly/')`` yields ``'/%7econnolly/'``.
-
-
-.. function:: quote_plus(string[, safe])
-
-   Like :func:`quote`, but also replaces spaces by plus signs, as required for
-   quoting HTML form values.  Plus signs in the original string are escaped unless
-   they are included in *safe*.  It also does not have *safe* default to ``'/'``.
-
-
-.. function:: unquote(string)
-
-   Replace ``%xx`` escapes by their single-character equivalent.
-
-   Example: ``unquote('/%7Econnolly/')`` yields ``'/~connolly/'``.
-
-
-.. function:: unquote_plus(string)
-
-   Like :func:`unquote`, but also replaces plus signs by spaces, as required for
-   unquoting HTML form values.
-
-
-.. function:: urlencode(query[, doseq])
-
-   Convert a mapping object or a sequence of two-element tuples  to a "url-encoded"
-   string, suitable to pass to :func:`urlopen` above as the optional *data*
-   argument.  This is useful to pass a dictionary of form fields to a ``POST``
-   request.  The resulting string is a series of ``key=value`` pairs separated by
-   ``'&'`` characters, where both *key* and *value* are quoted using
-   :func:`quote_plus` above.  If the optional parameter *doseq* is present and
-   evaluates to true, individual ``key=value`` pairs are generated for each element
-   of the sequence. When a sequence of two-element tuples is used as the *query*
-   argument, the first element of each tuple is a key and the second is a value.
-   The order of parameters in the encoded string will match the order of parameter
-   tuples in the sequence. The :mod:`cgi` module provides the functions
-   :func:`parse_qs` and :func:`parse_qsl` which are used to parse query strings
-   into Python data structures.
-
-
-.. function:: pathname2url(path)
-
-   Convert the pathname *path* from the local syntax for a path to the form used in
-   the path component of a URL.  This does not produce a complete URL.  The return
-   value will already be quoted using the :func:`quote` function.
-
-
-.. function:: url2pathname(path)
-
-   Convert the path component *path* from an encoded URL to the local syntax for a
-   path.  This does not accept a complete URL.  This function uses :func:`unquote`
-   to decode *path*.
-
-
-URL Opener objects
-------------------
-
-.. class:: URLopener([proxies[, **x509]])
-
-   Base class for opening and reading URLs.  Unless you need to support opening
-   objects using schemes other than :file:`http:`, :file:`ftp:`, or :file:`file:`,
-   you probably want to use :class:`FancyURLopener`.
-
-   By default, the :class:`URLopener` class sends a :mailheader:`User-Agent` header
-   of ``urllib/VVV``, where *VVV* is the :mod:`urllib` version number.
-   Applications can define their own :mailheader:`User-Agent` header by subclassing
-   :class:`URLopener` or :class:`FancyURLopener` and setting the class attribute
-   :attr:`version` to an appropriate string value in the subclass definition.
-
-   The optional *proxies* parameter should be a dictionary mapping scheme names to
-   proxy URLs, where an empty dictionary turns proxies off completely.  Its default
-   value is ``None``, in which case environmental proxy settings will be used if
-   present, as discussed in the definition of :func:`urlopen`, above.
-
-   Additional keyword parameters, collected in *x509*, may be used for
-   authentication of the client when using the :file:`https:` scheme.  The keywords
-   *key_file* and *cert_file* are supported to provide an  SSL key and certificate;
-   both are needed to support client authentication.
-
-   :class:`URLopener` objects will raise an :exc:`IOError` exception if the server
-   returns an error code.
-
-    .. method:: open(fullurl[, data])
-
-       Open *fullurl* using the appropriate protocol.  This method sets up cache and
-       proxy information, then calls the appropriate open method with its input
-       arguments.  If the scheme is not recognized, :meth:`open_unknown` is called.
-       The *data* argument has the same meaning as the *data* argument of
-       :func:`urlopen`.
-
-
-    .. method:: open_unknown(fullurl[, data])
-
-       Overridable interface to open unknown URL types.
-
-
-    .. method:: retrieve(url[, filename[, reporthook[, data]]])
-
-       Retrieves the contents of *url* and places it in *filename*.  The return value
-       is a tuple consisting of a local filename and either a
-       :class:`email.message.Message` object containing the response headers (for remote
-       URLs) or ``None`` (for local URLs).  The caller must then open and read the
-       contents of *filename*.  If *filename* is not given and the URL refers to a
-       local file, the input filename is returned.  If the URL is non-local and
-       *filename* is not given, the filename is the output of :func:`tempfile.mktemp`
-       with a suffix that matches the suffix of the last path component of the input
-       URL.  If *reporthook* is given, it must be a function accepting three numeric
-       parameters.  It will be called after each chunk of data is read from the
-       network.  *reporthook* is ignored for local URLs.
-
-       If the *url* uses the :file:`http:` scheme identifier, the optional *data*
-       argument may be given to specify a ``POST`` request (normally the request type
-       is ``GET``).  The *data* argument must in standard
-       :mimetype:`application/x-www-form-urlencoded` format; see the :func:`urlencode`
-       function below.
-
-
-    .. attribute:: version
-
-       Variable that specifies the user agent of the opener object.  To get
-       :mod:`urllib` to tell servers that it is a particular user agent, set this in a
-       subclass as a class variable or in the constructor before calling the base
-       constructor.
-
-
-.. class:: FancyURLopener(...)
-
-   :class:`FancyURLopener` subclasses :class:`URLopener` providing default handling
-   for the following HTTP response codes: 301, 302, 303, 307 and 401.  For the 30x
-   response codes listed above, the :mailheader:`Location` header is used to fetch
-   the actual URL.  For 401 response codes (authentication required), basic HTTP
-   authentication is performed.  For the 30x response codes, recursion is bounded
-   by the value of the *maxtries* attribute, which defaults to 10.
-
-   For all other response codes, the method :meth:`http_error_default` is called
-   which you can override in subclasses to handle the error appropriately.
-
-   .. note::
-
-      According to the letter of :rfc:`2616`, 301 and 302 responses to POST requests
-      must not be automatically redirected without confirmation by the user.  In
-      reality, browsers do allow automatic redirection of these responses, changing
-      the POST to a GET, and :mod:`urllib` reproduces this behaviour.
-
-   The parameters to the constructor are the same as those for :class:`URLopener`.
-
-   .. note::
-
-      When performing basic authentication, a :class:`FancyURLopener` instance calls
-      its :meth:`prompt_user_passwd` method.  The default implementation asks the
-      users for the required information on the controlling terminal.  A subclass may
-      override this method to support more appropriate behavior if needed.
-
-    The :class:`FancyURLopener` class offers one additional method that should be
-    overloaded to provide the appropriate behavior:
-
-    .. method:: prompt_user_passwd(host, realm)
-
-       Return information needed to authenticate the user at the given host in the
-       specified security realm.  The return value should be a tuple, ``(user,
-       password)``, which can be used for basic authentication.
-
-       The implementation prompts for this information on the terminal; an application
-       should override this method to use an appropriate interaction model in the local
-       environment.
-
-.. exception:: ContentTooShortError(msg[, content])
-
-   This exception is raised when the :func:`urlretrieve` function detects that the
-   amount of the downloaded data is less than the  expected amount (given by the
-   *Content-Length* header). The :attr:`content` attribute stores the downloaded
-   (and supposedly truncated) data.
-
-
-:mod:`urllib` Restrictions
---------------------------
-
-  .. index::
-     pair: HTTP; protocol
-     pair: FTP; protocol
-
-* Currently, only the following protocols are supported: HTTP, (versions 0.9 and
-  1.0),  FTP, and local files.
-
-* The caching feature of :func:`urlretrieve` has been disabled until I find the
-  time to hack proper processing of Expiration time headers.
-
-* There should be a function to query whether a particular URL is in the cache.
-
-* For backward compatibility, if a URL appears to point to a local file but the
-  file can't be opened, the URL is re-interpreted using the FTP protocol.  This
-  can sometimes cause confusing error messages.
-
-* The :func:`urlopen` and :func:`urlretrieve` functions can cause arbitrarily
-  long delays while waiting for a network connection to be set up.  This means
-  that it is difficult to build an interactive Web client using these functions
-  without using threads.
-
-  .. index::
-     single: HTML
-     pair: HTTP; protocol
-
-* The data returned by :func:`urlopen` or :func:`urlretrieve` is the raw data
-  returned by the server.  This may be binary data (such as an image), plain text
-  or (for example) HTML.  The HTTP protocol provides type information in the reply
-  header, which can be inspected by looking at the :mailheader:`Content-Type`
-  header.  If the returned data is HTML, you can use the module
-  :mod:`html.parser` to parse it.
-
-  .. index:: single: FTP
-
-* The code handling the FTP protocol cannot differentiate between a file and a
-  directory.  This can lead to unexpected behavior when attempting to read a URL
-  that points to a file that is not accessible.  If the URL ends in a ``/``, it is
-  assumed to refer to a directory and will be handled accordingly.  But if an
-  attempt to read a file leads to a 550 error (meaning the URL cannot be found or
-  is not accessible, often for permission reasons), then the path is treated as a
-  directory in order to handle the case when a directory is specified by a URL but
-  the trailing ``/`` has been left off.  This can cause misleading results when
-  you try to fetch a file whose read permissions make it inaccessible; the FTP
-  code will try to read it, fail with a 550 error, and then perform a directory
-  listing for the unreadable file. If fine-grained control is needed, consider
-  using the :mod:`ftplib` module, subclassing :class:`FancyURLOpener`, or changing
-  *_urlopener* to meet your needs.
-
-* This module does not support the use of proxies which require authentication.
-  This may be implemented in the future.
-
-  .. index:: module: urlparse
-
-* Although the :mod:`urllib` module contains (undocumented) routines to parse
-  and unparse URL strings, the recommended interface for URL manipulation is in
-  module :mod:`urlparse`.
-
-
-.. _urllib-examples:
-
-Examples
---------
-
-Here is an example session that uses the ``GET`` method to retrieve a URL
-containing parameters::
-
-   >>> import urllib
-   >>> params = urllib.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0})
-   >>> f = urllib.urlopen("http://www.musi-cal.com/cgi-bin/query?%s" % params)
-   >>> print(f.read())
-
-The following example uses the ``POST`` method instead::
-
-   >>> import urllib
-   >>> params = urllib.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0})
-   >>> f = urllib.urlopen("http://www.musi-cal.com/cgi-bin/query", params)
-   >>> print(f.read())
-
-The following example uses an explicitly specified HTTP proxy, overriding
-environment settings::
-
-   >>> import urllib
-   >>> proxies = {'http': 'http://proxy.example.com:8080/'}
-   >>> opener = urllib.FancyURLopener(proxies)
-   >>> f = opener.open("http://www.python.org")
-   >>> f.read()
-
-The following example uses no proxies at all, overriding environment settings::
-
-   >>> import urllib
-   >>> opener = urllib.FancyURLopener({})
-   >>> f = opener.open("http://www.python.org/")
-   >>> f.read()
-

Deleted: python/branches/py3k-urllib/Doc/library/urllib2.rst
==============================================================================
--- python/branches/py3k-urllib/Doc/library/urllib2.rst	Mon Jun 23 04:34:41 2008
+++ (empty file)
@@ -1,934 +0,0 @@
-:mod:`urllib2` --- extensible library for opening URLs
-======================================================
-
-.. module:: urllib2
-   :synopsis: Next generation URL opening library.
-.. moduleauthor:: Jeremy Hylton <jhylton at users.sourceforge.net>
-.. sectionauthor:: Moshe Zadka <moshez at users.sourceforge.net>
-
-
-The :mod:`urllib2` module defines functions and classes which help in opening
-URLs (mostly HTTP) in a complex world --- basic and digest authentication,
-redirections, cookies and more.
-
-The :mod:`urllib2` module defines the following functions:
-
-
-.. function:: urlopen(url[, data][, timeout])
-
-   Open the URL *url*, which can be either a string or a :class:`Request` object.
-
-   *data* may be a string specifying additional data to send to the server, or
-   ``None`` if no such data is needed.  Currently HTTP requests are the only ones
-   that use *data*; the HTTP request will be a POST instead of a GET when the
-   *data* parameter is provided.  *data* should be a buffer in the standard
-   :mimetype:`application/x-www-form-urlencoded` format.  The
-   :func:`urllib.urlencode` function takes a mapping or sequence of 2-tuples and
-   returns a string in this format.
-
-   The optional *timeout* parameter specifies a timeout in seconds for blocking
-   operations like the connection attempt (if not specified, the global default
-   timeout setting will be used).  This actually only works for HTTP, HTTPS,
-   FTP and FTPS connections.
-
-   This function returns a file-like object with two additional methods:
-
-   * :meth:`geturl` --- return the URL of the resource retrieved, commonly used to
-     determine if a redirect was followed
-
-   * :meth:`info` --- return the meta-information of the page, such as headers, in
-     the form of an ``http.client.HTTPMessage`` instance
-     (see `Quick Reference to HTTP Headers <http://www.cs.tut.fi/~jkorpela/http.html>`_)
-
-   Raises :exc:`URLError` on errors.
-
-   Note that ``None`` may be returned if no handler handles the request (though the
-   default installed global :class:`OpenerDirector` uses :class:`UnknownHandler` to
-   ensure this never happens).
-
-
-.. function:: install_opener(opener)
-
-   Install an :class:`OpenerDirector` instance as the default global opener.
-   Installing an opener is only necessary if you want urlopen to use that opener;
-   otherwise, simply call :meth:`OpenerDirector.open` instead of :func:`urlopen`.
-   The code does not check for a real :class:`OpenerDirector`, and any class with
-   the appropriate interface will work.
-
-
-.. function:: build_opener([handler, ...])
-
-   Return an :class:`OpenerDirector` instance, which chains the handlers in the
-   order given. *handler*\s can be either instances of :class:`BaseHandler`, or
-   subclasses of :class:`BaseHandler` (in which case it must be possible to call
-   the constructor without any parameters).  Instances of the following classes
-   will be in front of the *handler*\s, unless the *handler*\s contain them,
-   instances of them or subclasses of them: :class:`ProxyHandler`,
-   :class:`UnknownHandler`, :class:`HTTPHandler`, :class:`HTTPDefaultErrorHandler`,
-   :class:`HTTPRedirectHandler`, :class:`FTPHandler`, :class:`FileHandler`,
-   :class:`HTTPErrorProcessor`.
-
-   If the Python installation has SSL support (i.e., if the :mod:`ssl` module can be imported),
-   :class:`HTTPSHandler` will also be added.
-
-   A :class:`BaseHandler` subclass may also change its :attr:`handler_order`
-   member variable to modify its position in the handlers list.
-
-The following exceptions are raised as appropriate:
-
-
-.. exception:: URLError
-
-   The handlers raise this exception (or derived exceptions) when they run into a
-   problem.  It is a subclass of :exc:`IOError`.
-
-   .. attribute:: reason
-
-      The reason for this error.  It can be a message string or another exception
-      instance (:exc:`socket.error` for remote URLs, :exc:`OSError` for local
-      URLs).
-
-
-.. exception:: HTTPError
-
-   Though being an exception (a subclass of :exc:`URLError`), an :exc:`HTTPError`
-   can also function as a non-exceptional file-like return value (the same thing
-   that :func:`urlopen` returns).  This is useful when handling exotic HTTP
-   errors, such as requests for authentication.
-
-   .. attribute:: code
-
-      An HTTP status code as defined in `RFC 2616 <http://www.faqs.org/rfcs/rfc2616.html>`_. 
-      This numeric value corresponds to a value found in the dictionary of
-      codes as found in :attr:`http.server.BaseHTTPRequestHandler.responses`.
-
-
-
-The following classes are provided:
-
-
-.. class:: Request(url[, data][, headers][, origin_req_host][, unverifiable])
-
-   This class is an abstraction of a URL request.
-
-   *url* should be a string containing a valid URL.
-
-   *data* may be a string specifying additional data to send to the server, or
-   ``None`` if no such data is needed.  Currently HTTP requests are the only ones
-   that use *data*; the HTTP request will be a POST instead of a GET when the
-   *data* parameter is provided.  *data* should be a buffer in the standard
-   :mimetype:`application/x-www-form-urlencoded` format.  The
-   :func:`urllib.urlencode` function takes a mapping or sequence of 2-tuples and
-   returns a string in this format.
-
-   *headers* should be a dictionary, and will be treated as if :meth:`add_header`
-   was called with each key and value as arguments.  This is often used to "spoof"
-   the ``User-Agent`` header, which is used by a browser to identify itself --
-   some HTTP servers only allow requests coming from common browsers as opposed
-   to scripts.  For example, Mozilla Firefox may identify itself as ``"Mozilla/5.0
-   (X11; U; Linux i686) Gecko/20071127 Firefox/2.0.0.11"``, while :mod:`urllib2`'s
-   default user agent string is ``"Python-urllib/2.6"`` (on Python 2.6).
-
-   The final two arguments are only of interest for correct handling of third-party
-   HTTP cookies:
-
-   *origin_req_host* should be the request-host of the origin transaction, as
-   defined by :rfc:`2965`.  It defaults to ``http.cookiejar.request_host(self)``.
-   This is the host name or IP address of the original request that was
-   initiated by the user.  For example, if the request is for an image in an
-   HTML document, this should be the request-host of the request for the page
-   containing the image.
-
-   *unverifiable* should indicate whether the request is unverifiable, as defined
-   by RFC 2965.  It defaults to False.  An unverifiable request is one whose URL
-   the user did not have the option to approve.  For example, if the request is for
-   an image in an HTML document, and the user had no option to approve the
-   automatic fetching of the image, this should be true.
-
-
-.. class:: OpenerDirector()
-
-   The :class:`OpenerDirector` class opens URLs via :class:`BaseHandler`\ s chained
-   together. It manages the chaining of handlers, and recovery from errors.
-
-
-.. class:: BaseHandler()
-
-   This is the base class for all registered handlers --- and handles only the
-   simple mechanics of registration.
-
-
-.. class:: HTTPDefaultErrorHandler()
-
-   A class which defines a default handler for HTTP error responses; all responses
-   are turned into :exc:`HTTPError` exceptions.
-
-
-.. class:: HTTPRedirectHandler()
-
-   A class to handle redirections.
-
-
-.. class:: HTTPCookieProcessor([cookiejar])
-
-   A class to handle HTTP Cookies.
-
-
-.. class:: ProxyHandler([proxies])
-
-   Cause requests to go through a proxy. If *proxies* is given, it must be a
-   dictionary mapping protocol names to URLs of proxies. The default is to read the
-   list of proxies from the environment variables :envvar:`<protocol>_proxy`.
-   To disable autodetected proxy pass an empty dictionary.
-
-
-.. class:: HTTPPasswordMgr()
-
-   Keep a database of  ``(realm, uri) -> (user, password)`` mappings.
-
-
-.. class:: HTTPPasswordMgrWithDefaultRealm()
-
-   Keep a database of  ``(realm, uri) -> (user, password)`` mappings. A realm of
-   ``None`` is considered a catch-all realm, which is searched if no other realm
-   fits.
-
-
-.. class:: AbstractBasicAuthHandler([password_mgr])
-
-   This is a mixin class that helps with HTTP authentication, both to the remote
-   host and to a proxy. *password_mgr*, if given, should be something that is
-   compatible with :class:`HTTPPasswordMgr`; refer to section
-   :ref:`http-password-mgr` for information on the interface that must be
-   supported.
-
-
-.. class:: HTTPBasicAuthHandler([password_mgr])
-
-   Handle authentication with the remote host. *password_mgr*, if given, should be
-   something that is compatible with :class:`HTTPPasswordMgr`; refer to section
-   :ref:`http-password-mgr` for information on the interface that must be
-   supported.
-
-
-.. class:: ProxyBasicAuthHandler([password_mgr])
-
-   Handle authentication with the proxy. *password_mgr*, if given, should be
-   something that is compatible with :class:`HTTPPasswordMgr`; refer to section
-   :ref:`http-password-mgr` for information on the interface that must be
-   supported.
-
-
-.. class:: AbstractDigestAuthHandler([password_mgr])
-
-   This is a mixin class that helps with HTTP authentication, both to the remote
-   host and to a proxy. *password_mgr*, if given, should be something that is
-   compatible with :class:`HTTPPasswordMgr`; refer to section
-   :ref:`http-password-mgr` for information on the interface that must be
-   supported.
-
-
-.. class:: HTTPDigestAuthHandler([password_mgr])
-
-   Handle authentication with the remote host. *password_mgr*, if given, should be
-   something that is compatible with :class:`HTTPPasswordMgr`; refer to section
-   :ref:`http-password-mgr` for information on the interface that must be
-   supported.
-
-
-.. class:: ProxyDigestAuthHandler([password_mgr])
-
-   Handle authentication with the proxy. *password_mgr*, if given, should be
-   something that is compatible with :class:`HTTPPasswordMgr`; refer to section
-   :ref:`http-password-mgr` for information on the interface that must be
-   supported.
-
-
-.. class:: HTTPHandler()
-
-   A class to handle opening of HTTP URLs.
-
-
-.. class:: HTTPSHandler()
-
-   A class to handle opening of HTTPS URLs.
-
-
-.. class:: FileHandler()
-
-   Open local files.
-
-
-.. class:: FTPHandler()
-
-   Open FTP URLs.
-
-
-.. class:: CacheFTPHandler()
-
-   Open FTP URLs, keeping a cache of open FTP connections to minimize delays.
-
-
-.. class:: UnknownHandler()
-
-   A catch-all class to handle unknown URLs.
-
-
-.. _request-objects:
-
-Request Objects
----------------
-
-The following methods describe all of :class:`Request`'s public interface, and
-so all must be overridden in subclasses.
-
-
-.. method:: Request.add_data(data)
-
-   Set the :class:`Request` data to *data*.  This is ignored by all handlers except
-   HTTP handlers --- and there it should be a byte string, and will change the
-   request to be ``POST`` rather than ``GET``.
-
-
-.. method:: Request.get_method()
-
-   Return a string indicating the HTTP request method.  This is only meaningful for
-   HTTP requests, and currently always returns ``'GET'`` or ``'POST'``.
-
-
-.. method:: Request.has_data()
-
-   Return whether the instance has a non-\ ``None`` data.
-
-
-.. method:: Request.get_data()
-
-   Return the instance's data.
-
-
-.. method:: Request.add_header(key, val)
-
-   Add another header to the request.  Headers are currently ignored by all
-   handlers except HTTP handlers, where they are added to the list of headers sent
-   to the server.  Note that there cannot be more than one header with the same
-   name, and later calls will overwrite previous calls in case the *key* collides.
-   Currently, this is no loss of HTTP functionality, since all headers which have
-   meaning when used more than once have a (header-specific) way of gaining the
-   same functionality using only one header.
-
-
-.. method:: Request.add_unredirected_header(key, header)
-
-   Add a header that will not be added to a redirected request.
-
-
-.. method:: Request.has_header(header)
-
-   Return whether the instance has the named header (checks both regular and
-   unredirected).
-
-
-.. method:: Request.get_full_url()
-
-   Return the URL given in the constructor.
-
-
-.. method:: Request.get_type()
-
-   Return the type of the URL --- also known as the scheme.
-
-
-.. method:: Request.get_host()
-
-   Return the host to which a connection will be made.
-
-
-.. method:: Request.get_selector()
-
-   Return the selector --- the part of the URL that is sent to the server.
-
-
-.. method:: Request.set_proxy(host, type)
-
-   Prepare the request by connecting to a proxy server. The *host* and *type* will
-   replace those of the instance, and the instance's selector will be the original
-   URL given in the constructor.
-
-
-.. method:: Request.get_origin_req_host()
-
-   Return the request-host of the origin transaction, as defined by :rfc:`2965`.
-   See the documentation for the :class:`Request` constructor.
-
-
-.. method:: Request.is_unverifiable()
-
-   Return whether the request is unverifiable, as defined by RFC 2965. See the
-   documentation for the :class:`Request` constructor.
-
-
-.. _opener-director-objects:
-
-OpenerDirector Objects
-----------------------
-
-:class:`OpenerDirector` instances have the following methods:
-
-
-.. method:: OpenerDirector.add_handler(handler)
-
-   *handler* should be an instance of :class:`BaseHandler`.  The following methods
-   are searched, and added to the possible chains (note that HTTP errors are a
-   special case).
-
-   * :meth:`protocol_open` --- signal that the handler knows how to open *protocol*
-     URLs.
-
-   * :meth:`http_error_type` --- signal that the handler knows how to handle HTTP
-     errors with HTTP error code *type*.
-
-   * :meth:`protocol_error` --- signal that the handler knows how to handle errors
-     from (non-\ ``http``) *protocol*.
-
-   * :meth:`protocol_request` --- signal that the handler knows how to pre-process
-     *protocol* requests.
-
-   * :meth:`protocol_response` --- signal that the handler knows how to
-     post-process *protocol* responses.
-
-
-.. method:: OpenerDirector.open(url[, data][, timeout])
-
-   Open the given *url* (which can be a request object or a string), optionally
-   passing the given *data*. Arguments, return values and exceptions raised are
-   the same as those of :func:`urlopen` (which simply calls the :meth:`open`
-   method on the currently installed global :class:`OpenerDirector`).  The
-   optional *timeout* parameter specifies a timeout in seconds for blocking
-   operations like the connection attempt (if not specified, the global default
-   timeout setting will be usedi). The timeout feature actually works only for
-   HTTP, HTTPS, FTP and FTPS connections).
-
-
-.. method:: OpenerDirector.error(proto[, arg[, ...]])
-
-   Handle an error of the given protocol.  This will call the registered error
-   handlers for the given protocol with the given arguments (which are protocol
-   specific).  The HTTP protocol is a special case which uses the HTTP response
-   code to determine the specific error handler; refer to the :meth:`http_error_\*`
-   methods of the handler classes.
-
-   Return values and exceptions raised are the same as those of :func:`urlopen`.
-
-OpenerDirector objects open URLs in three stages:
-
-The order in which these methods are called within each stage is determined by
-sorting the handler instances.
-
-#. Every handler with a method named like :meth:`protocol_request` has that
-   method called to pre-process the request.
-
-#. Handlers with a method named like :meth:`protocol_open` are called to handle
-   the request. This stage ends when a handler either returns a non-\ :const:`None`
-   value (ie. a response), or raises an exception (usually :exc:`URLError`).
-   Exceptions are allowed to propagate.
-
-   In fact, the above algorithm is first tried for methods named
-   :meth:`default_open`.  If all such methods return :const:`None`, the algorithm
-   is repeated for methods named like :meth:`protocol_open`.  If all such methods
-   return :const:`None`, the algorithm is repeated for methods named
-   :meth:`unknown_open`.
-
-   Note that the implementation of these methods may involve calls of the parent
-   :class:`OpenerDirector` instance's :meth:`.open` and :meth:`.error` methods.
-
-#. Every handler with a method named like :meth:`protocol_response` has that
-   method called to post-process the response.
-
-
-.. _base-handler-objects:
-
-BaseHandler Objects
--------------------
-
-:class:`BaseHandler` objects provide a couple of methods that are directly
-useful, and others that are meant to be used by derived classes.  These are
-intended for direct use:
-
-
-.. method:: BaseHandler.add_parent(director)
-
-   Add a director as parent.
-
-
-.. method:: BaseHandler.close()
-
-   Remove any parents.
-
-The following members and methods should only be used by classes derived from
-:class:`BaseHandler`.
-
-.. note::
-
-   The convention has been adopted that subclasses defining
-   :meth:`protocol_request` or :meth:`protocol_response` methods are named
-   :class:`\*Processor`; all others are named :class:`\*Handler`.
-
-
-.. attribute:: BaseHandler.parent
-
-   A valid :class:`OpenerDirector`, which can be used to open using a different
-   protocol, or handle errors.
-
-
-.. method:: BaseHandler.default_open(req)
-
-   This method is *not* defined in :class:`BaseHandler`, but subclasses should
-   define it if they want to catch all URLs.
-
-   This method, if implemented, will be called by the parent
-   :class:`OpenerDirector`.  It should return a file-like object as described in
-   the return value of the :meth:`open` of :class:`OpenerDirector`, or ``None``.
-   It should raise :exc:`URLError`, unless a truly exceptional thing happens (for
-   example, :exc:`MemoryError` should not be mapped to :exc:`URLError`).
-
-   This method will be called before any protocol-specific open method.
-
-
-.. method:: BaseHandler.protocol_open(req)
-   :noindex:
-
-   This method is *not* defined in :class:`BaseHandler`, but subclasses should
-   define it if they want to handle URLs with the given protocol.
-
-   This method, if defined, will be called by the parent :class:`OpenerDirector`.
-   Return values should be the same as for  :meth:`default_open`.
-
-
-.. method:: BaseHandler.unknown_open(req)
-
-   This method is *not* defined in :class:`BaseHandler`, but subclasses should
-   define it if they want to catch all URLs with no specific registered handler to
-   open it.
-
-   This method, if implemented, will be called by the :attr:`parent`
-   :class:`OpenerDirector`.  Return values should be the same as for
-   :meth:`default_open`.
-
-
-.. method:: BaseHandler.http_error_default(req, fp, code, msg, hdrs)
-
-   This method is *not* defined in :class:`BaseHandler`, but subclasses should
-   override it if they intend to provide a catch-all for otherwise unhandled HTTP
-   errors.  It will be called automatically by the  :class:`OpenerDirector` getting
-   the error, and should not normally be called in other circumstances.
-
-   *req* will be a :class:`Request` object, *fp* will be a file-like object with
-   the HTTP error body, *code* will be the three-digit code of the error, *msg*
-   will be the user-visible explanation of the code and *hdrs* will be a mapping
-   object with the headers of the error.
-
-   Return values and exceptions raised should be the same as those of
-   :func:`urlopen`.
-
-
-.. method:: BaseHandler.http_error_nnn(req, fp, code, msg, hdrs)
-
-   *nnn* should be a three-digit HTTP error code.  This method is also not defined
-   in :class:`BaseHandler`, but will be called, if it exists, on an instance of a
-   subclass, when an HTTP error with code *nnn* occurs.
-
-   Subclasses should override this method to handle specific HTTP errors.
-
-   Arguments, return values and exceptions raised should be the same as for
-   :meth:`http_error_default`.
-
-
-.. method:: BaseHandler.protocol_request(req)
-   :noindex:
-
-   This method is *not* defined in :class:`BaseHandler`, but subclasses should
-   define it if they want to pre-process requests of the given protocol.
-
-   This method, if defined, will be called by the parent :class:`OpenerDirector`.
-   *req* will be a :class:`Request` object. The return value should be a
-   :class:`Request` object.
-
-
-.. method:: BaseHandler.protocol_response(req, response)
-   :noindex:
-
-   This method is *not* defined in :class:`BaseHandler`, but subclasses should
-   define it if they want to post-process responses of the given protocol.
-
-   This method, if defined, will be called by the parent :class:`OpenerDirector`.
-   *req* will be a :class:`Request` object. *response* will be an object
-   implementing the same interface as the return value of :func:`urlopen`.  The
-   return value should implement the same interface as the return value of
-   :func:`urlopen`.
-
-
-.. _http-redirect-handler:
-
-HTTPRedirectHandler Objects
----------------------------
-
-.. note::
-
-   Some HTTP redirections require action from this module's client code.  If this
-   is the case, :exc:`HTTPError` is raised.  See :rfc:`2616` for details of the
-   precise meanings of the various redirection codes.
-
-
-.. method:: HTTPRedirectHandler.redirect_request(req, fp, code, msg, hdrs)
-
-   Return a :class:`Request` or ``None`` in response to a redirect. This is called
-   by the default implementations of the :meth:`http_error_30\*` methods when a
-   redirection is received from the server.  If a redirection should take place,
-   return a new :class:`Request` to allow :meth:`http_error_30\*` to perform the
-   redirect.  Otherwise, raise :exc:`HTTPError` if no other handler should try to
-   handle this URL, or return ``None`` if you can't but another handler might.
-
-   .. note::
-
-      The default implementation of this method does not strictly follow :rfc:`2616`,
-      which says that 301 and 302 responses to ``POST`` requests must not be
-      automatically redirected without confirmation by the user.  In reality, browsers
-      do allow automatic redirection of these responses, changing the POST to a
-      ``GET``, and the default implementation reproduces this behavior.
-
-
-.. method:: HTTPRedirectHandler.http_error_301(req, fp, code, msg, hdrs)
-
-   Redirect to the ``Location:`` URL.  This method is called by the parent
-   :class:`OpenerDirector` when getting an HTTP 'moved permanently' response.
-
-
-.. method:: HTTPRedirectHandler.http_error_302(req, fp, code, msg, hdrs)
-
-   The same as :meth:`http_error_301`, but called for the 'found' response.
-
-
-.. method:: HTTPRedirectHandler.http_error_303(req, fp, code, msg, hdrs)
-
-   The same as :meth:`http_error_301`, but called for the 'see other' response.
-
-
-.. method:: HTTPRedirectHandler.http_error_307(req, fp, code, msg, hdrs)
-
-   The same as :meth:`http_error_301`, but called for the 'temporary redirect'
-   response.
-
-
-.. _http-cookie-processor:
-
-HTTPCookieProcessor Objects
----------------------------
-
-:class:`HTTPCookieProcessor` instances have one attribute:
-
-.. attribute:: HTTPCookieProcessor.cookiejar
-
-   The :class:`http.cookiejar.CookieJar` in which cookies are stored.
-
-
-.. _proxy-handler:
-
-ProxyHandler Objects
---------------------
-
-
-.. method:: ProxyHandler.protocol_open(request)
-   :noindex:
-
-   The :class:`ProxyHandler` will have a method :meth:`protocol_open` for every
-   *protocol* which has a proxy in the *proxies* dictionary given in the
-   constructor.  The method will modify requests to go through the proxy, by
-   calling ``request.set_proxy()``, and call the next handler in the chain to
-   actually execute the protocol.
-
-
-.. _http-password-mgr:
-
-HTTPPasswordMgr Objects
------------------------
-
-These methods are available on :class:`HTTPPasswordMgr` and
-:class:`HTTPPasswordMgrWithDefaultRealm` objects.
-
-
-.. method:: HTTPPasswordMgr.add_password(realm, uri, user, passwd)
-
-   *uri* can be either a single URI, or a sequence of URIs. *realm*, *user* and
-   *passwd* must be strings. This causes ``(user, passwd)`` to be used as
-   authentication tokens when authentication for *realm* and a super-URI of any of
-   the given URIs is given.
-
-
-.. method:: HTTPPasswordMgr.find_user_password(realm, authuri)
-
-   Get user/password for given realm and URI, if any.  This method will return
-   ``(None, None)`` if there is no matching user/password.
-
-   For :class:`HTTPPasswordMgrWithDefaultRealm` objects, the realm ``None`` will be
-   searched if the given *realm* has no matching user/password.
-
-
-.. _abstract-basic-auth-handler:
-
-AbstractBasicAuthHandler Objects
---------------------------------
-
-
-.. method:: AbstractBasicAuthHandler.http_error_auth_reqed(authreq, host, req, headers)
-
-   Handle an authentication request by getting a user/password pair, and re-trying
-   the request.  *authreq* should be the name of the header where the information
-   about the realm is included in the request, *host* specifies the URL and path to
-   authenticate for, *req* should be the (failed) :class:`Request` object, and
-   *headers* should be the error headers.
-
-   *host* is either an authority (e.g. ``"python.org"``) or a URL containing an
-   authority component (e.g. ``"http://python.org/"``). In either case, the
-   authority must not contain a userinfo component (so, ``"python.org"`` and
-   ``"python.org:80"`` are fine, ``"joe:password at python.org"`` is not).
-
-
-.. _http-basic-auth-handler:
-
-HTTPBasicAuthHandler Objects
-----------------------------
-
-
-.. method:: HTTPBasicAuthHandler.http_error_401(req, fp, code,  msg, hdrs)
-
-   Retry the request with authentication information, if available.
-
-
-.. _proxy-basic-auth-handler:
-
-ProxyBasicAuthHandler Objects
------------------------------
-
-
-.. method:: ProxyBasicAuthHandler.http_error_407(req, fp, code,  msg, hdrs)
-
-   Retry the request with authentication information, if available.
-
-
-.. _abstract-digest-auth-handler:
-
-AbstractDigestAuthHandler Objects
----------------------------------
-
-
-.. method:: AbstractDigestAuthHandler.http_error_auth_reqed(authreq, host, req, headers)
-
-   *authreq* should be the name of the header where the information about the realm
-   is included in the request, *host* should be the host to authenticate to, *req*
-   should be the (failed) :class:`Request` object, and *headers* should be the
-   error headers.
-
-
-.. _http-digest-auth-handler:
-
-HTTPDigestAuthHandler Objects
------------------------------
-
-
-.. method:: HTTPDigestAuthHandler.http_error_401(req, fp, code,  msg, hdrs)
-
-   Retry the request with authentication information, if available.
-
-
-.. _proxy-digest-auth-handler:
-
-ProxyDigestAuthHandler Objects
-------------------------------
-
-
-.. method:: ProxyDigestAuthHandler.http_error_407(req, fp, code,  msg, hdrs)
-
-   Retry the request with authentication information, if available.
-
-
-.. _http-handler-objects:
-
-HTTPHandler Objects
--------------------
-
-
-.. method:: HTTPHandler.http_open(req)
-
-   Send an HTTP request, which can be either GET or POST, depending on
-   ``req.has_data()``.
-
-
-.. _https-handler-objects:
-
-HTTPSHandler Objects
---------------------
-
-
-.. method:: HTTPSHandler.https_open(req)
-
-   Send an HTTPS request, which can be either GET or POST, depending on
-   ``req.has_data()``.
-
-
-.. _file-handler-objects:
-
-FileHandler Objects
--------------------
-
-
-.. method:: FileHandler.file_open(req)
-
-   Open the file locally, if there is no host name, or the host name is
-   ``'localhost'``. Change the protocol to ``ftp`` otherwise, and retry opening it
-   using :attr:`parent`.
-
-
-.. _ftp-handler-objects:
-
-FTPHandler Objects
-------------------
-
-
-.. method:: FTPHandler.ftp_open(req)
-
-   Open the FTP file indicated by *req*. The login is always done with empty
-   username and password.
-
-
-.. _cacheftp-handler-objects:
-
-CacheFTPHandler Objects
------------------------
-
-:class:`CacheFTPHandler` objects are :class:`FTPHandler` objects with the
-following additional methods:
-
-
-.. method:: CacheFTPHandler.setTimeout(t)
-
-   Set timeout of connections to *t* seconds.
-
-
-.. method:: CacheFTPHandler.setMaxConns(m)
-
-   Set maximum number of cached connections to *m*.
-
-
-.. _unknown-handler-objects:
-
-UnknownHandler Objects
-----------------------
-
-
-.. method:: UnknownHandler.unknown_open()
-
-   Raise a :exc:`URLError` exception.
-
-
-.. _http-error-processor-objects:
-
-HTTPErrorProcessor Objects
---------------------------
-
-.. method:: HTTPErrorProcessor.unknown_open()
-
-   Process HTTP error responses.
-
-   For 200 error codes, the response object is returned immediately.
-
-   For non-200 error codes, this simply passes the job on to the
-   :meth:`protocol_error_code` handler methods, via :meth:`OpenerDirector.error`.
-   Eventually, :class:`urllib2.HTTPDefaultErrorHandler` will raise an
-   :exc:`HTTPError` if no other handler handles the error.
-
-
-.. _urllib2-examples:
-
-Examples
---------
-
-This example gets the python.org main page and displays the first 100 bytes of
-it::
-
-   >>> import urllib2
-   >>> f = urllib2.urlopen('http://www.python.org/')
-   >>> print(f.read(100))
-   <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-   <?xml-stylesheet href="./css/ht2html
-
-Here we are sending a data-stream to the stdin of a CGI and reading the data it
-returns to us. Note that this example will only work when the Python
-installation supports SSL. ::
-
-   >>> import urllib2
-   >>> req = urllib2.Request(url='https://localhost/cgi-bin/test.cgi',
-   ...                       data='This data is passed to stdin of the CGI')
-   >>> f = urllib2.urlopen(req)
-   >>> print(f.read())
-   Got Data: "This data is passed to stdin of the CGI"
-
-The code for the sample CGI used in the above example is::
-
-   #!/usr/bin/env python
-   import sys
-   data = sys.stdin.read()
-   print('Content-type: text-plain\n\nGot Data: "%s"' % data)
-
-Use of Basic HTTP Authentication::
-
-   import urllib2
-   # Create an OpenerDirector with support for Basic HTTP Authentication...
-   auth_handler = urllib2.HTTPBasicAuthHandler()
-   auth_handler.add_password(realm='PDQ Application',
-                             uri='https://mahler:8092/site-updates.py',
-                             user='klem',
-                             passwd='kadidd!ehopper')
-   opener = urllib2.build_opener(auth_handler)
-   # ...and install it globally so it can be used with urlopen.
-   urllib2.install_opener(opener)
-   urllib2.urlopen('http://www.example.com/login.html')
-
-:func:`build_opener` provides many handlers by default, including a
-:class:`ProxyHandler`.  By default, :class:`ProxyHandler` uses the environment
-variables named ``<scheme>_proxy``, where ``<scheme>`` is the URL scheme
-involved.  For example, the :envvar:`http_proxy` environment variable is read to
-obtain the HTTP proxy's URL.
-
-This example replaces the default :class:`ProxyHandler` with one that uses
-programatically-supplied proxy URLs, and adds proxy authorization support with
-:class:`ProxyBasicAuthHandler`. ::
-
-   proxy_handler = urllib2.ProxyHandler({'http': 'http://www.example.com:3128/'})
-   proxy_auth_handler = urllib2.HTTPBasicAuthHandler()
-   proxy_auth_handler.add_password('realm', 'host', 'username', 'password')
-
-   opener = build_opener(proxy_handler, proxy_auth_handler)
-   # This time, rather than install the OpenerDirector, we use it directly:
-   opener.open('http://www.example.com/login.html')
-
-Adding HTTP headers:
-
-Use the *headers* argument to the :class:`Request` constructor, or::
-
-   import urllib2
-   req = urllib2.Request('http://www.example.com/')
-   req.add_header('Referer', 'http://www.python.org/')
-   r = urllib2.urlopen(req)
-
-:class:`OpenerDirector` automatically adds a :mailheader:`User-Agent` header to
-every :class:`Request`.  To change this::
-
-   import urllib2
-   opener = urllib2.build_opener()
-   opener.addheaders = [('User-agent', 'Mozilla/5.0')]
-   opener.open('http://www.example.com/')
-
-Also, remember that a few standard headers (:mailheader:`Content-Length`,
-:mailheader:`Content-Type` and :mailheader:`Host`) are added when the
-:class:`Request` is passed to :func:`urlopen` (or :meth:`OpenerDirector.open`).
-

Deleted: python/branches/py3k-urllib/Doc/library/urlparse.rst
==============================================================================
--- python/branches/py3k-urllib/Doc/library/urlparse.rst	Mon Jun 23 04:34:41 2008
+++ (empty file)
@@ -1,255 +0,0 @@
-:mod:`urlparse` --- Parse URLs into components
-==============================================
-
-.. module:: urlparse
-   :synopsis: Parse URLs into or assemble them from components.
-
-
-.. index::
-   single: WWW
-   single: World Wide Web
-   single: URL
-   pair: URL; parsing
-   pair: relative; URL
-
-This module defines a standard interface to break Uniform Resource Locator (URL)
-strings up in components (addressing scheme, network location, path etc.), to
-combine the components back into a URL string, and to convert a "relative URL"
-to an absolute URL given a "base URL."
-
-The module has been designed to match the Internet RFC on Relative Uniform
-Resource Locators (and discovered a bug in an earlier draft!). It supports the
-following URL schemes: ``file``, ``ftp``, ``gopher``, ``hdl``, ``http``,
-``https``, ``imap``, ``mailto``, ``mms``, ``news``,  ``nntp``, ``prospero``,
-``rsync``, ``rtsp``, ``rtspu``,  ``sftp``, ``shttp``, ``sip``, ``sips``,
-``snews``, ``svn``,  ``svn+ssh``, ``telnet``, ``wais``.
-
-The :mod:`urlparse` module defines the following functions:
-
-
-.. function:: urlparse(urlstring[, default_scheme[, allow_fragments]])
-
-   Parse a URL into six components, returning a 6-tuple.  This corresponds to the
-   general structure of a URL: ``scheme://netloc/path;parameters?query#fragment``.
-   Each tuple item is a string, possibly empty. The components are not broken up in
-   smaller parts (for example, the network location is a single string), and %
-   escapes are not expanded. The delimiters as shown above are not part of the
-   result, except for a leading slash in the *path* component, which is retained if
-   present.  For example:
-
-      >>> from urlparse import urlparse
-      >>> o = urlparse('http://www.cwi.nl:80/%7Eguido/Python.html')
-      >>> o   # doctest: +NORMALIZE_WHITESPACE
-      ParseResult(scheme='http', netloc='www.cwi.nl:80', path='/%7Eguido/Python.html',
-                  params='', query='', fragment='')
-      >>> o.scheme
-      'http'
-      >>> o.port
-      80
-      >>> o.geturl()
-      'http://www.cwi.nl:80/%7Eguido/Python.html'
-
-   If the *default_scheme* argument is specified, it gives the default addressing
-   scheme, to be used only if the URL does not specify one.  The default value for
-   this argument is the empty string.
-
-   If the *allow_fragments* argument is false, fragment identifiers are not
-   allowed, even if the URL's addressing scheme normally does support them.  The
-   default value for this argument is :const:`True`.
-
-   The return value is actually an instance of a subclass of :class:`tuple`.  This
-   class has the following additional read-only convenience attributes:
-
-   +------------------+-------+--------------------------+----------------------+
-   | Attribute        | Index | Value                    | Value if not present |
-   +==================+=======+==========================+======================+
-   | :attr:`scheme`   | 0     | URL scheme specifier     | empty string         |
-   +------------------+-------+--------------------------+----------------------+
-   | :attr:`netloc`   | 1     | Network location part    | empty string         |
-   +------------------+-------+--------------------------+----------------------+
-   | :attr:`path`     | 2     | Hierarchical path        | empty string         |
-   +------------------+-------+--------------------------+----------------------+
-   | :attr:`params`   | 3     | Parameters for last path | empty string         |
-   |                  |       | element                  |                      |
-   +------------------+-------+--------------------------+----------------------+
-   | :attr:`query`    | 4     | Query component          | empty string         |
-   +------------------+-------+--------------------------+----------------------+
-   | :attr:`fragment` | 5     | Fragment identifier      | empty string         |
-   +------------------+-------+--------------------------+----------------------+
-   | :attr:`username` |       | User name                | :const:`None`        |
-   +------------------+-------+--------------------------+----------------------+
-   | :attr:`password` |       | Password                 | :const:`None`        |
-   +------------------+-------+--------------------------+----------------------+
-   | :attr:`hostname` |       | Host name (lower case)   | :const:`None`        |
-   +------------------+-------+--------------------------+----------------------+
-   | :attr:`port`     |       | Port number as integer,  | :const:`None`        |
-   |                  |       | if present               |                      |
-   +------------------+-------+--------------------------+----------------------+
-
-   See section :ref:`urlparse-result-object` for more information on the result
-   object.
-
-
-.. function:: urlunparse(parts)
-
-   Construct a URL from a tuple as returned by ``urlparse()``. The *parts* argument
-   can be any six-item iterable. This may result in a slightly different, but
-   equivalent URL, if the URL that was parsed originally had unnecessary delimiters
-   (for example, a ? with an empty query; the RFC states that these are
-   equivalent).
-
-
-.. function:: urlsplit(urlstring[, default_scheme[, allow_fragments]])
-
-   This is similar to :func:`urlparse`, but does not split the params from the URL.
-   This should generally be used instead of :func:`urlparse` if the more recent URL
-   syntax allowing parameters to be applied to each segment of the *path* portion
-   of the URL (see :rfc:`2396`) is wanted.  A separate function is needed to
-   separate the path segments and parameters.  This function returns a 5-tuple:
-   (addressing scheme, network location, path, query, fragment identifier).
-
-   The return value is actually an instance of a subclass of :class:`tuple`.  This
-   class has the following additional read-only convenience attributes:
-
-   +------------------+-------+-------------------------+----------------------+
-   | Attribute        | Index | Value                   | Value if not present |
-   +==================+=======+=========================+======================+
-   | :attr:`scheme`   | 0     | URL scheme specifier    | empty string         |
-   +------------------+-------+-------------------------+----------------------+
-   | :attr:`netloc`   | 1     | Network location part   | empty string         |
-   +------------------+-------+-------------------------+----------------------+
-   | :attr:`path`     | 2     | Hierarchical path       | empty string         |
-   +------------------+-------+-------------------------+----------------------+
-   | :attr:`query`    | 3     | Query component         | empty string         |
-   +------------------+-------+-------------------------+----------------------+
-   | :attr:`fragment` | 4     | Fragment identifier     | empty string         |
-   +------------------+-------+-------------------------+----------------------+
-   | :attr:`username` |       | User name               | :const:`None`        |
-   +------------------+-------+-------------------------+----------------------+
-   | :attr:`password` |       | Password                | :const:`None`        |
-   +------------------+-------+-------------------------+----------------------+
-   | :attr:`hostname` |       | Host name (lower case)  | :const:`None`        |
-   +------------------+-------+-------------------------+----------------------+
-   | :attr:`port`     |       | Port number as integer, | :const:`None`        |
-   |                  |       | if present              |                      |
-   +------------------+-------+-------------------------+----------------------+
-
-   See section :ref:`urlparse-result-object` for more information on the result
-   object.
-
-
-.. function:: urlunsplit(parts)
-
-   Combine the elements of a tuple as returned by :func:`urlsplit` into a complete
-   URL as a string. The *parts* argument can be any five-item iterable. This may
-   result in a slightly different, but equivalent URL, if the URL that was parsed
-   originally had unnecessary delimiters (for example, a ? with an empty query; the
-   RFC states that these are equivalent).
-
-
-.. function:: urljoin(base, url[, allow_fragments])
-
-   Construct a full ("absolute") URL by combining a "base URL" (*base*) with
-   another URL (*url*).  Informally, this uses components of the base URL, in
-   particular the addressing scheme, the network location and (part of) the path,
-   to provide missing components in the relative URL.  For example:
-
-      >>> from urlparse import urljoin
-      >>> urljoin('http://www.cwi.nl/%7Eguido/Python.html', 'FAQ.html')
-      'http://www.cwi.nl/%7Eguido/FAQ.html'
-
-   The *allow_fragments* argument has the same meaning and default as for
-   :func:`urlparse`.
-
-   .. note::
-
-      If *url* is an absolute URL (that is, starting with ``//`` or ``scheme://``),
-      the *url*'s host name and/or scheme will be present in the result.  For example:
-
-   .. doctest::
-
-      >>> urljoin('http://www.cwi.nl/%7Eguido/Python.html',
-      ...         '//www.python.org/%7Eguido')
-      'http://www.python.org/%7Eguido'
-
-   If you do not want that behavior, preprocess the *url* with :func:`urlsplit` and
-   :func:`urlunsplit`, removing possible *scheme* and *netloc* parts.
-
-
-.. function:: urldefrag(url)
-
-   If *url* contains a fragment identifier, returns a modified version of *url*
-   with no fragment identifier, and the fragment identifier as a separate string.
-   If there is no fragment identifier in *url*, returns *url* unmodified and an
-   empty string.
-
-
-.. seealso::
-
-   :rfc:`1738` - Uniform Resource Locators (URL)
-      This specifies the formal syntax and semantics of absolute URLs.
-
-   :rfc:`1808` - Relative Uniform Resource Locators
-      This Request For Comments includes the rules for joining an absolute and a
-      relative URL, including a fair number of "Abnormal Examples" which govern the
-      treatment of border cases.
-
-   :rfc:`2396` - Uniform Resource Identifiers (URI): Generic Syntax
-      Document describing the generic syntactic requirements for both Uniform Resource
-      Names (URNs) and Uniform Resource Locators (URLs).
-
-
-.. _urlparse-result-object:
-
-Results of :func:`urlparse` and :func:`urlsplit`
-------------------------------------------------
-
-The result objects from the :func:`urlparse` and :func:`urlsplit` functions are
-subclasses of the :class:`tuple` type.  These subclasses add the attributes
-described in those functions, as well as provide an additional method:
-
-
-.. method:: ParseResult.geturl()
-
-   Return the re-combined version of the original URL as a string. This may differ
-   from the original URL in that the scheme will always be normalized to lower case
-   and empty components may be dropped. Specifically, empty parameters, queries,
-   and fragment identifiers will be removed.
-
-   The result of this method is a fixpoint if passed back through the original
-   parsing function:
-
-      >>> import urlparse
-      >>> url = 'HTTP://www.Python.org/doc/#'
-
-      >>> r1 = urlparse.urlsplit(url)
-      >>> r1.geturl()
-      'http://www.Python.org/doc/'
-
-      >>> r2 = urlparse.urlsplit(r1.geturl())
-      >>> r2.geturl()
-      'http://www.Python.org/doc/'
-
-
-The following classes provide the implementations of the parse results::
-
-
-.. class:: BaseResult
-
-   Base class for the concrete result classes.  This provides most of the attribute
-   definitions.  It does not provide a :meth:`geturl` method.  It is derived from
-   :class:`tuple`, but does not override the :meth:`__init__` or :meth:`__new__`
-   methods.
-
-
-.. class:: ParseResult(scheme, netloc, path, params, query, fragment)
-
-   Concrete class for :func:`urlparse` results.  The :meth:`__new__` method is
-   overridden to support checking that the right number of arguments are passed.
-
-
-.. class:: SplitResult(scheme, netloc, path, query, fragment)
-
-   Concrete class for :func:`urlsplit` results.  The :meth:`__new__` method is
-   overridden to support checking that the right number of arguments are passed.
-

From python-3000-checkins at python.org  Mon Jun 23 06:42:00 2008
From: python-3000-checkins at python.org (senthil.kumaran)
Date: Mon, 23 Jun 2008 06:42:00 +0200 (CEST)
Subject: [Python-3000-checkins] r64476 - in python/branches/py3k/Doc:
	howto/urllib2.rst library/contextlib.rst
	library/fileformats.rst library/ftplib.rst
	library/http.client.rst library/internet.rst
	library/urllib.error.rst library/urllib.parse.rst
	library/urllib.request.rst library/urllib.robotparser.rst
	library/urllib.rst library/urllib2.rst library/urlparse.rst
	tutorial/stdlib.rst
Message-ID: <20080623044200.A038B1E4007@bag.python.org>

Author: senthil.kumaran
Date: Mon Jun 23 06:41:59 2008
New Revision: 64476

Log:
Documentation updates for urllib package. Modified the documentation for the
urllib,urllib2 -> urllib.request,urllib.error
urlparse -> urllib.parse
RobotParser -> urllib.robotparser

Updated tutorial references and other module references (http.client.rst,
ftplib.rst,contextlib.rst)
Updated the examples in the urllib2-howto

Addresses Issue3142.



Added:
   python/branches/py3k/Doc/library/urllib.error.rst   (contents, props changed)
   python/branches/py3k/Doc/library/urllib.parse.rst   (contents, props changed)
   python/branches/py3k/Doc/library/urllib.request.rst   (contents, props changed)
   python/branches/py3k/Doc/library/urllib.robotparser.rst   (contents, props changed)
Removed:
   python/branches/py3k/Doc/library/urllib.rst
   python/branches/py3k/Doc/library/urllib2.rst
   python/branches/py3k/Doc/library/urlparse.rst
Modified:
   python/branches/py3k/Doc/howto/urllib2.rst
   python/branches/py3k/Doc/library/contextlib.rst
   python/branches/py3k/Doc/library/fileformats.rst
   python/branches/py3k/Doc/library/ftplib.rst
   python/branches/py3k/Doc/library/http.client.rst
   python/branches/py3k/Doc/library/internet.rst
   python/branches/py3k/Doc/tutorial/stdlib.rst

Modified: python/branches/py3k/Doc/howto/urllib2.rst
==============================================================================
--- python/branches/py3k/Doc/howto/urllib2.rst	(original)
+++ python/branches/py3k/Doc/howto/urllib2.rst	Mon Jun 23 06:41:59 2008
@@ -1,6 +1,6 @@
-************************************************
-  HOWTO Fetch Internet Resources Using urllib2
-************************************************
+*****************************************************
+  HOWTO Fetch Internet Resources Using urllib package
+*****************************************************
 
 :Author: `Michael Foord <http://www.voidspace.org.uk/python/index.shtml>`_
 
@@ -24,14 +24,14 @@
     
         A tutorial on *Basic Authentication*, with examples in Python.
 
-**urllib2** is a `Python <http://www.python.org>`_ module for fetching URLs
+**urllib.request** is a `Python <http://www.python.org>`_ module for fetching URLs
 (Uniform Resource Locators). It offers a very simple interface, in the form of
 the *urlopen* function. This is capable of fetching URLs using a variety of
 different protocols. It also offers a slightly more complex interface for
 handling common situations - like basic authentication, cookies, proxies and so
 on. These are provided by objects called handlers and openers.
 
-urllib2 supports fetching URLs for many "URL schemes" (identified by the string
+urllib.request supports fetching URLs for many "URL schemes" (identified by the string
 before the ":" in URL - for example "ftp" is the URL scheme of
 "ftp://python.org/") using their associated network protocols (e.g. FTP, HTTP).
 This tutorial focuses on the most common case, HTTP.
@@ -40,43 +40,43 @@
 encounter errors or non-trivial cases when opening HTTP URLs, you will need some
 understanding of the HyperText Transfer Protocol. The most comprehensive and
 authoritative reference to HTTP is :rfc:`2616`. This is a technical document and
-not intended to be easy to read. This HOWTO aims to illustrate using *urllib2*,
+not intended to be easy to read. This HOWTO aims to illustrate using *urllib*,
 with enough detail about HTTP to help you through. It is not intended to replace
-the :mod:`urllib2` docs, but is supplementary to them.
+the :mod:`urllib.request` docs, but is supplementary to them.
 
 
 Fetching URLs
 =============
 
-The simplest way to use urllib2 is as follows::
+The simplest way to use urllib.request is as follows::
 
-    import urllib2
-    response = urllib2.urlopen('http://python.org/')
+    import urllib.request
+    response = urllib.request.urlopen('http://python.org/')
     html = response.read()
 
-Many uses of urllib2 will be that simple (note that instead of an 'http:' URL we
+Many uses of urllib will be that simple (note that instead of an 'http:' URL we
 could have used an URL starting with 'ftp:', 'file:', etc.).  However, it's the
 purpose of this tutorial to explain the more complicated cases, concentrating on
 HTTP.
 
 HTTP is based on requests and responses - the client makes requests and servers
-send responses. urllib2 mirrors this with a ``Request`` object which represents
+send responses. urllib.request mirrors this with a ``Request`` object which represents
 the HTTP request you are making. In its simplest form you create a Request
 object that specifies the URL you want to fetch. Calling ``urlopen`` with this
 Request object returns a response object for the URL requested. This response is
 a file-like object, which means you can for example call ``.read()`` on the
 response::
 
-    import urllib2
+    import urllib.request
 
-    req = urllib2.Request('http://www.voidspace.org.uk')
-    response = urllib2.urlopen(req)
+    req = urllib.request.Request('http://www.voidspace.org.uk')
+    response = urllib.request.urlopen(req)
     the_page = response.read()
 
-Note that urllib2 makes use of the same Request interface to handle all URL
+Note that urllib.request makes use of the same Request interface to handle all URL
 schemes.  For example, you can make an FTP request like so::
 
-    req = urllib2.Request('ftp://example.com/')
+    req = urllib.request.Request('ftp://example.com/')
 
 In the case of HTTP, there are two extra things that Request objects allow you
 to do: First, you can pass data to be sent to the server.  Second, you can pass
@@ -94,20 +94,20 @@
 all POSTs have to come from forms: you can use a POST to transmit arbitrary data
 to your own application. In the common case of HTML forms, the data needs to be
 encoded in a standard way, and then passed to the Request object as the ``data``
-argument. The encoding is done using a function from the ``urllib`` library
-*not* from ``urllib2``. ::
+argument. The encoding is done using a function from the ``urllib.parse`` library
+*not* from ``urllib.request``. ::
 
-    import urllib
-    import urllib2  
+    import urllib.parse
+    import urllib.request 
 
     url = 'http://www.someserver.com/cgi-bin/register.cgi'
     values = {'name' : 'Michael Foord',
               'location' : 'Northampton',
               'language' : 'Python' }
 
-    data = urllib.urlencode(values)
-    req = urllib2.Request(url, data)
-    response = urllib2.urlopen(req)
+    data = urllib.parse.urlencode(values)
+    req = urllib.request.Request(url, data)
+    response = urllib.request.urlopen(req)
     the_page = response.read()
 
 Note that other encodings are sometimes required (e.g. for file upload from HTML
@@ -115,7 +115,7 @@
 <http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13>`_ for more
 details).
 
-If you do not pass the ``data`` argument, urllib2 uses a **GET** request. One
+If you do not pass the ``data`` argument, urllib.request uses a **GET** request. One
 way in which GET and POST requests differ is that POST requests often have
 "side-effects": they change the state of the system in some way (for example by
 placing an order with the website for a hundredweight of tinned spam to be
@@ -127,18 +127,18 @@
 
 This is done as follows::
 
-    >>> import urllib2
-    >>> import urllib
+    >>> import urllib.request
+    >>> import urllib.parse
     >>> data = {}
     >>> data['name'] = 'Somebody Here'
     >>> data['location'] = 'Northampton'
     >>> data['language'] = 'Python'
-    >>> url_values = urllib.urlencode(data)
+    >>> url_values = urllib.parse.urlencode(data)
     >>> print(url_values)
     name=Somebody+Here&language=Python&location=Northampton
     >>> url = 'http://www.example.com/example.cgi'
     >>> full_url = url + '?' + url_values
-    >>> data = urllib2.open(full_url)
+    >>> data = urllib.request.open(full_url)
 
 Notice that the full URL is created by adding a ``?`` to the URL, followed by
 the encoded values.
@@ -150,7 +150,7 @@
 to your HTTP request.
 
 Some websites [#]_ dislike being browsed by programs, or send different versions
-to different browsers [#]_ . By default urllib2 identifies itself as
+to different browsers [#]_ . By default urllib identifies itself as
 ``Python-urllib/x.y`` (where ``x`` and ``y`` are the major and minor version
 numbers of the Python release,
 e.g. ``Python-urllib/2.5``), which may confuse the site, or just plain
@@ -160,8 +160,8 @@
 request as above, but identifies itself as a version of Internet
 Explorer [#]_. ::
 
-    import urllib
-    import urllib2  
+    import urllib.parse
+    import urllib.request 
     
     url = 'http://www.someserver.com/cgi-bin/register.cgi'
     user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)' 
@@ -170,9 +170,9 @@
               'language' : 'Python' }
     headers = { 'User-Agent' : user_agent }
     
-    data = urllib.urlencode(values)
-    req = urllib2.Request(url, data, headers)
-    response = urllib2.urlopen(req)
+    data = urllib.parse.urlencode(values)
+    req = urllib.request.Request(url, data, headers)
+    response = urllib.request.urlopen(req)
     the_page = response.read()
 
 The response also has two useful methods. See the section on `info and geturl`_
@@ -182,7 +182,7 @@
 Handling Exceptions
 ===================
 
-*urlopen* raises ``URLError`` when it cannot handle a response (though as usual
+*urllib.error* raises ``URLError`` when it cannot handle a response (though as usual
 with Python APIs, builtin exceptions such as ValueError, TypeError etc. may also
 be raised).
 
@@ -199,9 +199,9 @@
 
 e.g. ::
 
-    >>> req = urllib2.Request('http://www.pretend_server.org')
-    >>> try: urllib2.urlopen(req)
-    >>> except URLError, e:
+    >>> req = urllib.request.Request('http://www.pretend_server.org')
+    >>> try: urllib.request.urlopen(req)
+    >>> except urllib.error.URLError, e:
     >>>    print(e.reason)
     >>>
     (4, 'getaddrinfo failed')
@@ -214,7 +214,7 @@
 the status code indicates that the server is unable to fulfil the request. The
 default handlers will handle some of these responses for you (for example, if
 the response is a "redirection" that requests the client fetch the document from
-a different URL, urllib2 will handle that for you). For those it can't handle,
+a different URL, urllib.request will handle that for you). For those it can't handle,
 urlopen will raise an ``HTTPError``. Typical errors include '404' (page not
 found), '403' (request forbidden), and '401' (authentication required).
 
@@ -305,12 +305,12 @@
 When an error is raised the server responds by returning an HTTP error code
 *and* an error page. You can use the ``HTTPError`` instance as a response on the
 page returned. This means that as well as the code attribute, it also has read,
-geturl, and info, methods. ::
+geturl, and info, methods as returned by the ``urllib.response`` module::
 
-    >>> req = urllib2.Request('http://www.python.org/fish.html')
+    >>> req = urllib.request.Request('http://www.python.org/fish.html')
     >>> try: 
-    >>>     urllib2.urlopen(req)
-    >>> except URLError, e:
+    >>>     urllib.request.urlopen(req)
+    >>> except urllib.error.URLError, e:
     >>>     print(e.code)
     >>>     print(e.read())
     >>> 
@@ -334,7 +334,8 @@
 ::
 
 
-    from urllib2 import Request, urlopen, URLError, HTTPError
+    from urllib.request import Request, urlopen
+    from urllib.error import URLError, HTTPError
     req = Request(someurl)
     try:
         response = urlopen(req)
@@ -358,7 +359,8 @@
 
 ::
 
-    from urllib2 import Request, urlopen, URLError
+    from urllib.request import Request, urlopen
+    from urllib.error import  URLError
     req = Request(someurl)
     try:
         response = urlopen(req)
@@ -377,7 +379,8 @@
 ===============
 
 The response returned by urlopen (or the ``HTTPError`` instance) has two useful
-methods ``info`` and ``geturl``.
+methods ``info`` and ``geturl`` and is defined in the module
+``urllib.response``.
 
 **geturl** - this returns the real URL of the page fetched. This is useful
 because ``urlopen`` (or the opener object used) may have followed a
@@ -397,7 +400,7 @@
 ====================
 
 When you fetch a URL you use an opener (an instance of the perhaps
-confusingly-named :class:`urllib2.OpenerDirector`). Normally we have been using
+confusingly-named :class:`urllib.request.OpenerDirector`). Normally we have been using
 the default opener - via ``urlopen`` - but you can create custom
 openers. Openers use handlers. All the "heavy lifting" is done by the
 handlers. Each handler knows how to open URLs for a particular URL scheme (http,
@@ -466,24 +469,24 @@
 than the URL you pass to .add_password() will also match. ::
 
     # create a password manager
-    password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm()                        
+    password_mgr = urllib.request.HTTPPasswordMgrWithDefaultRealm()                        
 
     # Add the username and password.
     # If we knew the realm, we could use it instead of ``None``.
     top_level_url = "http://example.com/foo/"
     password_mgr.add_password(None, top_level_url, username, password)
 
-    handler = urllib2.HTTPBasicAuthHandler(password_mgr)                            
+    handler = urllib.request.HTTPBasicAuthHandler(password_mgr)                            
 
     # create "opener" (OpenerDirector instance)
-    opener = urllib2.build_opener(handler)                       
+    opener = urllib.request.build_opener(handler)                       
 
     # use the opener to fetch a URL
     opener.open(a_url)      
 
     # Install the opener.
-    # Now all calls to urllib2.urlopen use our opener.
-    urllib2.install_opener(opener)                               
+    # Now all calls to urllib.request.urlopen use our opener.
+    urllib.request.install_opener(opener)                               
 
 .. note::
 
@@ -505,46 +508,46 @@
 Proxies
 =======
 
-**urllib2** will auto-detect your proxy settings and use those. This is through
+**urllib.request** will auto-detect your proxy settings and use those. This is through
 the ``ProxyHandler`` which is part of the normal handler chain. Normally that's
 a good thing, but there are occasions when it may not be helpful [#]_. One way
 to do this is to setup our own ``ProxyHandler``, with no proxies defined. This
 is done using similar steps to setting up a `Basic Authentication`_ handler : ::
 
-    >>> proxy_support = urllib2.ProxyHandler({})
-    >>> opener = urllib2.build_opener(proxy_support)
-    >>> urllib2.install_opener(opener)
+    >>> proxy_support = urllib.request.ProxyHandler({})
+    >>> opener = urllib.request.build_opener(proxy_support)
+    >>> urllib.request.install_opener(opener)
 
 .. note::
 
-    Currently ``urllib2`` *does not* support fetching of ``https`` locations
-    through a proxy.  However, this can be enabled by extending urllib2 as
+    Currently ``urllib.request`` *does not* support fetching of ``https`` locations
+    through a proxy.  However, this can be enabled by extending urllib.request as
     shown in the recipe [#]_.
 
 
 Sockets and Layers
 ==================
 
-The Python support for fetching resources from the web is layered. urllib2 uses
-the http.client library, which in turn uses the socket library.
+The Python support for fetching resources from the web is layered.
+urllib.request uses the http.client library, which in turn uses the socket library.
 
 As of Python 2.3 you can specify how long a socket should wait for a response
 before timing out. This can be useful in applications which have to fetch web
 pages. By default the socket module has *no timeout* and can hang. Currently,
-the socket timeout is not exposed at the http.client or urllib2 levels.
+the socket timeout is not exposed at the http.client or urllib.request levels.
 However, you can set the default timeout globally for all sockets using ::
 
     import socket
-    import urllib2
+    import urllib.request
 
     # timeout in seconds
     timeout = 10
     socket.setdefaulttimeout(timeout) 
 
-    # this call to urllib2.urlopen now uses the default timeout
+    # this call to urllib.request.urlopen now uses the default timeout
     # we have set in the socket module
-    req = urllib2.Request('http://www.voidspace.org.uk')
-    response = urllib2.urlopen(req)
+    req = urllib.request.Request('http://www.voidspace.org.uk')
+    response = urllib.request.urlopen(req)
 
 
 -------

Modified: python/branches/py3k/Doc/library/contextlib.rst
==============================================================================
--- python/branches/py3k/Doc/library/contextlib.rst	(original)
+++ python/branches/py3k/Doc/library/contextlib.rst	Mon Jun 23 06:41:59 2008
@@ -98,9 +98,9 @@
    And lets you write code like this::
 
       from contextlib import closing
-      import urllib
+      import urllib.request
 
-      with closing(urllib.urlopen('http://www.python.org')) as page:
+      with closing(urllib.request.urlopen('http://www.python.org')) as page:
           for line in page:
               print(line)
 

Modified: python/branches/py3k/Doc/library/fileformats.rst
==============================================================================
--- python/branches/py3k/Doc/library/fileformats.rst	(original)
+++ python/branches/py3k/Doc/library/fileformats.rst	Mon Jun 23 06:41:59 2008
@@ -13,7 +13,6 @@
 
    csv.rst
    configparser.rst
-   robotparser.rst
    netrc.rst
    xdrlib.rst
    plistlib.rst

Modified: python/branches/py3k/Doc/library/ftplib.rst
==============================================================================
--- python/branches/py3k/Doc/library/ftplib.rst	(original)
+++ python/branches/py3k/Doc/library/ftplib.rst	Mon Jun 23 06:41:59 2008
@@ -13,9 +13,9 @@
 This module defines the class :class:`FTP` and a few related items. The
 :class:`FTP` class implements the client side of the FTP protocol.  You can use
 this to write Python programs that perform a variety of automated FTP jobs, such
-as mirroring other ftp servers.  It is also used by the module :mod:`urllib` to
-handle URLs that use FTP.  For more information on FTP (File Transfer Protocol),
-see Internet :rfc:`959`.
+as mirroring other ftp servers.  It is also used by the module
+:mod:`urllib.request` to handle URLs that use FTP.  For more information on FTP
+(File Transfer Protocol), see Internet :rfc:`959`.
 
 Here's a sample session using the :mod:`ftplib` module::
 

Modified: python/branches/py3k/Doc/library/http.client.rst
==============================================================================
--- python/branches/py3k/Doc/library/http.client.rst	(original)
+++ python/branches/py3k/Doc/library/http.client.rst	Mon Jun 23 06:41:59 2008
@@ -9,10 +9,11 @@
    pair: HTTP; protocol
    single: HTTP; http.client (standard module)
 
-.. index:: module: urllib
+.. index:: module: urllib.request
 
 This module defines classes which implement the client side of the HTTP and
-HTTPS protocols.  It is normally not used directly --- the module :mod:`urllib`
+HTTPS protocols.  It is normally not used directly --- the module
+:mod:`urllib.request`
 uses it to handle URLs that use HTTP and HTTPS.
 
 .. note::
@@ -484,8 +485,8 @@
 
 Here is an example session that shows how to ``POST`` requests::
 
-   >>> import http.client, urllib
-   >>> params = urllib.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0})
+   >>> import http.client, urllib.parse
+   >>> params = urllib.parse.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0})
    >>> headers = {"Content-type": "application/x-www-form-urlencoded",
    ...            "Accept": "text/plain"}
    >>> conn = http.client.HTTPConnection("musi-cal.mojam.com:80")

Modified: python/branches/py3k/Doc/library/internet.rst
==============================================================================
--- python/branches/py3k/Doc/library/internet.rst	(original)
+++ python/branches/py3k/Doc/library/internet.rst	Mon Jun 23 06:41:59 2008
@@ -24,8 +24,10 @@
    cgi.rst
    cgitb.rst
    wsgiref.rst
-   urllib.rst
-   urllib2.rst
+   urllib.request.rst
+   urllib.parse.rst
+   urllib.error.rst
+   urllib.robotparser.rst
    http.client.rst
    ftplib.rst
    poplib.rst
@@ -35,7 +37,6 @@
    smtpd.rst
    telnetlib.rst
    uuid.rst
-   urlparse.rst
    socketserver.rst
    http.server.rst
    http.cookies.rst

Added: python/branches/py3k/Doc/library/urllib.error.rst
==============================================================================
--- (empty file)
+++ python/branches/py3k/Doc/library/urllib.error.rst	Mon Jun 23 06:41:59 2008
@@ -0,0 +1,48 @@
+:mod:`urllib.error` --- Exception classes raised by urllib.request
+==================================================================
+
+.. module:: urllib.error
+   :synopsis: Next generation URL opening library.
+.. moduleauthor:: Jeremy Hylton <jhylton at users.sourceforge.net>
+.. sectionauthor:: Senthil Kumaran <orsenthil at gmail.com>
+
+
+The :mod:`urllib.error` module defines exception classes raise by
+urllib.request. The base exception class is URLError, which inherits from
+IOError.
+
+The following exceptions are raised by :mod:`urllib.error` as appropriate:
+
+
+.. exception:: URLError
+
+   The handlers raise this exception (or derived exceptions) when they run into a
+   problem.  It is a subclass of :exc:`IOError`.
+
+   .. attribute:: reason
+
+      The reason for this error.  It can be a message string or another exception
+      instance (:exc:`socket.error` for remote URLs, :exc:`OSError` for local
+      URLs).
+
+
+.. exception:: HTTPError
+
+   Though being an exception (a subclass of :exc:`URLError`), an :exc:`HTTPError`
+   can also function as a non-exceptional file-like return value (the same thing
+   that :func:`urlopen` returns).  This is useful when handling exotic HTTP
+   errors, such as requests for authentication.
+
+   .. attribute:: code
+
+      An HTTP status code as defined in `RFC 2616 <http://www.faqs.org/rfcs/rfc2616.html>`_. 
+      This numeric value corresponds to a value found in the dictionary of
+      codes as found in :attr:`http.server.BaseHTTPRequestHandler.responses`.
+
+.. exception:: ContentTooShortError(msg[, content])
+
+   This exception is raised when the :func:`urlretrieve` function detects that the
+   amount of the downloaded data is less than the  expected amount (given by the
+   *Content-Length* header). The :attr:`content` attribute stores the downloaded
+   (and supposedly truncated) data.
+

Added: python/branches/py3k/Doc/library/urllib.parse.rst
==============================================================================
--- (empty file)
+++ python/branches/py3k/Doc/library/urllib.parse.rst	Mon Jun 23 06:41:59 2008
@@ -0,0 +1,301 @@
+:mod:`urllib.parse` --- Parse URLs into components
+==================================================
+
+.. module:: urllib.parse
+   :synopsis: Parse URLs into or assemble them from components.
+
+
+.. index::
+   single: WWW
+   single: World Wide Web
+   single: URL
+   pair: URL; parsing
+   pair: relative; URL
+
+This module defines a standard interface to break Uniform Resource Locator (URL)
+strings up in components (addressing scheme, network location, path etc.), to
+combine the components back into a URL string, and to convert a "relative URL"
+to an absolute URL given a "base URL."
+
+The module has been designed to match the Internet RFC on Relative Uniform
+Resource Locators (and discovered a bug in an earlier draft!). It supports the
+following URL schemes: ``file``, ``ftp``, ``gopher``, ``hdl``, ``http``,
+``https``, ``imap``, ``mailto``, ``mms``, ``news``,  ``nntp``, ``prospero``,
+``rsync``, ``rtsp``, ``rtspu``,  ``sftp``, ``shttp``, ``sip``, ``sips``,
+``snews``, ``svn``,  ``svn+ssh``, ``telnet``, ``wais``.
+
+The :mod:`urllib.parse` module defines the following functions:
+
+
+.. function:: urlparse(urlstring[, default_scheme[, allow_fragments]])
+
+   Parse a URL into six components, returning a 6-tuple.  This corresponds to the
+   general structure of a URL: ``scheme://netloc/path;parameters?query#fragment``.
+   Each tuple item is a string, possibly empty. The components are not broken up in
+   smaller parts (for example, the network location is a single string), and %
+   escapes are not expanded. The delimiters as shown above are not part of the
+   result, except for a leading slash in the *path* component, which is retained if
+   present.  For example:
+
+      >>> from urllib.parse import urlparse
+      >>> o = urlparse('http://www.cwi.nl:80/%7Eguido/Python.html')
+      >>> o   # doctest: +NORMALIZE_WHITESPACE
+      ParseResult(scheme='http', netloc='www.cwi.nl:80', path='/%7Eguido/Python.html',
+                  params='', query='', fragment='')
+      >>> o.scheme
+      'http'
+      >>> o.port
+      80
+      >>> o.geturl()
+      'http://www.cwi.nl:80/%7Eguido/Python.html'
+
+   If the *default_scheme* argument is specified, it gives the default addressing
+   scheme, to be used only if the URL does not specify one.  The default value for
+   this argument is the empty string.
+
+   If the *allow_fragments* argument is false, fragment identifiers are not
+   allowed, even if the URL's addressing scheme normally does support them.  The
+   default value for this argument is :const:`True`.
+
+   The return value is actually an instance of a subclass of :class:`tuple`.  This
+   class has the following additional read-only convenience attributes:
+
+   +------------------+-------+--------------------------+----------------------+
+   | Attribute        | Index | Value                    | Value if not present |
+   +==================+=======+==========================+======================+
+   | :attr:`scheme`   | 0     | URL scheme specifier     | empty string         |
+   +------------------+-------+--------------------------+----------------------+
+   | :attr:`netloc`   | 1     | Network location part    | empty string         |
+   +------------------+-------+--------------------------+----------------------+
+   | :attr:`path`     | 2     | Hierarchical path        | empty string         |
+   +------------------+-------+--------------------------+----------------------+
+   | :attr:`params`   | 3     | Parameters for last path | empty string         |
+   |                  |       | element                  |                      |
+   +------------------+-------+--------------------------+----------------------+
+   | :attr:`query`    | 4     | Query component          | empty string         |
+   +------------------+-------+--------------------------+----------------------+
+   | :attr:`fragment` | 5     | Fragment identifier      | empty string         |
+   +------------------+-------+--------------------------+----------------------+
+   | :attr:`username` |       | User name                | :const:`None`        |
+   +------------------+-------+--------------------------+----------------------+
+   | :attr:`password` |       | Password                 | :const:`None`        |
+   +------------------+-------+--------------------------+----------------------+
+   | :attr:`hostname` |       | Host name (lower case)   | :const:`None`        |
+   +------------------+-------+--------------------------+----------------------+
+   | :attr:`port`     |       | Port number as integer,  | :const:`None`        |
+   |                  |       | if present               |                      |
+   +------------------+-------+--------------------------+----------------------+
+
+   See section :ref:`urlparse-result-object` for more information on the result
+   object.
+
+
+.. function:: urlunparse(parts)
+
+   Construct a URL from a tuple as returned by ``urlparse()``. The *parts* argument
+   can be any six-item iterable. This may result in a slightly different, but
+   equivalent URL, if the URL that was parsed originally had unnecessary delimiters
+   (for example, a ? with an empty query; the RFC states that these are
+   equivalent).
+
+
+.. function:: urlsplit(urlstring[, default_scheme[, allow_fragments]])
+
+   This is similar to :func:`urlparse`, but does not split the params from the URL.
+   This should generally be used instead of :func:`urlparse` if the more recent URL
+   syntax allowing parameters to be applied to each segment of the *path* portion
+   of the URL (see :rfc:`2396`) is wanted.  A separate function is needed to
+   separate the path segments and parameters.  This function returns a 5-tuple:
+   (addressing scheme, network location, path, query, fragment identifier).
+
+   The return value is actually an instance of a subclass of :class:`tuple`.  This
+   class has the following additional read-only convenience attributes:
+
+   +------------------+-------+-------------------------+----------------------+
+   | Attribute        | Index | Value                   | Value if not present |
+   +==================+=======+=========================+======================+
+   | :attr:`scheme`   | 0     | URL scheme specifier    | empty string         |
+   +------------------+-------+-------------------------+----------------------+
+   | :attr:`netloc`   | 1     | Network location part   | empty string         |
+   +------------------+-------+-------------------------+----------------------+
+   | :attr:`path`     | 2     | Hierarchical path       | empty string         |
+   +------------------+-------+-------------------------+----------------------+
+   | :attr:`query`    | 3     | Query component         | empty string         |
+   +------------------+-------+-------------------------+----------------------+
+   | :attr:`fragment` | 4     | Fragment identifier     | empty string         |
+   +------------------+-------+-------------------------+----------------------+
+   | :attr:`username` |       | User name               | :const:`None`        |
+   +------------------+-------+-------------------------+----------------------+
+   | :attr:`password` |       | Password                | :const:`None`        |
+   +------------------+-------+-------------------------+----------------------+
+   | :attr:`hostname` |       | Host name (lower case)  | :const:`None`        |
+   +------------------+-------+-------------------------+----------------------+
+   | :attr:`port`     |       | Port number as integer, | :const:`None`        |
+   |                  |       | if present              |                      |
+   +------------------+-------+-------------------------+----------------------+
+
+   See section :ref:`urlparse-result-object` for more information on the result
+   object.
+
+
+.. function:: urlunsplit(parts)
+
+   Combine the elements of a tuple as returned by :func:`urlsplit` into a complete
+   URL as a string. The *parts* argument can be any five-item iterable. This may
+   result in a slightly different, but equivalent URL, if the URL that was parsed
+   originally had unnecessary delimiters (for example, a ? with an empty query; the
+   RFC states that these are equivalent).
+
+
+.. function:: urljoin(base, url[, allow_fragments])
+
+   Construct a full ("absolute") URL by combining a "base URL" (*base*) with
+   another URL (*url*).  Informally, this uses components of the base URL, in
+   particular the addressing scheme, the network location and (part of) the path,
+   to provide missing components in the relative URL.  For example:
+
+      >>> from urllib.parse import urljoin
+      >>> urljoin('http://www.cwi.nl/%7Eguido/Python.html', 'FAQ.html')
+      'http://www.cwi.nl/%7Eguido/FAQ.html'
+
+   The *allow_fragments* argument has the same meaning and default as for
+   :func:`urlparse`.
+
+   .. note::
+
+      If *url* is an absolute URL (that is, starting with ``//`` or ``scheme://``),
+      the *url*'s host name and/or scheme will be present in the result.  For example:
+
+   .. doctest::
+
+      >>> urljoin('http://www.cwi.nl/%7Eguido/Python.html',
+      ...         '//www.python.org/%7Eguido')
+      'http://www.python.org/%7Eguido'
+
+   If you do not want that behavior, preprocess the *url* with :func:`urlsplit` and
+   :func:`urlunsplit`, removing possible *scheme* and *netloc* parts.
+
+
+.. function:: urldefrag(url)
+
+   If *url* contains a fragment identifier, returns a modified version of *url*
+   with no fragment identifier, and the fragment identifier as a separate string.
+   If there is no fragment identifier in *url*, returns *url* unmodified and an
+   empty string.
+
+.. function:: quote(string[, safe])
+
+   Replace special characters in *string* using the ``%xx`` escape. Letters,
+   digits, and the characters ``'_.-'`` are never quoted. The optional *safe*
+   parameter specifies additional characters that should not be quoted --- its
+   default value is ``'/'``.
+
+   Example: ``quote('/~connolly/')`` yields ``'/%7econnolly/'``.
+
+
+.. function:: quote_plus(string[, safe])
+
+   Like :func:`quote`, but also replaces spaces by plus signs, as required for
+   quoting HTML form values.  Plus signs in the original string are escaped unless
+   they are included in *safe*.  It also does not have *safe* default to ``'/'``.
+
+
+.. function:: unquote(string)
+
+   Replace ``%xx`` escapes by their single-character equivalent.
+
+   Example: ``unquote('/%7Econnolly/')`` yields ``'/~connolly/'``.
+
+
+.. function:: unquote_plus(string)
+
+   Like :func:`unquote`, but also replaces plus signs by spaces, as required for
+   unquoting HTML form values.
+
+
+.. function:: urlencode(query[, doseq])
+
+   Convert a mapping object or a sequence of two-element tuples  to a "url-encoded"
+   string, suitable to pass to :func:`urlopen` above as the optional *data*
+   argument.  This is useful to pass a dictionary of form fields to a ``POST``
+   request.  The resulting string is a series of ``key=value`` pairs separated by
+   ``'&'`` characters, where both *key* and *value* are quoted using
+   :func:`quote_plus` above.  If the optional parameter *doseq* is present and
+   evaluates to true, individual ``key=value`` pairs are generated for each element
+   of the sequence. When a sequence of two-element tuples is used as the *query*
+   argument, the first element of each tuple is a key and the second is a value.
+   The order of parameters in the encoded string will match the order of parameter
+   tuples in the sequence. The :mod:`cgi` module provides the functions
+   :func:`parse_qs` and :func:`parse_qsl` which are used to parse query strings
+   into Python data structures.
+
+
+.. seealso::
+
+   :rfc:`1738` - Uniform Resource Locators (URL)
+      This specifies the formal syntax and semantics of absolute URLs.
+
+   :rfc:`1808` - Relative Uniform Resource Locators
+      This Request For Comments includes the rules for joining an absolute and a
+      relative URL, including a fair number of "Abnormal Examples" which govern the
+      treatment of border cases.
+
+   :rfc:`2396` - Uniform Resource Identifiers (URI): Generic Syntax
+      Document describing the generic syntactic requirements for both Uniform Resource
+      Names (URNs) and Uniform Resource Locators (URLs).
+
+
+.. _urlparse-result-object:
+
+Results of :func:`urlparse` and :func:`urlsplit`
+------------------------------------------------
+
+The result objects from the :func:`urlparse` and :func:`urlsplit` functions are
+subclasses of the :class:`tuple` type.  These subclasses add the attributes
+described in those functions, as well as provide an additional method:
+
+
+.. method:: ParseResult.geturl()
+
+   Return the re-combined version of the original URL as a string. This may differ
+   from the original URL in that the scheme will always be normalized to lower case
+   and empty components may be dropped. Specifically, empty parameters, queries,
+   and fragment identifiers will be removed.
+
+   The result of this method is a fixpoint if passed back through the original
+   parsing function:
+
+      >>> import urllib.parse
+      >>> url = 'HTTP://www.Python.org/doc/#'
+
+      >>> r1 = urllib.parse.urlsplit(url)
+      >>> r1.geturl()
+      'http://www.Python.org/doc/'
+
+      >>> r2 = urllib.parse.urlsplit(r1.geturl())
+      >>> r2.geturl()
+      'http://www.Python.org/doc/'
+
+
+The following classes provide the implementations of the parse results::
+
+
+.. class:: BaseResult
+
+   Base class for the concrete result classes.  This provides most of the attribute
+   definitions.  It does not provide a :meth:`geturl` method.  It is derived from
+   :class:`tuple`, but does not override the :meth:`__init__` or :meth:`__new__`
+   methods.
+
+
+.. class:: ParseResult(scheme, netloc, path, params, query, fragment)
+
+   Concrete class for :func:`urlparse` results.  The :meth:`__new__` method is
+   overridden to support checking that the right number of arguments are passed.
+
+
+.. class:: SplitResult(scheme, netloc, path, query, fragment)
+
+   Concrete class for :func:`urlsplit` results.  The :meth:`__new__` method is
+   overridden to support checking that the right number of arguments are passed.
+

Added: python/branches/py3k/Doc/library/urllib.request.rst
==============================================================================
--- (empty file)
+++ python/branches/py3k/Doc/library/urllib.request.rst	Mon Jun 23 06:41:59 2008
@@ -0,0 +1,1194 @@
+:mod:`urllib.request` --- extensible library for opening URLs
+=============================================================
+
+.. module:: urllib.request
+   :synopsis: Next generation URL opening library.
+.. moduleauthor:: Jeremy Hylton <jhylton at users.sourceforge.net>
+.. sectionauthor:: Moshe Zadka <moshez at users.sourceforge.net>
+
+
+The :mod:`urllib.request` module defines functions and classes which help in opening
+URLs (mostly HTTP) in a complex world --- basic and digest authentication,
+redirections, cookies and more.
+
+The :mod:`urllib.request` module defines the following functions:
+
+
+.. function:: urlopen(url[, data][, timeout])
+
+   Open the URL *url*, which can be either a string or a :class:`Request` object.
+
+   *data* may be a string specifying additional data to send to the server, or
+   ``None`` if no such data is needed.  Currently HTTP requests are the only ones
+   that use *data*; the HTTP request will be a POST instead of a GET when the
+   *data* parameter is provided.  *data* should be a buffer in the standard
+   :mimetype:`application/x-www-form-urlencoded` format.  The
+   :func:`urllib.urlencode` function takes a mapping or sequence of 2-tuples and
+   returns a string in this format.
+
+   The optional *timeout* parameter specifies a timeout in seconds for blocking
+   operations like the connection attempt (if not specified, the global default
+   timeout setting will be used).  This actually only works for HTTP, HTTPS,
+   FTP and FTPS connections.
+
+   This function returns a file-like object with two additional methods from
+   the :mod:`urllib.response` module
+
+   * :meth:`geturl` --- return the URL of the resource retrieved, commonly used to
+     determine if a redirect was followed
+
+   * :meth:`info` --- return the meta-information of the page, such as headers, in
+     the form of an ``http.client.HTTPMessage`` instance
+     (see `Quick Reference to HTTP Headers <http://www.cs.tut.fi/~jkorpela/http.html>`_)
+
+   Raises :exc:`URLError` on errors.
+
+   Note that ``None`` may be returned if no handler handles the request (though the
+   default installed global :class:`OpenerDirector` uses :class:`UnknownHandler` to
+   ensure this never happens).
+   The urlopen function from the previous version, Python 2.6 and earlier,  of
+   the module  urllib has been discontinued as urlopen can return the
+   file-object as the previous. The proxy handling, which in earlier was passed
+   as a dict parameter to urlopen can be availed by the use of `ProxyHandler`
+   objects.
+
+
+.. function:: install_opener(opener)
+
+   Install an :class:`OpenerDirector` instance as the default global opener.
+   Installing an opener is only necessary if you want urlopen to use that opener;
+   otherwise, simply call :meth:`OpenerDirector.open` instead of :func:`urlopen`.
+   The code does not check for a real :class:`OpenerDirector`, and any class with
+   the appropriate interface will work.
+
+
+.. function:: build_opener([handler, ...])
+
+   Return an :class:`OpenerDirector` instance, which chains the handlers in the
+   order given. *handler*\s can be either instances of :class:`BaseHandler`, or
+   subclasses of :class:`BaseHandler` (in which case it must be possible to call
+   the constructor without any parameters).  Instances of the following classes
+   will be in front of the *handler*\s, unless the *handler*\s contain them,
+   instances of them or subclasses of them: :class:`ProxyHandler`,
+   :class:`UnknownHandler`, :class:`HTTPHandler`, :class:`HTTPDefaultErrorHandler`,
+   :class:`HTTPRedirectHandler`, :class:`FTPHandler`, :class:`FileHandler`,
+   :class:`HTTPErrorProcessor`.
+
+   If the Python installation has SSL support (i.e., if the :mod:`ssl` module can be imported),
+   :class:`HTTPSHandler` will also be added.
+
+   A :class:`BaseHandler` subclass may also change its :attr:`handler_order`
+   member variable to modify its position in the handlers list.
+
+.. function:: urlretrieve(url[, filename[, reporthook[, data]]])
+
+   Copy a network object denoted by a URL to a local file, if necessary. If the URL
+   points to a local file, or a valid cached copy of the object exists, the object
+   is not copied.  Return a tuple ``(filename, headers)`` where *filename* is the
+   local file name under which the object can be found, and *headers* is whatever
+   the :meth:`info` method of the object returned by :func:`urlopen` returned (for
+   a remote object, possibly cached). Exceptions are the same as for
+   :func:`urlopen`.
+
+   The second argument, if present, specifies the file location to copy to (if
+   absent, the location will be a tempfile with a generated name). The third
+   argument, if present, is a hook function that will be called once on
+   establishment of the network connection and once after each block read
+   thereafter.  The hook will be passed three arguments; a count of blocks
+   transferred so far, a block size in bytes, and the total size of the file.  The
+   third argument may be ``-1`` on older FTP servers which do not return a file
+   size in response to a retrieval request.
+
+   If the *url* uses the :file:`http:` scheme identifier, the optional *data*
+   argument may be given to specify a ``POST`` request (normally the request type
+   is ``GET``).  The *data* argument must in standard
+   :mimetype:`application/x-www-form-urlencoded` format; see the :func:`urlencode`
+   function below.
+
+   :func:`urlretrieve` will raise :exc:`ContentTooShortError` when it detects that
+   the amount of data available  was less than the expected amount (which is the
+   size reported by a  *Content-Length* header). This can occur, for example, when
+   the  download is interrupted.
+
+   The *Content-Length* is treated as a lower bound: if there's more data  to read,
+   urlretrieve reads more data, but if less data is available,  it raises the
+   exception.
+
+   You can still retrieve the downloaded data in this case, it is stored  in the
+   :attr:`content` attribute of the exception instance.
+
+   If no *Content-Length* header was supplied, urlretrieve can not check the size
+   of the data it has downloaded, and just returns it.  In this case you just have
+   to assume that the download was successful.
+
+
+.. data:: _urlopener
+
+   The public functions :func:`urlopen` and :func:`urlretrieve` create an instance
+   of the :class:`FancyURLopener` class and use it to perform their requested
+   actions.  To override this functionality, programmers can create a subclass of
+   :class:`URLopener` or :class:`FancyURLopener`, then assign an instance of that
+   class to the ``urllib._urlopener`` variable before calling the desired function.
+   For example, applications may want to specify a different
+   :mailheader:`User-Agent` header than :class:`URLopener` defines.  This can be
+   accomplished with the following code::
+
+      import urllib.request
+
+      class AppURLopener(urllib.request.FancyURLopener):
+          version = "App/1.7"
+
+      urllib._urlopener = AppURLopener()
+
+
+.. function:: urlcleanup()
+
+   Clear the cache that may have been built up by previous calls to
+   :func:`urlretrieve`.
+
+.. function:: pathname2url(path)
+
+   Convert the pathname *path* from the local syntax for a path to the form used in
+   the path component of a URL.  This does not produce a complete URL.  The return
+   value will already be quoted using the :func:`quote` function.
+
+
+.. function:: url2pathname(path)
+
+   Convert the path component *path* from an encoded URL to the local syntax for a
+   path.  This does not accept a complete URL.  This function uses :func:`unquote`
+   to decode *path*.
+
+The following classes are provided:
+
+.. class:: Request(url[, data][, headers][, origin_req_host][, unverifiable])
+
+   This class is an abstraction of a URL request.
+
+   *url* should be a string containing a valid URL.
+
+   *data* may be a string specifying additional data to send to the server, or
+   ``None`` if no such data is needed.  Currently HTTP requests are the only ones
+   that use *data*; the HTTP request will be a POST instead of a GET when the
+   *data* parameter is provided.  *data* should be a buffer in the standard
+   :mimetype:`application/x-www-form-urlencoded` format.  The
+   :func:`urllib.urlencode` function takes a mapping or sequence of 2-tuples and
+   returns a string in this format.
+
+   *headers* should be a dictionary, and will be treated as if :meth:`add_header`
+   was called with each key and value as arguments.  This is often used to "spoof"
+   the ``User-Agent`` header, which is used by a browser to identify itself --
+   some HTTP servers only allow requests coming from common browsers as opposed
+   to scripts.  For example, Mozilla Firefox may identify itself as ``"Mozilla/5.0
+   (X11; U; Linux i686) Gecko/20071127 Firefox/2.0.0.11"``, while :mod:`urllib2`'s
+   default user agent string is ``"Python-urllib/2.6"`` (on Python 2.6).
+
+   The final two arguments are only of interest for correct handling of third-party
+   HTTP cookies:
+
+   *origin_req_host* should be the request-host of the origin transaction, as
+   defined by :rfc:`2965`.  It defaults to ``http.cookiejar.request_host(self)``.
+   This is the host name or IP address of the original request that was
+   initiated by the user.  For example, if the request is for an image in an
+   HTML document, this should be the request-host of the request for the page
+   containing the image.
+
+   *unverifiable* should indicate whether the request is unverifiable, as defined
+   by RFC 2965.  It defaults to False.  An unverifiable request is one whose URL
+   the user did not have the option to approve.  For example, if the request is for
+   an image in an HTML document, and the user had no option to approve the
+   automatic fetching of the image, this should be true.
+
+.. class:: URLopener([proxies[, **x509]])
+
+   Base class for opening and reading URLs.  Unless you need to support opening
+   objects using schemes other than :file:`http:`, :file:`ftp:`, or :file:`file:`,
+   you probably want to use :class:`FancyURLopener`.
+
+   By default, the :class:`URLopener` class sends a :mailheader:`User-Agent` header
+   of ``urllib/VVV``, where *VVV* is the :mod:`urllib` version number.
+   Applications can define their own :mailheader:`User-Agent` header by subclassing
+   :class:`URLopener` or :class:`FancyURLopener` and setting the class attribute
+   :attr:`version` to an appropriate string value in the subclass definition.
+
+   The optional *proxies* parameter should be a dictionary mapping scheme names to
+   proxy URLs, where an empty dictionary turns proxies off completely.  Its default
+   value is ``None``, in which case environmental proxy settings will be used if
+   present, as discussed in the definition of :func:`urlopen`, above.
+
+   Additional keyword parameters, collected in *x509*, may be used for
+   authentication of the client when using the :file:`https:` scheme.  The keywords
+   *key_file* and *cert_file* are supported to provide an  SSL key and certificate;
+   both are needed to support client authentication.
+
+   :class:`URLopener` objects will raise an :exc:`IOError` exception if the server
+   returns an error code.
+
+    .. method:: open(fullurl[, data])
+
+       Open *fullurl* using the appropriate protocol.  This method sets up cache and
+       proxy information, then calls the appropriate open method with its input
+       arguments.  If the scheme is not recognized, :meth:`open_unknown` is called.
+       The *data* argument has the same meaning as the *data* argument of
+       :func:`urlopen`.
+
+
+    .. method:: open_unknown(fullurl[, data])
+
+       Overridable interface to open unknown URL types.
+
+
+    .. method:: retrieve(url[, filename[, reporthook[, data]]])
+
+       Retrieves the contents of *url* and places it in *filename*.  The return value
+       is a tuple consisting of a local filename and either a
+       :class:`email.message.Message` object containing the response headers (for remote
+       URLs) or ``None`` (for local URLs).  The caller must then open and read the
+       contents of *filename*.  If *filename* is not given and the URL refers to a
+       local file, the input filename is returned.  If the URL is non-local and
+       *filename* is not given, the filename is the output of :func:`tempfile.mktemp`
+       with a suffix that matches the suffix of the last path component of the input
+       URL.  If *reporthook* is given, it must be a function accepting three numeric
+       parameters.  It will be called after each chunk of data is read from the
+       network.  *reporthook* is ignored for local URLs.
+
+       If the *url* uses the :file:`http:` scheme identifier, the optional *data*
+       argument may be given to specify a ``POST`` request (normally the request type
+       is ``GET``).  The *data* argument must in standard
+       :mimetype:`application/x-www-form-urlencoded` format; see the :func:`urlencode`
+       function below.
+
+
+    .. attribute:: version
+
+       Variable that specifies the user agent of the opener object.  To get
+       :mod:`urllib` to tell servers that it is a particular user agent, set this in a
+       subclass as a class variable or in the constructor before calling the base
+       constructor.
+
+
+.. class:: FancyURLopener(...)
+
+   :class:`FancyURLopener` subclasses :class:`URLopener` providing default handling
+   for the following HTTP response codes: 301, 302, 303, 307 and 401.  For the 30x
+   response codes listed above, the :mailheader:`Location` header is used to fetch
+   the actual URL.  For 401 response codes (authentication required), basic HTTP
+   authentication is performed.  For the 30x response codes, recursion is bounded
+   by the value of the *maxtries* attribute, which defaults to 10.
+
+   For all other response codes, the method :meth:`http_error_default` is called
+   which you can override in subclasses to handle the error appropriately.
+
+   .. note::
+
+      According to the letter of :rfc:`2616`, 301 and 302 responses to POST requests
+      must not be automatically redirected without confirmation by the user.  In
+      reality, browsers do allow automatic redirection of these responses, changing
+      the POST to a GET, and :mod:`urllib` reproduces this behaviour.
+
+   The parameters to the constructor are the same as those for :class:`URLopener`.
+
+   .. note::
+
+      When performing basic authentication, a :class:`FancyURLopener` instance calls
+      its :meth:`prompt_user_passwd` method.  The default implementation asks the
+      users for the required information on the controlling terminal.  A subclass may
+      override this method to support more appropriate behavior if needed.
+
+    The :class:`FancyURLopener` class offers one additional method that should be
+    overloaded to provide the appropriate behavior:
+
+    .. method:: prompt_user_passwd(host, realm)
+
+       Return information needed to authenticate the user at the given host in the
+       specified security realm.  The return value should be a tuple, ``(user,
+       password)``, which can be used for basic authentication.
+
+       The implementation prompts for this information on the terminal; an application
+       should override this method to use an appropriate interaction model in the local
+       environment.
+
+.. class:: OpenerDirector()
+
+   The :class:`OpenerDirector` class opens URLs via :class:`BaseHandler`\ s chained
+   together. It manages the chaining of handlers, and recovery from errors.
+
+
+.. class:: BaseHandler()
+
+   This is the base class for all registered handlers --- and handles only the
+   simple mechanics of registration.
+
+
+.. class:: HTTPDefaultErrorHandler()
+
+   A class which defines a default handler for HTTP error responses; all responses
+   are turned into :exc:`HTTPError` exceptions.
+
+
+.. class:: HTTPRedirectHandler()
+
+   A class to handle redirections.
+
+
+.. class:: HTTPCookieProcessor([cookiejar])
+
+   A class to handle HTTP Cookies.
+
+
+.. class:: ProxyHandler([proxies])
+
+   Cause requests to go through a proxy. If *proxies* is given, it must be a
+   dictionary mapping protocol names to URLs of proxies. The default is to read the
+   list of proxies from the environment variables :envvar:`<protocol>_proxy`.
+   To disable autodetected proxy pass an empty dictionary.
+
+
+.. class:: HTTPPasswordMgr()
+
+   Keep a database of  ``(realm, uri) -> (user, password)`` mappings.
+
+
+.. class:: HTTPPasswordMgrWithDefaultRealm()
+
+   Keep a database of  ``(realm, uri) -> (user, password)`` mappings. A realm of
+   ``None`` is considered a catch-all realm, which is searched if no other realm
+   fits.
+
+
+.. class:: AbstractBasicAuthHandler([password_mgr])
+
+   This is a mixin class that helps with HTTP authentication, both to the remote
+   host and to a proxy. *password_mgr*, if given, should be something that is
+   compatible with :class:`HTTPPasswordMgr`; refer to section
+   :ref:`http-password-mgr` for information on the interface that must be
+   supported.
+
+
+.. class:: HTTPBasicAuthHandler([password_mgr])
+
+   Handle authentication with the remote host. *password_mgr*, if given, should be
+   something that is compatible with :class:`HTTPPasswordMgr`; refer to section
+   :ref:`http-password-mgr` for information on the interface that must be
+   supported.
+
+
+.. class:: ProxyBasicAuthHandler([password_mgr])
+
+   Handle authentication with the proxy. *password_mgr*, if given, should be
+   something that is compatible with :class:`HTTPPasswordMgr`; refer to section
+   :ref:`http-password-mgr` for information on the interface that must be
+   supported.
+
+
+.. class:: AbstractDigestAuthHandler([password_mgr])
+
+   This is a mixin class that helps with HTTP authentication, both to the remote
+   host and to a proxy. *password_mgr*, if given, should be something that is
+   compatible with :class:`HTTPPasswordMgr`; refer to section
+   :ref:`http-password-mgr` for information on the interface that must be
+   supported.
+
+
+.. class:: HTTPDigestAuthHandler([password_mgr])
+
+   Handle authentication with the remote host. *password_mgr*, if given, should be
+   something that is compatible with :class:`HTTPPasswordMgr`; refer to section
+   :ref:`http-password-mgr` for information on the interface that must be
+   supported.
+
+
+.. class:: ProxyDigestAuthHandler([password_mgr])
+
+   Handle authentication with the proxy. *password_mgr*, if given, should be
+   something that is compatible with :class:`HTTPPasswordMgr`; refer to section
+   :ref:`http-password-mgr` for information on the interface that must be
+   supported.
+
+
+.. class:: HTTPHandler()
+
+   A class to handle opening of HTTP URLs.
+
+
+.. class:: HTTPSHandler()
+
+   A class to handle opening of HTTPS URLs.
+
+
+.. class:: FileHandler()
+
+   Open local files.
+
+
+.. class:: FTPHandler()
+
+   Open FTP URLs.
+
+
+.. class:: CacheFTPHandler()
+
+   Open FTP URLs, keeping a cache of open FTP connections to minimize delays.
+
+
+.. class:: UnknownHandler()
+
+   A catch-all class to handle unknown URLs.
+
+
+.. _request-objects:
+
+Request Objects
+---------------
+
+The following methods describe all of :class:`Request`'s public interface, and
+so all must be overridden in subclasses.
+
+
+.. method:: Request.add_data(data)
+
+   Set the :class:`Request` data to *data*.  This is ignored by all handlers except
+   HTTP handlers --- and there it should be a byte string, and will change the
+   request to be ``POST`` rather than ``GET``.
+
+
+.. method:: Request.get_method()
+
+   Return a string indicating the HTTP request method.  This is only meaningful for
+   HTTP requests, and currently always returns ``'GET'`` or ``'POST'``.
+
+
+.. method:: Request.has_data()
+
+   Return whether the instance has a non-\ ``None`` data.
+
+
+.. method:: Request.get_data()
+
+   Return the instance's data.
+
+
+.. method:: Request.add_header(key, val)
+
+   Add another header to the request.  Headers are currently ignored by all
+   handlers except HTTP handlers, where they are added to the list of headers sent
+   to the server.  Note that there cannot be more than one header with the same
+   name, and later calls will overwrite previous calls in case the *key* collides.
+   Currently, this is no loss of HTTP functionality, since all headers which have
+   meaning when used more than once have a (header-specific) way of gaining the
+   same functionality using only one header.
+
+
+.. method:: Request.add_unredirected_header(key, header)
+
+   Add a header that will not be added to a redirected request.
+
+
+.. method:: Request.has_header(header)
+
+   Return whether the instance has the named header (checks both regular and
+   unredirected).
+
+
+.. method:: Request.get_full_url()
+
+   Return the URL given in the constructor.
+
+
+.. method:: Request.get_type()
+
+   Return the type of the URL --- also known as the scheme.
+
+
+.. method:: Request.get_host()
+
+   Return the host to which a connection will be made.
+
+
+.. method:: Request.get_selector()
+
+   Return the selector --- the part of the URL that is sent to the server.
+
+
+.. method:: Request.set_proxy(host, type)
+
+   Prepare the request by connecting to a proxy server. The *host* and *type* will
+   replace those of the instance, and the instance's selector will be the original
+   URL given in the constructor.
+
+
+.. method:: Request.get_origin_req_host()
+
+   Return the request-host of the origin transaction, as defined by :rfc:`2965`.
+   See the documentation for the :class:`Request` constructor.
+
+
+.. method:: Request.is_unverifiable()
+
+   Return whether the request is unverifiable, as defined by RFC 2965. See the
+   documentation for the :class:`Request` constructor.
+
+
+.. _opener-director-objects:
+
+OpenerDirector Objects
+----------------------
+
+:class:`OpenerDirector` instances have the following methods:
+
+
+.. method:: OpenerDirector.add_handler(handler)
+
+   *handler* should be an instance of :class:`BaseHandler`.  The following methods
+   are searched, and added to the possible chains (note that HTTP errors are a
+   special case).
+
+   * :meth:`protocol_open` --- signal that the handler knows how to open *protocol*
+     URLs.
+
+   * :meth:`http_error_type` --- signal that the handler knows how to handle HTTP
+     errors with HTTP error code *type*.
+
+   * :meth:`protocol_error` --- signal that the handler knows how to handle errors
+     from (non-\ ``http``) *protocol*.
+
+   * :meth:`protocol_request` --- signal that the handler knows how to pre-process
+     *protocol* requests.
+
+   * :meth:`protocol_response` --- signal that the handler knows how to
+     post-process *protocol* responses.
+
+
+.. method:: OpenerDirector.open(url[, data][, timeout])
+
+   Open the given *url* (which can be a request object or a string), optionally
+   passing the given *data*. Arguments, return values and exceptions raised are
+   the same as those of :func:`urlopen` (which simply calls the :meth:`open`
+   method on the currently installed global :class:`OpenerDirector`).  The
+   optional *timeout* parameter specifies a timeout in seconds for blocking
+   operations like the connection attempt (if not specified, the global default
+   timeout setting will be usedi). The timeout feature actually works only for
+   HTTP, HTTPS, FTP and FTPS connections).
+
+
+.. method:: OpenerDirector.error(proto[, arg[, ...]])
+
+   Handle an error of the given protocol.  This will call the registered error
+   handlers for the given protocol with the given arguments (which are protocol
+   specific).  The HTTP protocol is a special case which uses the HTTP response
+   code to determine the specific error handler; refer to the :meth:`http_error_\*`
+   methods of the handler classes.
+
+   Return values and exceptions raised are the same as those of :func:`urlopen`.
+
+OpenerDirector objects open URLs in three stages:
+
+The order in which these methods are called within each stage is determined by
+sorting the handler instances.
+
+#. Every handler with a method named like :meth:`protocol_request` has that
+   method called to pre-process the request.
+
+#. Handlers with a method named like :meth:`protocol_open` are called to handle
+   the request. This stage ends when a handler either returns a non-\ :const:`None`
+   value (ie. a response), or raises an exception (usually :exc:`URLError`).
+   Exceptions are allowed to propagate.
+
+   In fact, the above algorithm is first tried for methods named
+   :meth:`default_open`.  If all such methods return :const:`None`, the algorithm
+   is repeated for methods named like :meth:`protocol_open`.  If all such methods
+   return :const:`None`, the algorithm is repeated for methods named
+   :meth:`unknown_open`.
+
+   Note that the implementation of these methods may involve calls of the parent
+   :class:`OpenerDirector` instance's :meth:`.open` and :meth:`.error` methods.
+
+#. Every handler with a method named like :meth:`protocol_response` has that
+   method called to post-process the response.
+
+
+.. _base-handler-objects:
+
+BaseHandler Objects
+-------------------
+
+:class:`BaseHandler` objects provide a couple of methods that are directly
+useful, and others that are meant to be used by derived classes.  These are
+intended for direct use:
+
+
+.. method:: BaseHandler.add_parent(director)
+
+   Add a director as parent.
+
+
+.. method:: BaseHandler.close()
+
+   Remove any parents.
+
+The following members and methods should only be used by classes derived from
+:class:`BaseHandler`.
+
+.. note::
+
+   The convention has been adopted that subclasses defining
+   :meth:`protocol_request` or :meth:`protocol_response` methods are named
+   :class:`\*Processor`; all others are named :class:`\*Handler`.
+
+
+.. attribute:: BaseHandler.parent
+
+   A valid :class:`OpenerDirector`, which can be used to open using a different
+   protocol, or handle errors.
+
+
+.. method:: BaseHandler.default_open(req)
+
+   This method is *not* defined in :class:`BaseHandler`, but subclasses should
+   define it if they want to catch all URLs.
+
+   This method, if implemented, will be called by the parent
+   :class:`OpenerDirector`.  It should return a file-like object as described in
+   the return value of the :meth:`open` of :class:`OpenerDirector`, or ``None``.
+   It should raise :exc:`URLError`, unless a truly exceptional thing happens (for
+   example, :exc:`MemoryError` should not be mapped to :exc:`URLError`).
+
+   This method will be called before any protocol-specific open method.
+
+
+.. method:: BaseHandler.protocol_open(req)
+   :noindex:
+
+   This method is *not* defined in :class:`BaseHandler`, but subclasses should
+   define it if they want to handle URLs with the given protocol.
+
+   This method, if defined, will be called by the parent :class:`OpenerDirector`.
+   Return values should be the same as for  :meth:`default_open`.
+
+
+.. method:: BaseHandler.unknown_open(req)
+
+   This method is *not* defined in :class:`BaseHandler`, but subclasses should
+   define it if they want to catch all URLs with no specific registered handler to
+   open it.
+
+   This method, if implemented, will be called by the :attr:`parent`
+   :class:`OpenerDirector`.  Return values should be the same as for
+   :meth:`default_open`.
+
+
+.. method:: BaseHandler.http_error_default(req, fp, code, msg, hdrs)
+
+   This method is *not* defined in :class:`BaseHandler`, but subclasses should
+   override it if they intend to provide a catch-all for otherwise unhandled HTTP
+   errors.  It will be called automatically by the  :class:`OpenerDirector` getting
+   the error, and should not normally be called in other circumstances.
+
+   *req* will be a :class:`Request` object, *fp* will be a file-like object with
+   the HTTP error body, *code* will be the three-digit code of the error, *msg*
+   will be the user-visible explanation of the code and *hdrs* will be a mapping
+   object with the headers of the error.
+
+   Return values and exceptions raised should be the same as those of
+   :func:`urlopen`.
+
+
+.. method:: BaseHandler.http_error_nnn(req, fp, code, msg, hdrs)
+
+   *nnn* should be a three-digit HTTP error code.  This method is also not defined
+   in :class:`BaseHandler`, but will be called, if it exists, on an instance of a
+   subclass, when an HTTP error with code *nnn* occurs.
+
+   Subclasses should override this method to handle specific HTTP errors.
+
+   Arguments, return values and exceptions raised should be the same as for
+   :meth:`http_error_default`.
+
+
+.. method:: BaseHandler.protocol_request(req)
+   :noindex:
+
+   This method is *not* defined in :class:`BaseHandler`, but subclasses should
+   define it if they want to pre-process requests of the given protocol.
+
+   This method, if defined, will be called by the parent :class:`OpenerDirector`.
+   *req* will be a :class:`Request` object. The return value should be a
+   :class:`Request` object.
+
+
+.. method:: BaseHandler.protocol_response(req, response)
+   :noindex:
+
+   This method is *not* defined in :class:`BaseHandler`, but subclasses should
+   define it if they want to post-process responses of the given protocol.
+
+   This method, if defined, will be called by the parent :class:`OpenerDirector`.
+   *req* will be a :class:`Request` object. *response* will be an object
+   implementing the same interface as the return value of :func:`urlopen`.  The
+   return value should implement the same interface as the return value of
+   :func:`urlopen`.
+
+
+.. _http-redirect-handler:
+
+HTTPRedirectHandler Objects
+---------------------------
+
+.. note::
+
+   Some HTTP redirections require action from this module's client code.  If this
+   is the case, :exc:`HTTPError` is raised.  See :rfc:`2616` for details of the
+   precise meanings of the various redirection codes.
+
+
+.. method:: HTTPRedirectHandler.redirect_request(req, fp, code, msg, hdrs)
+
+   Return a :class:`Request` or ``None`` in response to a redirect. This is called
+   by the default implementations of the :meth:`http_error_30\*` methods when a
+   redirection is received from the server.  If a redirection should take place,
+   return a new :class:`Request` to allow :meth:`http_error_30\*` to perform the
+   redirect.  Otherwise, raise :exc:`HTTPError` if no other handler should try to
+   handle this URL, or return ``None`` if you can't but another handler might.
+
+   .. note::
+
+      The default implementation of this method does not strictly follow :rfc:`2616`,
+      which says that 301 and 302 responses to ``POST`` requests must not be
+      automatically redirected without confirmation by the user.  In reality, browsers
+      do allow automatic redirection of these responses, changing the POST to a
+      ``GET``, and the default implementation reproduces this behavior.
+
+
+.. method:: HTTPRedirectHandler.http_error_301(req, fp, code, msg, hdrs)
+
+   Redirect to the ``Location:`` URL.  This method is called by the parent
+   :class:`OpenerDirector` when getting an HTTP 'moved permanently' response.
+
+
+.. method:: HTTPRedirectHandler.http_error_302(req, fp, code, msg, hdrs)
+
+   The same as :meth:`http_error_301`, but called for the 'found' response.
+
+
+.. method:: HTTPRedirectHandler.http_error_303(req, fp, code, msg, hdrs)
+
+   The same as :meth:`http_error_301`, but called for the 'see other' response.
+
+
+.. method:: HTTPRedirectHandler.http_error_307(req, fp, code, msg, hdrs)
+
+   The same as :meth:`http_error_301`, but called for the 'temporary redirect'
+   response.
+
+
+.. _http-cookie-processor:
+
+HTTPCookieProcessor Objects
+---------------------------
+
+:class:`HTTPCookieProcessor` instances have one attribute:
+
+.. attribute:: HTTPCookieProcessor.cookiejar
+
+   The :class:`http.cookiejar.CookieJar` in which cookies are stored.
+
+
+.. _proxy-handler:
+
+ProxyHandler Objects
+--------------------
+
+
+.. method:: ProxyHandler.protocol_open(request)
+   :noindex:
+
+   The :class:`ProxyHandler` will have a method :meth:`protocol_open` for every
+   *protocol* which has a proxy in the *proxies* dictionary given in the
+   constructor.  The method will modify requests to go through the proxy, by
+   calling ``request.set_proxy()``, and call the next handler in the chain to
+   actually execute the protocol.
+
+
+.. _http-password-mgr:
+
+HTTPPasswordMgr Objects
+-----------------------
+
+These methods are available on :class:`HTTPPasswordMgr` and
+:class:`HTTPPasswordMgrWithDefaultRealm` objects.
+
+
+.. method:: HTTPPasswordMgr.add_password(realm, uri, user, passwd)
+
+   *uri* can be either a single URI, or a sequence of URIs. *realm*, *user* and
+   *passwd* must be strings. This causes ``(user, passwd)`` to be used as
+   authentication tokens when authentication for *realm* and a super-URI of any of
+   the given URIs is given.
+
+
+.. method:: HTTPPasswordMgr.find_user_password(realm, authuri)
+
+   Get user/password for given realm and URI, if any.  This method will return
+   ``(None, None)`` if there is no matching user/password.
+
+   For :class:`HTTPPasswordMgrWithDefaultRealm` objects, the realm ``None`` will be
+   searched if the given *realm* has no matching user/password.
+
+
+.. _abstract-basic-auth-handler:
+
+AbstractBasicAuthHandler Objects
+--------------------------------
+
+
+.. method:: AbstractBasicAuthHandler.http_error_auth_reqed(authreq, host, req, headers)
+
+   Handle an authentication request by getting a user/password pair, and re-trying
+   the request.  *authreq* should be the name of the header where the information
+   about the realm is included in the request, *host* specifies the URL and path to
+   authenticate for, *req* should be the (failed) :class:`Request` object, and
+   *headers* should be the error headers.
+
+   *host* is either an authority (e.g. ``"python.org"``) or a URL containing an
+   authority component (e.g. ``"http://python.org/"``). In either case, the
+   authority must not contain a userinfo component (so, ``"python.org"`` and
+   ``"python.org:80"`` are fine, ``"joe:password at python.org"`` is not).
+
+
+.. _http-basic-auth-handler:
+
+HTTPBasicAuthHandler Objects
+----------------------------
+
+
+.. method:: HTTPBasicAuthHandler.http_error_401(req, fp, code,  msg, hdrs)
+
+   Retry the request with authentication information, if available.
+
+
+.. _proxy-basic-auth-handler:
+
+ProxyBasicAuthHandler Objects
+-----------------------------
+
+
+.. method:: ProxyBasicAuthHandler.http_error_407(req, fp, code,  msg, hdrs)
+
+   Retry the request with authentication information, if available.
+
+
+.. _abstract-digest-auth-handler:
+
+AbstractDigestAuthHandler Objects
+---------------------------------
+
+
+.. method:: AbstractDigestAuthHandler.http_error_auth_reqed(authreq, host, req, headers)
+
+   *authreq* should be the name of the header where the information about the realm
+   is included in the request, *host* should be the host to authenticate to, *req*
+   should be the (failed) :class:`Request` object, and *headers* should be the
+   error headers.
+
+
+.. _http-digest-auth-handler:
+
+HTTPDigestAuthHandler Objects
+-----------------------------
+
+
+.. method:: HTTPDigestAuthHandler.http_error_401(req, fp, code,  msg, hdrs)
+
+   Retry the request with authentication information, if available.
+
+
+.. _proxy-digest-auth-handler:
+
+ProxyDigestAuthHandler Objects
+------------------------------
+
+
+.. method:: ProxyDigestAuthHandler.http_error_407(req, fp, code,  msg, hdrs)
+
+   Retry the request with authentication information, if available.
+
+
+.. _http-handler-objects:
+
+HTTPHandler Objects
+-------------------
+
+
+.. method:: HTTPHandler.http_open(req)
+
+   Send an HTTP request, which can be either GET or POST, depending on
+   ``req.has_data()``.
+
+
+.. _https-handler-objects:
+
+HTTPSHandler Objects
+--------------------
+
+
+.. method:: HTTPSHandler.https_open(req)
+
+   Send an HTTPS request, which can be either GET or POST, depending on
+   ``req.has_data()``.
+
+
+.. _file-handler-objects:
+
+FileHandler Objects
+-------------------
+
+
+.. method:: FileHandler.file_open(req)
+
+   Open the file locally, if there is no host name, or the host name is
+   ``'localhost'``. Change the protocol to ``ftp`` otherwise, and retry opening it
+   using :attr:`parent`.
+
+
+.. _ftp-handler-objects:
+
+FTPHandler Objects
+------------------
+
+
+.. method:: FTPHandler.ftp_open(req)
+
+   Open the FTP file indicated by *req*. The login is always done with empty
+   username and password.
+
+
+.. _cacheftp-handler-objects:
+
+CacheFTPHandler Objects
+-----------------------
+
+:class:`CacheFTPHandler` objects are :class:`FTPHandler` objects with the
+following additional methods:
+
+
+.. method:: CacheFTPHandler.setTimeout(t)
+
+   Set timeout of connections to *t* seconds.
+
+
+.. method:: CacheFTPHandler.setMaxConns(m)
+
+   Set maximum number of cached connections to *m*.
+
+
+.. _unknown-handler-objects:
+
+UnknownHandler Objects
+----------------------
+
+
+.. method:: UnknownHandler.unknown_open()
+
+   Raise a :exc:`URLError` exception.
+
+
+.. _http-error-processor-objects:
+
+HTTPErrorProcessor Objects
+--------------------------
+
+.. method:: HTTPErrorProcessor.unknown_open()
+
+   Process HTTP error responses.
+
+   For 200 error codes, the response object is returned immediately.
+
+   For non-200 error codes, this simply passes the job on to the
+   :meth:`protocol_error_code` handler methods, via :meth:`OpenerDirector.error`.
+   Eventually, :class:`urllib2.HTTPDefaultErrorHandler` will raise an
+   :exc:`HTTPError` if no other handler handles the error.
+
+.. _urllib2-examples:
+
+Examples
+--------
+
+This example gets the python.org main page and displays the first 100 bytes of
+it::
+
+   >>> import urllib.request
+   >>> f = urllib.request.urlopen('http://www.python.org/')
+   >>> print(f.read(100))
+   <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+   <?xml-stylesheet href="./css/ht2html
+
+Here we are sending a data-stream to the stdin of a CGI and reading the data it
+returns to us. Note that this example will only work when the Python
+installation supports SSL. ::
+
+   >>> import urllib.request
+   >>> req = urllib.request.Request(url='https://localhost/cgi-bin/test.cgi',
+   ...                       data='This data is passed to stdin of the CGI')
+   >>> f = urllib.request.urlopen(req)
+   >>> print(f.read())
+   Got Data: "This data is passed to stdin of the CGI"
+
+The code for the sample CGI used in the above example is::
+
+   #!/usr/bin/env python
+   import sys
+   data = sys.stdin.read()
+   print('Content-type: text-plain\n\nGot Data: "%s"' % data)
+
+Use of Basic HTTP Authentication::
+
+   import urllib.request
+   # Create an OpenerDirector with support for Basic HTTP Authentication...
+   auth_handler = urllib.request.HTTPBasicAuthHandler()
+   auth_handler.add_password(realm='PDQ Application',
+                             uri='https://mahler:8092/site-updates.py',
+                             user='klem',
+                             passwd='kadidd!ehopper')
+   opener = urllib.request.build_opener(auth_handler)
+   # ...and install it globally so it can be used with urlopen.
+   urllib.request.install_opener(opener)
+   urllib.request.urlopen('http://www.example.com/login.html')
+
+:func:`build_opener` provides many handlers by default, including a
+:class:`ProxyHandler`.  By default, :class:`ProxyHandler` uses the environment
+variables named ``<scheme>_proxy``, where ``<scheme>`` is the URL scheme
+involved.  For example, the :envvar:`http_proxy` environment variable is read to
+obtain the HTTP proxy's URL.
+
+This example replaces the default :class:`ProxyHandler` with one that uses
+programatically-supplied proxy URLs, and adds proxy authorization support with
+:class:`ProxyBasicAuthHandler`. ::
+
+   proxy_handler = urllib.request.ProxyHandler({'http': 'http://www.example.com:3128/'})
+   proxy_auth_handler = urllib.request.HTTPBasicAuthHandler()
+   proxy_auth_handler.add_password('realm', 'host', 'username', 'password')
+
+   opener = build_opener(proxy_handler, proxy_auth_handler)
+   # This time, rather than install the OpenerDirector, we use it directly:
+   opener.open('http://www.example.com/login.html')
+
+Adding HTTP headers:
+
+Use the *headers* argument to the :class:`Request` constructor, or::
+
+   import urllib
+   req = urllib.request.Request('http://www.example.com/')
+   req.add_header('Referer', 'http://www.python.org/')
+   r = urllib.request.urlopen(req)
+
+:class:`OpenerDirector` automatically adds a :mailheader:`User-Agent` header to
+every :class:`Request`.  To change this::
+
+   import urllib
+   opener = urllib.request.build_opener()
+   opener.addheaders = [('User-agent', 'Mozilla/5.0')]
+   opener.open('http://www.example.com/')
+
+Also, remember that a few standard headers (:mailheader:`Content-Length`,
+:mailheader:`Content-Type` and :mailheader:`Host`) are added when the
+:class:`Request` is passed to :func:`urlopen` (or :meth:`OpenerDirector.open`).
+
+.. _urllib-examples:
+
+Here is an example session that uses the ``GET`` method to retrieve a URL
+containing parameters::
+
+   >>> import urllib.request
+   >>> import urllib.parse
+   >>> params = urllib.parse.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0})
+   >>> f = urllib.request.urlopen("http://www.musi-cal.com/cgi-bin/query?%s" % params)
+   >>> print(f.read())
+
+The following example uses the ``POST`` method instead::
+
+   >>> import urllib.request
+   >>> import urllib.parse
+   >>> params = urllib.parse.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0})
+   >>> f = urllib.request.urlopen("http://www.musi-cal.com/cgi-bin/query", params)
+   >>> print(f.read())
+
+The following example uses an explicitly specified HTTP proxy, overriding
+environment settings::
+
+   >>> import urllib.request
+   >>> proxies = {'http': 'http://proxy.example.com:8080/'}
+   >>> opener = urllib.request.FancyURLopener(proxies)
+   >>> f = opener.open("http://www.python.org")
+   >>> f.read()
+
+The following example uses no proxies at all, overriding environment settings::
+
+   >>> import urllib.request
+   >>> opener = urllib.request.FancyURLopener({})
+   >>> f = opener.open("http://www.python.org/")
+   >>> f.read()
+
+
+:mod:`urllib.request` Restrictions
+----------------------------------
+
+  .. index::
+     pair: HTTP; protocol
+     pair: FTP; protocol
+
+* Currently, only the following protocols are supported: HTTP, (versions 0.9 and
+  1.0),  FTP, and local files.
+
+* The caching feature of :func:`urlretrieve` has been disabled until I find the
+  time to hack proper processing of Expiration time headers.
+
+* There should be a function to query whether a particular URL is in the cache.
+
+* For backward compatibility, if a URL appears to point to a local file but the
+  file can't be opened, the URL is re-interpreted using the FTP protocol.  This
+  can sometimes cause confusing error messages.
+
+* The :func:`urlopen` and :func:`urlretrieve` functions can cause arbitrarily
+  long delays while waiting for a network connection to be set up.  This means
+  that it is difficult to build an interactive Web client using these functions
+  without using threads.
+
+  .. index::
+     single: HTML
+     pair: HTTP; protocol
+
+* The data returned by :func:`urlopen` or :func:`urlretrieve` is the raw data
+  returned by the server.  This may be binary data (such as an image), plain text
+  or (for example) HTML.  The HTTP protocol provides type information in the reply
+  header, which can be inspected by looking at the :mailheader:`Content-Type`
+  header.  If the returned data is HTML, you can use the module
+  :mod:`html.parser` to parse it.
+
+  .. index:: single: FTP
+
+* The code handling the FTP protocol cannot differentiate between a file and a
+  directory.  This can lead to unexpected behavior when attempting to read a URL
+  that points to a file that is not accessible.  If the URL ends in a ``/``, it is
+  assumed to refer to a directory and will be handled accordingly.  But if an
+  attempt to read a file leads to a 550 error (meaning the URL cannot be found or
+  is not accessible, often for permission reasons), then the path is treated as a
+  directory in order to handle the case when a directory is specified by a URL but
+  the trailing ``/`` has been left off.  This can cause misleading results when
+  you try to fetch a file whose read permissions make it inaccessible; the FTP
+  code will try to read it, fail with a 550 error, and then perform a directory
+  listing for the unreadable file. If fine-grained control is needed, consider
+  using the :mod:`ftplib` module, subclassing :class:`FancyURLOpener`, or changing
+  *_urlopener* to meet your needs.
+
+:mod:`urllib.response` --- Response classes used by urllib.
+===========================================================
+.. module:: urllib.response
+   :synopsis: Response classes used by urllib.
+
+The :mod:`urllib.response` module defines functions and classes which define a
+minimal file like interface, including read() and readline(). The typical
+response object is an addinfourl instance, which defines and info() method and
+that returns headers and a geturl() method that returns the url. 
+Functions defined by this module are used internally by the
+:mod:`urllib.request` module.
+

Added: python/branches/py3k/Doc/library/urllib.robotparser.rst
==============================================================================
--- (empty file)
+++ python/branches/py3k/Doc/library/urllib.robotparser.rst	Mon Jun 23 06:41:59 2008
@@ -0,0 +1,73 @@
+
+:mod:`urllib.robotparser` ---  Parser for robots.txt
+====================================================
+
+.. module:: urllib.robotparser
+   :synopsis: Loads a robots.txt file and answers questions about
+              fetchability of other URLs.
+.. sectionauthor:: Skip Montanaro <skip at pobox.com>
+
+
+.. index::
+   single: WWW
+   single: World Wide Web
+   single: URL
+   single: robots.txt
+
+This module provides a single class, :class:`RobotFileParser`, which answers
+questions about whether or not a particular user agent can fetch a URL on the
+Web site that published the :file:`robots.txt` file.  For more details on the
+structure of :file:`robots.txt` files, see http://www.robotstxt.org/orig.html.
+
+
+.. class:: RobotFileParser()
+
+   This class provides a set of methods to read, parse and answer questions
+   about a single :file:`robots.txt` file.
+
+
+   .. method:: set_url(url)
+
+      Sets the URL referring to a :file:`robots.txt` file.
+
+
+   .. method:: read()
+
+      Reads the :file:`robots.txt` URL and feeds it to the parser.
+
+
+   .. method:: parse(lines)
+
+      Parses the lines argument.
+
+
+   .. method:: can_fetch(useragent, url)
+
+      Returns ``True`` if the *useragent* is allowed to fetch the *url*
+      according to the rules contained in the parsed :file:`robots.txt`
+      file.
+
+
+   .. method:: mtime()
+
+      Returns the time the ``robots.txt`` file was last fetched.  This is
+      useful for long-running web spiders that need to check for new
+      ``robots.txt`` files periodically.
+
+
+   .. method:: modified()
+
+      Sets the time the ``robots.txt`` file was last fetched to the current
+      time.
+
+The following example demonstrates basic use of the RobotFileParser class. ::
+
+   >>> import urllib.robotparser
+   >>> rp = urllib.robotparser.RobotFileParser()
+   >>> rp.set_url("http://www.musi-cal.com/robots.txt")
+   >>> rp.read()
+   >>> rp.can_fetch("*", "http://www.musi-cal.com/cgi-bin/search?city=San+Francisco")
+   False
+   >>> rp.can_fetch("*", "http://www.musi-cal.com/")
+   True
+

Deleted: python/branches/py3k/Doc/library/urllib.rst
==============================================================================
--- python/branches/py3k/Doc/library/urllib.rst	Mon Jun 23 06:41:59 2008
+++ (empty file)
@@ -1,459 +0,0 @@
-:mod:`urllib` --- Open arbitrary resources by URL
-=================================================
-
-.. module:: urllib
-   :synopsis: Open an arbitrary network resource by URL (requires sockets).
-
-
-.. index::
-   single: WWW
-   single: World Wide Web
-   single: URL
-
-This module provides a high-level interface for fetching data across the World
-Wide Web.  In particular, the :func:`urlopen` function is similar to the
-built-in function :func:`open`, but accepts Universal Resource Locators (URLs)
-instead of filenames.  Some restrictions apply --- it can only open URLs for
-reading, and no seek operations are available.
-
-High-level interface
---------------------
-
-.. function:: urlopen(url[, data[, proxies]])
-
-   Open a network object denoted by a URL for reading.  If the URL does not have a
-   scheme identifier, or if it has :file:`file:` as its scheme identifier, this
-   opens a local file (without universal newlines); otherwise it opens a socket to
-   a server somewhere on the network.  If the connection cannot be made the
-   :exc:`IOError` exception is raised.  If all went well, a file-like object is
-   returned.  This supports the following methods: :meth:`read`, :meth:`readline`,
-   :meth:`readlines`, :meth:`fileno`, :meth:`close`, :meth:`info`, :meth:`getcode` and
-   :meth:`geturl`.  It also has proper support for the :term:`iterator` protocol. One
-   caveat: the :meth:`read` method, if the size argument is omitted or negative,
-   may not read until the end of the data stream; there is no good way to determine
-   that the entire stream from a socket has been read in the general case.
-
-   Except for the :meth:`info`, :meth:`getcode` and :meth:`geturl` methods,
-   these methods have the same interface as for file objects --- see section
-   :ref:`bltin-file-objects` in this manual.  (It is not a built-in file object,
-   however, so it can't be used at those few places where a true built-in file
-   object is required.)
-
-   The :meth:`info` method returns an instance of the class
-   :class:`email.message.Message` containing meta-information associated with
-   the URL.  When the method is HTTP, these headers are those returned by the
-   server at the head of the retrieved HTML page (including Content-Length and
-   Content-Type).  When the method is FTP, a Content-Length header will be
-   present if (as is now usual) the server passed back a file length in response
-   to the FTP retrieval request. A Content-Type header will be present if the
-   MIME type can be guessed.  When the method is local-file, returned headers
-   will include a Date representing the file's last-modified time, a
-   Content-Length giving file size, and a Content-Type containing a guess at the
-   file's type.
-
-   The :meth:`geturl` method returns the real URL of the page.  In some cases, the
-   HTTP server redirects a client to another URL.  The :func:`urlopen` function
-   handles this transparently, but in some cases the caller needs to know which URL
-   the client was redirected to.  The :meth:`geturl` method can be used to get at
-   this redirected URL.
-
-   The :meth:`getcode` method returns the HTTP status code that was sent with the
-   response, or ``None`` if the URL is no HTTP URL.
-
-   If the *url* uses the :file:`http:` scheme identifier, the optional *data*
-   argument may be given to specify a ``POST`` request (normally the request type
-   is ``GET``).  The *data* argument must be in standard
-   :mimetype:`application/x-www-form-urlencoded` format; see the :func:`urlencode`
-   function below.
-
-   The :func:`urlopen` function works transparently with proxies which do not
-   require authentication.  In a Unix or Windows environment, set the
-   :envvar:`http_proxy`, or :envvar:`ftp_proxy` environment variables to a URL that
-   identifies the proxy server before starting the Python interpreter.  For example
-   (the ``'%'`` is the command prompt)::
-
-      % http_proxy="http://www.someproxy.com:3128"
-      % export http_proxy
-      % python
-      ...
-
-   The :envvar:`no_proxy` environment variable can be used to specify hosts which
-   shouldn't be reached via proxy; if set, it should be a comma-separated list
-   of hostname suffixes, optionally with ``:port`` appended, for example
-   ``cern.ch,ncsa.uiuc.edu,some.host:8080``.
-
-   In a Windows environment, if no proxy environment variables are set, proxy
-   settings are obtained from the registry's Internet Settings section.
-
-   .. index:: single: Internet Config
-
-   In a Macintosh environment, :func:`urlopen` will retrieve proxy information from
-   Internet Config.
-
-   Alternatively, the optional *proxies* argument may be used to explicitly specify
-   proxies.  It must be a dictionary mapping scheme names to proxy URLs, where an
-   empty dictionary causes no proxies to be used, and ``None`` (the default value)
-   causes environmental proxy settings to be used as discussed above.  For
-   example::
-
-      # Use http://www.someproxy.com:3128 for http proxying
-      proxies = {'http': 'http://www.someproxy.com:3128'}
-      filehandle = urllib.urlopen(some_url, proxies=proxies)
-      # Don't use any proxies
-      filehandle = urllib.urlopen(some_url, proxies={})
-      # Use proxies from environment - both versions are equivalent
-      filehandle = urllib.urlopen(some_url, proxies=None)
-      filehandle = urllib.urlopen(some_url)
-
-   Proxies which require authentication for use are not currently supported; this
-   is considered an implementation limitation.
-
-
-.. function:: urlretrieve(url[, filename[, reporthook[, data]]])
-
-   Copy a network object denoted by a URL to a local file, if necessary. If the URL
-   points to a local file, or a valid cached copy of the object exists, the object
-   is not copied.  Return a tuple ``(filename, headers)`` where *filename* is the
-   local file name under which the object can be found, and *headers* is whatever
-   the :meth:`info` method of the object returned by :func:`urlopen` returned (for
-   a remote object, possibly cached). Exceptions are the same as for
-   :func:`urlopen`.
-
-   The second argument, if present, specifies the file location to copy to (if
-   absent, the location will be a tempfile with a generated name). The third
-   argument, if present, is a hook function that will be called once on
-   establishment of the network connection and once after each block read
-   thereafter.  The hook will be passed three arguments; a count of blocks
-   transferred so far, a block size in bytes, and the total size of the file.  The
-   third argument may be ``-1`` on older FTP servers which do not return a file
-   size in response to a retrieval request.
-
-   If the *url* uses the :file:`http:` scheme identifier, the optional *data*
-   argument may be given to specify a ``POST`` request (normally the request type
-   is ``GET``).  The *data* argument must in standard
-   :mimetype:`application/x-www-form-urlencoded` format; see the :func:`urlencode`
-   function below.
-
-   :func:`urlretrieve` will raise :exc:`ContentTooShortError` when it detects that
-   the amount of data available  was less than the expected amount (which is the
-   size reported by a  *Content-Length* header). This can occur, for example, when
-   the  download is interrupted.
-
-   The *Content-Length* is treated as a lower bound: if there's more data  to read,
-   urlretrieve reads more data, but if less data is available,  it raises the
-   exception.
-
-   You can still retrieve the downloaded data in this case, it is stored  in the
-   :attr:`content` attribute of the exception instance.
-
-   If no *Content-Length* header was supplied, urlretrieve can not check the size
-   of the data it has downloaded, and just returns it.  In this case you just have
-   to assume that the download was successful.
-
-
-.. data:: _urlopener
-
-   The public functions :func:`urlopen` and :func:`urlretrieve` create an instance
-   of the :class:`FancyURLopener` class and use it to perform their requested
-   actions.  To override this functionality, programmers can create a subclass of
-   :class:`URLopener` or :class:`FancyURLopener`, then assign an instance of that
-   class to the ``urllib._urlopener`` variable before calling the desired function.
-   For example, applications may want to specify a different
-   :mailheader:`User-Agent` header than :class:`URLopener` defines.  This can be
-   accomplished with the following code::
-
-      import urllib
-
-      class AppURLopener(urllib.FancyURLopener):
-          version = "App/1.7"
-
-      urllib._urlopener = AppURLopener()
-
-
-.. function:: urlcleanup()
-
-   Clear the cache that may have been built up by previous calls to
-   :func:`urlretrieve`.
-
-
-Utility functions
------------------
-
-.. function:: quote(string[, safe])
-
-   Replace special characters in *string* using the ``%xx`` escape. Letters,
-   digits, and the characters ``'_.-'`` are never quoted. The optional *safe*
-   parameter specifies additional characters that should not be quoted --- its
-   default value is ``'/'``.
-
-   Example: ``quote('/~connolly/')`` yields ``'/%7econnolly/'``.
-
-
-.. function:: quote_plus(string[, safe])
-
-   Like :func:`quote`, but also replaces spaces by plus signs, as required for
-   quoting HTML form values.  Plus signs in the original string are escaped unless
-   they are included in *safe*.  It also does not have *safe* default to ``'/'``.
-
-
-.. function:: unquote(string)
-
-   Replace ``%xx`` escapes by their single-character equivalent.
-
-   Example: ``unquote('/%7Econnolly/')`` yields ``'/~connolly/'``.
-
-
-.. function:: unquote_plus(string)
-
-   Like :func:`unquote`, but also replaces plus signs by spaces, as required for
-   unquoting HTML form values.
-
-
-.. function:: urlencode(query[, doseq])
-
-   Convert a mapping object or a sequence of two-element tuples  to a "url-encoded"
-   string, suitable to pass to :func:`urlopen` above as the optional *data*
-   argument.  This is useful to pass a dictionary of form fields to a ``POST``
-   request.  The resulting string is a series of ``key=value`` pairs separated by
-   ``'&'`` characters, where both *key* and *value* are quoted using
-   :func:`quote_plus` above.  If the optional parameter *doseq* is present and
-   evaluates to true, individual ``key=value`` pairs are generated for each element
-   of the sequence. When a sequence of two-element tuples is used as the *query*
-   argument, the first element of each tuple is a key and the second is a value.
-   The order of parameters in the encoded string will match the order of parameter
-   tuples in the sequence. The :mod:`cgi` module provides the functions
-   :func:`parse_qs` and :func:`parse_qsl` which are used to parse query strings
-   into Python data structures.
-
-
-.. function:: pathname2url(path)
-
-   Convert the pathname *path* from the local syntax for a path to the form used in
-   the path component of a URL.  This does not produce a complete URL.  The return
-   value will already be quoted using the :func:`quote` function.
-
-
-.. function:: url2pathname(path)
-
-   Convert the path component *path* from an encoded URL to the local syntax for a
-   path.  This does not accept a complete URL.  This function uses :func:`unquote`
-   to decode *path*.
-
-
-URL Opener objects
-------------------
-
-.. class:: URLopener([proxies[, **x509]])
-
-   Base class for opening and reading URLs.  Unless you need to support opening
-   objects using schemes other than :file:`http:`, :file:`ftp:`, or :file:`file:`,
-   you probably want to use :class:`FancyURLopener`.
-
-   By default, the :class:`URLopener` class sends a :mailheader:`User-Agent` header
-   of ``urllib/VVV``, where *VVV* is the :mod:`urllib` version number.
-   Applications can define their own :mailheader:`User-Agent` header by subclassing
-   :class:`URLopener` or :class:`FancyURLopener` and setting the class attribute
-   :attr:`version` to an appropriate string value in the subclass definition.
-
-   The optional *proxies* parameter should be a dictionary mapping scheme names to
-   proxy URLs, where an empty dictionary turns proxies off completely.  Its default
-   value is ``None``, in which case environmental proxy settings will be used if
-   present, as discussed in the definition of :func:`urlopen`, above.
-
-   Additional keyword parameters, collected in *x509*, may be used for
-   authentication of the client when using the :file:`https:` scheme.  The keywords
-   *key_file* and *cert_file* are supported to provide an  SSL key and certificate;
-   both are needed to support client authentication.
-
-   :class:`URLopener` objects will raise an :exc:`IOError` exception if the server
-   returns an error code.
-
-    .. method:: open(fullurl[, data])
-
-       Open *fullurl* using the appropriate protocol.  This method sets up cache and
-       proxy information, then calls the appropriate open method with its input
-       arguments.  If the scheme is not recognized, :meth:`open_unknown` is called.
-       The *data* argument has the same meaning as the *data* argument of
-       :func:`urlopen`.
-
-
-    .. method:: open_unknown(fullurl[, data])
-
-       Overridable interface to open unknown URL types.
-
-
-    .. method:: retrieve(url[, filename[, reporthook[, data]]])
-
-       Retrieves the contents of *url* and places it in *filename*.  The return value
-       is a tuple consisting of a local filename and either a
-       :class:`email.message.Message` object containing the response headers (for remote
-       URLs) or ``None`` (for local URLs).  The caller must then open and read the
-       contents of *filename*.  If *filename* is not given and the URL refers to a
-       local file, the input filename is returned.  If the URL is non-local and
-       *filename* is not given, the filename is the output of :func:`tempfile.mktemp`
-       with a suffix that matches the suffix of the last path component of the input
-       URL.  If *reporthook* is given, it must be a function accepting three numeric
-       parameters.  It will be called after each chunk of data is read from the
-       network.  *reporthook* is ignored for local URLs.
-
-       If the *url* uses the :file:`http:` scheme identifier, the optional *data*
-       argument may be given to specify a ``POST`` request (normally the request type
-       is ``GET``).  The *data* argument must in standard
-       :mimetype:`application/x-www-form-urlencoded` format; see the :func:`urlencode`
-       function below.
-
-
-    .. attribute:: version
-
-       Variable that specifies the user agent of the opener object.  To get
-       :mod:`urllib` to tell servers that it is a particular user agent, set this in a
-       subclass as a class variable or in the constructor before calling the base
-       constructor.
-
-
-.. class:: FancyURLopener(...)
-
-   :class:`FancyURLopener` subclasses :class:`URLopener` providing default handling
-   for the following HTTP response codes: 301, 302, 303, 307 and 401.  For the 30x
-   response codes listed above, the :mailheader:`Location` header is used to fetch
-   the actual URL.  For 401 response codes (authentication required), basic HTTP
-   authentication is performed.  For the 30x response codes, recursion is bounded
-   by the value of the *maxtries* attribute, which defaults to 10.
-
-   For all other response codes, the method :meth:`http_error_default` is called
-   which you can override in subclasses to handle the error appropriately.
-
-   .. note::
-
-      According to the letter of :rfc:`2616`, 301 and 302 responses to POST requests
-      must not be automatically redirected without confirmation by the user.  In
-      reality, browsers do allow automatic redirection of these responses, changing
-      the POST to a GET, and :mod:`urllib` reproduces this behaviour.
-
-   The parameters to the constructor are the same as those for :class:`URLopener`.
-
-   .. note::
-
-      When performing basic authentication, a :class:`FancyURLopener` instance calls
-      its :meth:`prompt_user_passwd` method.  The default implementation asks the
-      users for the required information on the controlling terminal.  A subclass may
-      override this method to support more appropriate behavior if needed.
-
-    The :class:`FancyURLopener` class offers one additional method that should be
-    overloaded to provide the appropriate behavior:
-
-    .. method:: prompt_user_passwd(host, realm)
-
-       Return information needed to authenticate the user at the given host in the
-       specified security realm.  The return value should be a tuple, ``(user,
-       password)``, which can be used for basic authentication.
-
-       The implementation prompts for this information on the terminal; an application
-       should override this method to use an appropriate interaction model in the local
-       environment.
-
-.. exception:: ContentTooShortError(msg[, content])
-
-   This exception is raised when the :func:`urlretrieve` function detects that the
-   amount of the downloaded data is less than the  expected amount (given by the
-   *Content-Length* header). The :attr:`content` attribute stores the downloaded
-   (and supposedly truncated) data.
-
-
-:mod:`urllib` Restrictions
---------------------------
-
-  .. index::
-     pair: HTTP; protocol
-     pair: FTP; protocol
-
-* Currently, only the following protocols are supported: HTTP, (versions 0.9 and
-  1.0),  FTP, and local files.
-
-* The caching feature of :func:`urlretrieve` has been disabled until I find the
-  time to hack proper processing of Expiration time headers.
-
-* There should be a function to query whether a particular URL is in the cache.
-
-* For backward compatibility, if a URL appears to point to a local file but the
-  file can't be opened, the URL is re-interpreted using the FTP protocol.  This
-  can sometimes cause confusing error messages.
-
-* The :func:`urlopen` and :func:`urlretrieve` functions can cause arbitrarily
-  long delays while waiting for a network connection to be set up.  This means
-  that it is difficult to build an interactive Web client using these functions
-  without using threads.
-
-  .. index::
-     single: HTML
-     pair: HTTP; protocol
-
-* The data returned by :func:`urlopen` or :func:`urlretrieve` is the raw data
-  returned by the server.  This may be binary data (such as an image), plain text
-  or (for example) HTML.  The HTTP protocol provides type information in the reply
-  header, which can be inspected by looking at the :mailheader:`Content-Type`
-  header.  If the returned data is HTML, you can use the module
-  :mod:`html.parser` to parse it.
-
-  .. index:: single: FTP
-
-* The code handling the FTP protocol cannot differentiate between a file and a
-  directory.  This can lead to unexpected behavior when attempting to read a URL
-  that points to a file that is not accessible.  If the URL ends in a ``/``, it is
-  assumed to refer to a directory and will be handled accordingly.  But if an
-  attempt to read a file leads to a 550 error (meaning the URL cannot be found or
-  is not accessible, often for permission reasons), then the path is treated as a
-  directory in order to handle the case when a directory is specified by a URL but
-  the trailing ``/`` has been left off.  This can cause misleading results when
-  you try to fetch a file whose read permissions make it inaccessible; the FTP
-  code will try to read it, fail with a 550 error, and then perform a directory
-  listing for the unreadable file. If fine-grained control is needed, consider
-  using the :mod:`ftplib` module, subclassing :class:`FancyURLOpener`, or changing
-  *_urlopener* to meet your needs.
-
-* This module does not support the use of proxies which require authentication.
-  This may be implemented in the future.
-
-  .. index:: module: urlparse
-
-* Although the :mod:`urllib` module contains (undocumented) routines to parse
-  and unparse URL strings, the recommended interface for URL manipulation is in
-  module :mod:`urlparse`.
-
-
-.. _urllib-examples:
-
-Examples
---------
-
-Here is an example session that uses the ``GET`` method to retrieve a URL
-containing parameters::
-
-   >>> import urllib
-   >>> params = urllib.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0})
-   >>> f = urllib.urlopen("http://www.musi-cal.com/cgi-bin/query?%s" % params)
-   >>> print(f.read())
-
-The following example uses the ``POST`` method instead::
-
-   >>> import urllib
-   >>> params = urllib.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0})
-   >>> f = urllib.urlopen("http://www.musi-cal.com/cgi-bin/query", params)
-   >>> print(f.read())
-
-The following example uses an explicitly specified HTTP proxy, overriding
-environment settings::
-
-   >>> import urllib
-   >>> proxies = {'http': 'http://proxy.example.com:8080/'}
-   >>> opener = urllib.FancyURLopener(proxies)
-   >>> f = opener.open("http://www.python.org")
-   >>> f.read()
-
-The following example uses no proxies at all, overriding environment settings::
-
-   >>> import urllib
-   >>> opener = urllib.FancyURLopener({})
-   >>> f = opener.open("http://www.python.org/")
-   >>> f.read()
-

Deleted: python/branches/py3k/Doc/library/urllib2.rst
==============================================================================
--- python/branches/py3k/Doc/library/urllib2.rst	Mon Jun 23 06:41:59 2008
+++ (empty file)
@@ -1,934 +0,0 @@
-:mod:`urllib2` --- extensible library for opening URLs
-======================================================
-
-.. module:: urllib2
-   :synopsis: Next generation URL opening library.
-.. moduleauthor:: Jeremy Hylton <jhylton at users.sourceforge.net>
-.. sectionauthor:: Moshe Zadka <moshez at users.sourceforge.net>
-
-
-The :mod:`urllib2` module defines functions and classes which help in opening
-URLs (mostly HTTP) in a complex world --- basic and digest authentication,
-redirections, cookies and more.
-
-The :mod:`urllib2` module defines the following functions:
-
-
-.. function:: urlopen(url[, data][, timeout])
-
-   Open the URL *url*, which can be either a string or a :class:`Request` object.
-
-   *data* may be a string specifying additional data to send to the server, or
-   ``None`` if no such data is needed.  Currently HTTP requests are the only ones
-   that use *data*; the HTTP request will be a POST instead of a GET when the
-   *data* parameter is provided.  *data* should be a buffer in the standard
-   :mimetype:`application/x-www-form-urlencoded` format.  The
-   :func:`urllib.urlencode` function takes a mapping or sequence of 2-tuples and
-   returns a string in this format.
-
-   The optional *timeout* parameter specifies a timeout in seconds for blocking
-   operations like the connection attempt (if not specified, the global default
-   timeout setting will be used).  This actually only works for HTTP, HTTPS,
-   FTP and FTPS connections.
-
-   This function returns a file-like object with two additional methods:
-
-   * :meth:`geturl` --- return the URL of the resource retrieved, commonly used to
-     determine if a redirect was followed
-
-   * :meth:`info` --- return the meta-information of the page, such as headers, in
-     the form of an ``http.client.HTTPMessage`` instance
-     (see `Quick Reference to HTTP Headers <http://www.cs.tut.fi/~jkorpela/http.html>`_)
-
-   Raises :exc:`URLError` on errors.
-
-   Note that ``None`` may be returned if no handler handles the request (though the
-   default installed global :class:`OpenerDirector` uses :class:`UnknownHandler` to
-   ensure this never happens).
-
-
-.. function:: install_opener(opener)
-
-   Install an :class:`OpenerDirector` instance as the default global opener.
-   Installing an opener is only necessary if you want urlopen to use that opener;
-   otherwise, simply call :meth:`OpenerDirector.open` instead of :func:`urlopen`.
-   The code does not check for a real :class:`OpenerDirector`, and any class with
-   the appropriate interface will work.
-
-
-.. function:: build_opener([handler, ...])
-
-   Return an :class:`OpenerDirector` instance, which chains the handlers in the
-   order given. *handler*\s can be either instances of :class:`BaseHandler`, or
-   subclasses of :class:`BaseHandler` (in which case it must be possible to call
-   the constructor without any parameters).  Instances of the following classes
-   will be in front of the *handler*\s, unless the *handler*\s contain them,
-   instances of them or subclasses of them: :class:`ProxyHandler`,
-   :class:`UnknownHandler`, :class:`HTTPHandler`, :class:`HTTPDefaultErrorHandler`,
-   :class:`HTTPRedirectHandler`, :class:`FTPHandler`, :class:`FileHandler`,
-   :class:`HTTPErrorProcessor`.
-
-   If the Python installation has SSL support (i.e., if the :mod:`ssl` module can be imported),
-   :class:`HTTPSHandler` will also be added.
-
-   A :class:`BaseHandler` subclass may also change its :attr:`handler_order`
-   member variable to modify its position in the handlers list.
-
-The following exceptions are raised as appropriate:
-
-
-.. exception:: URLError
-
-   The handlers raise this exception (or derived exceptions) when they run into a
-   problem.  It is a subclass of :exc:`IOError`.
-
-   .. attribute:: reason
-
-      The reason for this error.  It can be a message string or another exception
-      instance (:exc:`socket.error` for remote URLs, :exc:`OSError` for local
-      URLs).
-
-
-.. exception:: HTTPError
-
-   Though being an exception (a subclass of :exc:`URLError`), an :exc:`HTTPError`
-   can also function as a non-exceptional file-like return value (the same thing
-   that :func:`urlopen` returns).  This is useful when handling exotic HTTP
-   errors, such as requests for authentication.
-
-   .. attribute:: code
-
-      An HTTP status code as defined in `RFC 2616 <http://www.faqs.org/rfcs/rfc2616.html>`_. 
-      This numeric value corresponds to a value found in the dictionary of
-      codes as found in :attr:`http.server.BaseHTTPRequestHandler.responses`.
-
-
-
-The following classes are provided:
-
-
-.. class:: Request(url[, data][, headers][, origin_req_host][, unverifiable])
-
-   This class is an abstraction of a URL request.
-
-   *url* should be a string containing a valid URL.
-
-   *data* may be a string specifying additional data to send to the server, or
-   ``None`` if no such data is needed.  Currently HTTP requests are the only ones
-   that use *data*; the HTTP request will be a POST instead of a GET when the
-   *data* parameter is provided.  *data* should be a buffer in the standard
-   :mimetype:`application/x-www-form-urlencoded` format.  The
-   :func:`urllib.urlencode` function takes a mapping or sequence of 2-tuples and
-   returns a string in this format.
-
-   *headers* should be a dictionary, and will be treated as if :meth:`add_header`
-   was called with each key and value as arguments.  This is often used to "spoof"
-   the ``User-Agent`` header, which is used by a browser to identify itself --
-   some HTTP servers only allow requests coming from common browsers as opposed
-   to scripts.  For example, Mozilla Firefox may identify itself as ``"Mozilla/5.0
-   (X11; U; Linux i686) Gecko/20071127 Firefox/2.0.0.11"``, while :mod:`urllib2`'s
-   default user agent string is ``"Python-urllib/2.6"`` (on Python 2.6).
-
-   The final two arguments are only of interest for correct handling of third-party
-   HTTP cookies:
-
-   *origin_req_host* should be the request-host of the origin transaction, as
-   defined by :rfc:`2965`.  It defaults to ``http.cookiejar.request_host(self)``.
-   This is the host name or IP address of the original request that was
-   initiated by the user.  For example, if the request is for an image in an
-   HTML document, this should be the request-host of the request for the page
-   containing the image.
-
-   *unverifiable* should indicate whether the request is unverifiable, as defined
-   by RFC 2965.  It defaults to False.  An unverifiable request is one whose URL
-   the user did not have the option to approve.  For example, if the request is for
-   an image in an HTML document, and the user had no option to approve the
-   automatic fetching of the image, this should be true.
-
-
-.. class:: OpenerDirector()
-
-   The :class:`OpenerDirector` class opens URLs via :class:`BaseHandler`\ s chained
-   together. It manages the chaining of handlers, and recovery from errors.
-
-
-.. class:: BaseHandler()
-
-   This is the base class for all registered handlers --- and handles only the
-   simple mechanics of registration.
-
-
-.. class:: HTTPDefaultErrorHandler()
-
-   A class which defines a default handler for HTTP error responses; all responses
-   are turned into :exc:`HTTPError` exceptions.
-
-
-.. class:: HTTPRedirectHandler()
-
-   A class to handle redirections.
-
-
-.. class:: HTTPCookieProcessor([cookiejar])
-
-   A class to handle HTTP Cookies.
-
-
-.. class:: ProxyHandler([proxies])
-
-   Cause requests to go through a proxy. If *proxies* is given, it must be a
-   dictionary mapping protocol names to URLs of proxies. The default is to read the
-   list of proxies from the environment variables :envvar:`<protocol>_proxy`.
-   To disable autodetected proxy pass an empty dictionary.
-
-
-.. class:: HTTPPasswordMgr()
-
-   Keep a database of  ``(realm, uri) -> (user, password)`` mappings.
-
-
-.. class:: HTTPPasswordMgrWithDefaultRealm()
-
-   Keep a database of  ``(realm, uri) -> (user, password)`` mappings. A realm of
-   ``None`` is considered a catch-all realm, which is searched if no other realm
-   fits.
-
-
-.. class:: AbstractBasicAuthHandler([password_mgr])
-
-   This is a mixin class that helps with HTTP authentication, both to the remote
-   host and to a proxy. *password_mgr*, if given, should be something that is
-   compatible with :class:`HTTPPasswordMgr`; refer to section
-   :ref:`http-password-mgr` for information on the interface that must be
-   supported.
-
-
-.. class:: HTTPBasicAuthHandler([password_mgr])
-
-   Handle authentication with the remote host. *password_mgr*, if given, should be
-   something that is compatible with :class:`HTTPPasswordMgr`; refer to section
-   :ref:`http-password-mgr` for information on the interface that must be
-   supported.
-
-
-.. class:: ProxyBasicAuthHandler([password_mgr])
-
-   Handle authentication with the proxy. *password_mgr*, if given, should be
-   something that is compatible with :class:`HTTPPasswordMgr`; refer to section
-   :ref:`http-password-mgr` for information on the interface that must be
-   supported.
-
-
-.. class:: AbstractDigestAuthHandler([password_mgr])
-
-   This is a mixin class that helps with HTTP authentication, both to the remote
-   host and to a proxy. *password_mgr*, if given, should be something that is
-   compatible with :class:`HTTPPasswordMgr`; refer to section
-   :ref:`http-password-mgr` for information on the interface that must be
-   supported.
-
-
-.. class:: HTTPDigestAuthHandler([password_mgr])
-
-   Handle authentication with the remote host. *password_mgr*, if given, should be
-   something that is compatible with :class:`HTTPPasswordMgr`; refer to section
-   :ref:`http-password-mgr` for information on the interface that must be
-   supported.
-
-
-.. class:: ProxyDigestAuthHandler([password_mgr])
-
-   Handle authentication with the proxy. *password_mgr*, if given, should be
-   something that is compatible with :class:`HTTPPasswordMgr`; refer to section
-   :ref:`http-password-mgr` for information on the interface that must be
-   supported.
-
-
-.. class:: HTTPHandler()
-
-   A class to handle opening of HTTP URLs.
-
-
-.. class:: HTTPSHandler()
-
-   A class to handle opening of HTTPS URLs.
-
-
-.. class:: FileHandler()
-
-   Open local files.
-
-
-.. class:: FTPHandler()
-
-   Open FTP URLs.
-
-
-.. class:: CacheFTPHandler()
-
-   Open FTP URLs, keeping a cache of open FTP connections to minimize delays.
-
-
-.. class:: UnknownHandler()
-
-   A catch-all class to handle unknown URLs.
-
-
-.. _request-objects:
-
-Request Objects
----------------
-
-The following methods describe all of :class:`Request`'s public interface, and
-so all must be overridden in subclasses.
-
-
-.. method:: Request.add_data(data)
-
-   Set the :class:`Request` data to *data*.  This is ignored by all handlers except
-   HTTP handlers --- and there it should be a byte string, and will change the
-   request to be ``POST`` rather than ``GET``.
-
-
-.. method:: Request.get_method()
-
-   Return a string indicating the HTTP request method.  This is only meaningful for
-   HTTP requests, and currently always returns ``'GET'`` or ``'POST'``.
-
-
-.. method:: Request.has_data()
-
-   Return whether the instance has a non-\ ``None`` data.
-
-
-.. method:: Request.get_data()
-
-   Return the instance's data.
-
-
-.. method:: Request.add_header(key, val)
-
-   Add another header to the request.  Headers are currently ignored by all
-   handlers except HTTP handlers, where they are added to the list of headers sent
-   to the server.  Note that there cannot be more than one header with the same
-   name, and later calls will overwrite previous calls in case the *key* collides.
-   Currently, this is no loss of HTTP functionality, since all headers which have
-   meaning when used more than once have a (header-specific) way of gaining the
-   same functionality using only one header.
-
-
-.. method:: Request.add_unredirected_header(key, header)
-
-   Add a header that will not be added to a redirected request.
-
-
-.. method:: Request.has_header(header)
-
-   Return whether the instance has the named header (checks both regular and
-   unredirected).
-
-
-.. method:: Request.get_full_url()
-
-   Return the URL given in the constructor.
-
-
-.. method:: Request.get_type()
-
-   Return the type of the URL --- also known as the scheme.
-
-
-.. method:: Request.get_host()
-
-   Return the host to which a connection will be made.
-
-
-.. method:: Request.get_selector()
-
-   Return the selector --- the part of the URL that is sent to the server.
-
-
-.. method:: Request.set_proxy(host, type)
-
-   Prepare the request by connecting to a proxy server. The *host* and *type* will
-   replace those of the instance, and the instance's selector will be the original
-   URL given in the constructor.
-
-
-.. method:: Request.get_origin_req_host()
-
-   Return the request-host of the origin transaction, as defined by :rfc:`2965`.
-   See the documentation for the :class:`Request` constructor.
-
-
-.. method:: Request.is_unverifiable()
-
-   Return whether the request is unverifiable, as defined by RFC 2965. See the
-   documentation for the :class:`Request` constructor.
-
-
-.. _opener-director-objects:
-
-OpenerDirector Objects
-----------------------
-
-:class:`OpenerDirector` instances have the following methods:
-
-
-.. method:: OpenerDirector.add_handler(handler)
-
-   *handler* should be an instance of :class:`BaseHandler`.  The following methods
-   are searched, and added to the possible chains (note that HTTP errors are a
-   special case).
-
-   * :meth:`protocol_open` --- signal that the handler knows how to open *protocol*
-     URLs.
-
-   * :meth:`http_error_type` --- signal that the handler knows how to handle HTTP
-     errors with HTTP error code *type*.
-
-   * :meth:`protocol_error` --- signal that the handler knows how to handle errors
-     from (non-\ ``http``) *protocol*.
-
-   * :meth:`protocol_request` --- signal that the handler knows how to pre-process
-     *protocol* requests.
-
-   * :meth:`protocol_response` --- signal that the handler knows how to
-     post-process *protocol* responses.
-
-
-.. method:: OpenerDirector.open(url[, data][, timeout])
-
-   Open the given *url* (which can be a request object or a string), optionally
-   passing the given *data*. Arguments, return values and exceptions raised are
-   the same as those of :func:`urlopen` (which simply calls the :meth:`open`
-   method on the currently installed global :class:`OpenerDirector`).  The
-   optional *timeout* parameter specifies a timeout in seconds for blocking
-   operations like the connection attempt (if not specified, the global default
-   timeout setting will be usedi). The timeout feature actually works only for
-   HTTP, HTTPS, FTP and FTPS connections).
-
-
-.. method:: OpenerDirector.error(proto[, arg[, ...]])
-
-   Handle an error of the given protocol.  This will call the registered error
-   handlers for the given protocol with the given arguments (which are protocol
-   specific).  The HTTP protocol is a special case which uses the HTTP response
-   code to determine the specific error handler; refer to the :meth:`http_error_\*`
-   methods of the handler classes.
-
-   Return values and exceptions raised are the same as those of :func:`urlopen`.
-
-OpenerDirector objects open URLs in three stages:
-
-The order in which these methods are called within each stage is determined by
-sorting the handler instances.
-
-#. Every handler with a method named like :meth:`protocol_request` has that
-   method called to pre-process the request.
-
-#. Handlers with a method named like :meth:`protocol_open` are called to handle
-   the request. This stage ends when a handler either returns a non-\ :const:`None`
-   value (ie. a response), or raises an exception (usually :exc:`URLError`).
-   Exceptions are allowed to propagate.
-
-   In fact, the above algorithm is first tried for methods named
-   :meth:`default_open`.  If all such methods return :const:`None`, the algorithm
-   is repeated for methods named like :meth:`protocol_open`.  If all such methods
-   return :const:`None`, the algorithm is repeated for methods named
-   :meth:`unknown_open`.
-
-   Note that the implementation of these methods may involve calls of the parent
-   :class:`OpenerDirector` instance's :meth:`.open` and :meth:`.error` methods.
-
-#. Every handler with a method named like :meth:`protocol_response` has that
-   method called to post-process the response.
-
-
-.. _base-handler-objects:
-
-BaseHandler Objects
--------------------
-
-:class:`BaseHandler` objects provide a couple of methods that are directly
-useful, and others that are meant to be used by derived classes.  These are
-intended for direct use:
-
-
-.. method:: BaseHandler.add_parent(director)
-
-   Add a director as parent.
-
-
-.. method:: BaseHandler.close()
-
-   Remove any parents.
-
-The following members and methods should only be used by classes derived from
-:class:`BaseHandler`.
-
-.. note::
-
-   The convention has been adopted that subclasses defining
-   :meth:`protocol_request` or :meth:`protocol_response` methods are named
-   :class:`\*Processor`; all others are named :class:`\*Handler`.
-
-
-.. attribute:: BaseHandler.parent
-
-   A valid :class:`OpenerDirector`, which can be used to open using a different
-   protocol, or handle errors.
-
-
-.. method:: BaseHandler.default_open(req)
-
-   This method is *not* defined in :class:`BaseHandler`, but subclasses should
-   define it if they want to catch all URLs.
-
-   This method, if implemented, will be called by the parent
-   :class:`OpenerDirector`.  It should return a file-like object as described in
-   the return value of the :meth:`open` of :class:`OpenerDirector`, or ``None``.
-   It should raise :exc:`URLError`, unless a truly exceptional thing happens (for
-   example, :exc:`MemoryError` should not be mapped to :exc:`URLError`).
-
-   This method will be called before any protocol-specific open method.
-
-
-.. method:: BaseHandler.protocol_open(req)
-   :noindex:
-
-   This method is *not* defined in :class:`BaseHandler`, but subclasses should
-   define it if they want to handle URLs with the given protocol.
-
-   This method, if defined, will be called by the parent :class:`OpenerDirector`.
-   Return values should be the same as for  :meth:`default_open`.
-
-
-.. method:: BaseHandler.unknown_open(req)
-
-   This method is *not* defined in :class:`BaseHandler`, but subclasses should
-   define it if they want to catch all URLs with no specific registered handler to
-   open it.
-
-   This method, if implemented, will be called by the :attr:`parent`
-   :class:`OpenerDirector`.  Return values should be the same as for
-   :meth:`default_open`.
-
-
-.. method:: BaseHandler.http_error_default(req, fp, code, msg, hdrs)
-
-   This method is *not* defined in :class:`BaseHandler`, but subclasses should
-   override it if they intend to provide a catch-all for otherwise unhandled HTTP
-   errors.  It will be called automatically by the  :class:`OpenerDirector` getting
-   the error, and should not normally be called in other circumstances.
-
-   *req* will be a :class:`Request` object, *fp* will be a file-like object with
-   the HTTP error body, *code* will be the three-digit code of the error, *msg*
-   will be the user-visible explanation of the code and *hdrs* will be a mapping
-   object with the headers of the error.
-
-   Return values and exceptions raised should be the same as those of
-   :func:`urlopen`.
-
-
-.. method:: BaseHandler.http_error_nnn(req, fp, code, msg, hdrs)
-
-   *nnn* should be a three-digit HTTP error code.  This method is also not defined
-   in :class:`BaseHandler`, but will be called, if it exists, on an instance of a
-   subclass, when an HTTP error with code *nnn* occurs.
-
-   Subclasses should override this method to handle specific HTTP errors.
-
-   Arguments, return values and exceptions raised should be the same as for
-   :meth:`http_error_default`.
-
-
-.. method:: BaseHandler.protocol_request(req)
-   :noindex:
-
-   This method is *not* defined in :class:`BaseHandler`, but subclasses should
-   define it if they want to pre-process requests of the given protocol.
-
-   This method, if defined, will be called by the parent :class:`OpenerDirector`.
-   *req* will be a :class:`Request` object. The return value should be a
-   :class:`Request` object.
-
-
-.. method:: BaseHandler.protocol_response(req, response)
-   :noindex:
-
-   This method is *not* defined in :class:`BaseHandler`, but subclasses should
-   define it if they want to post-process responses of the given protocol.
-
-   This method, if defined, will be called by the parent :class:`OpenerDirector`.
-   *req* will be a :class:`Request` object. *response* will be an object
-   implementing the same interface as the return value of :func:`urlopen`.  The
-   return value should implement the same interface as the return value of
-   :func:`urlopen`.
-
-
-.. _http-redirect-handler:
-
-HTTPRedirectHandler Objects
----------------------------
-
-.. note::
-
-   Some HTTP redirections require action from this module's client code.  If this
-   is the case, :exc:`HTTPError` is raised.  See :rfc:`2616` for details of the
-   precise meanings of the various redirection codes.
-
-
-.. method:: HTTPRedirectHandler.redirect_request(req, fp, code, msg, hdrs)
-
-   Return a :class:`Request` or ``None`` in response to a redirect. This is called
-   by the default implementations of the :meth:`http_error_30\*` methods when a
-   redirection is received from the server.  If a redirection should take place,
-   return a new :class:`Request` to allow :meth:`http_error_30\*` to perform the
-   redirect.  Otherwise, raise :exc:`HTTPError` if no other handler should try to
-   handle this URL, or return ``None`` if you can't but another handler might.
-
-   .. note::
-
-      The default implementation of this method does not strictly follow :rfc:`2616`,
-      which says that 301 and 302 responses to ``POST`` requests must not be
-      automatically redirected without confirmation by the user.  In reality, browsers
-      do allow automatic redirection of these responses, changing the POST to a
-      ``GET``, and the default implementation reproduces this behavior.
-
-
-.. method:: HTTPRedirectHandler.http_error_301(req, fp, code, msg, hdrs)
-
-   Redirect to the ``Location:`` URL.  This method is called by the parent
-   :class:`OpenerDirector` when getting an HTTP 'moved permanently' response.
-
-
-.. method:: HTTPRedirectHandler.http_error_302(req, fp, code, msg, hdrs)
-
-   The same as :meth:`http_error_301`, but called for the 'found' response.
-
-
-.. method:: HTTPRedirectHandler.http_error_303(req, fp, code, msg, hdrs)
-
-   The same as :meth:`http_error_301`, but called for the 'see other' response.
-
-
-.. method:: HTTPRedirectHandler.http_error_307(req, fp, code, msg, hdrs)
-
-   The same as :meth:`http_error_301`, but called for the 'temporary redirect'
-   response.
-
-
-.. _http-cookie-processor:
-
-HTTPCookieProcessor Objects
----------------------------
-
-:class:`HTTPCookieProcessor` instances have one attribute:
-
-.. attribute:: HTTPCookieProcessor.cookiejar
-
-   The :class:`http.cookiejar.CookieJar` in which cookies are stored.
-
-
-.. _proxy-handler:
-
-ProxyHandler Objects
---------------------
-
-
-.. method:: ProxyHandler.protocol_open(request)
-   :noindex:
-
-   The :class:`ProxyHandler` will have a method :meth:`protocol_open` for every
-   *protocol* which has a proxy in the *proxies* dictionary given in the
-   constructor.  The method will modify requests to go through the proxy, by
-   calling ``request.set_proxy()``, and call the next handler in the chain to
-   actually execute the protocol.
-
-
-.. _http-password-mgr:
-
-HTTPPasswordMgr Objects
------------------------
-
-These methods are available on :class:`HTTPPasswordMgr` and
-:class:`HTTPPasswordMgrWithDefaultRealm` objects.
-
-
-.. method:: HTTPPasswordMgr.add_password(realm, uri, user, passwd)
-
-   *uri* can be either a single URI, or a sequence of URIs. *realm*, *user* and
-   *passwd* must be strings. This causes ``(user, passwd)`` to be used as
-   authentication tokens when authentication for *realm* and a super-URI of any of
-   the given URIs is given.
-
-
-.. method:: HTTPPasswordMgr.find_user_password(realm, authuri)
-
-   Get user/password for given realm and URI, if any.  This method will return
-   ``(None, None)`` if there is no matching user/password.
-
-   For :class:`HTTPPasswordMgrWithDefaultRealm` objects, the realm ``None`` will be
-   searched if the given *realm* has no matching user/password.
-
-
-.. _abstract-basic-auth-handler:
-
-AbstractBasicAuthHandler Objects
---------------------------------
-
-
-.. method:: AbstractBasicAuthHandler.http_error_auth_reqed(authreq, host, req, headers)
-
-   Handle an authentication request by getting a user/password pair, and re-trying
-   the request.  *authreq* should be the name of the header where the information
-   about the realm is included in the request, *host* specifies the URL and path to
-   authenticate for, *req* should be the (failed) :class:`Request` object, and
-   *headers* should be the error headers.
-
-   *host* is either an authority (e.g. ``"python.org"``) or a URL containing an
-   authority component (e.g. ``"http://python.org/"``). In either case, the
-   authority must not contain a userinfo component (so, ``"python.org"`` and
-   ``"python.org:80"`` are fine, ``"joe:password at python.org"`` is not).
-
-
-.. _http-basic-auth-handler:
-
-HTTPBasicAuthHandler Objects
-----------------------------
-
-
-.. method:: HTTPBasicAuthHandler.http_error_401(req, fp, code,  msg, hdrs)
-
-   Retry the request with authentication information, if available.
-
-
-.. _proxy-basic-auth-handler:
-
-ProxyBasicAuthHandler Objects
------------------------------
-
-
-.. method:: ProxyBasicAuthHandler.http_error_407(req, fp, code,  msg, hdrs)
-
-   Retry the request with authentication information, if available.
-
-
-.. _abstract-digest-auth-handler:
-
-AbstractDigestAuthHandler Objects
----------------------------------
-
-
-.. method:: AbstractDigestAuthHandler.http_error_auth_reqed(authreq, host, req, headers)
-
-   *authreq* should be the name of the header where the information about the realm
-   is included in the request, *host* should be the host to authenticate to, *req*
-   should be the (failed) :class:`Request` object, and *headers* should be the
-   error headers.
-
-
-.. _http-digest-auth-handler:
-
-HTTPDigestAuthHandler Objects
------------------------------
-
-
-.. method:: HTTPDigestAuthHandler.http_error_401(req, fp, code,  msg, hdrs)
-
-   Retry the request with authentication information, if available.
-
-
-.. _proxy-digest-auth-handler:
-
-ProxyDigestAuthHandler Objects
-------------------------------
-
-
-.. method:: ProxyDigestAuthHandler.http_error_407(req, fp, code,  msg, hdrs)
-
-   Retry the request with authentication information, if available.
-
-
-.. _http-handler-objects:
-
-HTTPHandler Objects
--------------------
-
-
-.. method:: HTTPHandler.http_open(req)
-
-   Send an HTTP request, which can be either GET or POST, depending on
-   ``req.has_data()``.
-
-
-.. _https-handler-objects:
-
-HTTPSHandler Objects
---------------------
-
-
-.. method:: HTTPSHandler.https_open(req)
-
-   Send an HTTPS request, which can be either GET or POST, depending on
-   ``req.has_data()``.
-
-
-.. _file-handler-objects:
-
-FileHandler Objects
--------------------
-
-
-.. method:: FileHandler.file_open(req)
-
-   Open the file locally, if there is no host name, or the host name is
-   ``'localhost'``. Change the protocol to ``ftp`` otherwise, and retry opening it
-   using :attr:`parent`.
-
-
-.. _ftp-handler-objects:
-
-FTPHandler Objects
-------------------
-
-
-.. method:: FTPHandler.ftp_open(req)
-
-   Open the FTP file indicated by *req*. The login is always done with empty
-   username and password.
-
-
-.. _cacheftp-handler-objects:
-
-CacheFTPHandler Objects
------------------------
-
-:class:`CacheFTPHandler` objects are :class:`FTPHandler` objects with the
-following additional methods:
-
-
-.. method:: CacheFTPHandler.setTimeout(t)
-
-   Set timeout of connections to *t* seconds.
-
-
-.. method:: CacheFTPHandler.setMaxConns(m)
-
-   Set maximum number of cached connections to *m*.
-
-
-.. _unknown-handler-objects:
-
-UnknownHandler Objects
-----------------------
-
-
-.. method:: UnknownHandler.unknown_open()
-
-   Raise a :exc:`URLError` exception.
-
-
-.. _http-error-processor-objects:
-
-HTTPErrorProcessor Objects
---------------------------
-
-.. method:: HTTPErrorProcessor.unknown_open()
-
-   Process HTTP error responses.
-
-   For 200 error codes, the response object is returned immediately.
-
-   For non-200 error codes, this simply passes the job on to the
-   :meth:`protocol_error_code` handler methods, via :meth:`OpenerDirector.error`.
-   Eventually, :class:`urllib2.HTTPDefaultErrorHandler` will raise an
-   :exc:`HTTPError` if no other handler handles the error.
-
-
-.. _urllib2-examples:
-
-Examples
---------
-
-This example gets the python.org main page and displays the first 100 bytes of
-it::
-
-   >>> import urllib2
-   >>> f = urllib2.urlopen('http://www.python.org/')
-   >>> print(f.read(100))
-   <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-   <?xml-stylesheet href="./css/ht2html
-
-Here we are sending a data-stream to the stdin of a CGI and reading the data it
-returns to us. Note that this example will only work when the Python
-installation supports SSL. ::
-
-   >>> import urllib2
-   >>> req = urllib2.Request(url='https://localhost/cgi-bin/test.cgi',
-   ...                       data='This data is passed to stdin of the CGI')
-   >>> f = urllib2.urlopen(req)
-   >>> print(f.read())
-   Got Data: "This data is passed to stdin of the CGI"
-
-The code for the sample CGI used in the above example is::
-
-   #!/usr/bin/env python
-   import sys
-   data = sys.stdin.read()
-   print('Content-type: text-plain\n\nGot Data: "%s"' % data)
-
-Use of Basic HTTP Authentication::
-
-   import urllib2
-   # Create an OpenerDirector with support for Basic HTTP Authentication...
-   auth_handler = urllib2.HTTPBasicAuthHandler()
-   auth_handler.add_password(realm='PDQ Application',
-                             uri='https://mahler:8092/site-updates.py',
-                             user='klem',
-                             passwd='kadidd!ehopper')
-   opener = urllib2.build_opener(auth_handler)
-   # ...and install it globally so it can be used with urlopen.
-   urllib2.install_opener(opener)
-   urllib2.urlopen('http://www.example.com/login.html')
-
-:func:`build_opener` provides many handlers by default, including a
-:class:`ProxyHandler`.  By default, :class:`ProxyHandler` uses the environment
-variables named ``<scheme>_proxy``, where ``<scheme>`` is the URL scheme
-involved.  For example, the :envvar:`http_proxy` environment variable is read to
-obtain the HTTP proxy's URL.
-
-This example replaces the default :class:`ProxyHandler` with one that uses
-programatically-supplied proxy URLs, and adds proxy authorization support with
-:class:`ProxyBasicAuthHandler`. ::
-
-   proxy_handler = urllib2.ProxyHandler({'http': 'http://www.example.com:3128/'})
-   proxy_auth_handler = urllib2.HTTPBasicAuthHandler()
-   proxy_auth_handler.add_password('realm', 'host', 'username', 'password')
-
-   opener = build_opener(proxy_handler, proxy_auth_handler)
-   # This time, rather than install the OpenerDirector, we use it directly:
-   opener.open('http://www.example.com/login.html')
-
-Adding HTTP headers:
-
-Use the *headers* argument to the :class:`Request` constructor, or::
-
-   import urllib2
-   req = urllib2.Request('http://www.example.com/')
-   req.add_header('Referer', 'http://www.python.org/')
-   r = urllib2.urlopen(req)
-
-:class:`OpenerDirector` automatically adds a :mailheader:`User-Agent` header to
-every :class:`Request`.  To change this::
-
-   import urllib2
-   opener = urllib2.build_opener()
-   opener.addheaders = [('User-agent', 'Mozilla/5.0')]
-   opener.open('http://www.example.com/')
-
-Also, remember that a few standard headers (:mailheader:`Content-Length`,
-:mailheader:`Content-Type` and :mailheader:`Host`) are added when the
-:class:`Request` is passed to :func:`urlopen` (or :meth:`OpenerDirector.open`).
-

Deleted: python/branches/py3k/Doc/library/urlparse.rst
==============================================================================
--- python/branches/py3k/Doc/library/urlparse.rst	Mon Jun 23 06:41:59 2008
+++ (empty file)
@@ -1,255 +0,0 @@
-:mod:`urlparse` --- Parse URLs into components
-==============================================
-
-.. module:: urlparse
-   :synopsis: Parse URLs into or assemble them from components.
-
-
-.. index::
-   single: WWW
-   single: World Wide Web
-   single: URL
-   pair: URL; parsing
-   pair: relative; URL
-
-This module defines a standard interface to break Uniform Resource Locator (URL)
-strings up in components (addressing scheme, network location, path etc.), to
-combine the components back into a URL string, and to convert a "relative URL"
-to an absolute URL given a "base URL."
-
-The module has been designed to match the Internet RFC on Relative Uniform
-Resource Locators (and discovered a bug in an earlier draft!). It supports the
-following URL schemes: ``file``, ``ftp``, ``gopher``, ``hdl``, ``http``,
-``https``, ``imap``, ``mailto``, ``mms``, ``news``,  ``nntp``, ``prospero``,
-``rsync``, ``rtsp``, ``rtspu``,  ``sftp``, ``shttp``, ``sip``, ``sips``,
-``snews``, ``svn``,  ``svn+ssh``, ``telnet``, ``wais``.
-
-The :mod:`urlparse` module defines the following functions:
-
-
-.. function:: urlparse(urlstring[, default_scheme[, allow_fragments]])
-
-   Parse a URL into six components, returning a 6-tuple.  This corresponds to the
-   general structure of a URL: ``scheme://netloc/path;parameters?query#fragment``.
-   Each tuple item is a string, possibly empty. The components are not broken up in
-   smaller parts (for example, the network location is a single string), and %
-   escapes are not expanded. The delimiters as shown above are not part of the
-   result, except for a leading slash in the *path* component, which is retained if
-   present.  For example:
-
-      >>> from urlparse import urlparse
-      >>> o = urlparse('http://www.cwi.nl:80/%7Eguido/Python.html')
-      >>> o   # doctest: +NORMALIZE_WHITESPACE
-      ParseResult(scheme='http', netloc='www.cwi.nl:80', path='/%7Eguido/Python.html',
-                  params='', query='', fragment='')
-      >>> o.scheme
-      'http'
-      >>> o.port
-      80
-      >>> o.geturl()
-      'http://www.cwi.nl:80/%7Eguido/Python.html'
-
-   If the *default_scheme* argument is specified, it gives the default addressing
-   scheme, to be used only if the URL does not specify one.  The default value for
-   this argument is the empty string.
-
-   If the *allow_fragments* argument is false, fragment identifiers are not
-   allowed, even if the URL's addressing scheme normally does support them.  The
-   default value for this argument is :const:`True`.
-
-   The return value is actually an instance of a subclass of :class:`tuple`.  This
-   class has the following additional read-only convenience attributes:
-
-   +------------------+-------+--------------------------+----------------------+
-   | Attribute        | Index | Value                    | Value if not present |
-   +==================+=======+==========================+======================+
-   | :attr:`scheme`   | 0     | URL scheme specifier     | empty string         |
-   +------------------+-------+--------------------------+----------------------+
-   | :attr:`netloc`   | 1     | Network location part    | empty string         |
-   +------------------+-------+--------------------------+----------------------+
-   | :attr:`path`     | 2     | Hierarchical path        | empty string         |
-   +------------------+-------+--------------------------+----------------------+
-   | :attr:`params`   | 3     | Parameters for last path | empty string         |
-   |                  |       | element                  |                      |
-   +------------------+-------+--------------------------+----------------------+
-   | :attr:`query`    | 4     | Query component          | empty string         |
-   +------------------+-------+--------------------------+----------------------+
-   | :attr:`fragment` | 5     | Fragment identifier      | empty string         |
-   +------------------+-------+--------------------------+----------------------+
-   | :attr:`username` |       | User name                | :const:`None`        |
-   +------------------+-------+--------------------------+----------------------+
-   | :attr:`password` |       | Password                 | :const:`None`        |
-   +------------------+-------+--------------------------+----------------------+
-   | :attr:`hostname` |       | Host name (lower case)   | :const:`None`        |
-   +------------------+-------+--------------------------+----------------------+
-   | :attr:`port`     |       | Port number as integer,  | :const:`None`        |
-   |                  |       | if present               |                      |
-   +------------------+-------+--------------------------+----------------------+
-
-   See section :ref:`urlparse-result-object` for more information on the result
-   object.
-
-
-.. function:: urlunparse(parts)
-
-   Construct a URL from a tuple as returned by ``urlparse()``. The *parts* argument
-   can be any six-item iterable. This may result in a slightly different, but
-   equivalent URL, if the URL that was parsed originally had unnecessary delimiters
-   (for example, a ? with an empty query; the RFC states that these are
-   equivalent).
-
-
-.. function:: urlsplit(urlstring[, default_scheme[, allow_fragments]])
-
-   This is similar to :func:`urlparse`, but does not split the params from the URL.
-   This should generally be used instead of :func:`urlparse` if the more recent URL
-   syntax allowing parameters to be applied to each segment of the *path* portion
-   of the URL (see :rfc:`2396`) is wanted.  A separate function is needed to
-   separate the path segments and parameters.  This function returns a 5-tuple:
-   (addressing scheme, network location, path, query, fragment identifier).
-
-   The return value is actually an instance of a subclass of :class:`tuple`.  This
-   class has the following additional read-only convenience attributes:
-
-   +------------------+-------+-------------------------+----------------------+
-   | Attribute        | Index | Value                   | Value if not present |
-   +==================+=======+=========================+======================+
-   | :attr:`scheme`   | 0     | URL scheme specifier    | empty string         |
-   +------------------+-------+-------------------------+----------------------+
-   | :attr:`netloc`   | 1     | Network location part   | empty string         |
-   +------------------+-------+-------------------------+----------------------+
-   | :attr:`path`     | 2     | Hierarchical path       | empty string         |
-   +------------------+-------+-------------------------+----------------------+
-   | :attr:`query`    | 3     | Query component         | empty string         |
-   +------------------+-------+-------------------------+----------------------+
-   | :attr:`fragment` | 4     | Fragment identifier     | empty string         |
-   +------------------+-------+-------------------------+----------------------+
-   | :attr:`username` |       | User name               | :const:`None`        |
-   +------------------+-------+-------------------------+----------------------+
-   | :attr:`password` |       | Password                | :const:`None`        |
-   +------------------+-------+-------------------------+----------------------+
-   | :attr:`hostname` |       | Host name (lower case)  | :const:`None`        |
-   +------------------+-------+-------------------------+----------------------+
-   | :attr:`port`     |       | Port number as integer, | :const:`None`        |
-   |                  |       | if present              |                      |
-   +------------------+-------+-------------------------+----------------------+
-
-   See section :ref:`urlparse-result-object` for more information on the result
-   object.
-
-
-.. function:: urlunsplit(parts)
-
-   Combine the elements of a tuple as returned by :func:`urlsplit` into a complete
-   URL as a string. The *parts* argument can be any five-item iterable. This may
-   result in a slightly different, but equivalent URL, if the URL that was parsed
-   originally had unnecessary delimiters (for example, a ? with an empty query; the
-   RFC states that these are equivalent).
-
-
-.. function:: urljoin(base, url[, allow_fragments])
-
-   Construct a full ("absolute") URL by combining a "base URL" (*base*) with
-   another URL (*url*).  Informally, this uses components of the base URL, in
-   particular the addressing scheme, the network location and (part of) the path,
-   to provide missing components in the relative URL.  For example:
-
-      >>> from urlparse import urljoin
-      >>> urljoin('http://www.cwi.nl/%7Eguido/Python.html', 'FAQ.html')
-      'http://www.cwi.nl/%7Eguido/FAQ.html'
-
-   The *allow_fragments* argument has the same meaning and default as for
-   :func:`urlparse`.
-
-   .. note::
-
-      If *url* is an absolute URL (that is, starting with ``//`` or ``scheme://``),
-      the *url*'s host name and/or scheme will be present in the result.  For example:
-
-   .. doctest::
-
-      >>> urljoin('http://www.cwi.nl/%7Eguido/Python.html',
-      ...         '//www.python.org/%7Eguido')
-      'http://www.python.org/%7Eguido'
-
-   If you do not want that behavior, preprocess the *url* with :func:`urlsplit` and
-   :func:`urlunsplit`, removing possible *scheme* and *netloc* parts.
-
-
-.. function:: urldefrag(url)
-
-   If *url* contains a fragment identifier, returns a modified version of *url*
-   with no fragment identifier, and the fragment identifier as a separate string.
-   If there is no fragment identifier in *url*, returns *url* unmodified and an
-   empty string.
-
-
-.. seealso::
-
-   :rfc:`1738` - Uniform Resource Locators (URL)
-      This specifies the formal syntax and semantics of absolute URLs.
-
-   :rfc:`1808` - Relative Uniform Resource Locators
-      This Request For Comments includes the rules for joining an absolute and a
-      relative URL, including a fair number of "Abnormal Examples" which govern the
-      treatment of border cases.
-
-   :rfc:`2396` - Uniform Resource Identifiers (URI): Generic Syntax
-      Document describing the generic syntactic requirements for both Uniform Resource
-      Names (URNs) and Uniform Resource Locators (URLs).
-
-
-.. _urlparse-result-object:
-
-Results of :func:`urlparse` and :func:`urlsplit`
-------------------------------------------------
-
-The result objects from the :func:`urlparse` and :func:`urlsplit` functions are
-subclasses of the :class:`tuple` type.  These subclasses add the attributes
-described in those functions, as well as provide an additional method:
-
-
-.. method:: ParseResult.geturl()
-
-   Return the re-combined version of the original URL as a string. This may differ
-   from the original URL in that the scheme will always be normalized to lower case
-   and empty components may be dropped. Specifically, empty parameters, queries,
-   and fragment identifiers will be removed.
-
-   The result of this method is a fixpoint if passed back through the original
-   parsing function:
-
-      >>> import urlparse
-      >>> url = 'HTTP://www.Python.org/doc/#'
-
-      >>> r1 = urlparse.urlsplit(url)
-      >>> r1.geturl()
-      'http://www.Python.org/doc/'
-
-      >>> r2 = urlparse.urlsplit(r1.geturl())
-      >>> r2.geturl()
-      'http://www.Python.org/doc/'
-
-
-The following classes provide the implementations of the parse results::
-
-
-.. class:: BaseResult
-
-   Base class for the concrete result classes.  This provides most of the attribute
-   definitions.  It does not provide a :meth:`geturl` method.  It is derived from
-   :class:`tuple`, but does not override the :meth:`__init__` or :meth:`__new__`
-   methods.
-
-
-.. class:: ParseResult(scheme, netloc, path, params, query, fragment)
-
-   Concrete class for :func:`urlparse` results.  The :meth:`__new__` method is
-   overridden to support checking that the right number of arguments are passed.
-
-
-.. class:: SplitResult(scheme, netloc, path, query, fragment)
-
-   Concrete class for :func:`urlsplit` results.  The :meth:`__new__` method is
-   overridden to support checking that the right number of arguments are passed.
-

Modified: python/branches/py3k/Doc/tutorial/stdlib.rst
==============================================================================
--- python/branches/py3k/Doc/tutorial/stdlib.rst	(original)
+++ python/branches/py3k/Doc/tutorial/stdlib.rst	Mon Jun 23 06:41:59 2008
@@ -147,11 +147,11 @@
 ===============
 
 There are a number of modules for accessing the internet and processing internet
-protocols. Two of the simplest are :mod:`urllib2` for retrieving data from urls
-and :mod:`smtplib` for sending mail::
+protocols. Two of the simplest are :mod:`urllib.request` for retrieving data
+from urls and :mod:`smtplib` for sending mail::
 
-   >>> import urllib2
-   >>> for line in urllib2.urlopen('http://tycho.usno.navy.mil/cgi-bin/timer.pl'):
+   >>> import urllib.request
+   >>> for line in urllib.request.urlopen('http://tycho.usno.navy.mil/cgi-bin/timer.pl'):
    ...     if 'EST' in line or 'EDT' in line:  # look for Eastern Time
    ...         print(line)
 

From python-3000-checkins at python.org  Mon Jun 23 13:23:32 2008
From: python-3000-checkins at python.org (georg.brandl)
Date: Mon, 23 Jun 2008 13:23:32 +0200 (CEST)
Subject: [Python-3000-checkins] r64477 - in python/branches/py3k/Doc:
	howto/urllib2.rst library/contextlib.rst
	library/http.client.rst library/robotparser.rst
	library/urllib.error.rst library/urllib.parse.rst
	library/urllib.request.rst library/urllib.robotparser.rst
	tutorial/stdlib.rst
Message-ID: <20080623112332.914211E4008@bag.python.org>

Author: georg.brandl
Date: Mon Jun 23 13:23:31 2008
New Revision: 64477

Log:
Review the doc changes for the urllib package creation.


Removed:
   python/branches/py3k/Doc/library/robotparser.rst
Modified:
   python/branches/py3k/Doc/howto/urllib2.rst
   python/branches/py3k/Doc/library/contextlib.rst
   python/branches/py3k/Doc/library/http.client.rst
   python/branches/py3k/Doc/library/urllib.error.rst
   python/branches/py3k/Doc/library/urllib.parse.rst
   python/branches/py3k/Doc/library/urllib.request.rst
   python/branches/py3k/Doc/library/urllib.robotparser.rst
   python/branches/py3k/Doc/tutorial/stdlib.rst

Modified: python/branches/py3k/Doc/howto/urllib2.rst
==============================================================================
--- python/branches/py3k/Doc/howto/urllib2.rst	(original)
+++ python/branches/py3k/Doc/howto/urllib2.rst	Mon Jun 23 13:23:31 2008
@@ -1,12 +1,12 @@
-*****************************************************
-  HOWTO Fetch Internet Resources Using urllib package
-*****************************************************
+***********************************************************
+  HOWTO Fetch Internet Resources Using The urllib Package
+***********************************************************
 
 :Author: `Michael Foord <http://www.voidspace.org.uk/python/index.shtml>`_
 
 .. note::
 
-    There is an French translation of an earlier revision of this
+    There is a French translation of an earlier revision of this
     HOWTO, available at `urllib2 - Le Manuel manquant
     <http://www.voidspace.org.uk/python/articles/urllib2_francais.shtml>`_.
 
@@ -18,7 +18,7 @@
 .. sidebar:: Related Articles
 
     You may also find useful the following article on fetching web resources
-    with Python :
+    with Python:
     
     * `Basic Authentication <http://www.voidspace.org.uk/python/articles/authentication.shtml>`_
     
@@ -94,8 +94,8 @@
 all POSTs have to come from forms: you can use a POST to transmit arbitrary data
 to your own application. In the common case of HTML forms, the data needs to be
 encoded in a standard way, and then passed to the Request object as the ``data``
-argument. The encoding is done using a function from the ``urllib.parse`` library
-*not* from ``urllib.request``. ::
+argument. The encoding is done using a function from the :mod:`urllib.parse`
+library. ::
 
     import urllib.parse
     import urllib.request 
@@ -115,7 +115,7 @@
 <http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13>`_ for more
 details).
 
-If you do not pass the ``data`` argument, urllib.request uses a **GET** request. One
+If you do not pass the ``data`` argument, urllib uses a **GET** request. One
 way in which GET and POST requests differ is that POST requests often have
 "side-effects": they change the state of the system in some way (for example by
 placing an order with the website for a hundredweight of tinned spam to be
@@ -182,13 +182,15 @@
 Handling Exceptions
 ===================
 
-*urllib.error* raises ``URLError`` when it cannot handle a response (though as usual
+*urlopen* raises ``URLError`` when it cannot handle a response (though as usual
 with Python APIs, builtin exceptions such as ValueError, TypeError etc. may also
 be raised).
 
 ``HTTPError`` is the subclass of ``URLError`` raised in the specific case of
 HTTP URLs.
 
+The exception classes are exported from the :mod:`urllib.error` module.
+
 URLError
 --------
 
@@ -214,7 +216,7 @@
 the status code indicates that the server is unable to fulfil the request. The
 default handlers will handle some of these responses for you (for example, if
 the response is a "redirection" that requests the client fetch the document from
-a different URL, urllib.request will handle that for you). For those it can't handle,
+a different URL, urllib will handle that for you). For those it can't handle,
 urlopen will raise an ``HTTPError``. Typical errors include '404' (page not
 found), '403' (request forbidden), and '401' (authentication required).
 
@@ -380,7 +382,7 @@
 
 The response returned by urlopen (or the ``HTTPError`` instance) has two useful
 methods ``info`` and ``geturl`` and is defined in the module
-``urllib.response``.
+:mod:`urllib.response`.
 
 **geturl** - this returns the real URL of the page fetched. This is useful
 because ``urlopen`` (or the opener object used) may have followed a
@@ -388,7 +390,7 @@
 
 **info** - this returns a dictionary-like object that describes the page
 fetched, particularly the headers sent by the server. It is currently an
-``http.client.HTTPMessage`` instance.
+:class:`http.client.HTTPMessage` instance.
 
 Typical headers include 'Content-length', 'Content-type', and so on. See the
 `Quick Reference to HTTP Headers <http://www.cs.tut.fi/~jkorpela/http.html>`_
@@ -508,7 +510,7 @@
 Proxies
 =======
 
-**urllib.request** will auto-detect your proxy settings and use those. This is through
+**urllib** will auto-detect your proxy settings and use those. This is through
 the ``ProxyHandler`` which is part of the normal handler chain. Normally that's
 a good thing, but there are occasions when it may not be helpful [#]_. One way
 to do this is to setup our own ``ProxyHandler``, with no proxies defined. This
@@ -528,8 +530,8 @@
 Sockets and Layers
 ==================
 
-The Python support for fetching resources from the web is layered.
-urllib.request uses the http.client library, which in turn uses the socket library.
+The Python support for fetching resources from the web is layered.  urllib uses
+the :mod:`http.client` library, which in turn uses the socket library.
 
 As of Python 2.3 you can specify how long a socket should wait for a response
 before timing out. This can be useful in applications which have to fetch web
@@ -573,9 +575,9 @@
        `Quick Reference to HTTP Headers`_.
 .. [#] In my case I have to use a proxy to access the internet at work. If you
        attempt to fetch *localhost* URLs through this proxy it blocks them. IE
-       is set to use the proxy, which urllib2 picks up on. In order to test
-       scripts with a localhost server, I have to prevent urllib2 from using
+       is set to use the proxy, which urllib picks up on. In order to test
+       scripts with a localhost server, I have to prevent urllib from using
        the proxy.
-.. [#] urllib2 opener for SSL proxy (CONNECT method): `ASPN Cookbook Recipe 
+.. [#] urllib opener for SSL proxy (CONNECT method): `ASPN Cookbook Recipe 
        <http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/456195>`_.
  

Modified: python/branches/py3k/Doc/library/contextlib.rst
==============================================================================
--- python/branches/py3k/Doc/library/contextlib.rst	(original)
+++ python/branches/py3k/Doc/library/contextlib.rst	Mon Jun 23 13:23:31 2008
@@ -98,9 +98,9 @@
    And lets you write code like this::
 
       from contextlib import closing
-      import urllib.request
+      from urllib.request import urlopen
 
-      with closing(urllib.request.urlopen('http://www.python.org')) as page:
+      with closing(urlopen('http://www.python.org')) as page:
           for line in page:
               print(line)
 

Modified: python/branches/py3k/Doc/library/http.client.rst
==============================================================================
--- python/branches/py3k/Doc/library/http.client.rst	(original)
+++ python/branches/py3k/Doc/library/http.client.rst	Mon Jun 23 13:23:31 2008
@@ -13,8 +13,7 @@
 
 This module defines classes which implement the client side of the HTTP and
 HTTPS protocols.  It is normally not used directly --- the module
-:mod:`urllib.request`
-uses it to handle URLs that use HTTP and HTTPS.
+:mod:`urllib.request` uses it to handle URLs that use HTTP and HTTPS.
 
 .. note::
 

Deleted: python/branches/py3k/Doc/library/robotparser.rst
==============================================================================
--- python/branches/py3k/Doc/library/robotparser.rst	Mon Jun 23 13:23:31 2008
+++ (empty file)
@@ -1,73 +0,0 @@
-
-:mod:`robotparser` ---  Parser for robots.txt
-=============================================
-
-.. module:: robotparser
-   :synopsis: Loads a robots.txt file and answers questions about
-              fetchability of other URLs.
-.. sectionauthor:: Skip Montanaro <skip at pobox.com>
-
-
-.. index::
-   single: WWW
-   single: World Wide Web
-   single: URL
-   single: robots.txt
-
-This module provides a single class, :class:`RobotFileParser`, which answers
-questions about whether or not a particular user agent can fetch a URL on the
-Web site that published the :file:`robots.txt` file.  For more details on the
-structure of :file:`robots.txt` files, see http://www.robotstxt.org/orig.html.
-
-
-.. class:: RobotFileParser()
-
-   This class provides a set of methods to read, parse and answer questions
-   about a single :file:`robots.txt` file.
-
-
-   .. method:: set_url(url)
-
-      Sets the URL referring to a :file:`robots.txt` file.
-
-
-   .. method:: read()
-
-      Reads the :file:`robots.txt` URL and feeds it to the parser.
-
-
-   .. method:: parse(lines)
-
-      Parses the lines argument.
-
-
-   .. method:: can_fetch(useragent, url)
-
-      Returns ``True`` if the *useragent* is allowed to fetch the *url*
-      according to the rules contained in the parsed :file:`robots.txt`
-      file.
-
-
-   .. method:: mtime()
-
-      Returns the time the ``robots.txt`` file was last fetched.  This is
-      useful for long-running web spiders that need to check for new
-      ``robots.txt`` files periodically.
-
-
-   .. method:: modified()
-
-      Sets the time the ``robots.txt`` file was last fetched to the current
-      time.
-
-The following example demonstrates basic use of the RobotFileParser class. ::
-
-   >>> import robotparser
-   >>> rp = robotparser.RobotFileParser()
-   >>> rp.set_url("http://www.musi-cal.com/robots.txt")
-   >>> rp.read()
-   >>> rp.can_fetch("*", "http://www.musi-cal.com/cgi-bin/search?city=San+Francisco")
-   False
-   >>> rp.can_fetch("*", "http://www.musi-cal.com/")
-   True
-

Modified: python/branches/py3k/Doc/library/urllib.error.rst
==============================================================================
--- python/branches/py3k/Doc/library/urllib.error.rst	(original)
+++ python/branches/py3k/Doc/library/urllib.error.rst	Mon Jun 23 13:23:31 2008
@@ -2,47 +2,47 @@
 ==================================================================
 
 .. module:: urllib.error
-   :synopsis: Next generation URL opening library.
+   :synopsis: Exception classes raised by urllib.request.
 .. moduleauthor:: Jeremy Hylton <jhylton at users.sourceforge.net>
 .. sectionauthor:: Senthil Kumaran <orsenthil at gmail.com>
 
 
-The :mod:`urllib.error` module defines exception classes raise by
-urllib.request. The base exception class is URLError, which inherits from
-IOError.
+The :mod:`urllib.error` module defines the exception classes for exceptions
+raised by :mod:`urllib.request`.  The base exception class is :exc:`URLError`,
+which inherits from :exc:`IOError`.
 
 The following exceptions are raised by :mod:`urllib.error` as appropriate:
 
-
 .. exception:: URLError
 
-   The handlers raise this exception (or derived exceptions) when they run into a
-   problem.  It is a subclass of :exc:`IOError`.
+   The handlers raise this exception (or derived exceptions) when they run into
+   a problem.  It is a subclass of :exc:`IOError`.
 
    .. attribute:: reason
 
-      The reason for this error.  It can be a message string or another exception
-      instance (:exc:`socket.error` for remote URLs, :exc:`OSError` for local
-      URLs).
+      The reason for this error.  It can be a message string or another
+      exception instance (:exc:`socket.error` for remote URLs, :exc:`OSError`
+      for local URLs).
 
 
 .. exception:: HTTPError
 
-   Though being an exception (a subclass of :exc:`URLError`), an :exc:`HTTPError`
-   can also function as a non-exceptional file-like return value (the same thing
-   that :func:`urlopen` returns).  This is useful when handling exotic HTTP
-   errors, such as requests for authentication.
+   Though being an exception (a subclass of :exc:`URLError`), an
+   :exc:`HTTPError` can also function as a non-exceptional file-like return
+   value (the same thing that :func:`urlopen` returns).  This is useful when
+   handling exotic HTTP errors, such as requests for authentication.
 
    .. attribute:: code
 
-      An HTTP status code as defined in `RFC 2616 <http://www.faqs.org/rfcs/rfc2616.html>`_. 
-      This numeric value corresponds to a value found in the dictionary of
-      codes as found in :attr:`http.server.BaseHTTPRequestHandler.responses`.
+      An HTTP status code as defined in `RFC 2616
+      <http://www.faqs.org/rfcs/rfc2616.html>`_.  This numeric value corresponds
+      to a value found in the dictionary of codes as found in
+      :attr:`http.server.BaseHTTPRequestHandler.responses`.
 
 .. exception:: ContentTooShortError(msg[, content])
 
-   This exception is raised when the :func:`urlretrieve` function detects that the
-   amount of the downloaded data is less than the  expected amount (given by the
-   *Content-Length* header). The :attr:`content` attribute stores the downloaded
-   (and supposedly truncated) data.
+   This exception is raised when the :func:`urlretrieve` function detects that
+   the amount of the downloaded data is less than the expected amount (given by
+   the *Content-Length* header).  The :attr:`content` attribute stores the
+   downloaded (and supposedly truncated) data.
 

Modified: python/branches/py3k/Doc/library/urllib.parse.rst
==============================================================================
--- python/branches/py3k/Doc/library/urllib.parse.rst	(original)
+++ python/branches/py3k/Doc/library/urllib.parse.rst	Mon Jun 23 13:23:31 2008
@@ -20,13 +20,12 @@
 The module has been designed to match the Internet RFC on Relative Uniform
 Resource Locators (and discovered a bug in an earlier draft!). It supports the
 following URL schemes: ``file``, ``ftp``, ``gopher``, ``hdl``, ``http``,
-``https``, ``imap``, ``mailto``, ``mms``, ``news``,  ``nntp``, ``prospero``,
-``rsync``, ``rtsp``, ``rtspu``,  ``sftp``, ``shttp``, ``sip``, ``sips``,
-``snews``, ``svn``,  ``svn+ssh``, ``telnet``, ``wais``.
+``https``, ``imap``, ``mailto``, ``mms``, ``news``, ``nntp``, ``prospero``,
+``rsync``, ``rtsp``, ``rtspu``, ``sftp``, ``shttp``, ``sip``, ``sips``,
+``snews``, ``svn``, ``svn+ssh``, ``telnet``, ``wais``.
 
 The :mod:`urllib.parse` module defines the following functions:
 
-
 .. function:: urlparse(urlstring[, default_scheme[, allow_fragments]])
 
    Parse a URL into six components, returning a 6-tuple.  This corresponds to the
@@ -92,11 +91,11 @@
 
 .. function:: urlunparse(parts)
 
-   Construct a URL from a tuple as returned by ``urlparse()``. The *parts* argument
-   can be any six-item iterable. This may result in a slightly different, but
-   equivalent URL, if the URL that was parsed originally had unnecessary delimiters
-   (for example, a ? with an empty query; the RFC states that these are
-   equivalent).
+   Construct a URL from a tuple as returned by ``urlparse()``. The *parts*
+   argument can be any six-item iterable. This may result in a slightly
+   different, but equivalent URL, if the URL that was parsed originally had
+   unnecessary delimiters (for example, a ``?`` with an empty query; the RFC
+   states that these are equivalent).
 
 
 .. function:: urlsplit(urlstring[, default_scheme[, allow_fragments]])
@@ -140,19 +139,19 @@
 
 .. function:: urlunsplit(parts)
 
-   Combine the elements of a tuple as returned by :func:`urlsplit` into a complete
-   URL as a string. The *parts* argument can be any five-item iterable. This may
-   result in a slightly different, but equivalent URL, if the URL that was parsed
-   originally had unnecessary delimiters (for example, a ? with an empty query; the
-   RFC states that these are equivalent).
+   Combine the elements of a tuple as returned by :func:`urlsplit` into a
+   complete URL as a string. The *parts* argument can be any five-item
+   iterable. This may result in a slightly different, but equivalent URL, if the
+   URL that was parsed originally had unnecessary delimiters (for example, a ?
+   with an empty query; the RFC states that these are equivalent).
 
 
 .. function:: urljoin(base, url[, allow_fragments])
 
    Construct a full ("absolute") URL by combining a "base URL" (*base*) with
    another URL (*url*).  Informally, this uses components of the base URL, in
-   particular the addressing scheme, the network location and (part of) the path,
-   to provide missing components in the relative URL.  For example:
+   particular the addressing scheme, the network location and (part of) the
+   path, to provide missing components in the relative URL.  For example:
 
       >>> from urllib.parse import urljoin
       >>> urljoin('http://www.cwi.nl/%7Eguido/Python.html', 'FAQ.html')
@@ -178,10 +177,10 @@
 
 .. function:: urldefrag(url)
 
-   If *url* contains a fragment identifier, returns a modified version of *url*
-   with no fragment identifier, and the fragment identifier as a separate string.
-   If there is no fragment identifier in *url*, returns *url* unmodified and an
-   empty string.
+   If *url* contains a fragment identifier, return a modified version of *url*
+   with no fragment identifier, and the fragment identifier as a separate
+   string.  If there is no fragment identifier in *url*, return *url* unmodified
+   and an empty string.
 
 .. function:: quote(string[, safe])
 
@@ -195,9 +194,10 @@
 
 .. function:: quote_plus(string[, safe])
 
-   Like :func:`quote`, but also replaces spaces by plus signs, as required for
-   quoting HTML form values.  Plus signs in the original string are escaped unless
-   they are included in *safe*.  It also does not have *safe* default to ``'/'``.
+   Like :func:`quote`, but also replace spaces by plus signs, as required for
+   quoting HTML form values.  Plus signs in the original string are escaped
+   unless they are included in *safe*.  It also does not have *safe* default to
+   ``'/'``.
 
 
 .. function:: unquote(string)
@@ -209,7 +209,7 @@
 
 .. function:: unquote_plus(string)
 
-   Like :func:`unquote`, but also replaces plus signs by spaces, as required for
+   Like :func:`unquote`, but also replace plus signs by spaces, as required for
    unquoting HTML form values.
 
 
@@ -254,7 +254,6 @@
 subclasses of the :class:`tuple` type.  These subclasses add the attributes
 described in those functions, as well as provide an additional method:
 
-
 .. method:: ParseResult.geturl()
 
    Return the re-combined version of the original URL as a string. This may differ
@@ -279,13 +278,12 @@
 
 The following classes provide the implementations of the parse results::
 
-
 .. class:: BaseResult
 
-   Base class for the concrete result classes.  This provides most of the attribute
-   definitions.  It does not provide a :meth:`geturl` method.  It is derived from
-   :class:`tuple`, but does not override the :meth:`__init__` or :meth:`__new__`
-   methods.
+   Base class for the concrete result classes.  This provides most of the
+   attribute definitions.  It does not provide a :meth:`geturl` method.  It is
+   derived from :class:`tuple`, but does not override the :meth:`__init__` or
+   :meth:`__new__` methods.
 
 
 .. class:: ParseResult(scheme, netloc, path, params, query, fragment)

Modified: python/branches/py3k/Doc/library/urllib.request.rst
==============================================================================
--- python/branches/py3k/Doc/library/urllib.request.rst	(original)
+++ python/branches/py3k/Doc/library/urllib.request.rst	Mon Jun 23 13:23:31 2008
@@ -7,9 +7,9 @@
 .. sectionauthor:: Moshe Zadka <moshez at users.sourceforge.net>
 
 
-The :mod:`urllib.request` module defines functions and classes which help in opening
-URLs (mostly HTTP) in a complex world --- basic and digest authentication,
-redirections, cookies and more.
+The :mod:`urllib.request` module defines functions and classes which help in
+opening URLs (mostly HTTP) in a complex world --- basic and digest
+authentication, redirections, cookies and more.
 
 The :mod:`urllib.request` module defines the following functions:
 
@@ -180,7 +180,7 @@
    the ``User-Agent`` header, which is used by a browser to identify itself --
    some HTTP servers only allow requests coming from common browsers as opposed
    to scripts.  For example, Mozilla Firefox may identify itself as ``"Mozilla/5.0
-   (X11; U; Linux i686) Gecko/20071127 Firefox/2.0.0.11"``, while :mod:`urllib2`'s
+   (X11; U; Linux i686) Gecko/20071127 Firefox/2.0.0.11"``, while :mod:`urllib`'s
    default user agent string is ``"Python-urllib/2.6"`` (on Python 2.6).
 
    The final two arguments are only of interest for correct handling of third-party
@@ -1005,10 +1005,11 @@
 
    For non-200 error codes, this simply passes the job on to the
    :meth:`protocol_error_code` handler methods, via :meth:`OpenerDirector.error`.
-   Eventually, :class:`urllib2.HTTPDefaultErrorHandler` will raise an
+   Eventually, :class:`HTTPDefaultErrorHandler` will raise an
    :exc:`HTTPError` if no other handler handles the error.
 
-.. _urllib2-examples:
+
+.. _urllib-request-examples:
 
 Examples
 --------
@@ -1180,15 +1181,18 @@
   using the :mod:`ftplib` module, subclassing :class:`FancyURLOpener`, or changing
   *_urlopener* to meet your needs.
 
+
+
 :mod:`urllib.response` --- Response classes used by urllib.
 ===========================================================
+
 .. module:: urllib.response
    :synopsis: Response classes used by urllib.
 
 The :mod:`urllib.response` module defines functions and classes which define a
-minimal file like interface, including read() and readline(). The typical
-response object is an addinfourl instance, which defines and info() method and
-that returns headers and a geturl() method that returns the url. 
+minimal file like interface, including ``read()`` and ``readline()``. The
+typical response object is an addinfourl instance, which defines and ``info()``
+method and that returns headers and a ``geturl()`` method that returns the url.
 Functions defined by this module are used internally by the
 :mod:`urllib.request` module.
 

Modified: python/branches/py3k/Doc/library/urllib.robotparser.rst
==============================================================================
--- python/branches/py3k/Doc/library/urllib.robotparser.rst	(original)
+++ python/branches/py3k/Doc/library/urllib.robotparser.rst	Mon Jun 23 13:23:31 2008
@@ -1,9 +1,8 @@
-
 :mod:`urllib.robotparser` ---  Parser for robots.txt
 ====================================================
 
 .. module:: urllib.robotparser
-   :synopsis: Loads a robots.txt file and answers questions about
+   :synopsis: Load a robots.txt file and answer questions about
               fetchability of other URLs.
 .. sectionauthor:: Skip Montanaro <skip at pobox.com>
 
@@ -25,42 +24,37 @@
    This class provides a set of methods to read, parse and answer questions
    about a single :file:`robots.txt` file.
 
-
    .. method:: set_url(url)
 
       Sets the URL referring to a :file:`robots.txt` file.
 
-
    .. method:: read()
 
       Reads the :file:`robots.txt` URL and feeds it to the parser.
 
-
    .. method:: parse(lines)
 
       Parses the lines argument.
 
-
    .. method:: can_fetch(useragent, url)
 
       Returns ``True`` if the *useragent* is allowed to fetch the *url*
       according to the rules contained in the parsed :file:`robots.txt`
       file.
 
-
    .. method:: mtime()
 
       Returns the time the ``robots.txt`` file was last fetched.  This is
       useful for long-running web spiders that need to check for new
       ``robots.txt`` files periodically.
 
-
    .. method:: modified()
 
       Sets the time the ``robots.txt`` file was last fetched to the current
       time.
 
-The following example demonstrates basic use of the RobotFileParser class. ::
+
+The following example demonstrates basic use of the RobotFileParser class.
 
    >>> import urllib.robotparser
    >>> rp = urllib.robotparser.RobotFileParser()

Modified: python/branches/py3k/Doc/tutorial/stdlib.rst
==============================================================================
--- python/branches/py3k/Doc/tutorial/stdlib.rst	(original)
+++ python/branches/py3k/Doc/tutorial/stdlib.rst	Mon Jun 23 13:23:31 2008
@@ -150,8 +150,8 @@
 protocols. Two of the simplest are :mod:`urllib.request` for retrieving data
 from urls and :mod:`smtplib` for sending mail::
 
-   >>> import urllib.request
-   >>> for line in urllib.request.urlopen('http://tycho.usno.navy.mil/cgi-bin/timer.pl'):
+   >>> from urllib.request import urlopen
+   >>> for line in urlopen('http://tycho.usno.navy.mil/cgi-bin/timer.pl'):
    ...     if 'EST' in line or 'EDT' in line:  # look for Eastern Time
    ...         print(line)
 

From python-3000-checkins at python.org  Mon Jun 23 13:44:15 2008
From: python-3000-checkins at python.org (georg.brandl)
Date: Mon, 23 Jun 2008 13:44:15 +0200 (CEST)
Subject: [Python-3000-checkins] r64478 - in python/branches/py3k:
	Doc/library/http.cookiejar.rst Doc/library/urllib.request.rst
	Lib/http/cookiejar.py Lib/logging/handlers.py
	Lib/urllib/request.py Mac/BuildScript/build-installer.py
	Misc/cheatsheet
Message-ID: <20080623114415.9C62E1E4008@bag.python.org>

Author: georg.brandl
Date: Mon Jun 23 13:44:14 2008
New Revision: 64478

Log:
Fix old urllib/urllib2/urlparse usage.


Modified:
   python/branches/py3k/Doc/library/http.cookiejar.rst
   python/branches/py3k/Doc/library/urllib.request.rst
   python/branches/py3k/Lib/http/cookiejar.py
   python/branches/py3k/Lib/logging/handlers.py
   python/branches/py3k/Lib/urllib/request.py
   python/branches/py3k/Mac/BuildScript/build-installer.py
   python/branches/py3k/Misc/cheatsheet

Modified: python/branches/py3k/Doc/library/http.cookiejar.rst
==============================================================================
--- python/branches/py3k/Doc/library/http.cookiejar.rst	(original)
+++ python/branches/py3k/Doc/library/http.cookiejar.rst	Mon Jun 23 13:44:14 2008
@@ -100,7 +100,7 @@
 
 .. seealso::
 
-   Module :mod:`urllib2`
+   Module :mod:`urllib.request`
       URL opening with automatic cookie handling.
 
    Module :mod:`http.cookies`
@@ -149,11 +149,11 @@
    the :class:`CookieJar`'s :class:`CookiePolicy` instance are true and false
    respectively), the :mailheader:`Cookie2` header is also added when appropriate.
 
-   The *request* object (usually a :class:`urllib2.Request` instance) must support
-   the methods :meth:`get_full_url`, :meth:`get_host`, :meth:`get_type`,
-   :meth:`unverifiable`, :meth:`get_origin_req_host`, :meth:`has_header`,
-   :meth:`get_header`, :meth:`header_items`, and :meth:`add_unredirected_header`,as
-   documented by :mod:`urllib2`.
+   The *request* object (usually a :class:`urllib.request..Request` instance)
+   must support the methods :meth:`get_full_url`, :meth:`get_host`,
+   :meth:`get_type`, :meth:`unverifiable`, :meth:`get_origin_req_host`,
+   :meth:`has_header`, :meth:`get_header`, :meth:`header_items`, and
+   :meth:`add_unredirected_header`, as documented by :mod:`urllib.request`.
 
 
 .. method:: CookieJar.extract_cookies(response, request)
@@ -166,14 +166,15 @@
    as appropriate (subject to the :meth:`CookiePolicy.set_ok` method's approval).
 
    The *response* object (usually the result of a call to
-   :meth:`urllib2.urlopen`, or similar) should support an :meth:`info` method,
-   which returns a :class:`email.message.Message` instance.
+   :meth:`urllib.request.urlopen`, or similar) should support an :meth:`info`
+   method, which returns a :class:`email.message.Message` instance.
 
-   The *request* object (usually a :class:`urllib2.Request` instance) must support
-   the methods :meth:`get_full_url`, :meth:`get_host`, :meth:`unverifiable`, and
-   :meth:`get_origin_req_host`, as documented by :mod:`urllib2`.  The request is
-   used to set default values for cookie-attributes as well as for checking that
-   the cookie is allowed to be set.
+   The *request* object (usually a :class:`urllib.request.Request` instance)
+   must support the methods :meth:`get_full_url`, :meth:`get_host`,
+   :meth:`unverifiable`, and :meth:`get_origin_req_host`, as documented by
+   :mod:`urllib.request`.  The request is used to set default values for
+   cookie-attributes as well as for checking that the cookie is allowed to be
+   set.
 
 
 .. method:: CookieJar.set_policy(policy)
@@ -715,18 +716,18 @@
 
 The first example shows the most common usage of :mod:`http.cookiejar`::
 
-   import http.cookiejar, urllib2
+   import http.cookiejar, urllib.request
    cj = http.cookiejar.CookieJar()
-   opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
+   opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj))
    r = opener.open("http://example.com/")
 
 This example illustrates how to open a URL using your Netscape, Mozilla, or Lynx
 cookies (assumes Unix/Netscape convention for location of the cookies file)::
 
-   import os, http.cookiejar, urllib2
+   import os, http.cookiejar, urllib.request
    cj = http.cookiejar.MozillaCookieJar()
    cj.load(os.path.join(os.environ["HOME"], ".netscape/cookies.txt"))
-   opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
+   opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj))
    r = opener.open("http://example.com/")
 
 The next example illustrates the use of :class:`DefaultCookiePolicy`. Turn on
@@ -734,12 +735,12 @@
 Netscape cookies, and block some domains from setting cookies or having them
 returned::
 
-   import urllib2
+   import urllib.request
    from http.cookiejar import CookieJar, DefaultCookiePolicy
    policy = DefaultCookiePolicy(
        rfc2965=True, strict_ns_domain=Policy.DomainStrict,
        blocked_domains=["ads.net", ".ads.net"])
    cj = CookieJar(policy)
-   opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
+   opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj))
    r = opener.open("http://example.com/")
 

Modified: python/branches/py3k/Doc/library/urllib.request.rst
==============================================================================
--- python/branches/py3k/Doc/library/urllib.request.rst	(original)
+++ python/branches/py3k/Doc/library/urllib.request.rst	Mon Jun 23 13:44:14 2008
@@ -1077,7 +1077,7 @@
 
 Use the *headers* argument to the :class:`Request` constructor, or::
 
-   import urllib
+   import urllib.request
    req = urllib.request.Request('http://www.example.com/')
    req.add_header('Referer', 'http://www.python.org/')
    r = urllib.request.urlopen(req)
@@ -1085,7 +1085,7 @@
 :class:`OpenerDirector` automatically adds a :mailheader:`User-Agent` header to
 every :class:`Request`.  To change this::
 
-   import urllib
+   import urllib.request
    opener = urllib.request.build_opener()
    opener.addheaders = [('User-agent', 'Mozilla/5.0')]
    opener.open('http://www.example.com/')

Modified: python/branches/py3k/Lib/http/cookiejar.py
==============================================================================
--- python/branches/py3k/Lib/http/cookiejar.py	(original)
+++ python/branches/py3k/Lib/http/cookiejar.py	Mon Jun 23 13:44:14 2008
@@ -1305,7 +1305,7 @@
         return attrs
 
     def add_cookie_header(self, request):
-        """Add correct Cookie: header to request (urllib2.Request object).
+        """Add correct Cookie: header to request (urllib.request.Request object).
 
         The Cookie2 header is also added unless policy.hide_cookie2 is true.
 

Modified: python/branches/py3k/Lib/logging/handlers.py
==============================================================================
--- python/branches/py3k/Lib/logging/handlers.py	(original)
+++ python/branches/py3k/Lib/logging/handlers.py	Mon Jun 23 13:44:14 2008
@@ -1002,11 +1002,11 @@
         Send the record to the Web server as an URL-encoded dictionary
         """
         try:
-            import http.client, urllib
+            import http.client, urllib.parse
             host = self.host
             h = http.client.HTTP(host)
             url = self.url
-            data = urllib.urlencode(self.mapLogRecord(record))
+            data = urllib.parse.urlencode(self.mapLogRecord(record))
             if self.method == "GET":
                 if (url.find('?') >= 0):
                     sep = '&'

Modified: python/branches/py3k/Lib/urllib/request.py
==============================================================================
--- python/branches/py3k/Lib/urllib/request.py	(original)
+++ python/branches/py3k/Lib/urllib/request.py	Mon Jun 23 13:44:14 2008
@@ -47,24 +47,25 @@
 
 Example usage:
 
-import urllib2
+import urllib.request
 
 # set up authentication info
-authinfo = urllib2.HTTPBasicAuthHandler()
+authinfo = urllib.request.HTTPBasicAuthHandler()
 authinfo.add_password(realm='PDQ Application',
                       uri='https://mahler:8092/site-updates.py',
                       user='klem',
                       passwd='geheim$parole')
 
-proxy_support = urllib2.ProxyHandler({"http" : "http://ahad-haam:3128"})
+proxy_support = urllib.request.ProxyHandler({"http" : "http://ahad-haam:3128"})
 
 # build a new opener that adds authentication and caching FTP handlers
-opener = urllib2.build_opener(proxy_support, authinfo, urllib2.CacheFTPHandler)
+opener = urllib.request.build_opener(proxy_support, authinfo,
+                                     urllib.request.CacheFTPHandler)
 
 # install it
-urllib2.install_opener(opener)
+urllib.request.install_opener(opener)
 
-f = urllib2.urlopen('http://www.python.org/')
+f = urllib.request.urlopen('http://www.python.org/')
 """
 
 # XXX issues:
@@ -502,7 +503,7 @@
 
         # Strictly (according to RFC 2616), 301 or 302 in response to
         # a POST MUST NOT cause a redirection without confirmation
-        # from the user (of urllib2, in this case).  In practice,
+        # from the user (of urllib.request, in this case).  In practice,
         # essentially all clients do redirect in this case, so we do
         # the same.
         # be conciliant with URIs containing a space
@@ -655,7 +656,7 @@
         if proxy_type is None:
             proxy_type = orig_type
         if user and password:
-            user_pass = '%s:%s' % (unquote(user),
+            user_pass = '%s:%s' % (urllib.parse.unquote(user),
                                    urllib.parse.unquote(password))
             creds = base64.b64encode(user_pass.encode()).decode("ascii")
             req.add_header('Proxy-authorization', 'Basic ' + creds)
@@ -808,7 +809,7 @@
 
     def http_error_407(self, req, fp, code, msg, headers):
         # http_error_auth_reqed requires that there is no userinfo component in
-        # authority.  Assume there isn't one, since urllib2 does not (and
+        # authority.  Assume there isn't one, since urllib.request does not (and
         # should not, RFC 3986 s. 3.2.1) support requests for URLs containing
         # userinfo.
         authority = req.get_host()
@@ -1194,7 +1195,7 @@
                 return urllib.response.addinfourl(open(localfile, 'rb'),
                                                   headers, 'file:'+file)
         except OSError as msg:
-            # urllib2 users shouldn't expect OSErrors coming from urlopen()
+            # users shouldn't expect OSErrors coming from urlopen()
             raise urllib.error.URLError(msg)
         raise urllib.error.URLError('file not on local host')
 

Modified: python/branches/py3k/Mac/BuildScript/build-installer.py
==============================================================================
--- python/branches/py3k/Mac/BuildScript/build-installer.py	(original)
+++ python/branches/py3k/Mac/BuildScript/build-installer.py	Mon Jun 23 13:44:14 2008
@@ -9,7 +9,8 @@
 
 Usage: see USAGE variable in the script.
 """
-import platform, os, sys, getopt, textwrap, shutil, urllib2, stat, time, pwd
+import platform, os, sys, getopt, textwrap, shutil, stat, time, pwd
+import urllib.request
 import grp
 
 INCLUDE_TIMESTAMP = 1
@@ -442,7 +443,7 @@
         if KNOWNSIZES.get(url) == size:
             print("Using existing file for", url)
             return
-    fpIn = urllib2.urlopen(url)
+    fpIn = urllib.request.urlopen(url)
     fpOut = open(fname, 'wb')
     block = fpIn.read(10240)
     try:

Modified: python/branches/py3k/Misc/cheatsheet
==============================================================================
--- python/branches/py3k/Misc/cheatsheet	(original)
+++ python/branches/py3k/Misc/cheatsheet	Mon Jun 23 13:44:14 2008
@@ -1889,7 +1889,6 @@
 re               Regular Expressions.
 reprlib          Redo repr() but with limits on most sizes.
 rlcompleter      Word completion for GNU readline 2.0.
-robotparser      Parse robots.txt files, useful for web spiders.
 sched            A generally useful event scheduler class.
 shelve           Manage shelves of pickled objects.
 shlex            Lexical analyzer class for simple shell-like syntaxes.
@@ -1920,8 +1919,9 @@
 types            Define names for all type symbols in the std interpreter.
 tzparse          Parse a timezone specification.
 unicodedata      Interface to unicode properties.
-urllib           Open an arbitrary URL.
-urlparse         Parse URLs according to latest draft of standard.
+urllib.parse     Parse URLs according to latest draft of standard.
+urllib.request   Open an arbitrary URL.
+urllib.robotparser  Parse robots.txt files, useful for web spiders.
 user             Hook to allow user-specified customization code to run.
 uu               UUencode/UUdecode.
 unittest         Utilities for implementing unit testing.

From python-3000-checkins at python.org  Mon Jun 23 13:45:20 2008
From: python-3000-checkins at python.org (georg.brandl)
Date: Mon, 23 Jun 2008 13:45:20 +0200 (CEST)
Subject: [Python-3000-checkins] r64479 - in python/branches/py3k/Tools:
	faqwiz/faqwiz.py versioncheck/pyversioncheck.py
	webchecker/webchecker.py webchecker/websucker.py
Message-ID: <20080623114520.A78B41E4008@bag.python.org>

Author: georg.brandl
Date: Mon Jun 23 13:45:20 2008
New Revision: 64479

Log:
More old urllib usage.


Modified:
   python/branches/py3k/Tools/faqwiz/faqwiz.py
   python/branches/py3k/Tools/versioncheck/pyversioncheck.py
   python/branches/py3k/Tools/webchecker/webchecker.py
   python/branches/py3k/Tools/webchecker/websucker.py

Modified: python/branches/py3k/Tools/faqwiz/faqwiz.py
==============================================================================
--- python/branches/py3k/Tools/faqwiz/faqwiz.py	(original)
+++ python/branches/py3k/Tools/faqwiz/faqwiz.py	Mon Jun 23 13:45:20 2008
@@ -138,8 +138,8 @@
         value = cookies[COOKIE_NAME]
     except KeyError:
         return {}
-    import urllib
-    value = urllib.unquote(value)
+    import urllib.parse
+    value = urllib.parse.unquote(value)
     words = value.split('/')
     while len(words) < 3:
         words.append('')
@@ -153,8 +153,8 @@
 def send_my_cookie(ui):
     name = COOKIE_NAME
     value = "%s/%s/%s" % (ui.author, ui.email, ui.password)
-    import urllib
-    value = urllib.quote(value)
+    import urllib.parse
+    value = urllib.parse.quote(value)
     then = now + COOKIE_LIFETIME
     gmt = time.gmtime(then)
     path = os.environ.get('SCRIPT_NAME', '/cgi-bin/')

Modified: python/branches/py3k/Tools/versioncheck/pyversioncheck.py
==============================================================================
--- python/branches/py3k/Tools/versioncheck/pyversioncheck.py	(original)
+++ python/branches/py3k/Tools/versioncheck/pyversioncheck.py	Mon Jun 23 13:45:20 2008
@@ -1,5 +1,5 @@
 """pyversioncheck - Module to help with checking versions"""
-import urllib
+import urllib.request
 import email
 import sys
 
@@ -47,7 +47,7 @@
     if verbose >= VERBOSE_EACHFILE:
         print('  Checking %s'%url)
     try:
-        fp = urllib.urlopen(url)
+        fp = urllib.request.urlopen(url)
     except IOError as arg:
         if verbose >= VERBOSE_EACHFILE:
             print('    Cannot open:', arg)

Modified: python/branches/py3k/Tools/webchecker/webchecker.py
==============================================================================
--- python/branches/py3k/Tools/webchecker/webchecker.py	(original)
+++ python/branches/py3k/Tools/webchecker/webchecker.py	Mon Jun 23 13:45:20 2008
@@ -113,13 +113,13 @@
 import getopt
 import pickle
 
-import urllib
-import urlparse
+import urllib.request
+import urllib.parse as urlparse
 import sgmllib
 import cgi
 
 import mimetypes
-import robotparser
+from urllib import robotparser
 
 # Extract real version number if necessary
 if __version__[0] == '$':
@@ -487,7 +487,7 @@
         if url in self.name_table:
             return self.name_table[url]
 
-        scheme, path = urllib.splittype(url)
+        scheme, path = urllib.request.splittype(url)
         if scheme in ('mailto', 'news', 'javascript', 'telnet'):
             self.note(1, " Not checking %s URL" % scheme)
             return None
@@ -733,13 +733,13 @@
         return self.__url
 
 
-class MyURLopener(urllib.FancyURLopener):
+class MyURLopener(urllib.request.FancyURLopener):
 
-    http_error_default = urllib.URLopener.http_error_default
+    http_error_default = urllib.request.URLopener.http_error_default
 
     def __init__(*args):
         self = args[0]
-        urllib.FancyURLopener.__init__(*args)
+        urllib.request.FancyURLopener.__init__(*args)
         self.addheaders = [
             ('User-agent', 'Python-webchecker/%s' % __version__),
             ]
@@ -769,7 +769,7 @@
                 s.write('<A HREF="%s">%s</A>\n' % (q, q))
             s.seek(0)
             return s
-        return urllib.FancyURLopener.open_file(self, url)
+        return urllib.request.FancyURLopener.open_file(self, url)
 
 
 class MyHTMLParser(sgmllib.SGMLParser):

Modified: python/branches/py3k/Tools/webchecker/websucker.py
==============================================================================
--- python/branches/py3k/Tools/webchecker/websucker.py	(original)
+++ python/branches/py3k/Tools/webchecker/websucker.py	Mon Jun 23 13:45:20 2008
@@ -6,8 +6,8 @@
 
 import os
 import sys
-import urllib
 import getopt
+import urllib.parse
 
 import webchecker
 
@@ -87,11 +87,11 @@
             self.message("didn't save %s: %s", path, str(msg))
 
     def savefilename(self, url):
-        type, rest = urllib.splittype(url)
-        host, path = urllib.splithost(rest)
+        type, rest = urllib.parse.splittype(url)
+        host, path = urllib.parse.splithost(rest)
         path = path.lstrip("/")
-        user, host = urllib.splituser(host)
-        host, port = urllib.splitnport(host)
+        user, host = urllib.parse.splituser(host)
+        host, port = urllib.parse.splitnport(host)
         host = host.lower()
         if not path or path[-1] == "/":
             path = path + "index.html"

From python-3000-checkins at python.org  Tue Jun 24 03:06:47 2008
From: python-3000-checkins at python.org (eric.smith)
Date: Tue, 24 Jun 2008 03:06:47 +0200 (CEST)
Subject: [Python-3000-checkins] r64492 - in python/branches/py3k:
	Include/bytesobject.h Include/unicodeobject.h
	Objects/stringlib/formatter.h Objects/stringlib/localeutil.h
	Python/pystrtod.c
Message-ID: <20080624010647.8BC161E4008@bag.python.org>

Author: eric.smith
Date: Tue Jun 24 03:06:47 2008
New Revision: 64492

Log:
Merged revisions 64491 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/trunk

........
  r64491 | eric.smith | 2008-06-23 20:42:10 -0400 (Mon, 23 Jun 2008) | 1 line
  
  Modified interface to _Py_[String|Unicode]InsertThousandsGrouping, in anticipation of fixing issue 3140.
........


Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Include/bytesobject.h
   python/branches/py3k/Include/unicodeobject.h
   python/branches/py3k/Objects/stringlib/formatter.h
   python/branches/py3k/Objects/stringlib/localeutil.h
   python/branches/py3k/Python/pystrtod.c

Modified: python/branches/py3k/Include/bytesobject.h
==============================================================================
--- python/branches/py3k/Include/bytesobject.h	(original)
+++ python/branches/py3k/Include/bytesobject.h	Tue Jun 24 03:06:47 2008
@@ -91,8 +91,8 @@
    see Objects/stringlib/localeutil.h */
 
 PyAPI_FUNC(int) _PyBytes_InsertThousandsGrouping(char *buffer,
-						  Py_ssize_t len,
-						  char *plast,
+						  Py_ssize_t n_buffer,
+						  Py_ssize_t n_digits,
 						  Py_ssize_t buf_size,
 						  Py_ssize_t *count,
 						  int append_zero_char);

Modified: python/branches/py3k/Include/unicodeobject.h
==============================================================================
--- python/branches/py3k/Include/unicodeobject.h	(original)
+++ python/branches/py3k/Include/unicodeobject.h	Tue Jun 24 03:06:47 2008
@@ -1458,8 +1458,8 @@
    see Objects/stringlib/localeutil.h */
 
 PyAPI_FUNC(int) _PyUnicode_InsertThousandsGrouping(Py_UNICODE *buffer,
-						  Py_ssize_t len,
-						  Py_UNICODE *plast,
+						  Py_ssize_t n_buffer,
+						  Py_ssize_t n_digits,
 						  Py_ssize_t buf_size,
 						  Py_ssize_t *count,
 						  int append_zero_char);

Modified: python/branches/py3k/Objects/stringlib/formatter.h
==============================================================================
--- python/branches/py3k/Objects/stringlib/formatter.h	(original)
+++ python/branches/py3k/Objects/stringlib/formatter.h	Tue Jun 24 03:06:47 2008
@@ -563,8 +563,7 @@
     if (format->type == 'n')
 	    /* Compute how many additional chars we need to allocate
 	       to hold the thousands grouping. */
-	    STRINGLIB_GROUPING(pnumeric_chars, n_digits,
-			       pnumeric_chars+n_digits,
+	    STRINGLIB_GROUPING(NULL, n_digits, n_digits,
 			       0, &n_grouping_chars, 0);
 
     /* Allocate a new string to hold the result */
@@ -592,8 +591,7 @@
 	    /* We know this can't fail, since we've already
 	       reserved enough space. */
 	    STRINGLIB_CHAR *pstart = p + n_leading_chars;
-	    int r = STRINGLIB_GROUPING(pstart, n_digits,
-				       pstart + n_digits,
+	    int r = STRINGLIB_GROUPING(pstart, n_digits, n_digits,
 				       spec.n_total+n_grouping_chars-n_leading_chars,
 				       NULL, 0);
 	    assert(r);

Modified: python/branches/py3k/Objects/stringlib/localeutil.h
==============================================================================
--- python/branches/py3k/Objects/stringlib/localeutil.h	(original)
+++ python/branches/py3k/Objects/stringlib/localeutil.h	Tue Jun 24 03:06:47 2008
@@ -8,10 +8,9 @@
 /**
  * _Py_InsertThousandsGrouping:
  * @buffer: A pointer to the start of a string.
- * @len: The length of the string.
- * @plast: A pointer to the end of of the digits in the string.  This
- *         may be before the end of the string (if the string contains
- *         decimals, for example).
+ * @n_buffer: The length of the string.
+ * @n_digits: The number of digits in the string, in which we want
+ *            to put the grouping chars.
  * @buf_size: The maximum size of the buffer pointed to by buffer.
  * @count: If non-NULL, points to a variable that will receive the
  *         number of characters we need to insert (and no formatting
@@ -21,10 +20,11 @@
  *         string.
  *
  * Inserts thousand grouping characters (as defined in the current
- *  locale) into the string between buffer and plast.  If count is
- *  non-NULL, don't do any formatting, just count the number of
- *  characters to insert.  This is used by the caller to appropriately
- *  resize the buffer, if needed.
+ *  locale) into the string between buffer and buffer+n_digits.  If
+ *  count is non-NULL, don't do any formatting, just count the number
+ *  of characters to insert.  This is used by the caller to
+ *  appropriately resize the buffer, if needed.  If count is non-NULL,
+ *  buffer can be NULL (it is not dereferenced at all in that case).
  *
  * Return value: 0 on error, else 1.  Note that no error can occur if
  *  count is non-NULL.
@@ -34,8 +34,8 @@
  **/
 int
 _Py_InsertThousandsGrouping(STRINGLIB_CHAR *buffer,
-			    Py_ssize_t len,
-			    STRINGLIB_CHAR *plast,
+			    Py_ssize_t n_buffer,
+			    Py_ssize_t n_digits,
 			    Py_ssize_t buf_size,
 			    Py_ssize_t *count,
 			    int append_zero_char)
@@ -44,15 +44,22 @@
 	const char *grouping = locale_data->grouping;
 	const char *thousands_sep = locale_data->thousands_sep;
 	Py_ssize_t thousands_sep_len = strlen(thousands_sep);
-	STRINGLIB_CHAR *pend = buffer + len; /* current end of buffer */
-	STRINGLIB_CHAR *pmax = buffer + buf_size;       /* max of buffer */
+	STRINGLIB_CHAR *pend = NULL; /* current end of buffer */
+	STRINGLIB_CHAR *pmax = NULL; /* max of buffer */
 	char current_grouping;
+	Py_ssize_t remaining = n_digits; /* Number of chars remaining to
+					    be looked at */
 
 	/* Initialize the character count, if we're just counting. */
 	if (count)
 		*count = 0;
+	else {
+		/* We're not just counting, we're modifying buffer */
+		pend = buffer + n_buffer;
+		pmax = buffer + buf_size;
+	}
 
-	/* Starting at plast and working right-to-left, keep track of
+	/* Starting at the end and working right-to-left, keep track of
 	   what grouping needs to be added and insert that. */
 	current_grouping = *grouping++;
 
@@ -60,11 +67,11 @@
 	if (current_grouping == 0)
 		return 1;
 
-	while (plast - buffer > current_grouping) {
+	while (remaining > current_grouping) {
 		/* Always leave buffer and pend valid at the end of this
 		   loop, since we might leave with a return statement. */
 
-		plast -= current_grouping;
+		remaining -= current_grouping;
 		if (count) {
 			/* We're only counting, not touching the memory. */
 			*count += thousands_sep_len;
@@ -72,6 +79,8 @@
 		else {
 			/* Do the formatting. */
 
+			STRINGLIB_CHAR *plast = buffer + remaining;
+
 			/* Is there room to insert thousands_sep_len chars? */
 			if (pmax - pend < thousands_sep_len)
 				/* No room. */
@@ -111,7 +120,7 @@
 	if (append_zero_char) {
 		/* Append a zero character to mark the end of the string,
 		   if there's room. */
-		if (pend - plast < 1)
+		if (pend - (buffer + remaining) < 1)
 			/* No room, error. */
 			return 0;
 		*pend = 0;

Modified: python/branches/py3k/Python/pystrtod.c
==============================================================================
--- python/branches/py3k/Python/pystrtod.c	(original)
+++ python/branches/py3k/Python/pystrtod.c	Tue Jun 24 03:06:47 2008
@@ -364,8 +364,8 @@
 	/* At this point, p points just past the right-most character we
 	   want to format.  We need to add the grouping string for the
 	   characters between buffer and p. */
-	return _PyBytes_InsertThousandsGrouping(buffer, len, p,
-						 buf_size, NULL, 1);
+	return _PyBytes_InsertThousandsGrouping(buffer, len, p-buffer,
+						buf_size, NULL, 1);
 }
 
 /* see FORMATBUFLEN in unicodeobject.c */

From python-3000-checkins at python.org  Tue Jun 24 08:07:03 2008
From: python-3000-checkins at python.org (eric.smith)
Date: Tue, 24 Jun 2008 08:07:03 +0200 (CEST)
Subject: [Python-3000-checkins] r64497 - in python/branches/py3k:
	Objects/stringlib/formatter.h
Message-ID: <20080624060703.8489D1E4009@bag.python.org>

Author: eric.smith
Date: Tue Jun 24 08:07:03 2008
New Revision: 64497

Log:
Merged revisions 64496 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/trunk

........
  r64496 | eric.smith | 2008-06-24 02:05:30 -0400 (Tue, 24 Jun 2008) | 1 line
  
  Typo in comment.
........


Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Objects/stringlib/formatter.h

Modified: python/branches/py3k/Objects/stringlib/formatter.h
==============================================================================
--- python/branches/py3k/Objects/stringlib/formatter.h	(original)
+++ python/branches/py3k/Objects/stringlib/formatter.h	Tue Jun 24 08:07:03 2008
@@ -586,7 +586,7 @@
     }
 
     /* Insert the grouping, if any, after the uppercasing of 'X', so we can
-       ensure that grouping chars won't be affeted. */
+       ensure that grouping chars won't be affected. */
     if (n_grouping_chars && format->type == 'n') {
 	    /* We know this can't fail, since we've already
 	       reserved enough space. */

From python-3000-checkins at python.org  Tue Jun 24 13:21:04 2008
From: python-3000-checkins at python.org (eric.smith)
Date: Tue, 24 Jun 2008 13:21:04 +0200 (CEST)
Subject: [Python-3000-checkins] r64500 - in python/branches/py3k:
	Lib/test/test_types.py Objects/stringlib/formatter.h
Message-ID: <20080624112104.9A04E1E4017@bag.python.org>

Author: eric.smith
Date: Tue Jun 24 13:21:04 2008
New Revision: 64500

Log:
Merged revisions 64499 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/trunk

........
  r64499 | eric.smith | 2008-06-24 07:11:59 -0400 (Tue, 24 Jun 2008) | 1 line
  
  Fixed formatting with thousands separator and padding.  Resolves issue 3140.
........


Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Lib/test/test_types.py
   python/branches/py3k/Objects/stringlib/formatter.h

Modified: python/branches/py3k/Lib/test/test_types.py
==============================================================================
--- python/branches/py3k/Lib/test/test_types.py	(original)
+++ python/branches/py3k/Lib/test/test_types.py	Tue Jun 24 13:21:04 2008
@@ -428,6 +428,14 @@
             # move to the next integer to test
             x = x // 10
 
+        rfmt = ">20n"
+        lfmt = "<20n"
+        cfmt = "^20n"
+        for x in (1234, 12345, 123456, 1234567, 12345678, 123456789, 1234567890, 12345678900):
+            self.assertEqual(len(format(0, rfmt)), len(format(x, rfmt)))
+            self.assertEqual(len(format(0, lfmt)), len(format(x, lfmt)))
+            self.assertEqual(len(format(0, cfmt)), len(format(x, cfmt)))
+
     def test_float__format__(self):
         # these should be rewritten to use both format(x, spec) and
         # x.__format__(spec)

Modified: python/branches/py3k/Objects/stringlib/formatter.h
==============================================================================
--- python/branches/py3k/Objects/stringlib/formatter.h	(original)
+++ python/branches/py3k/Objects/stringlib/formatter.h	Tue Jun 24 13:21:04 2008
@@ -313,8 +313,8 @@
    as determined in _calc_integer_widths().  returns the pointer to
    where the digits go. */
 static STRINGLIB_CHAR *
-fill_number(STRINGLIB_CHAR *p_buf, const NumberFieldWidths *spec,
-            Py_ssize_t n_digits, STRINGLIB_CHAR fill_char)
+fill_non_digits(STRINGLIB_CHAR *p_buf, const NumberFieldWidths *spec,
+		Py_ssize_t n_digits, STRINGLIB_CHAR fill_char)
 {
     STRINGLIB_CHAR* p_digits;
 
@@ -557,17 +557,17 @@
 	pnumeric_chars += leading_chars_to_skip;
     }
 
-    /* Calculate the widths of the various leading and trailing parts */
-    calc_number_widths(&spec, sign, n_digits, format);
-
     if (format->type == 'n')
 	    /* Compute how many additional chars we need to allocate
 	       to hold the thousands grouping. */
 	    STRINGLIB_GROUPING(NULL, n_digits, n_digits,
 			       0, &n_grouping_chars, 0);
 
+    /* Calculate the widths of the various leading and trailing parts */
+    calc_number_widths(&spec, sign, n_digits + n_grouping_chars, format);
+
     /* Allocate a new string to hold the result */
-    result = STRINGLIB_NEW(NULL, spec.n_total + n_grouping_chars);
+    result = STRINGLIB_NEW(NULL, spec.n_total);
     if (!result)
 	goto done;
     p = STRINGLIB_STR(result);
@@ -587,7 +587,7 @@
 
     /* Insert the grouping, if any, after the uppercasing of 'X', so we can
        ensure that grouping chars won't be affected. */
-    if (n_grouping_chars && format->type == 'n') {
+    if (n_grouping_chars) {
 	    /* We know this can't fail, since we've already
 	       reserved enough space. */
 	    STRINGLIB_CHAR *pstart = p + n_leading_chars;
@@ -597,9 +597,9 @@
 	    assert(r);
     }
 
-    /* Fill in the non-digit parts */
-    fill_number(p, &spec, n_digits,
-                format->fill_char == '\0' ? ' ' : format->fill_char);
+    /* Fill in the non-digit parts (padding, sign, etc.) */
+    fill_non_digits(p, &spec, n_digits + n_grouping_chars,
+		    format->fill_char == '\0' ? ' ' : format->fill_char);
 
 done:
     Py_XDECREF(tmp);
@@ -737,9 +737,9 @@
     if (result == NULL)
         goto done;
 
-    /* fill in the non-digit parts */
-    fill_number(STRINGLIB_STR(result), &spec, n_digits,
-                format->fill_char == '\0' ? ' ' : format->fill_char);
+    /* Fill in the non-digit parts (padding, sign, etc.) */
+    fill_non_digits(STRINGLIB_STR(result), &spec, n_digits,
+		    format->fill_char == '\0' ? ' ' : format->fill_char);
 
     /* fill in the digit parts */
     memmove(STRINGLIB_STR(result) +

From python-3000-checkins at python.org  Tue Jun 24 16:26:25 2008
From: python-3000-checkins at python.org (mark.dickinson)
Date: Tue, 24 Jun 2008 16:26:25 +0200 (CEST)
Subject: [Python-3000-checkins] r64503 -
	python/branches/py3k/Doc/library/fractions.rst
Message-ID: <20080624142625.256051E400A@bag.python.org>

Author: mark.dickinson
Date: Tue Jun 24 16:26:24 2008
New Revision: 64503

Log:
Remove trailing 'L's from integers in limit_denominator examples.


Modified:
   python/branches/py3k/Doc/library/fractions.rst

Modified: python/branches/py3k/Doc/library/fractions.rst
==============================================================================
--- python/branches/py3k/Doc/library/fractions.rst	(original)
+++ python/branches/py3k/Doc/library/fractions.rst	Tue Jun 24 16:26:24 2008
@@ -51,15 +51,15 @@
 
          >>> from fractions import Fraction
          >>> Fraction('3.1415926535897932').limit_denominator(1000)
-         Fraction(355L, 113L)
+         Fraction(355, 113)
 
       or for recovering a rational number that's represented as a float:
 
          >>> from math import pi, cos
          >>> Fraction.from_float(cos(pi/3))
-         Fraction(4503599627370497L, 9007199254740992L)
+         Fraction(4503599627370497, 9007199254740992)
          >>> Fraction.from_float(cos(pi/3)).limit_denominator()
-         Fraction(1L, 2L)
+         Fraction(1, 2)
 
 
    .. method:: __floor__()

From python-3000-checkins at python.org  Tue Jun 24 17:32:28 2008
From: python-3000-checkins at python.org (mark.dickinson)
Date: Tue, 24 Jun 2008 17:32:28 +0200 (CEST)
Subject: [Python-3000-checkins] r64507 -
	python/branches/py3k/Doc/library/fractions.rst
Message-ID: <20080624153228.292D91E4024@bag.python.org>

Author: mark.dickinson
Date: Tue Jun 24 17:32:27 2008
New Revision: 64507

Log:
Rewrite references to Py3k in __floor__, __ceil__ and __round__ documentation.


Modified:
   python/branches/py3k/Doc/library/fractions.rst

Modified: python/branches/py3k/Doc/library/fractions.rst
==============================================================================
--- python/branches/py3k/Doc/library/fractions.rst	(original)
+++ python/branches/py3k/Doc/library/fractions.rst	Tue Jun 24 17:32:27 2008
@@ -21,8 +21,8 @@
    ``Fraction`` representing ``numerator/denominator``. If
    *denominator* is :const:`0`, raises a :exc:`ZeroDivisionError`. The
    second version requires that *other_fraction* is an instance of
-   :class:`numbers.Fraction` and returns an instance of
-   :class:`Rational` with the same value. The third version expects a
+   :class:`numbers.Rational` and returns an instance of
+   :class:`Fraction` with the same value. The third version expects a
    string of the form ``[-+]?[0-9]+(/[0-9]+)?``, optionally surrounded
    by spaces.
 
@@ -40,7 +40,7 @@
    .. method:: from_decimal(dec)
 
       This classmethod constructs a :class:`Fraction` representing the exact
-      value of *dec*, which must be a :class:`decimal.Decimal`.
+      value of *dec*, which must be a :class:`decimal.Decimal` instance.
 
 
    .. method:: limit_denominator(max_denominator=1000000)
@@ -64,24 +64,28 @@
 
    .. method:: __floor__()
 
-      Returns the greatest :class:`int` ``<= self``. Will be accessible through
-      :func:`math.floor` in Py3k.
+      Returns the greatest :class:`int` ``<= self``.  This method can
+      also be accessed through the :func:`math.floor` function:
+
+        >>> from math import floor
+        >>> floor(Fraction(355, 113))
+        3
 
 
    .. method:: __ceil__()
 
-      Returns the least :class:`int` ``>= self``. Will be accessible through
-      :func:`math.ceil` in Py3k.
+      Returns the least :class:`int` ``>= self``.  This method can
+      also be accessed through the :func:`math.ceil` function.
 
 
    .. method:: __round__()
                __round__(ndigits)
 
-      The first version returns the nearest :class:`int` to ``self``, rounding
-      half to even. The second version rounds ``self`` to the nearest multiple
-      of ``Fraction(1, 10**ndigits)`` (logically, if ``ndigits`` is negative),
-      again rounding half toward even. Will be accessible through :func:`round`
-      in Py3k.
+      The first version returns the nearest :class:`int` to ``self``,
+      rounding half to even. The second version rounds ``self`` to the
+      nearest multiple of ``Fraction(1, 10**ndigits)`` (logically, if
+      ``ndigits`` is negative), again rounding half toward even.  This
+      method can also be accessed through the :func:`round` function.
 
 
 .. seealso::

From python-3000-checkins at python.org  Tue Jun 24 17:37:23 2008
From: python-3000-checkins at python.org (mark.dickinson)
Date: Tue, 24 Jun 2008 17:37:23 +0200 (CEST)
Subject: [Python-3000-checkins] r64509 - python/branches/py3k
Message-ID: <20080624153723.700511E4009@bag.python.org>

Author: mark.dickinson
Date: Tue Jun 24 17:37:23 2008
New Revision: 64509

Log:
Blocked revisions 64508 via svnmerge

........
  r64508 | mark.dickinson | 2008-06-24 16:35:14 +0100 (Tue, 24 Jun 2008) | 2 lines
  
  Remove references to Py3k in __floor__, __ceil__ and __round__ documentation.
........


Modified:
   python/branches/py3k/   (props changed)

From python-3000-checkins at python.org  Wed Jun 25 00:28:56 2008
From: python-3000-checkins at python.org (raymond.hettinger)
Date: Wed, 25 Jun 2008 00:28:56 +0200 (CEST)
Subject: [Python-3000-checkins] r64515 - in python/branches/py3k:
	Include/floatobject.h Lib/test/test_builtin.py
	Objects/abstract.c Objects/floatobject.c
Message-ID: <20080624222856.F2C5B1E4009@bag.python.org>

Author: raymond.hettinger
Date: Wed Jun 25 00:28:56 2008
New Revision: 64515

Log:
Revert 64451.

Modified:
   python/branches/py3k/Include/floatobject.h
   python/branches/py3k/Lib/test/test_builtin.py
   python/branches/py3k/Objects/abstract.c
   python/branches/py3k/Objects/floatobject.c

Modified: python/branches/py3k/Include/floatobject.h
==============================================================================
--- python/branches/py3k/Include/floatobject.h	(original)
+++ python/branches/py3k/Include/floatobject.h	Wed Jun 25 00:28:56 2008
@@ -111,8 +111,6 @@
 					       Py_UNICODE *format_spec,
 					       Py_ssize_t format_spec_len);
 
-PyAPI_FUNC(PyObject *) _float_to_base(PyObject *v, int base);
-
 #ifdef __cplusplus
 }
 #endif

Modified: python/branches/py3k/Lib/test/test_builtin.py
==============================================================================
--- python/branches/py3k/Lib/test/test_builtin.py	(original)
+++ python/branches/py3k/Lib/test/test_builtin.py	Wed Jun 25 00:28:56 2008
@@ -553,15 +553,6 @@
         self.assertEqual(hex(-16), '-0x10')
         self.assertEqual(hex(-16), '-0x10')
         self.assertRaises(TypeError, hex, {})
-        self.assertEqual(hex(3.125), '0x19 * 2.0 ** -3')
-        self.assertEqual(hex(0.0), '0x0 * 2.0 ** 0')
-        for sv in float('nan'), float('inf'), float('-inf'):
-            self.assertEqual(hex(sv), repr(sv))
-        for i in range(100):
-            x = random.expovariate(.05)
-            self.assertEqual(eval(hex(x)), x, (x, hex(x), eval(hex(x))))
-            self.assertEqual(eval(hex(-x)), -x)
-            self.assertEqual(hex(-x), ('-' + hex(x)))
 
     def test_id(self):
         id(None)
@@ -805,15 +796,6 @@
         self.assertEqual(oct(-100), '-0o144')
         self.assertEqual(oct(-100), '-0o144')
         self.assertRaises(TypeError, oct, ())
-        self.assertEqual(oct(3.125), '0o31 * 2.0 ** -3')
-        self.assertEqual(oct(0.0), '0o0 * 2.0 ** 0')
-        for sv in float('nan'), float('inf'), float('-inf'):
-            self.assertEqual(oct(sv), repr(sv))
-        for i in range(100):
-            x = random.expovariate(.05)
-            self.assertEqual(eval(oct(x)), x)
-            self.assertEqual(eval(oct(-x)), -x)
-            self.assertEqual(oct(-x), ('-' + oct(x)))
 
     def write_testfile(self):
         # NB the first 4 lines are also used to test input, below
@@ -1231,15 +1213,6 @@
         self.assertEqual(bin(2**65-1), '0b' + '1' * 65)
         self.assertEqual(bin(-(2**65)), '-0b1' + '0' * 65)
         self.assertEqual(bin(-(2**65-1)), '-0b' + '1' * 65)
-        self.assertEqual(bin(3.125), '0b11001 * 2.0 ** -3')
-        self.assertEqual(bin(0.0), '0b0 * 2.0 ** 0')
-        for sv in float('nan'), float('inf'), float('-inf'):
-            self.assertEqual(bin(sv), repr(sv))
-        for i in range(100):
-            x = random.expovariate(.05)
-            self.assertEqual(eval(bin(x)), x)
-            self.assertEqual(eval(bin(-x)), -x)
-            self.assertEqual(bin(-x), ('-' + bin(x)))
 
 class TestSorted(unittest.TestCase):
 

Modified: python/branches/py3k/Objects/abstract.c
==============================================================================
--- python/branches/py3k/Objects/abstract.c	(original)
+++ python/branches/py3k/Objects/abstract.c	Wed Jun 25 00:28:56 2008
@@ -1451,11 +1451,8 @@
 PyNumber_ToBase(PyObject *n, int base)
 {
 	PyObject *res = NULL;
-	PyObject *index;
+	PyObject *index = PyNumber_Index(n);
 
-	if (PyFloat_Check(n))
-		return _float_to_base(n, base);
-	index = PyNumber_Index(n);
 	if (!index)
 		return NULL;
 	if (PyLong_Check(index))

Modified: python/branches/py3k/Objects/floatobject.c
==============================================================================
--- python/branches/py3k/Objects/floatobject.c	(original)
+++ python/branches/py3k/Objects/floatobject.c	Wed Jun 25 00:28:56 2008
@@ -1113,36 +1113,6 @@
 ">>> (-.25).as_integer_ratio()\n"
 "(-1, 4)");
 
-PyObject *
-_float_to_base(PyObject *v, int base)
-{
-	PyObject *mant, *conv, *result;
-	double x, fr;
-	int i, exp;
-
-	if (!PyFloat_Check(v)) {
-		PyErr_BadInternalCall();
-		return NULL;
-	}
-	CONVERT_TO_DOUBLE(v, x);
-	if (!Py_IS_FINITE(x))
-		return PyObject_Repr(v);
-	fr = frexp(x, &exp);
-	for (i=0; i<300 && fr != floor(fr) ; i++) {
-		fr *= 2.0;
-		exp--;
-	}
-	mant = PyLong_FromDouble(floor(fr));
-	if (mant == NULL)
-		return NULL;
-	conv = PyNumber_ToBase(mant, base);
-	Py_DECREF(mant);
-	if (conv == NULL)
-		return NULL;
-	result = PyUnicode_FromFormat("%U * 2.0 ** %d", conv, exp);
-	Py_DECREF(conv);
-	return result;
-}
 
 static PyObject *
 float_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds);

From python-3000-checkins at python.org  Wed Jun 25 14:46:04 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Wed, 25 Jun 2008 14:46:04 +0200 (CEST)
Subject: [Python-3000-checkins] r64521 - python/branches/py3k
Message-ID: <20080625124604.95C761E4002@bag.python.org>

Author: benjamin.peterson
Date: Wed Jun 25 14:46:04 2008
New Revision: 64521

Log:
Blocked revisions 64520 via svnmerge

........
  r64520 | benjamin.peterson | 2008-06-25 07:44:29 -0500 (Wed, 25 Jun 2008) | 1 line
  
  get rid of 2.6/3.0 switch statements in multiprocessing
........


Modified:
   python/branches/py3k/   (props changed)

From python-3000-checkins at python.org  Wed Jun 25 14:54:22 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Wed, 25 Jun 2008 14:54:22 +0200 (CEST)
Subject: [Python-3000-checkins] r64522 - in python/branches/py3k:
	Lib/multiprocessing/connection.py Lib/multiprocessing/managers.py
	Lib/multiprocessing/process.py
Message-ID: <20080625125422.A268F1E4002@bag.python.org>

Author: benjamin.peterson
Date: Wed Jun 25 14:54:22 2008
New Revision: 64522

Log:
Merged revisions 64517,64519 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/trunk

........
  r64517 | benjamin.peterson | 2008-06-24 22:09:05 -0500 (Tue, 24 Jun 2008) | 1 line
  
  remove bytes alias in multiprocessing
........
  r64519 | benjamin.peterson | 2008-06-25 07:39:05 -0500 (Wed, 25 Jun 2008) | 1 line
  
  use byte literals in multiprocessing
........


Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Lib/multiprocessing/connection.py
   python/branches/py3k/Lib/multiprocessing/managers.py
   python/branches/py3k/Lib/multiprocessing/process.py

Modified: python/branches/py3k/Lib/multiprocessing/connection.py
==============================================================================
--- python/branches/py3k/Lib/multiprocessing/connection.py	(original)
+++ python/branches/py3k/Lib/multiprocessing/connection.py	Wed Jun 25 14:54:22 2008
@@ -352,14 +352,9 @@
 
 MESSAGE_LENGTH = 20
 
-CHALLENGE = '#CHALLENGE#'
-WELCOME = '#WELCOME#'
-FAILURE = '#FAILURE#'
-
-if sys.version_info >= (3, 0):         # XXX can use bytes literals in 2.6/3.0
-    CHALLENGE = CHALLENGE.encode('ascii')
-    WELCOME = WELCOME.encode('ascii')
-    FAILURE = FAILURE.encode('ascii')
+CHALLENGE = b'#CHALLENGE#'
+WELCOME = b'#WELCOME#'
+FAILURE = b'#FAILURE#'
 
 def deliver_challenge(connection, authkey):
     import hmac

Modified: python/branches/py3k/Lib/multiprocessing/managers.py
==============================================================================
--- python/branches/py3k/Lib/multiprocessing/managers.py	(original)
+++ python/branches/py3k/Lib/multiprocessing/managers.py	Wed Jun 25 14:54:22 2008
@@ -33,15 +33,6 @@
     from pickle import PicklingError
 
 #
-#
-#
-
-try:
-    bytes
-except NameError:
-    bytes = str                  # XXX not needed in Py2.6 and Py3.0
-
-#
 # Register some things for pickling
 #
 

Modified: python/branches/py3k/Lib/multiprocessing/process.py
==============================================================================
--- python/branches/py3k/Lib/multiprocessing/process.py	(original)
+++ python/branches/py3k/Lib/multiprocessing/process.py	Wed Jun 25 14:54:22 2008
@@ -26,11 +26,6 @@
 except OSError:
     ORIGINAL_DIR = None
 
-try:
-    bytes
-except NameError:
-    bytes = str                  # XXX not needed in Py2.6 and Py3.0
-
 #
 # Public functions
 #

From python-3000-checkins at python.org  Wed Jun 25 15:04:48 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Wed, 25 Jun 2008 15:04:48 +0200 (CEST)
Subject: [Python-3000-checkins] r64524 -
	python/branches/py3k/Lib/multiprocessing/managers.py
Message-ID: <20080625130448.A6D721E4002@bag.python.org>

Author: benjamin.peterson
Date: Wed Jun 25 15:04:48 2008
New Revision: 64524

Log:
make changes for py3k for multiprocessing

Modified:
   python/branches/py3k/Lib/multiprocessing/managers.py

Modified: python/branches/py3k/Lib/multiprocessing/managers.py
==============================================================================
--- python/branches/py3k/Lib/multiprocessing/managers.py	(original)
+++ python/branches/py3k/Lib/multiprocessing/managers.py	Wed Jun 25 15:04:48 2008
@@ -41,7 +41,7 @@
 copyreg.pickle(array.array, reduce_array)
 
 view_types = [type(getattr({}, name)()) for name in ('items','keys','values')]
-if view_types[0] is not list:       # XXX only needed in Py3.0
+if view_types[0] is not list:       # only needed in Py3.0
     def rebuild_as_list(obj):
         return list, (list(obj),)
     for view_type in view_types:
@@ -930,14 +930,11 @@
 #
 
 class IteratorProxy(BaseProxy):
-    # XXX remove methods for Py3.0 and Py2.6
-    _exposed_ = ('__next__', 'next', 'send', 'throw', 'close')
+    _exposed_ = ('__next__', 'send', 'throw', 'close')
     def __iter__(self):
         return self
     def __next__(self, *args):
         return self._callmethod('__next__', args)
-    def next(self, *args):
-        return self._callmethod('next', args)
     def send(self, *args):
         return self._callmethod('send', args)
     def throw(self, *args):

From nnorwitz at gmail.com  Thu Jun 26 14:42:55 2008
From: nnorwitz at gmail.com (Neal Norwitz)
Date: Thu, 26 Jun 2008 08:42:55 -0400
Subject: [Python-3000-checkins] Python Regression Test Failures doc (1)
Message-ID: <20080626124255.GA8336@python.psfb.org>

svn update tools/sphinx
U    tools/sphinx/quickstart.py
U    tools/sphinx/search.py
U    tools/sphinx/templates/genindex-single.html
U    tools/sphinx/templates/genindex.html
U    tools/sphinx/builder.py
A    tools/sphinx/util/_json.py
U    tools/sphinx/util/json.py
Updated to revision 64531.
svn update tools/docutils
At revision 64531.
svn update tools/jinja
At revision 64531.
svn update tools/pygments
At revision 64531.
mkdir -p build/html build/doctrees
python2.5 tools/sphinx-build.py -b html -d build/doctrees -D latex_paper_size=  . build/html 
Sphinx v0.4, building html
trying to load pickled env... done
building [html]: targets for 380 source files that are out of date
updating environment: 0 added, 0 changed, 0 removed
writing output... about bugs c-api/abstract c-api/allocation c-api/arg c-api/bool c-api/buffer c-api/bytearray c-api/bytes c-api/cell c-api/cobject c-api/complex c-api/concrete c-api/conversion c-api/datetime c-api/descriptor c-api/dict c-api/exceptions c-api/file c-api/float c-api/function c-api/gcsupport c-api/gen c-api/import c-api/index c-api/init c-api/intro c-api/iter c-api/iterator c-api/list c-api/long c-api/mapping c-api/marshal c-api/memory c-api/method c-api/module c-api/none c-api/number c-api/objbuffer c-api/object c-api/objimpl c-api/refcounting c-api/reflection c-api/sequence c-api/set c-api/slice c-api/structures c-api/sys c-api/tuple c-api/type c-api/typeobj c-api/unicode c-api/utilities c-api/veryhigh c-api/weakref contents copyright distutils/apiref distutils/builtdist distutils/commandref distutils/configfile distutils/examples distutils/extending distutils/index distutils/introduction distutils/packageindex distutils/setupscript distutils/sourcedist distutils/uploading documenting/fromlatex documenting/index documenting/intro documenting/markup documenting/rest documenting/sphinx documenting/style extending/building extending/embedding extending/extending extending/index extending/newtypes extending/windows glossary howto/advocacy howto/curses howto/doanddont howto/functional howto/index howto/regex howto/sockets howto/unicode howto/urllib2 install/index library/__future__ library/__main__ library/_dummy_thread library/_thread library/abc library/aifc library/allos library/archiving library/array library/ast library/asynchat library/asyncore library/atexit library/audioop library/base64 library/bdb library/binascii library/binhex library/bisect library/bsddb library/builtins library/bz2 library/calendar library/cgi library/cgitb library/chunk library/cmath library/cmd library/code library/codecs library/codeop library/collections library/colorsys library/compileall library/configparser library/constants library/contextlib library/copy library/copyreg library/crypt library/crypto library/csv library/ctypes library/curses library/curses.ascii library/curses.panel library/custominterp library/datatypes library/datetime library/dbm library/debug library/decimal library/development library/difflib library/dis library/distutils library/doctest library/dummy_threading library/email library/email-examples library/email.charset library/email.encoders library/email.errors library/email.generator library/email.header library/email.iterators library/email.message library/email.mime library/email.parser library/email.util library/errno library/exceptions library/fcntl library/filecmp library/fileformats library/fileinput library/filesys library/fnmatch library/formatter library/fpectl library/fractions library/frameworks library/ftplib library/functions library/functools library/gc library/getopt library/getpass library/gettext library/glob library/grp library/gzip library/hashlib library/heapq library/hmac library/html.entities library/html.parser library/http.client library/http.cookiejar library/http.cookies library/http.server library/i18n library/idle library/imaplib library/imghdr library/imp library/index library/inspect library/internet library/intro library/io library/ipc library/itertools library/json library/keyword library/language library/linecache library/locale library/logging library/macpath library/mailbox library/mailcap library/markup library/marshal library/math library/mimetypes library/misc library/mm library/mmap library/modulefinder library/modules library/msilib library/msvcrt library/multiprocessing library/netdata library/netrc library/nis library/nntplib library/numbers library/numeric library/objects library/operator library/optparse library/os library/os.path library/ossaudiodev library/othergui library/parser library/pdb library/persistence library/pickle library/pickletools library/pipes library/pkgutil library/platform library/plistlib library/poplib library/posix library/pprint library/profile library/pty library/pwd library/py_compile library/pyclbr library/pydoc library/pyexpat library/python library/queue library/quopri library/random library/re library/readline library/reprlib library/resource library/rlcompleter library/runpy library/sched library/select library/shelve library/shlex library/shutil library/signal library/site library/smtpd library/smtplib library/sndhdr library/socket library/socketserver library/someos library/spwd library/sqlite3 library/ssl library/stat library/stdtypes library/string library/stringprep library/strings library/struct library/subprocess library/sunau library/symbol library/sys library/syslog library/tabnanny library/tarfile library/telnetlib library/tempfile library/termios library/test library/textwrap library/threading library/time library/timeit library/tk library/tkinter library/tkinter.scrolledtext library/tkinter.tix library/tkinter.turtle library/token library/tokenize library/trace library/traceback library/tty library/types library/undoc library/unicodedata library/unittest library/unix library/urllib.error library/urllib.parse library/urllib.request library/urllib.robotparser library/uu library/uuid library/warnings library/wave library/weakref library/webbrowser library/windows library/winreg library/winsound library/wsgiref library/xdrlib library/xml.dom library/xml.dom.minidom library/xml.dom.pulldom library/xml.etree.elementtree library/xml.sax library/xml.sax.handler library/xml.sax.reader library/xml.sax.utils library/xmlrpc.client library/xmlrpc.server library/zipfile library/zipimport library/zlib license reference/compound_stmts reference/datamodel reference/executionmodel reference/expressions reference/index reference/introduction reference/lexical_analysis reference/simple_stmts reference/toplevel_components tutorial/appetite tutorial/classes tutorial/controlflow tutorial/datastructures tutorial/errors tutorial/floatingpoint tutorial/index tutorial/inputoutput tutorial/interactive tutorial/interpreter tutorial/introduction tutorial/modules tutorial/stdlib tutorial/stdlib2 tutorial/whatnow using/cmdline using/index using/mac using/unix using/windows whatsnew/3.0 
finishing... 
writing additional files... genindexException occurred:
  File "genindex.html", line 289, in generate
TypeError: unsupported operand type(s) for +: 'int' and 'list'
The full traceback has been saved in /tmp/sphinx-err-HtqH3O.log, if you want to report the issue to the author.
Please also report this if it was a user error, so that a better error message can be provided next time.
Send reports to sphinx-dev at googlegroups.com. Thanks!
make: *** [build] Error 1

From python-3000-checkins at python.org  Thu Jun 26 21:00:11 2008
From: python-3000-checkins at python.org (georg.brandl)
Date: Thu, 26 Jun 2008 21:00:11 +0200 (CEST)
Subject: [Python-3000-checkins] r64536 -
	python/branches/py3k/Doc/library/operator.rst
Message-ID: <20080626190011.B47BC1E400E@bag.python.org>

Author: georg.brandl
Date: Thu Jun 26 21:00:11 2008
New Revision: 64536

Log:
#3204: remove slice operations from operator doc.


Modified:
   python/branches/py3k/Doc/library/operator.rst

Modified: python/branches/py3k/Doc/library/operator.rst
==============================================================================
--- python/branches/py3k/Doc/library/operator.rst	(original)
+++ python/branches/py3k/Doc/library/operator.rst	Thu Jun 26 21:00:11 2008
@@ -210,24 +210,12 @@
    Remove the value of *a* at index *b*.
 
  
-.. function:: delslice(a, b, c)
-              __delslice__(a, b, c)
-
-   Delete the slice of *a* from index *b* to index *c-1*.
-
-
 .. function:: getitem(a, b)
               __getitem__(a, b)
 
    Return the value of *a* at index *b*.
 
 
-.. function:: getslice(a, b, c)
-              __getslice__(a, b, c)
-
-   Return the slice of *a* from index *b* to index *c-1*.
-
-
 .. function:: indexOf(a, b)
 
    Return the index of the first of occurrence of *b* in *a*.
@@ -245,12 +233,6 @@
    Set the value of *a* at index *b* to *c*.
 
 
-.. function:: setslice(a, b, c, v)
-              __setslice__(a, b, c, v)
-
-   Set the slice of *a* from index *b* to index *c-1* to the sequence *v*.
-
-
 Many operations have an "in-place" version.  The following functions provide a
 more primitive access to in-place operators than the usual syntax does; for
 example, the :term:`statement` ``x += y`` is equivalent to
@@ -533,12 +515,6 @@
 +-----------------------+-------------------------+---------------------------------+
 | Sequence Repitition   | ``seq * i``             | ``repeat(seq, i)``              |
 +-----------------------+-------------------------+---------------------------------+
-| Slice Assignment      | ``seq[i:j] = values``   | ``setslice(seq, i, j, values)`` |
-+-----------------------+-------------------------+---------------------------------+
-| Slice Deletion        | ``del seq[i:j]``        | ``delslice(seq, i, j)``         |
-+-----------------------+-------------------------+---------------------------------+
-| Slicing               | ``seq[i:j]``            | ``getslice(seq, i, j)``         |
-+-----------------------+-------------------------+---------------------------------+
 | String Formatting     | ``s % obj``             | ``mod(s, obj)``                 |
 +-----------------------+-------------------------+---------------------------------+
 | Subtraction           | ``a - b``               | ``sub(a, b)``                   |

From python-3000-checkins at python.org  Thu Jun 26 23:45:04 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Thu, 26 Jun 2008 23:45:04 +0200 (CEST)
Subject: [Python-3000-checkins] r64548 - python/branches/py3k
Message-ID: <20080626214504.6AFC91E4003@bag.python.org>

Author: benjamin.peterson
Date: Thu Jun 26 23:45:04 2008
New Revision: 64548

Log:
Blocked revisions 64546-64547 via svnmerge

........
  r64546 | benjamin.peterson | 2008-06-26 16:24:35 -0500 (Thu, 26 Jun 2008) | 1 line
  
  use the new API
........
  r64547 | benjamin.peterson | 2008-06-26 16:29:19 -0500 (Thu, 26 Jun 2008) | 1 line
  
  fix isSet in _exposed
........


Modified:
   python/branches/py3k/   (props changed)

From python-3000-checkins at python.org  Fri Jun 27 02:35:36 2008
From: python-3000-checkins at python.org (brett.cannon)
Date: Fri, 27 Jun 2008 02:35:36 +0200 (CEST)
Subject: [Python-3000-checkins] r64551 -
	python/branches/py3k/Python/marshal.c
Message-ID: <20080627003536.5807F1E4003@bag.python.org>

Author: brett.cannon
Date: Fri Jun 27 02:35:35 2008
New Revision: 64551

Log:
Rename a variable to be more in line with the name of the module.


Modified:
   python/branches/py3k/Python/marshal.c

Modified: python/branches/py3k/Python/marshal.c
==============================================================================
--- python/branches/py3k/Python/marshal.c	(original)
+++ python/branches/py3k/Python/marshal.c	Fri Jun 27 02:35:35 2008
@@ -1191,7 +1191,7 @@
 	{NULL,		NULL}		/* sentinel */
 };
 
-static struct PyModuleDef impmodule = {
+static struct PyModuleDef marshalmodule = {
 	PyModuleDef_HEAD_INIT,
 	"marshal",
 	NULL,
@@ -1208,7 +1208,7 @@
 PyMODINIT_FUNC
 PyMarshal_Init(void)
 {
-	PyObject *mod = PyModule_Create(&impmodule);
+	PyObject *mod = PyModule_Create(&marshalmodule);
 	if (mod == NULL)
 		return NULL;
 	PyModule_AddIntConstant(mod, "version", Py_MARSHAL_VERSION);

From python-3000-checkins at python.org  Fri Jun 27 02:52:16 2008
From: python-3000-checkins at python.org (brett.cannon)
Date: Fri, 27 Jun 2008 02:52:16 +0200 (CEST)
Subject: [Python-3000-checkins] r64552 - in python/branches/py3k:
	Lib/test/test_warnings.py Lib/warnings.py Misc/NEWS
	Python/_warnings.c
Message-ID: <20080627005216.145F51E4003@bag.python.org>

Author: brett.cannon
Date: Fri Jun 27 02:52:15 2008
New Revision: 64552

Log:
Merged revisions 64549 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/trunk

........
  r64549 | brett.cannon | 2008-06-26 17:31:13 -0700 (Thu, 26 Jun 2008) | 7 lines
  
  warnings.warn_explicit() did not have the proper TypeErrors in place to prevent
  bus errors or SystemError being raised. As a side effect of fixing this, a bad
  DECREF that could be triggered when 'message' and 'category' were both None was
  fixed.
  
  Closes issue 3211. Thanks JP Calderone for the bug report.
........


Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Lib/test/test_warnings.py
   python/branches/py3k/Lib/warnings.py
   python/branches/py3k/Misc/NEWS
   python/branches/py3k/Python/_warnings.c

Modified: python/branches/py3k/Lib/test/test_warnings.py
==============================================================================
--- python/branches/py3k/Lib/test/test_warnings.py	(original)
+++ python/branches/py3k/Lib/test/test_warnings.py	Fri Jun 27 02:52:15 2008
@@ -301,6 +301,21 @@
             warning_tests.__name__ = module_name
             sys.argv = argv
 
+    def test_warn_explicit_type_errors(self):
+        # warn_explicit() shoud error out gracefully if it is given objects
+        # of the wrong types.
+        # lineno is expected to be an integer.
+        self.assertRaises(TypeError, self.module.warn_explicit,
+                            None, UserWarning, None, None)
+        # Either 'message' needs to be an instance of Warning or 'category'
+        # needs to be a subclass.
+        self.assertRaises(TypeError, self.module.warn_explicit,
+                            None, None, None, 1)
+        # 'registry' must be a dict or None.
+        self.assertRaises((TypeError, AttributeError),
+                            self.module.warn_explicit,
+                            None, Warning, None, 1, registry=42)
+
 
 
 class CWarnTests(BaseTest, WarnTests):

Modified: python/branches/py3k/Lib/warnings.py
==============================================================================
--- python/branches/py3k/Lib/warnings.py	(original)
+++ python/branches/py3k/Lib/warnings.py	Fri Jun 27 02:52:15 2008
@@ -188,6 +188,7 @@
 
 def warn_explicit(message, category, filename, lineno,
                   module=None, registry=None, module_globals=None):
+    lineno = int(lineno)
     if module is None:
         module = filename or "<unknown>"
         if module[-3:].lower() == ".py":

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Fri Jun 27 02:52:15 2008
@@ -27,6 +27,11 @@
 Core and Builtins
 -----------------
 
+- Issue #3211: warnings.warn_explicit() did not guard against its 'registry'
+  argument being anything other than a dict or None. Also fixed a bug in error
+  handling when 'message' and 'category' were both set to None, triggering a
+  bus error.
+
 - Issue #3100: Corrected a crash on deallocation of a subclassed weakref which
   holds the last (strong) reference to its referent.
 

Modified: python/branches/py3k/Python/_warnings.c
==============================================================================
--- python/branches/py3k/Python/_warnings.c	(original)
+++ python/branches/py3k/Python/_warnings.c	Fri Jun 27 02:52:15 2008
@@ -280,6 +280,11 @@
     PyObject *item = Py_None;
     const char *action;
     int rc;
+    
+    if (registry && !PyDict_Check(registry) && (registry != Py_None)) {
+        PyErr_SetString(PyExc_TypeError, "'registry' must be a dict");
+        return NULL;
+    }
 
     /* Normalize module. */
     if (module == NULL) {
@@ -303,6 +308,8 @@
     else {
         text = message;
         message = PyObject_CallFunction(category, "O", message);
+        if (message == NULL)
+            goto cleanup;
     }
 
     lineno_obj = PyLong_FromLong(lineno);
@@ -314,7 +321,7 @@
     if (key == NULL)
         goto cleanup;
 
-    if (registry != NULL) {
+    if ((registry != NULL) && (registry != Py_None)) {
         rc = already_warned(registry, key, 0);
         if (rc == -1)
             goto cleanup;
@@ -336,12 +343,13 @@
        is "always". */
     rc = 0;
     if (strcmp(action, "always") != 0) {
-        if (registry != NULL && PyDict_SetItem(registry, key, Py_True) < 0)
+        if (registry != NULL && registry != Py_None &&
+                PyDict_SetItem(registry, key, Py_True) < 0)
             goto cleanup;
         else if (strcmp(action, "ignore") == 0)
             goto return_none;
         else if (strcmp(action, "once") == 0) {
-            if (registry == NULL) {
+            if (registry == NULL || registry == Py_None) {
                 registry = get_once_registry();
                 if (registry == NULL)
                     goto cleanup;
@@ -351,7 +359,7 @@
         }
         else if (strcmp(action, "module") == 0) {
             /* registry[(text, category, 0)] = 1 */
-            if (registry != NULL)
+            if (registry != NULL && registry != Py_None)
                 rc = update_registry(registry, text, category, 0); 
         }
         else if (strcmp(action, "default") != 0) {
@@ -435,7 +443,7 @@
     Py_XDECREF(text);
     Py_XDECREF(lineno_obj);
     Py_DECREF(module);
-    Py_DECREF(message);
+    Py_XDECREF(message);
     return result;  /* Py_None or NULL. */
 }
 

From python-3000-checkins at python.org  Fri Jun 27 02:53:19 2008
From: python-3000-checkins at python.org (brett.cannon)
Date: Fri, 27 Jun 2008 02:53:19 +0200 (CEST)
Subject: [Python-3000-checkins] r64553 - python/branches/py3k/Lib/urllib
Message-ID: <20080627005319.45BAA1E4003@bag.python.org>

Author: brett.cannon
Date: Fri Jun 27 02:53:19 2008
New Revision: 64553

Log:
Ignore *.pyc and *.pyo files.


Modified:
   python/branches/py3k/Lib/urllib/   (props changed)

From python-3000-checkins at python.org  Fri Jun 27 04:47:27 2008
From: python-3000-checkins at python.org (trent.nelson)
Date: Fri, 27 Jun 2008 04:47:27 +0200 (CEST)
Subject: [Python-3000-checkins] r64556 - python/branches/py3k
Message-ID: <20080627024727.8E3BA1E4003@bag.python.org>

Author: trent.nelson
Date: Fri Jun 27 04:47:27 2008
New Revision: 64556

Log:
Blocked revisions 64555 via svnmerge

................
  r64555 | trent.nelson | 2008-06-26 21:30:34 -0500 (Thu, 26 Jun 2008) | 13 lines
  
  Merged revisions 64368-64369 via svnmerge from 
  svn+ssh://pythondev at svn.python.org/python/branches/tnelson-trunk-bsddb-47-upgrade
  
  ........
    r64368 | trent.nelson | 2008-06-17 23:13:44 -0500 (Tue, 17 Jun 2008) | 1 line
    
    Initial commit of work pertaining to switching the Windows build from Berkeley DB 4.4.20 to 4.7.25.  Note that I've deprecated the standalone '_bsddb44.vcproj' in lieu of adding the sources in a separate folder to the _bsddb project.  This was a conscious decision and actually makes everything far more easier to manage.  With this approach, entire test suite passed straight off the bat.  Well, almost -- the timeout in bsddb/test/test_replication.py needed bumping up a little -- 2 seconds was too short.  10 seconds seems to be fine for me, but I'll make sure Jesus verifies.  More documentation to come once I've been able to test out this approach on the buildbots (hence keeping the changes in a separate branch for now).
  ........
    r64369 | trent.nelson | 2008-06-17 23:19:12 -0500 (Tue, 17 Jun 2008) | 1 line
    
    Bump Berkeley DB version from 4.4.20 to 4.7.25.
  ........
................


Modified:
   python/branches/py3k/   (props changed)

From python-3000-checkins at python.org  Fri Jun 27 19:01:18 2008
From: python-3000-checkins at python.org (mark.dickinson)
Date: Fri, 27 Jun 2008 19:01:18 +0200 (CEST)
Subject: [Python-3000-checkins] r64562 - in python/branches/py3k:
	Doc/library/fractions.rst
Message-ID: <20080627170118.1A8BF1E4003@bag.python.org>

Author: mark.dickinson
Date: Fri Jun 27 19:01:17 2008
New Revision: 64562

Log:
Merged revisions 64561 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/trunk

........
  r64561 | mark.dickinson | 2008-06-27 17:49:27 +0100 (Fri, 27 Jun 2008) | 2 lines
  
  Issue #3197: rework documentation for fractions module.
........


Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Doc/library/fractions.rst

Modified: python/branches/py3k/Doc/library/fractions.rst
==============================================================================
--- python/branches/py3k/Doc/library/fractions.rst	(original)
+++ python/branches/py3k/Doc/library/fractions.rst	Fri Jun 27 19:01:17 2008
@@ -8,38 +8,74 @@
 .. sectionauthor:: Jeffrey Yasskin <jyasskin at gmail.com>
 
 
-The :mod:`fractions` module defines an immutable, infinite-precision
-Rational number class.
+The :mod:`fractions` module provides support for rational number arithmetic.
 
 
+A Fraction instance can be constructed from a pair of integers, from
+another rational number, or from a string.
+
 .. class:: Fraction(numerator=0, denominator=1)
            Fraction(other_fraction)
            Fraction(string)
 
    The first version requires that *numerator* and *denominator* are
    instances of :class:`numbers.Integral` and returns a new
-   ``Fraction`` representing ``numerator/denominator``. If
-   *denominator* is :const:`0`, raises a :exc:`ZeroDivisionError`. The
-   second version requires that *other_fraction* is an instance of
-   :class:`numbers.Rational` and returns an instance of
-   :class:`Fraction` with the same value. The third version expects a
-   string of the form ``[-+]?[0-9]+(/[0-9]+)?``, optionally surrounded
-   by spaces.
-
-   Implements all of the methods and operations from
-   :class:`numbers.Rational` and is immutable and hashable.
+   :class:`Fraction` instance with value ``numerator/denominator``. If
+   *denominator* is :const:`0`, it raises a
+   :exc:`ZeroDivisionError`. The second version requires that
+   *other_fraction* is an instance of :class:`numbers.Rational` and
+   returns an :class:`Fraction` instance with the same value.  The
+   last version of the constructor expects a string or unicode
+   instance in one of two possible forms.  The first form is::
+
+      [sign] numerator ['/' denominator]
+
+   where the optional ``sign`` may be either '+' or '-' and
+   ``numerator`` and ``denominator`` (if present) are strings of
+   decimal digits.  The second permitted form is that of a number
+   containing a decimal point::
+
+      [sign] integer '.' [fraction] | [sign] '.' fraction
+
+   where ``integer`` and ``fraction`` are strings of digits.  In
+   either form the input string may also have leading and/or trailing
+   whitespace.  Here are some examples::
+
+      >>> from fractions import Fraction
+      >>> Fraction(16, -10)
+      Fraction(-8, 5)
+      >>> Fraction(123)
+      Fraction(123, 1)
+      >>> Fraction()
+      Fraction(0, 1)
+      >>> Fraction('3/7')
+      Fraction(3, 7)
+      [40794 refs]
+      >>> Fraction(' -3/7 ')
+      Fraction(-3, 7)
+      >>> Fraction('1.414213 \t\n')
+      Fraction(1414213, 1000000)
+      >>> Fraction('-.125')
+      Fraction(-1, 8)
+
+
+   The :class:`Fraction` class inherits from the abstract base class
+   :class:`numbers.Rational`, and implements all of the methods and
+   operations from that class.  :class:`Fraction` instances are hashable,
+   and should be treated as immutable.  In addition,
+   :class:`Fraction` has the following methods:
 
 
    .. method:: from_float(flt)
 
-      This classmethod constructs a :class:`Fraction` representing the exact
+      This class method constructs a :class:`Fraction` representing the exact
       value of *flt*, which must be a :class:`float`. Beware that
-      ``Fraction.from_float(0.3)`` is not the same value as ``Rational(3, 10)``
+      ``Fraction.from_float(0.3)`` is not the same value as ``Fraction(3, 10)``
 
 
    .. method:: from_decimal(dec)
 
-      This classmethod constructs a :class:`Fraction` representing the exact
+      This class method constructs a :class:`Fraction` representing the exact
       value of *dec*, which must be a :class:`decimal.Decimal` instance.
 
 
@@ -88,6 +124,15 @@
       method can also be accessed through the :func:`round` function.
 
 
+.. function:: gcd(a, b)
+
+   Return the greatest common divisor of the integers `a` and `b`.  If
+   either `a` or `b` is nonzero, then the absolute value of `gcd(a,
+   b)` is the largest integer that divides both `a` and `b`.  `gcd(a,b)`
+   has the same sign as `b` if `b` is nonzero; otherwise it takes the sign
+   of `a`.  `gcd(0, 0)` returns `0`.
+
+
 .. seealso::
 
    Module :mod:`numbers`

From python-3000-checkins at python.org  Sat Jun 28 00:16:48 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Sat, 28 Jun 2008 00:16:48 +0200 (CEST)
Subject: [Python-3000-checkins] r64566 -
	python/branches/py3k/Lib/multiprocessing/sharedctypes.py
Message-ID: <20080627221648.19E631E4003@bag.python.org>

Author: benjamin.peterson
Date: Sat Jun 28 00:16:47 2008
New Revision: 64566

Log:
make multiprocessing.sharedctypes.Value's lock argument a keyword-only argument for real

Modified:
   python/branches/py3k/Lib/multiprocessing/sharedctypes.py

Modified: python/branches/py3k/Lib/multiprocessing/sharedctypes.py
==============================================================================
--- python/branches/py3k/Lib/multiprocessing/sharedctypes.py	(original)
+++ python/branches/py3k/Lib/multiprocessing/sharedctypes.py	Sat Jun 28 00:16:47 2008
@@ -62,13 +62,10 @@
         result.__init__(*size_or_initializer)
         return result
 
-def Value(typecode_or_type, *args, **kwds):
+def Value(typecode_or_type, *args, lock=None):
     '''
     Return a synchronization wrapper for a Value
     '''
-    lock = kwds.pop('lock', None)
-    if kwds:
-        raise ValueError('unrecognized keyword argument(s): %s' % list(kwds.keys()))
     obj = RawValue(typecode_or_type, *args)
     if lock is None:
         lock = RLock()

From python-3000-checkins at python.org  Sat Jun 28 02:40:54 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Sat, 28 Jun 2008 02:40:54 +0200 (CEST)
Subject: [Python-3000-checkins] r64569 - in python/branches/py3k:
	Doc/library/multiprocessing.rst
Message-ID: <20080628004054.9F8921E4003@bag.python.org>

Author: benjamin.peterson
Date: Sat Jun 28 02:40:54 2008
New Revision: 64569

Log:
Merged revisions 64407,64568 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/trunk

........
  r64407 | andrew.kuchling | 2008-06-19 14:48:42 -0500 (Thu, 19 Jun 2008) | 1 line
  
  Remove some standalone material from the introduction; various markup and typo fixes
........
  r64568 | benjamin.peterson | 2008-06-27 18:22:06 -0500 (Fri, 27 Jun 2008) | 1 line
  
  edit multiprocessing docs
........


Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Doc/library/multiprocessing.rst

Modified: python/branches/py3k/Doc/library/multiprocessing.rst
==============================================================================
--- python/branches/py3k/Doc/library/multiprocessing.rst	(original)
+++ python/branches/py3k/Doc/library/multiprocessing.rst	Sat Jun 28 02:40:54 2008
@@ -4,81 +4,24 @@
 .. module:: multiprocessing
    :synopsis: Process-based "threading" interface.
 
-:mod:`multiprocessing` is a package for the Python language which supports the
-spawning of processes using a similar API of the :mod:`threading` module.  It
-runs on both Unix and Windows.
-
-The :mod:`multiprocessing` module offers the capability of both local and remote
-concurrency effectively side-stepping the Global Interpreter Lock by utilizing
-subprocesses for "threads".  Due to this, the :mod:`multiprocessing` module
-allows the programmer to fully leverage multiple processors on a given machine.
-
 
 Introduction
-------------
-
-
-Threads, processes and the GIL
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-To run more than one piece of code at the same time on the same computer one has
-the choice of either using multiple processes or multiple threads.
+----------------------
 
-Although a program can be made up of multiple processes, these processes are in
-effect completely independent of one another: different processes are not able
-to cooperate with one another unless one sets up some means of communication
-between them (such as by using sockets).  If a lot of data must be transferred
-between processes then this can be inefficient.
-
-On the other hand, multiple threads within a single process are intimately
-connected: they share their data but often can interfere badly with one another.
-It is often argued that the only way to make multithreaded programming "easy" is
-to avoid relying on any shared state and for the threads to only communicate by
-passing messages to each other.
-
-CPython has a *Global Interpreter Lock* (GIL) which in many ways makes threading
-easier than it is in most languages by making sure that only one thread can
-manipulate the interpreter's objects at a time.  As a result, it is often safe
-to let multiple threads access data without using any additional locking as one
-would need to in a language such as C.
-
-One downside of the GIL is that on multi-processor (or multi-core) systems a
-multithreaded Python program can only make use of one processor at a time unless
-your application makes heavy use of I/O which effectively side-steps this.  This
-is a problem that can be overcome by using multiple processes instead.
-
-This package allows one to write multi-process programs using much the same API
-that one uses for writing threaded programs.
-
-
-Forking and spawning
-~~~~~~~~~~~~~~~~~~~~
-
-There are two ways of creating a new process in Python:
-
-* The current process can *fork* a new child process by using the
-  :func:`os.fork` function.  This effectively creates an identical copy of the
-  current process which is now able to go off and perform some task set by the
-  parent process.  This means that the child process inherits *copies* of all
-  variables that the parent process had.  However, :func:`os.fork` is not
-  available on every platform: in particular Windows does not support it.
-
-* Alternatively, the current process can spawn a completely new Python
-  interpreter by using the :mod:`subprocess` module or one of the
-  :func:`os.spawn*` functions.  Getting this new interpreter in to a fit state
-  to perform the task set for it by its parent process is, however, a bit of a
-  challenge.
-
-The :mod:`multiprocessing` module uses :func:`os.fork` if it is available since
-it makes life a lot simpler.  Forking the process is also more efficient in
-terms of memory usage and the time needed to create the new process.
+:mod:`multiprocessing` is a package that supports spawning processes using an
+API similar to the :mod:`threading` module.  The :mod:`multiprocessing` package
+offers both local and remote concurrency, effectively side-stepping the
+:term:`Global Interpreter Lock` by using subprocesses instead of threads.  Due
+to this, the :mod:`multiprocessing` module allows the programmer to fully
+leverage multiple processors on a given machine.  It runs on both Unix and
+Windows.
 
 
 The :class:`Process` class
 ~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 In :mod:`multiprocessing`, processes are spawned by creating a :class:`Process`
-object and then calling its :meth:`Process.start` method.  :class:`Process`
+object and then calling its :meth:`~Process.start` method.  :class:`Process`
 follows the API of :class:`threading.Thread`.  A trivial example of a
 multiprocess program is ::
 
@@ -143,11 +86,12 @@
           p.join()
 
    The two connection objects returned by :func:`Pipe` represent the two ends of
-   the pipe.  Each connection object has :meth:`send` and :meth:`recv` methods
-   (among others).  Note that data in a pipe may become corrupted if two
-   processes (or threads) try to read from or write to the *same* end of the
-   pipe at the same time.  Of course there is no risk of corruption from
-   processes using different ends of the pipe at the same time.
+   the pipe.  Each connection object has :meth:`~Connection.send` and
+   :meth:`~Connection.recv` methods (among others).  Note that data in a pipe
+   may become corrupted if two processes (or threads) try to read from or write
+   to the *same* end of the pipe at the same time.  Of course there is no risk
+   of corruption from processes using different ends of the pipe at the same
+   time.
 
 
 Synchronization between processes
@@ -268,7 +212,7 @@
 Using a pool of workers
 ~~~~~~~~~~~~~~~~~~~~~~~
 
-The :class:`multiprocessing.pool.Pool()` class represens a pool of worker
+The :class:`~multiprocessing.pool.Pool` class represents a pool of worker
 processes.  It has methods which allows tasks to be offloaded to the worker
 processes in a few different ways.
 
@@ -303,9 +247,9 @@
    :class:`threading.Thread`.
 
    The constructor should always be called with keyword arguments. *group*
-   should always be ``None``; it exists soley for compatibility with
-   :class:`threading.Thread`.  *target* is the callable object to be invoked by
-   the :meth:`run()` method.  It defaults to None, meaning nothing is
+   should always be ``None``; it exists solely for compatibility with
+   :class:`~threading.Thread`.  *target* is the callable object to be invoked by
+   the :meth:`run()` method.  It defaults to ``None``, meaning nothing is
    called. *name* is the process name.  By default, a unique name is constructed
    of the form 'Process-N\ :sub:`1`:N\ :sub:`2`:...:N\ :sub:`k`' where N\
    :sub:`1`,N\ :sub:`2`,...,N\ :sub:`k` is a sequence of integers whose length
@@ -413,11 +357,11 @@
 
       Set the process's authentication key which must be a byte string.
 
-   .. method:: terminate()`
+   .. method:: terminate()
 
-      Terminate the process.  On Unix this is done using the ``SIGTERM`` signal,
-      on Windows ``TerminateProcess()`` is used.  Note that exit handlers and
-      finally clauses etc will not be executed.
+      Terminate the process.  On Unix this is done using the ``SIGTERM`` signal;
+      on Windows :cfunc:`TerminateProcess` is used.  Note that exit handlers and
+      finally clauses, etc., will not be executed.
 
       Note that descendant processes of the process will *not* be terminated --
       they will simply become orphaned.
@@ -472,14 +416,17 @@
 The :class:`Queue` and :class:`JoinableQueue` types are multi-producer,
 multi-consumer FIFO queues modelled on the :class:`Queue.Queue` class in the
 standard library.  They differ in that :class:`Queue` lacks the
-:meth:`task_done` and :meth:`join` methods introduced into Python 2.5's
-:class:`Queue.Queue` class.
+:meth:`~Queue.Queue.task_done` and :meth:`~Queue.Queue.join` methods introduced
+into Python 2.5's :class:`Queue.Queue` class.
 
 If you use :class:`JoinableQueue` then you **must** call
 :meth:`JoinableQueue.task_done` for each task removed from the queue or else the
 semaphore used to count the number of unfinished tasks may eventually overflow
 raising an exception.
 
+Note that one can also create a shared queue by using a manager object -- see
+:ref:`multiprocessing-managers`.
+
 .. note::
 
    :mod:`multiprocessing` uses the usual :exc:`Queue.Empty` and
@@ -509,9 +456,6 @@
    Note that a queue created using a manager does not have this issue.  See
    :ref:`multiprocessing-programming`.
 
-Note that one can also create a shared queue by using a manager object -- see
-:ref:`multiprocessing-managers`.
-
 For an example of the usage of queues for interprocess communication see
 :ref:`multiprocessing-examples`.
 
@@ -537,7 +481,7 @@
    standard library's :mod:`Queue` module are raised to signal timeouts.
 
    :class:`Queue` implements all the methods of :class:`Queue.Queue` except for
-   :meth:`task_done` and :meth:`join`.
+   :meth:`~Queue.Queue.task_done` and :meth:`~Queue.Queue.join`.
 
    .. method:: qsize()
 
@@ -557,10 +501,10 @@
       Return ``True`` if the queue is full, ``False`` otherwise.  Because of
       multithreading/multiprocessing semantics, this is not reliable.
 
-   .. method:: put(item[, block[, timeout]])`
+   .. method:: put(item[, block[, timeout]])
 
-      Put item into the queue.  If optional args *block* is ``True`` (the
-      default) and *timeout* is ``None`` (the default), block if necessary until
+      Put item into the queue.  If the optional argument *block* is ``True`` 
+      (the default) and *timeout* is ``None`` (the default), block if necessary until
       a free slot is available.  If *timeout* is a positive number, it blocks at
       most *timeout* seconds and raises the :exc:`Queue.Full` exception if no
       free slot was available within that time.  Otherwise (*block* is
@@ -605,13 +549,13 @@
 
       By default if a process is not the creator of the queue then on exit it
       will attempt to join the queue's background thread.  The process can call
-      :meth:`cancel_join_thread()` to make :meth:`join_thread()` do nothing.
+      :meth:`cancel_join_thread` to make :meth:`join_thread` do nothing.
 
    .. method:: cancel_join_thread()
 
       Prevent :meth:`join_thread` from blocking.  In particular, this prevents
       the background thread from being joined automatically when the process
-      exits -- see :meth:`join_thread()`.
+      exits -- see :meth:`join_thread`.
 
 
 .. class:: JoinableQueue([maxsize])
@@ -622,13 +566,13 @@
    .. method:: task_done()
 
       Indicate that a formerly enqueued task is complete. Used by queue consumer
-      threads.  For each :meth:`get` used to fetch a task, a subsequent call to
-      :meth:`task_done` tells the queue that the processing on the task is
-      complete.
-
-      If a :meth:`join` is currently blocking, it will resume when all items
-      have been processed (meaning that a :meth:`task_done` call was received
-      for every item that had been :meth:`put` into the queue).
+      threads.  For each :meth:`~Queue.get` used to fetch a task, a subsequent
+      call to :meth:`task_done` tells the queue that the processing on the task
+      is complete.
+
+      If a :meth:`~Queue.join` is currently blocking, it will resume when all
+      items have been processed (meaning that a :meth:`task_done` call was
+      received for every item that had been :meth:`~Queue.put` into the queue).
 
       Raises a :exc:`ValueError` if called more times than there were items
       placed in the queue.
@@ -642,7 +586,7 @@
       queue.  The count goes down whenever a consumer thread calls
       :meth:`task_done` to indicate that the item was retrieved and all work on
       it is complete.  When the count of unfinished tasks drops to zero,
-      :meth:`join` unblocks.
+      :meth:`~Queue.join` unblocks.
 
 
 Miscellaneous
@@ -684,17 +628,17 @@
           freeze_support()
           Process(target=f).start()
 
-   If the :func:`freeze_support()` line is missed out then trying to run the
-   frozen executable will raise :exc:`RuntimeError`.
+   If the ``freeze_support()`` line is missed out then trying to run the frozen
+   executable will raise :exc:`RuntimeError`.
 
    If the module is being run normally by the Python interpreter then
-   :func:`freeze_support()` has no effect.
+   :func:`freeze_support` has no effect.
 
 .. function:: set_executable()
 
    Sets the path of the python interpreter to use when starting a child process.
-   (By default `sys.executable` is used).  Embedders will probably need to do
-   some thing like ::
+   (By default :data:`sys.executable` is used).  Embedders will probably need to
+   do some thing like ::
 
       setExecutable(os.path.join(sys.exec_prefix, 'pythonw.exe'))
 
@@ -715,7 +659,7 @@
 Connection objects allow the sending and receiving of picklable objects or
 strings.  They can be thought of as message oriented connected sockets.
 
-Connection objects usually created using :func:`Pipe()` -- see also
+Connection objects usually created using :func:`Pipe` -- see also
 :ref:`multiprocessing-listeners-clients`.
 
 .. class:: Connection
@@ -812,9 +756,10 @@
     receives, which can be a security risk unless you can trust the process
     which sent the message.
 
-    Therefore, unless the connection object was produced using :func:`Pipe()`
-    you should only use the `recv()` and `send()` methods after performing some
-    sort of authentication.  See :ref:`multiprocessing-auth-keys`.
+    Therefore, unless the connection object was produced using :func:`Pipe` you
+    should only use the :meth:`~Connection.recv` and :meth:`~Connection.send`
+    methods after performing some sort of authentication.  See
+    :ref:`multiprocessing-auth-keys`.
 
 .. warning::
 
@@ -827,8 +772,8 @@
 ~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 Generally synchronization primitives are not as necessary in a multiprocess
-program as they are in a mulithreaded program.  See the documentation for the
-standard library's :mod:`threading` module.
+program as they are in a mulithreaded program.  See the documentation for
+:mod:`threading` module.
 
 Note that one can also create synchronization primitives by using a manager
 object -- see :ref:`multiprocessing-managers`.
@@ -842,7 +787,7 @@
 
 .. class:: Condition([lock])
 
-   A condition variable: a clone of `threading.Condition`.
+   A condition variable: a clone of :class:`threading.Condition`.
 
    If *lock* is specified then it should be a :class:`Lock` or :class:`RLock`
    object from :mod:`multiprocessing`.
@@ -865,7 +810,7 @@
 
 .. note::
 
-   The :meth:`acquire()` method of :class:`BoundedSemaphore`, :class:`Lock`,
+   The :meth:`acquire` method of :class:`BoundedSemaphore`, :class:`Lock`,
    :class:`RLock` and :class:`Semaphore` has a timeout parameter not supported
    by the equivalents in :mod:`threading`.  The signature is
    ``acquire(block=True, timeout=None)`` with keyword parameters being
@@ -891,7 +836,7 @@
 It is possible to create shared objects using shared memory which can be
 inherited by child processes.
 
-.. function:: Value(typecode_or_type[, lock[, *args]])
+.. function:: Value(typecode_or_type[, *args, lock]])
 
    Return a :mod:`ctypes` object allocated from shared memory.  By default the
    return value is actually a synchronized wrapper for the object.
@@ -983,7 +928,7 @@
    attributes which allow one to use it to store and retrieve strings -- see
    documentation for :mod:`ctypes`.
 
-.. function:: Array(typecode_or_type, size_or_initializer[, lock[, *args]])
+.. function:: Array(typecode_or_type, size_or_initializer[, *args[, lock]])
 
    The same as :func:`RawArray` except that depending on the value of *lock* a
    process-safe synchronization wrapper may be returned instead of a raw ctypes
@@ -1025,11 +970,11 @@
    :class:`multiprocessing.RLock` object is created automatically.
 
    A synchronized wrapper will have two methods in addition to those of the
-   object it wraps: :meth:`get_obj()` returns the wrapped object and
-   :meth:`get_lock()` returns the lock object used for synchronization.
+   object it wraps: :meth:`get_obj` returns the wrapped object and
+   :meth:`get_lock` returns the lock object used for synchronization.
 
    Note that accessing the ctypes object through the wrapper can be a lot slower
-   han accessing the raw ctypes object.
+   than accessing the raw ctypes object.
 
 
 The table below compares the syntax for creating shared ctypes objects from
@@ -1105,10 +1050,10 @@
 
 .. function:: multiprocessing.Manager()
 
-   Returns a started :class:`SyncManager` object which can be used for sharing
-   objects between processes.  The returned manager object corresponds to a
-   spawned child process and has methods which will create shared objects and
-   return corresponding proxies.
+   Returns a started :class:`~multiprocessing.managers.SyncManager` object which
+   can be used for sharing objects between processes.  The returned manager
+   object corresponds to a spawned child process and has methods which will
+   create shared objects and return corresponding proxies.
 
 .. module:: multiprocessing.managers
    :synopsis: Share data between process with shared objects.
@@ -1148,7 +1093,7 @@
    .. method:: shutdown()
 
       Stop the process used by the manager.  This is only available if
-      meth:`start` has been used to start the server process.
+      :meth:`start` has been used to start the server process.
 
       This can be called multiple times.
 
@@ -1162,12 +1107,12 @@
 
       *callable* is a callable used for creating objects for this type
       identifier.  If a manager instance will be created using the
-      :meth:`from_address()` classmethod or if the *create_method* argument is
+      :meth:`from_address` classmethod or if the *create_method* argument is
       ``False`` then this can be left as ``None``.
 
-      *proxytype* is a subclass of :class:`multiprocessing.managers.BaseProxy`
-      which is used to create proxies for shared objects with this *typeid*.  If
-      ``None`` then a proxy class is created automatically.
+      *proxytype* is a subclass of :class:`BaseProxy` which is used to create
+      proxies for shared objects with this *typeid*.  If ``None`` then a proxy
+      class is created automatically.
 
       *exposed* is used to specify a sequence of method names which proxies for
       this typeid should be allowed to access using
@@ -1175,7 +1120,7 @@
       :attr:`proxytype._exposed_` is used instead if it exists.)  In the case
       where no exposed list is specified, all "public methods" of the shared
       object will be accessible.  (Here a "public method" means any attribute
-      which has a ``__call__()`` method and whose name does not begin with
+      which has a :meth:`__call__` method and whose name does not begin with
       ``'_'``.)
 
       *method_to_typeid* is a mapping used to specify the return type of those
@@ -1200,7 +1145,7 @@
 
    A subclass of :class:`BaseManager` which can be used for the synchronization
    of processes.  Objects of this type are returned by
-   :func:`multiprocessing.Manager()`.
+   :func:`multiprocessing.Manager`.
 
    It also supports creation of shared lists and dictionaries.
 
@@ -1231,7 +1176,7 @@
 
    .. method:: Queue([maxsize])
 
-      Create a shared `Queue.Queue` object and return a proxy for it.
+      Create a shared :class:`Queue.Queue` object and return a proxy for it.
 
    .. method:: RLock()
 
@@ -1244,7 +1189,7 @@
 
    .. method:: Array(typecode, sequence)
 
-      Create an array and return a proxy for it.  (*format* is ignored.)
+      Create an array and return a proxy for it.
 
    .. method:: Value(typecode, value)
 
@@ -1285,8 +1230,8 @@
 >>>>>>>>>>>>>>>>>>>
 
 To create one's own manager, one creates a subclass of :class:`BaseManager` and
-use the :meth:`resgister()` classmethod to register new types or callables with
-the manager class.  For example::
+use the :meth:`~BaseManager.resgister` classmethod to register new types or
+callables with the manager class.  For example::
 
    from multiprocessing.managers import BaseManager
 
@@ -1385,7 +1330,7 @@
 
    >>> a = manager.list()
    >>> b = manager.list()
-   >>> a.append(b)         # referent of `a` now contains referent of `b`
+   >>> a.append(b)         # referent of a now contains referent of b
    >>> print a, b
    [[]] []
    >>> b.append('hello')
@@ -1432,7 +1377,7 @@
       Note in particular that an exception will be raised if *methodname* has
       not been *exposed*
 
-      An example of the usage of :meth:`_call_method()`::
+      An example of the usage of :meth:`_call_method`::
 
          >>> l = manager.list(range(10))
          >>> l._call_method('__len__')
@@ -1476,7 +1421,7 @@
    :synopsis: Create pools of processes.
 
 One can create a pool of processes which will carry out tasks submitted to it
-with the :class:`Pool` class in :mod:`multiprocess.pool`.
+with the :class:`Pool` class.
 
 .. class:: multiprocessing.Pool([processes[, initializer[, initargs]]])
 
@@ -1514,7 +1459,7 @@
 
    .. method:: map_async(func, iterable[, chunksize[, callback]])
 
-      A variant of the :meth:`.map` method which returns a result object.
+      A variant of the :meth:`map` method which returns a result object.
 
       If *callback* is specified then it should be a callable which accepts a
       single argument.  When the result becomes ready *callback* is applied to
@@ -1622,7 +1567,7 @@
 However, the :mod:`multiprocessing.connection` module allows some extra
 flexibility.  It basically gives a high level message oriented API for dealing
 with sockets or Windows named pipes, and also has support for *digest
-authentication* using the :mod:`hmac` module from the standard library.
+authentication* using the :mod:`hmac` module.
 
 
 .. function:: deliver_challenge(connection, authkey)
@@ -1645,7 +1590,7 @@
 .. function:: Client(address[, family[, authenticate[, authkey]]])
 
    Attempt to set up a connection to the listener which is using address
-   *address*, returning a :class:`Connection`.
+   *address*, returning a :class:`~multiprocessing.Connection`.
 
    The type of the connection is determined by *family* argument, but this can
    generally be omitted since it can usually be inferred from the format of
@@ -1721,15 +1666,6 @@
 
    Exception raised when there is an authentication error.
 
-.. exception:: BufferTooShort
-
-   Exception raise by the :meth:`Connection.recv_bytes_into` method of a
-   connection object when the supplied buffer object is too small for the
-   message read.
-
-   If *e* is an instance of :exc:`BufferTooShort` then ``e.args[0]`` will give
-   the message as a byte string.
-
 
 **Examples**
 
@@ -1780,10 +1716,10 @@
 Address Formats
 >>>>>>>>>>>>>>>
 
-* An ``'AF_INET'`` address is a tuple of the form ``(hostname, port)``` where
+* An ``'AF_INET'`` address is a tuple of the form ``(hostname, port)`` where
   *hostname* is a string and *port* is an integer.
 
-* An ``'AF_UNIX'``` address is a string representing a filename on the
+* An ``'AF_UNIX'`` address is a string representing a filename on the
   filesystem.
 
 * An ``'AF_PIPE'`` address is a string of the form
@@ -1812,11 +1748,11 @@
 
 If authentication is requested but do authentication key is specified then the
 return value of ``current_process().get_auth_key`` is used (see
-:class:`Process`).  This value will automatically inherited by any
-:class:`Process` object that the current process creates.  This means that (by
-default) all processes of a multi-process program will share a single
-authentication key which can be used when setting up connections between the
-themselves.
+:class:`~multiprocessing.Process`).  This value will automatically inherited by
+any :class:`~multiprocessing.Process` object that the current process creates.
+This means that (by default) all processes of a multi-process program will share
+a single authentication key which can be used when setting up connections
+between the themselves.
 
 Suitable authentication keys can also be generated by using :func:`os.urandom`.
 
@@ -1866,7 +1802,7 @@
    :synopsis: Dumb wrapper around threading.
 
 :mod:`multiprocessing.dummy` replicates the API of :mod:`multiprocessing` but is
-no more than a wrapper around the `threading` module.
+no more than a wrapper around the :mod:`threading` module.
 
 
 .. _multiprocessing-programming:
@@ -1912,7 +1848,7 @@
 
 Better to inherit than pickle/unpickle
 
-    On Windows many of types from :mod:`multiprocessing` need to be picklable so
+    On Windows many types from :mod:`multiprocessing` need to be picklable so
     that child processes can use them.  However, one should generally avoid
     sending shared objects to other processes using pipes or queues.  Instead
     you should arrange the program so that a process which need access to a
@@ -1926,8 +1862,7 @@
     processes.
 
     Therefore it is probably best to only consider using
-    :meth:`Process.terminate()` on processes which never use any shared
-    resources.
+    :meth:`Process.terminate` on processes which never use any shared resources.
 
 Joining processes that use queues
 
@@ -1959,7 +1894,7 @@
     A fix here would be to swap the last two lines round (or simply remove the
     ``p.join()`` line).
 
-Explicity pass resources to child processes
+Explicitly pass resources to child processes
 
     On Unix a child process can make use of a shared resource created in a
     parent process using a global resource.  However, it is better to pass the
@@ -2050,7 +1985,7 @@
            p = Process(target=foo)
            p.start()
 
-    (The :func:`freeze_support()` line can be omitted if the program will be run
+    (The ``freeze_support()`` line can be omitted if the program will be run
     normally instead of frozen.)
 
     This allows the newly spawned Python interpreter to safely import the module

From python-3000-checkins at python.org  Sat Jun 28 03:42:42 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Sat, 28 Jun 2008 03:42:42 +0200 (CEST)
Subject: [Python-3000-checkins] r64571 -
	python/branches/py3k/Doc/library/multiprocessing.rst
Message-ID: <20080628014242.280791E4003@bag.python.org>

Author: benjamin.peterson
Date: Sat Jun 28 03:42:41 2008
New Revision: 64571

Log:
change references to Queue module to queue in multiprocessing docs

Modified:
   python/branches/py3k/Doc/library/multiprocessing.rst

Modified: python/branches/py3k/Doc/library/multiprocessing.rst
==============================================================================
--- python/branches/py3k/Doc/library/multiprocessing.rst	(original)
+++ python/branches/py3k/Doc/library/multiprocessing.rst	Sat Jun 28 03:42:41 2008
@@ -50,7 +50,7 @@
 
 **Queues**
 
-   The :class:`Queue` class is a near clone of :class:`Queue.Queue`.  For
+   The :class:`Queue` class is a near clone of :class:`queue.Queue`.  For
    example::
 
       from multiprocessing import Process, Queue
@@ -414,10 +414,10 @@
 processes) or a queue (which allows multiple producers and consumers).
 
 The :class:`Queue` and :class:`JoinableQueue` types are multi-producer,
-multi-consumer FIFO queues modelled on the :class:`Queue.Queue` class in the
+multi-consumer FIFO queues modelled on the :class:`queue.Queue` class in the
 standard library.  They differ in that :class:`Queue` lacks the
-:meth:`~Queue.Queue.task_done` and :meth:`~Queue.Queue.join` methods introduced
-into Python 2.5's :class:`Queue.Queue` class.
+:meth:`~queue.Queue.task_done` and :meth:`~queue.Queue.join` methods introduced
+into Python 2.5's :class:`queue.Queue` class.
 
 If you use :class:`JoinableQueue` then you **must** call
 :meth:`JoinableQueue.task_done` for each task removed from the queue or else the
@@ -429,10 +429,10 @@
 
 .. note::
 
-   :mod:`multiprocessing` uses the usual :exc:`Queue.Empty` and
-   :exc:`Queue.Full` exceptions to signal a timeout.  They are not available in
+   :mod:`multiprocessing` uses the usual :exc:`queue.Empty` and
+   :exc:`queue.Full` exceptions to signal a timeout.  They are not available in
    the :mod:`multiprocessing` namespace so you need to import them from
-   :mod:`Queue`.
+   :mod:`queue`.
 
 
 .. warning::
@@ -477,11 +477,11 @@
    locks/semaphores.  When a process first puts an item on the queue a feeder
    thread is started which transfers objects from a buffer into the pipe.
 
-   The usual :exc:`Queue.Empty` and :exc:`Queue.Full` exceptions from the
+   The usual :exc:`queue.Empty` and :exc:`queue.Full` exceptions from the
    standard library's :mod:`Queue` module are raised to signal timeouts.
 
-   :class:`Queue` implements all the methods of :class:`Queue.Queue` except for
-   :meth:`~Queue.Queue.task_done` and :meth:`~Queue.Queue.join`.
+   :class:`Queue` implements all the methods of :class:`queue.Queue` except for
+   :meth:`~queue.Queue.task_done` and :meth:`~queue.Queue.join`.
 
    .. method:: qsize()
 
@@ -506,10 +506,10 @@
       Put item into the queue.  If the optional argument *block* is ``True`` 
       (the default) and *timeout* is ``None`` (the default), block if necessary until
       a free slot is available.  If *timeout* is a positive number, it blocks at
-      most *timeout* seconds and raises the :exc:`Queue.Full` exception if no
+      most *timeout* seconds and raises the :exc:`queue.Full` exception if no
       free slot was available within that time.  Otherwise (*block* is
       ``False``), put an item on the queue if a free slot is immediately
-      available, else raise the :exc:`Queue.Full` exception (*timeout* is
+      available, else raise the :exc:`queue.Full` exception (*timeout* is
       ignored in that case).
 
    .. method:: put_nowait(item)
@@ -521,10 +521,10 @@
       Remove and return an item from the queue.  If optional args *block* is
       ``True`` (the default) and *timeout* is ``None`` (the default), block if
       necessary until an item is available.  If *timeout* is a positive number,
-      it blocks at most *timeout* seconds and raises the :exc:`Queue.Empty`
+      it blocks at most *timeout* seconds and raises the :exc:`queue.Empty`
       exception if no item was available within that time.  Otherwise (block is
       ``False``), return an item if one is immediately available, else raise the
-      :exc:`Queue.Empty` exception (*timeout* is ignored in that case).
+      :exc:`queue.Empty` exception (*timeout* is ignored in that case).
 
    .. method:: get_nowait()
                get_no_wait()
@@ -532,7 +532,7 @@
       Equivalent to ``get(False)``.
 
    :class:`multiprocessing.Queue` has a few additional methods not found in
-   :class:`Queue.Queue` which are usually unnecessary:
+   :class:`queue.Queue` which are usually unnecessary:
 
    .. method:: close()
 
@@ -1176,7 +1176,7 @@
 
    .. method:: Queue([maxsize])
 
-      Create a shared :class:`Queue.Queue` object and return a proxy for it.
+      Create a shared :class:`queue.Queue` object and return a proxy for it.
 
    .. method:: RLock()
 
@@ -1264,8 +1264,8 @@
 remote clients can access::
 
    >>> from multiprocessing.managers import BaseManager
-   >>> import Queue
-   >>> queue = Queue.Queue()
+   >>> import queue
+   >>> queue = queue.Queue()
    >>> class QueueManager(BaseManager): pass
    ...
    >>> QueueManager.register('getQueue', callable=lambda:queue)

From python-3000-checkins at python.org  Sat Jun 28 16:10:43 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Sat, 28 Jun 2008 16:10:43 +0200 (CEST)
Subject: [Python-3000-checkins] r64573 - python/branches/py3k/Mac/Makefile.in
Message-ID: <20080628141043.2B9B01E4003@bag.python.org>

Author: benjamin.peterson
Date: Sat Jun 28 16:10:42 2008
New Revision: 64573

Log:
remove usage of cachesrc.py in Mac/Makefile

Modified:
   python/branches/py3k/Mac/Makefile.in

Modified: python/branches/py3k/Mac/Makefile.in
==============================================================================
--- python/branches/py3k/Mac/Makefile.in	(original)
+++ python/branches/py3k/Mac/Makefile.in	Sat Jun 28 16:10:42 2008
@@ -43,7 +43,6 @@
 	Resources/English.lproj/Documentation/ide
 DOCDIR=$(srcdir)/Resources/app/Resources/English.lproj/Documentation
 DOCINDEX=$(DOCDIR)/"Documentation idx"
-CACHERSRC=$(srcdir)/scripts/cachersrc.py
 compileall=$(srcdir)/../Lib/compileall.py
 
 installapps: install_Python install_BuildApplet install_PythonLauncher \
@@ -225,7 +224,6 @@
 	done
 
 
-	$(RUNSHARED) $(BUILDPYTHON) $(CACHERSRC) -v $(DESTDIR)$(MACLIBDEST) $(DESTDIR)$(MACTOOLSDEST)
 	$(RUNSHARED) $(BUILDPYTHON) -Wi $(compileall) -d $(MACTOOLSDEST) -x badsyntax $(DESTDIR)$(MACTOOLSDEST)
 	$(RUNSHARED) $(BUILDPYTHON) -O -Wi $(compileall) -d $(MACTOOLSDEST) -x badsyntax $(DESTDIR)$(MACTOOLSDEST)
 

From python-3000-checkins at python.org  Sat Jun 28 20:23:49 2008
From: python-3000-checkins at python.org (matthias.klose)
Date: Sat, 28 Jun 2008 20:23:49 +0200 (CEST)
Subject: [Python-3000-checkins] r64576 - python/branches/py3k/setup.py
Message-ID: <20080628182349.DC17F1E4003@bag.python.org>

Author: matthias.klose
Date: Sat Jun 28 20:23:49 2008
New Revision: 64576

Log:
- allow to configure with db4.7, test with 4.7 on some buildds
  needs to be reviewed before release.


Modified:
   python/branches/py3k/setup.py

Modified: python/branches/py3k/setup.py
==============================================================================
--- python/branches/py3k/setup.py	(original)
+++ python/branches/py3k/setup.py	Sat Jun 28 20:23:49 2008
@@ -656,6 +656,7 @@
                              # have issues on many platforms.  I've temporarily
                              # disabled 4.6 to see what the odd platform
                              # buildbots say.
+        max_db_ver = (4, 7)  # XXX(matthias.klose): test with 4.7 on some buildds
         min_db_ver = (3, 3)
         db_setup_debug = False   # verbose debug prints from this script?
 

From python-3000-checkins at python.org  Sun Jun 29 01:05:03 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Sun, 29 Jun 2008 01:05:03 +0200 (CEST)
Subject: [Python-3000-checkins] r64581 -
	python/branches/py3k/Doc/reference/compound_stmts.rst
Message-ID: <20080628230503.DE5D21E4003@bag.python.org>

Author: benjamin.peterson
Date: Sun Jun 29 01:05:03 2008
New Revision: 64581

Log:
#3229 fix typo and expand notes a little

Modified:
   python/branches/py3k/Doc/reference/compound_stmts.rst

Modified: python/branches/py3k/Doc/reference/compound_stmts.rst
==============================================================================
--- python/branches/py3k/Doc/reference/compound_stmts.rst	(original)
+++ python/branches/py3k/Doc/reference/compound_stmts.rst	Sun Jun 29 01:05:03 2008
@@ -569,12 +569,13 @@
    Foo = f1(arg)(f2(Foo))
 
 **Programmer's note:** Variables defined in the class definition are class
-can be set in a method with ``self.name = value``.  Both class and instance
-variables are accessible through the notation "``self.name``", and an instance
-variable hides a class variable with the same name when accessed in this way.
-Class variables can be used as defaults for instance variables, but using
-mutable values there can lead to unexpected results.  Descriptors can be used
-to create instance variables with different implementation details.
+variables; they are shared by instances. Instance variables can be set in a
+method with ``self.name = value``.  Both class and instance variables are
+accessible through the notation "``self.name``", and an instance variable hides
+a class variable with the same name when accessed in this way.  Class variables
+can be used as defaults for instance variables, but using mutable values there
+can lead to unexpected results.  Descriptors can be used to create instance
+variables with different implementation details.
 
 .. XXX add link to descriptor docs above
 

From python-3000-checkins at python.org  Sun Jun 29 01:34:01 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Sun, 29 Jun 2008 01:34:01 +0200 (CEST)
Subject: [Python-3000-checkins] r64584 -
	python/branches/py3k/Lib/test/test_binop.py
Message-ID: <20080628233401.1A01E1E4004@bag.python.org>

Author: benjamin.peterson
Date: Sun Jun 29 01:34:00 2008
New Revision: 64584

Log:
division is no longer a future thing for test_binop

Modified:
   python/branches/py3k/Lib/test/test_binop.py

Modified: python/branches/py3k/Lib/test/test_binop.py
==============================================================================
--- python/branches/py3k/Lib/test/test_binop.py	(original)
+++ python/branches/py3k/Lib/test/test_binop.py	Sun Jun 29 01:34:00 2008
@@ -301,21 +301,16 @@
         self.assertEqual(Rat(10), 10.0)
         self.assertEqual(10.0, Rat(10))
 
-    def test_future_div(self):
-        exec(future_test)
+    def test_true_div(self):
+        self.assertEqual(Rat(10, 3) / Rat(5, 7), Rat(14, 3))
+        self.assertEqual(Rat(10, 3) / 3, Rat(10, 9))
+        self.assertEqual(2 / Rat(5), Rat(2, 5))
+        self.assertEqual(3.0 * Rat(1, 2), 1.5)
+        self.assertEqual(Rat(1, 2) * 3.0, 1.5)
+        self.assertEqual(eval('1/2'), 0.5)
 
     # XXX Ran out of steam; TO DO: divmod, div, future division
 
-future_test = """
-from __future__ import division
-self.assertEqual(Rat(10, 3) / Rat(5, 7), Rat(14, 3))
-self.assertEqual(Rat(10, 3) / 3, Rat(10, 9))
-self.assertEqual(2 / Rat(5), Rat(2, 5))
-self.assertEqual(3.0 * Rat(1, 2), 1.5)
-self.assertEqual(Rat(1, 2) * 3.0, 1.5)
-self.assertEqual(eval('1/2'), 0.5)
-"""
-
 def test_main():
     support.run_unittest(RatTestCase)
 

From python-3000-checkins at python.org  Sun Jun 29 01:58:48 2008
From: python-3000-checkins at python.org (robert.schuppenies)
Date: Sun, 29 Jun 2008 01:58:48 +0200 (CEST)
Subject: [Python-3000-checkins] r64586 - in python/branches/py3k:
	Lib/test/test_sys.py Objects/dictobject.c
Message-ID: <20080628235848.5E6A41E4004@bag.python.org>

Author: robert.schuppenies
Date: Sun Jun 29 01:58:47 2008
New Revision: 64586

Log:
Merged revisions 64518,64521-64525,64528-64533 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/trunk

........
  r64518 | robert.schuppenies | 2008-06-25 11:20:03 +0200 (Wed, 25 Jun 2008) | 2 lines
  
  Issue 3147: Fixed SizeofTest failure for LLP64 systems.
........
  r64533 | robert.schuppenies | 2008-06-26 17:20:35 +0200 (Thu, 26 Jun 2008) | 3 lines
  
  Corrected inconsistencies in sizeof tests and addressed issue pointed
  out by Jean Brouwers.
........


Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Lib/test/test_sys.py
   python/branches/py3k/Objects/dictobject.c

Modified: python/branches/py3k/Lib/test/test_sys.py
==============================================================================
--- python/branches/py3k/Lib/test/test_sys.py	(original)
+++ python/branches/py3k/Lib/test/test_sys.py	Sun Jun 29 01:58:47 2008
@@ -1,6 +1,7 @@
 # -*- coding: iso-8859-1 -*-
 import unittest, test.support
 import sys, io, os
+import struct
 
 class SysModuleTest(unittest.TestCase):
 
@@ -373,13 +374,16 @@
 class SizeofTest(unittest.TestCase):
 
     def setUp(self):
-        import struct
+        self.c = len(struct.pack('c', ' '))
+        self.H = len(struct.pack('H', 0))
         self.i = len(struct.pack('i', 0))
         self.l = len(struct.pack('l', 0))
-        self.p = len(struct.pack('P', 0))
-        self.headersize = self.l + self.p
+        self.P = len(struct.pack('P', 0))
+        # due to missing size_t information from struct, it is assumed that
+        # sizeof(Py_ssize_t) = sizeof(void*)
+        self.header = 'PP'
         if hasattr(sys, "gettotalrefcount"):
-            self.headersize += 2 * self.p
+            self.header += '2P'
         self.file = open(test.support.TESTFN, 'wb')
 
     def tearDown(self):
@@ -395,52 +399,38 @@
         else:
             self.assertEqual(result, size, msg + str(size))
 
-    def align(self, value):
-        mod = value % self.p
-        if mod != 0:
-            return value - mod + self.p
-        else:
-            return value
-
-    def test_align(self):
-        self.assertEqual(self.align(0) % self.p, 0)
-        self.assertEqual(self.align(1) % self.p, 0)
-        self.assertEqual(self.align(3) % self.p, 0)
-        self.assertEqual(self.align(4) % self.p, 0)
-        self.assertEqual(self.align(7) % self.p, 0)
-        self.assertEqual(self.align(8) % self.p, 0)
-        self.assertEqual(self.align(9) % self.p, 0)
+    def calcsize(self, fmt):
+        """Wrapper around struct.calcsize which enforces the alignment of the
+        end of a structure to the alignment requirement of pointer.
+
+        Note: This wrapper should only be used if a pointer member is included
+        and no member with a size larger than a pointer exists.
+        """
+        return struct.calcsize(fmt + '0P')
 
     def test_standardtypes(self):
-        i = self.i
-        l = self.l
-        p = self.p
-        h = self.headersize
-        # bool
-        self.check_sizeof(True, h + 2*l)
-        # bytearray
-        self.check_sizeof(bytes(), h + self.align(i) + l + p)
+        h = self.header
+        size = self.calcsize
         # cell
         def get_cell():
             x = 42
             def inner():
                 return x
             return inner
-        self.check_sizeof(get_cell().__closure__[0], h + p)
+        self.check_sizeof(get_cell().__closure__[0], size(h + 'P'))
         # code
-        self.check_sizeof(get_cell().__code__, h + self.align(5*i) + 8*p +\
-                           self.align(i) + 2*p)
+        self.check_sizeof(get_cell().__code__, size(h + '5i8Pi2P'))
         # complex
-        self.check_sizeof(complex(0,1), h + 2*8)
+        self.check_sizeof(complex(0,1), size(h + '2d'))
         # enumerate
-        self.check_sizeof(enumerate([]), h + l + 3*p)
+        self.check_sizeof(enumerate([]), size(h + 'l3P'))
         # reverse
-        self.check_sizeof(reversed(''), h + l + p )
+        self.check_sizeof(reversed(''), size(h + 'PP'))
         # float
-        self.check_sizeof(float(0), h + 8)
+        self.check_sizeof(float(0), size(h + 'd'))
         # function
         def func(): pass
-        self.check_sizeof(func, h + 11 * p)
+        self.check_sizeof(func, size(h + '11P'))
         class c():
             @staticmethod
             def foo():
@@ -449,58 +439,47 @@
             def bar(cls):
                 pass
             # staticmethod
-            self.check_sizeof(foo, h + l)
+            self.check_sizeof(foo, size(h + 'P'))
             # classmethod
-            self.check_sizeof(bar, h + l)
+            self.check_sizeof(bar, size(h + 'P'))
         # generator
         def get_gen(): yield 1
-        self.check_sizeof(get_gen(), h + p + self.align(i) + 2*p)
+        self.check_sizeof(get_gen(), size(h + 'Pi2P'))
         # builtin_function_or_method
-        self.check_sizeof(abs, h + 3*p)
+        self.check_sizeof(abs, size(h + '3P'))
         # module
-        self.check_sizeof(unittest, h + 3*p)
+        self.check_sizeof(unittest, size(h + '3P'))
         # range
-        self.check_sizeof(range(1), h + 3*p)
+        self.check_sizeof(range(1), size(h + '3P'))
         # slice
-        self.check_sizeof(slice(0), h + 3*p)
+        self.check_sizeof(slice(0), size(h + '3P'))
 
-        h += l
+        h += 'P'
+        # bool
+        self.check_sizeof(True, size(h + 'H'))
         # new-style class
         class class_newstyle(object):
             def method():
                 pass
         # type (PyTypeObject + PyNumberMethods + PyMappingMethods +
         #       PySequenceMethods + PyBufferProcs)
-        self.check_sizeof(class_newstyle, h +
-                          # PyTypeObject
-                          p + 2*l + 15*p + l + 4*p + l + 9*p + l + 11*p +
-                          self.align(4) +
-                          # PyNumberMethods
-                          16*p + self.align(i) + 17*p +
-                          3*p  + # PyMappingMethods
-                          10*p + # PySequenceMethods
-                          2*p  + # PyBufferProcs
-                          2*p)   # *ht_name and *ht_slots
+        self.check_sizeof(class_newstyle, size(h + 'P2P15Pl4PP9PP11PI') +\
+                                          size('16Pi17P 3P 10P 2P 2P'))
 
     def test_specialtypes(self):
-        i = self.i
-        l = self.l
-        p = self.p
-        h = self.headersize
+        h = self.header
+        size = self.calcsize
         # dict
-        self.check_sizeof({}, h + 3*l + 3*p + 8*(l + 2*p))
+        self.check_sizeof({}, size(h + '3P2P') + 8*size('P2P'))
         longdict = {1:1, 2:2, 3:3, 4:4, 5:5, 6:6, 7:7, 8:8}
-        self.check_sizeof(longdict, h + 3*l + 3*p + 8*(l + 2*p) + 16*(l + 2*p))
-        # list
-        self.check_sizeof([], h + l + p + l)
-        self.check_sizeof([1, 2, 3], h + l + p + l + 3*l)
+        self.check_sizeof(longdict, size(h + '3P2P') + (8+16)*size('P2P'))
         # unicode
         usize = len('\0'.encode('unicode-internal'))
         samples = ['', '1'*100]
         # we need to test for both sizes, because we don't know if the string
         # has been cached
         for s in samples:
-            basicsize =  h + l + p + l + l + p + usize * (len(s) + 1)
+            basicsize =  size(h + 'PPliP') + usize * (len(s) + 1)
             defenc = bytes(s, 'ascii')
             self.check_sizeof(s, basicsize,
                               size2=basicsize + sys.getsizeof(defenc))
@@ -512,17 +491,20 @@
             finally:
                 self.check_sizeof(s, basicsize + sys.getsizeof(defenc))
 
-        h += l
+        h += 'P'
+        # list
+        self.check_sizeof([], size(h + 'PP'))
+        self.check_sizeof([1, 2, 3], size(h + 'PP') + 3*self.P)
         # long
-        self.check_sizeof(0, h + self.align(2))
-        self.check_sizeof(1, h + self.align(2))
-        self.check_sizeof(-1, h + self.align(2))
-        self.check_sizeof(32768, h + self.align(2) + 2)
-        self.check_sizeof(32768*32768-1, h + self.align(2) + 2)
-        self.check_sizeof(32768*32768, h + self.align(2) + 4)
+        self.check_sizeof(0, size(h + 'H'))
+        self.check_sizeof(1, size(h + 'H'))
+        self.check_sizeof(-1, size(h + 'H'))
+        self.check_sizeof(32768, size(h + 'H') + self.H)
+        self.check_sizeof(32768*32768-1, size(h + 'H') + self.H)
+        self.check_sizeof(32768*32768, size(h + 'H') + 2*self.H)
         # tuple
-        self.check_sizeof((), h)
-        self.check_sizeof((1,2,3), h + 3*p)
+        self.check_sizeof((), size(h))
+        self.check_sizeof((1,2,3), size(h) + 3*self.P)
 
 
 def test_main():

Modified: python/branches/py3k/Objects/dictobject.c
==============================================================================
--- python/branches/py3k/Objects/dictobject.c	(original)
+++ python/branches/py3k/Objects/dictobject.c	Sun Jun 29 01:58:47 2008
@@ -1845,7 +1845,7 @@
 {
 	Py_ssize_t res;
 
-	res = sizeof(PyDictObject) + sizeof(mp->ma_table);
+	res = sizeof(PyDictObject);
 	if (mp->ma_table != mp->ma_smalltable)
 		res = res + (mp->ma_mask + 1) * sizeof(PyDictEntry);
 	return PyLong_FromSsize_t(res);

From python-3000-checkins at python.org  Sun Jun 29 02:05:51 2008
From: python-3000-checkins at python.org (bill.janssen)
Date: Sun, 29 Jun 2008 02:05:51 +0200 (CEST)
Subject: [Python-3000-checkins] r64587 - in python/branches/py3k:
	Doc/library/ssl.rst Lib/ssl.py
Message-ID: <20080629000551.61A3D1E4004@bag.python.org>

Author: bill.janssen
Date: Sun Jun 29 02:05:51 2008
New Revision: 64587

Log:
fix bad method names in ssl module (and typo in ssl doc)

Modified:
   python/branches/py3k/Doc/library/ssl.rst
   python/branches/py3k/Lib/ssl.py

Modified: python/branches/py3k/Doc/library/ssl.rst
==============================================================================
--- python/branches/py3k/Doc/library/ssl.rst	(original)
+++ python/branches/py3k/Doc/library/ssl.rst	Sun Jun 29 02:05:51 2008
@@ -129,7 +129,7 @@
    method should signal unexpected EOF from the other end of the connection.  If specified
    as :const:`True` (the default), it returns a normal EOF in response to unexpected
    EOF errors raised from the underlying socket; if :const:`False`, it will raise
-   the exceptions back the caller.
+   the exceptions back to the caller.
 
 .. function:: RAND_status()
 

Modified: python/branches/py3k/Lib/ssl.py
==============================================================================
--- python/branches/py3k/Lib/ssl.py	(original)
+++ python/branches/py3k/Lib/ssl.py	Sun Jun 29 02:05:51 2008
@@ -215,13 +215,13 @@
         else:
             return socket.send(self, data, flags)
 
-    def send_to(self, data, addr, flags=0):
+    def sendto(self, data, addr, flags=0):
         self._checkClosed()
         if self._sslobj:
-            raise ValueError("send_to not allowed on instances of %s" %
+            raise ValueError("sendto not allowed on instances of %s" %
                              self.__class__)
         else:
-            return socket.send_to(self, data, addr, flags)
+            return socket.sendto(self, data, addr, flags)
 
     def sendall(self, data, flags=0):
         self._checkClosed()
@@ -276,13 +276,13 @@
         else:
             return socket.recv_into(self, buffer, nbytes, flags)
 
-    def recv_from(self, addr, buflen=1024, flags=0):
+    def recvfrom(self, addr, buflen=1024, flags=0):
         self._checkClosed()
         if self._sslobj:
-            raise ValueError("recv_from not allowed on instances of %s" %
+            raise ValueError("recvfrom not allowed on instances of %s" %
                              self.__class__)
         else:
-            return socket.recv_from(self, addr, buflen, flags)
+            return socket.recvfrom(self, addr, buflen, flags)
 
     def pending(self):
         self._checkClosed()

From python-3000-checkins at python.org  Sun Jun 29 02:08:13 2008
From: python-3000-checkins at python.org (bill.janssen)
Date: Sun, 29 Jun 2008 02:08:13 +0200 (CEST)
Subject: [Python-3000-checkins] r64588 -
	python/branches/py3k/Lib/test/test_ssl.py
Message-ID: <20080629000813.389921E401F@bag.python.org>

Author: bill.janssen
Date: Sun Jun 29 02:08:12 2008
New Revision: 64588

Log:
close asyncore.dispatcher on EOF

Modified:
   python/branches/py3k/Lib/test/test_ssl.py

Modified: python/branches/py3k/Lib/test/test_ssl.py
==============================================================================
--- python/branches/py3k/Lib/test/test_ssl.py	(original)
+++ python/branches/py3k/Lib/test/test_ssl.py	Sun Jun 29 02:08:12 2008
@@ -529,6 +529,7 @@
                         self.send(str(data, 'ASCII', 'strict').lower().encode('ASCII', 'strict'))
 
                 def handle_close(self):
+                    self.close()
                     if support.verbose:
                         sys.stdout.write(" server:  closed connection %s\n" % self.socket)
 

From python-3000-checkins at python.org  Mon Jun 30 06:06:08 2008
From: python-3000-checkins at python.org (martin.v.loewis)
Date: Mon, 30 Jun 2008 06:06:08 +0200 (CEST)
Subject: [Python-3000-checkins] r64596 - in python/branches/py3k:
	Lib/test/test_int.py Misc/NEWS Objects/longobject.c
Message-ID: <20080630040608.E09181E4007@bag.python.org>

Author: martin.v.loewis
Date: Mon Jun 30 06:06:08 2008
New Revision: 64596

Log:
Issue #3236: Return small longs from PyLong_FromString.


Modified:
   python/branches/py3k/Lib/test/test_int.py
   python/branches/py3k/Misc/NEWS
   python/branches/py3k/Objects/longobject.c

Modified: python/branches/py3k/Lib/test/test_int.py
==============================================================================
--- python/branches/py3k/Lib/test/test_int.py	(original)
+++ python/branches/py3k/Lib/test/test_int.py	Mon Jun 30 06:06:08 2008
@@ -95,6 +95,9 @@
         self.assertRaises(ValueError, int, "0b", 2)
         self.assertRaises(ValueError, int, "0b", 0)
 
+        # Bug #3236: Return small longs from PyLong_FromString
+        self.assert_(int("10") is 10)
+        self.assert_(int("-1") is -1)
 
         # SF bug 1334662: int(string, base) wrong answers
         # Various representations of 2**32 evaluated to 0

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Mon Jun 30 06:06:08 2008
@@ -12,6 +12,8 @@
 Core and Builtins
 -----------------
 
+- Issue #3236: Return small longs from PyLong_FromString.
+
 Library
 -------
 

Modified: python/branches/py3k/Objects/longobject.c
==============================================================================
--- python/branches/py3k/Objects/longobject.c	(original)
+++ python/branches/py3k/Objects/longobject.c	Mon Jun 30 06:06:08 2008
@@ -1981,6 +1981,14 @@
 		goto onError;
 	if (pend)
 		*pend = str;
+	long_normalize(z);
+	if (ABS(Py_SIZE(z)) <= 1) {
+		long res = MEDIUM_VALUE(z);
+		if (-NSMALLPOSINTS <= res && res <= NSMALLPOSINTS) {
+			Py_DECREF(z);
+			return PyLong_FromLong(res);
+		}
+	}
 	return (PyObject *) z;
 
  onError:

From python-3000-checkins at python.org  Mon Jun 30 09:03:57 2008
From: python-3000-checkins at python.org (martin.v.loewis)
Date: Mon, 30 Jun 2008 09:03:57 +0200 (CEST)
Subject: [Python-3000-checkins] r64599 - in python/branches/py3k:
	PCbuild/sqlite3.vcproj Tools/msi/msi.py
Message-ID: <20080630070357.6365D1E4007@bag.python.org>

Author: martin.v.loewis
Date: Mon Jun 30 09:03:57 2008
New Revision: 64599

Log:
Merged revisions 64597-64598 via svnmerge from 
svn+ssh://pythondev at svn.python.org/python/trunk

........
  r64597 | martin.v.loewis | 2008-06-30 08:57:39 +0200 (Mo, 30 Jun 2008) | 1 line
  
  Issue #3215: Build sqlite3 as sqlite3.dll, not sqlite3.pyd
........
  r64598 | martin.v.loewis | 2008-06-30 09:01:09 +0200 (Mo, 30 Jun 2008) | 1 line
  
  Add _multiprocessing module.
........


Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/PCbuild/sqlite3.vcproj
   python/branches/py3k/Tools/msi/msi.py

Modified: python/branches/py3k/PCbuild/sqlite3.vcproj
==============================================================================
--- python/branches/py3k/PCbuild/sqlite3.vcproj	(original)
+++ python/branches/py3k/PCbuild/sqlite3.vcproj	Mon Jun 30 09:03:57 2008
@@ -305,6 +305,7 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\$(ProjectName).dll"
 			/>
 			<Tool
 				Name="VCALinkTool"
@@ -428,6 +429,7 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\$(ProjectName).dll"
 			/>
 			<Tool
 				Name="VCALinkTool"

Modified: python/branches/py3k/Tools/msi/msi.py
==============================================================================
--- python/branches/py3k/Tools/msi/msi.py	(original)
+++ python/branches/py3k/Tools/msi/msi.py	Mon Jun 30 09:03:57 2008
@@ -92,7 +92,8 @@
     '_ctypes.pyd',
     '_ctypes_test.pyd',
     '_sqlite3.pyd',
-    '_hashlib.pyd'
+    '_hashlib.pyd',
+    '_multiprocessing.pyd'
 ]
 
 # Well-known component UUIDs

From python-3000-checkins at python.org  Mon Jun 30 17:01:21 2008
From: python-3000-checkins at python.org (benjamin.peterson)
Date: Mon, 30 Jun 2008 17:01:21 +0200 (CEST)
Subject: [Python-3000-checkins] r64600 -
	python/branches/py3k/Lib/test/test_compile.py
Message-ID: <20080630150121.B8E991E402D@bag.python.org>

Author: benjamin.peterson
Date: Mon Jun 30 17:01:21 2008
New Revision: 64600

Log:
now that exec is a function, we can use the shorter assertRaises to test

Modified:
   python/branches/py3k/Lib/test/test_compile.py

Modified: python/branches/py3k/Lib/test/test_compile.py
==============================================================================
--- python/branches/py3k/Lib/test/test_compile.py	(original)
+++ python/branches/py3k/Lib/test/test_compile.py	Mon Jun 30 17:01:21 2008
@@ -18,21 +18,9 @@
         self.assertRaises(SyntaxError, eval, 'lambda a,a:0')
         self.assertRaises(SyntaxError, eval, 'lambda a,a=1:0')
         self.assertRaises(SyntaxError, eval, 'lambda a=1,a=1:0')
-        try:
-            exec('def f(a, a): pass')
-            self.fail("duplicate arguments")
-        except SyntaxError:
-            pass
-        try:
-            exec('def f(a = 0, a = 1): pass')
-            self.fail("duplicate keyword arguments")
-        except SyntaxError:
-            pass
-        try:
-            exec('def f(a): global a; a = 1')
-            self.fail("variable is global and local")
-        except SyntaxError:
-            pass
+        self.assertRaises(SyntaxError, exec, 'def f(a, a): pass')
+        self.assertRaises(SyntaxError, exec, 'def f(a = 0, a = 1): pass')
+        self.assertRaises(SyntaxError, exec, 'def f(a): global a; a = 1')
 
     def test_syntax_error(self):
         self.assertRaises(SyntaxError, compile, "1+*3", "filename", "exec")
@@ -41,11 +29,7 @@
         self.assertRaises(SyntaxError, compile, "f(None=1)", "<string>", "exec")
 
     def test_duplicate_global_local(self):
-        try:
-            exec('def f(a): global a; a = 1')
-            self.fail("variable is global and local")
-        except SyntaxError:
-            pass
+        self.assertRaises(SyntaxError, exec, 'def f(a): global a; a = 1')
 
     def test_exec_with_general_mapping_for_locals(self):
 
@@ -76,23 +60,13 @@
         self.assertEqual(m.results, ('z', g))
         exec('z = locals()', g, m)
         self.assertEqual(m.results, ('z', m))
-        try:
-            exec('z = b', m)
-        except TypeError:
-            pass
-        else:
-            self.fail('Did not validate globals as a real dict')
+        self.assertRaises(TypeError, exec, 'z = b', m)
 
         class A:
             "Non-mapping"
             pass
         m = A()
-        try:
-            exec('z = a', g, m)
-        except TypeError:
-            pass
-        else:
-            self.fail('Did not validate locals as a mapping')
+        self.assertRaises(TypeError, exec, 'z = a', g, m)
 
         # Verify that dict subclasses work as well
         class D(dict):
@@ -129,11 +103,7 @@
         self.assertEqual(g['f'](5), 0)
 
     def test_argument_order(self):
-        try:
-            exec('def f(a=1, b): pass')
-            self.fail("non-default args after default")
-        except SyntaxError:
-            pass
+        self.assertRaises(SyntaxError, exec, 'def f(a=1, b): pass')
 
     def test_float_literals(self):
         # testing bad float literals

From guido at python.org  Mon Jun 30 17:26:38 2008
From: guido at python.org (Guido van Rossum)
Date: Mon, 30 Jun 2008 08:26:38 -0700
Subject: [Python-3000-checkins] r64596 - in python/branches/py3k:
	Lib/test/test_int.py Misc/NEWS Objects/longobject.c
In-Reply-To: <20080630040608.E09181E4007@bag.python.org>
References: <20080630040608.E09181E4007@bag.python.org>
Message-ID: <ca471dc20806300826q9c31db7ic8b774812a6b7800@mail.gmail.com>

On Sun, Jun 29, 2008 at 9:06 PM, martin.v.loewis
<python-3000-checkins at python.org> wrote:
> Author: martin.v.loewis
> Date: Mon Jun 30 06:06:08 2008
> New Revision: 64596
>
> Log:
> Issue #3236: Return small longs from PyLong_FromString.
>
>
> Modified:
>   python/branches/py3k/Lib/test/test_int.py
>   python/branches/py3k/Misc/NEWS
>   python/branches/py3k/Objects/longobject.c
>
> Modified: python/branches/py3k/Lib/test/test_int.py
> ==============================================================================
> --- python/branches/py3k/Lib/test/test_int.py   (original)
> +++ python/branches/py3k/Lib/test/test_int.py   Mon Jun 30 06:06:08 2008
> @@ -95,6 +95,9 @@
>         self.assertRaises(ValueError, int, "0b", 2)
>         self.assertRaises(ValueError, int, "0b", 0)
>
> +        # Bug #3236: Return small longs from PyLong_FromString
> +        self.assert_(int("10") is 10)
> +        self.assert_(int("-1") is -1)

This is the kind of test that other implementations may not wish to
comply with. Do we have a mechanism yet for flagging tests as specific
to CPython?

>         # SF bug 1334662: int(string, base) wrong answers
>         # Various representations of 2**32 evaluated to 0
>
> Modified: python/branches/py3k/Misc/NEWS
> ==============================================================================
> --- python/branches/py3k/Misc/NEWS      (original)
> +++ python/branches/py3k/Misc/NEWS      Mon Jun 30 06:06:08 2008
> @@ -12,6 +12,8 @@
>  Core and Builtins
>  -----------------
>
> +- Issue #3236: Return small longs from PyLong_FromString.
> +
>  Library
>  -------
>
>
> Modified: python/branches/py3k/Objects/longobject.c
> ==============================================================================
> --- python/branches/py3k/Objects/longobject.c   (original)
> +++ python/branches/py3k/Objects/longobject.c   Mon Jun 30 06:06:08 2008
> @@ -1981,6 +1981,14 @@
>                goto onError;
>        if (pend)
>                *pend = str;
> +       long_normalize(z);
> +       if (ABS(Py_SIZE(z)) <= 1) {
> +               long res = MEDIUM_VALUE(z);
> +               if (-NSMALLPOSINTS <= res && res <= NSMALLPOSINTS) {
> +                       Py_DECREF(z);
> +                       return PyLong_FromLong(res);
> +               }
> +       }
>        return (PyObject *) z;
>
>  onError:
> _______________________________________________
> Python-3000-checkins mailing list
> Python-3000-checkins at python.org
> http://mail.python.org/mailman/listinfo/python-3000-checkins
>



-- 
--Guido van Rossum (home page: http://www.python.org/~guido/)

From musiccomposition at gmail.com  Mon Jun 30 17:30:32 2008
From: musiccomposition at gmail.com (Benjamin Peterson)
Date: Mon, 30 Jun 2008 10:30:32 -0500
Subject: [Python-3000-checkins] r64596 - in python/branches/py3k:
	Lib/test/test_int.py Misc/NEWS Objects/longobject.c
In-Reply-To: <ca471dc20806300826q9c31db7ic8b774812a6b7800@mail.gmail.com>
References: <20080630040608.E09181E4007@bag.python.org>
	<ca471dc20806300826q9c31db7ic8b774812a6b7800@mail.gmail.com>
Message-ID: <1afaf6160806300830k1412304dgea0bd3a74868a41f@mail.gmail.com>

On Mon, Jun 30, 2008 at 10:26 AM, Guido van Rossum <guido at python.org> wrote:
>>
>> +        # Bug #3236: Return small longs from PyLong_FromString
>> +        self.assert_(int("10") is 10)
>> +        self.assert_(int("-1") is -1)
>
> This is the kind of test that other implementations may not wish to
> comply with. Do we have a mechanism yet for flagging tests as specific
> to CPython?

When I merge my test branch, you can mark things with
@test_support.cpython_only.


-- 
Cheers,
Benjamin Peterson
"There's no place like 127.0.0.1."