merge 2.7.9 release branch
diff --git a/Doc/library/idle.rst b/Doc/library/idle.rst
index 36d78b0..e9a91ae 100644
--- a/Doc/library/idle.rst
+++ b/Doc/library/idle.rst
@@ -1,202 +1,293 @@
 .. _idle:
 
-IDLE
-====
-
-.. moduleauthor:: Guido van Rossum <guido@Python.org>
-
 .. index::
    single: IDLE
    single: Python Editor
    single: Integrated Development Environment
 
+IDLE
+====
+
+.. moduleauthor:: Guido van Rossum <guido@Python.org>
+
 IDLE is the Python IDE built with the :mod:`tkinter` GUI toolkit.
 
 IDLE has the following features:
 
 * coded in 100% pure Python, using the :mod:`tkinter` GUI toolkit
 
-* cross-platform: works on Windows and Unix
+* cross-platform: works on Windows, Unix, and Mac OS X
 
-* multi-window text editor with multiple undo, Python colorizing and many other
-  features, e.g. smart indent and call tips
+* multi-window text editor with multiple undo, Python colorizing,
+  smart indent, call tips, and many other features
 
 * Python shell window (a.k.a. interactive interpreter)
 
-* debugger (not complete, but you can set breakpoints, view  and step)
+* debugger (not complete, but you can set breakpoints, view and step)
 
 
 Menus
 -----
 
+IDLE has two main window types, the Shell window and the Editor window.  It is
+possible to have multiple editor windows simultaneously.  Output windows, such
+as used for Edit / Find in Files, are a subtype of edit window.  They currently
+have the same top menu as Editor windows but a different default title and
+context menu.
 
-File menu
-^^^^^^^^^
+IDLE's menus dynamically change based on which window is currently selected.
+Each menu documented below indicates which window type it is associated with.
+Click on the dotted line at the top of a menu to "tear it off": a separate
+window containing the menu is created (for Unix and Windows only).
 
-New file
-   create a new file editing window
+File menu (Shell and Editor)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+New File
+   Create a new file editing window.
 
 Open...
-   open an existing file
+   Open an existing file with an Open dialog.
 
-Open module...
-   open an existing module (searches sys.path)
+Recent Files
+   Open a list of recent files.  Click one to open it.
 
-Class browser
-   show classes and methods in current file
-
-Path browser
-   show sys.path directories, modules, classes and methods
+Open Module...
+   Open an existing module (searches sys.path).
 
 .. index::
    single: Class browser
    single: Path browser
 
+Class Browser
+   Show functions, classes, and methods in the current Editor file in a
+   tree structure.  In the shell, open a module first.
+
+Path Browser
+   Show sys.path directories, modules, functions, classes and methods in a
+   tree structure.
+
 Save
-   save current window to the associated file (unsaved windows have a \* before and
-   after the window title)
+   Save the current window to the associated file, if there is one.  Windows
+   that have been changed since being opened or last saved have a \* before
+   and after the window title.  If there is no associated file,
+   do Save As instead.
 
 Save As...
-   save current window to new file, which becomes the associated file
+   Save the current window with a Save As dialog.  The file saved becomes the
+   new associated file for the window.
 
 Save Copy As...
-   save current window to different file without changing the associated file
+   Save the current window to different file without changing the associated
+   file.
+
+Print Window
+   Print the current window to the default printer.
 
 Close
-   close current window (asks to save if unsaved)
+   Close the current window (ask to save if unsaved).
 
 Exit
-   close all windows and quit IDLE (asks to save if unsaved)
+   Close all windows and quit IDLE (ask to save unsaved windows).
 
-
-Edit menu
-^^^^^^^^^
+Edit menu (Shell and Editor)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 Undo
-   Undo last change to current window (max 1000 changes)
+   Undo the last change to the current window.  A maximum of 1000 changes may
+   be undone.
 
 Redo
-   Redo last undone change to current window
+   Redo the last undone change to the current window.
 
 Cut
-   Copy selection into system-wide clipboard; then delete selection
+   Copy selection into the system-wide clipboard; then delete the selection.
 
 Copy
-   Copy selection into system-wide clipboard
+   Copy selection into the system-wide clipboard.
 
 Paste
-   Insert system-wide clipboard into window
+   Insert contents of the system-wide clipboard into the current window.
+
+The clipboard functions are also available in context menus.
 
 Select All
-   Select the entire contents of the edit buffer
+   Select the entire contents of the current window.
 
 Find...
-   Open a search dialog box with many options
+   Open a search dialog with many options
 
-Find again
-   Repeat last search
+Find Again
+   Repeat the last search, if there is one.
 
-Find selection
-   Search for the string in the selection
+Find Selection
+   Search for the currently selected string, if there is one.
 
 Find in Files...
-   Open a search dialog box for searching files
+   Open a file search dialog.  Put results in an new output window.
 
 Replace...
-   Open a search-and-replace dialog box
+   Open a search-and-replace dialog.
 
-Go to line
-   Ask for a line number and show that line
+Go to Line
+   Move cursor to the line number requested and make that line visible.
 
-Indent region
-   Shift selected lines right 4 spaces
+Show Completions
+   Open a scrollable list allowing selection of keywords and attributes. See
+   Completions in the Tips sections below.
 
-Dedent region
-   Shift selected lines left 4 spaces
+Expand Word
+   Expand a prefix you have typed to match a full word in the same window;
+   repeat to get a different expansion.
 
-Comment out region
-   Insert ## in front of selected lines
+Show call tip
+   After an unclosed parenthesis for a function, open a small window with
+   function parameter hints.
 
-Uncomment region
-   Remove leading # or ## from selected lines
+Show surrounding parens
+   Highlight the surrounding parenthesis.
 
-Tabify region
-   Turns *leading* stretches of spaces into tabs
+Format menu (Editor window only)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-Untabify region
-   Turn *all* tabs into the right number of spaces
+Indent Region
+   Shift selected lines right by the indent width (default 4 spaces).
 
-Expand word
-   Expand the word you have typed to match another word in the same buffer; repeat
-   to get a different expansion
+Dedent Region
+   Shift selected lines left by the indent width (default 4 spaces).
+
+Comment Out Region
+   Insert ## in front of selected lines.
+
+Uncomment Region
+   Remove leading # or ## from selected lines.
+
+Tabify Region
+   Turn *leading* stretches of spaces into tabs. (Note: We recommend using
+   4 space blocks to indent Python code.)
+
+Untabify Region
+   Turn *all* tabs into the correct number of spaces.
+
+Toggle Tabs
+   Open a dialog to switch between indenting with spaces and tabs.
+
+New Indent Width
+   Open a dialog to change indent width. The accepted default by the Python
+   community is 4 spaces.
 
 Format Paragraph
-   Reformat the current blank-line-separated paragraph
+   Reformat the current blank-line-delimited paragraph in comment block or
+   multiline string or selected line in a string.  All lines in the
+   paragraph will be formatted to less than N columns, where N defaults to 72.
 
-Import module
-   Import or reload the current module
-
-Run script
-   Execute the current file in the __main__ namespace
+Strip trailing whitespace
+   Remove any space characters after the last non-space character of a line.
 
 .. index::
-   single: Import module
    single: Run script
 
+Run menu (Editor window only)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-Windows menu
-^^^^^^^^^^^^
+Python Shell
+   Open or wake up the Python Shell window.
+
+Check Module
+   Check the syntax of the module currently open in the Editor window. If the
+   module has not been saved IDLE will either prompt the user to save or
+   autosave, as selected in the General tab of the Idle Settings dialog.  If
+   there is a syntax error, the approximate location is indicated in the
+   Editor window.
+
+Run Module
+   Do Check Module (above).  If no error, restart the shell to clean the
+   environment, then execute the module.
+
+Shell menu (Shell window only)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+View Last Restart
+  Scroll the shell window to the last Shell restart.
+
+Restart Shell
+  Restart the shell to clean the environment.
+
+Debug menu (Shell window only)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Go to File/Line
+   Look on the current line. with the cursor, and the line above for a filename
+   and line number.  If found, open the file if not already open, and show the
+   line.  Use this to view source lines referenced in an exception traceback
+   and lines found by Find in Files. Also available in the context menu of
+   the Shell window and Output windows.
+
+.. index::
+   single: debugger
+   single: stack viewer
+
+Debugger (toggle)
+   When actived, code entered in the Shell or run from an Editor will run
+   under the debugger.  In the Editor, breakpoints can be set with the context
+   menu.  This feature is still incomplete and somewhat experimental.
+
+Stack Viewer
+   Show the stack traceback of the last exception in a tree widget, with
+   access to locals and globals.
+
+Auto-open Stack Viewer
+   Toggle automatically opening the stack viewer on an unhandled exception.
+
+Options menu (Shell and Editor)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Configure IDLE
+   Open a configuration dialog.  Fonts, indentation, keybindings, and color
+   themes may be altered.  Startup Preferences may be set, and additional
+   help sources can be specified.  Non-default user setting are saved in a
+   .idlerc directory in the user's home directory.  Problems caused by bad user
+   configuration files are solved by editing or deleting one or more of the
+   files in .idlerc.
+
+Configure Extensions
+   Open a configuration dialog for setting preferences for extensions
+   (discussed below).  See note above about the location of user settings.
+
+Code Context (toggle)(Editor Window only)
+   Open a pane at the top of the edit window which shows the block context
+   of the code which has scrolled above the top of the window.
+
+Windows menu (Shell and Editor)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 Zoom Height
-   toggles the window between normal size (24x80) and maximum height.
+   Toggles the window between normal size and maximum height. The initial size
+   defaults to 40 lines by 80 chars unless changed on the General tab of the
+   Configure IDLE dialog.
 
 The rest of this menu lists the names of all open windows; select one to bring
 it to the foreground (deiconifying it if necessary).
 
+Help menu (Shell and Editor)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-Debug menu
-^^^^^^^^^^
+About IDLE
+   Display version, copyright, license, credits, and more.
 
-* in the Python Shell window only
+IDLE Help
+   Display a help file for IDLE detailing the menu options, basic editing and
+   navigation, and other tips.
 
-Go to file/line
-   Look around the insert point for a filename and line number, open the file,
-   and show the line.  Useful to view the source lines referenced in an
-   exception traceback.
+Python Docs
+   Access local Python documentation, if installed, or start a web browser
+   and open docs.python.org showing the latest Python documentation.
 
-Debugger
-   Run commands in the shell under the debugger.
+Turtle Demo
+   Run the turtledemo module with example python code and turtle drawings.
 
-Stack viewer
-   Show the stack traceback of the last exception.
-
-Auto-open Stack Viewer
-   Open stack viewer on traceback.
-
-.. index::
-   single: stack viewer
-   single: debugger
-
-
-Edit context menu
-^^^^^^^^^^^^^^^^^
-
-* Right-click in Edit window (Control-click on OS X)
-
-Cut
-   Copy selection into system-wide clipboard; then delete selection
-
-Copy
-   Copy selection into system-wide clipboard
-
-Paste
-   Insert system-wide clipboard into window
-
-Set Breakpoint
-   Sets a breakpoint.  Breakpoints are only enabled when the debugger is open.
-
-Clear Breakpoint
-   Clears the breakpoint on that line.
+Additional help sources may be added here with the Configure IDLE dialog under
+the General tab.
 
 .. index::
    single: Cut
@@ -206,38 +297,78 @@
    single: Clear Breakpoint
    single: breakpoints
 
+Context Menus
+^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-Shell context menu
-^^^^^^^^^^^^^^^^^^
-
-* Right-click in Python Shell window (Control-click on OS X)
+Open a context menu by right-clicking in a window (Control-click on OS X).
+Context menus have the standard clipboard functions also on the Edit menu.
 
 Cut
-   Copy selection into system-wide clipboard; then delete selection
+   Copy selection into the system-wide clipboard; then delete the selection.
 
 Copy
-   Copy selection into system-wide clipboard
+   Copy selection into the system-wide clipboard.
 
 Paste
-   Insert system-wide clipboard into window
+   Insert contents of the system-wide clipboard into the current window.
+
+Editor windows also have breakpoint functions.  Lines with a breakpoint set are
+specially marked.  Breakpoints only have an effect when running under the
+debugger.  Breakpoints for a file are saved in the user's .idlerc directory.
+
+Set Breakpoint
+   Set a breakpoint on the current line.
+
+Clear Breakpoint
+   Clear the breakpoint on that line.
+
+Shell and Output windows have the following.
 
 Go to file/line
    Same as in Debug menu.
 
 
-Basic editing and navigation
-----------------------------
+Editing and navigation
+----------------------
+
+In this section, 'C' refers to the Control key on Windows and Unix and
+the Command key on Mac OSX.
 
 * :kbd:`Backspace` deletes to the left; :kbd:`Del` deletes to the right
 
+* :kbd:`C-Backspace` delete word left; :kbd:`C-Del` delete word to the right
+
 * Arrow keys and :kbd:`Page Up`/:kbd:`Page Down` to move around
 
+* :kbd:`C-LeftArrow` and :kbd:`C-RightArrow` moves by words
+
 * :kbd:`Home`/:kbd:`End` go to begin/end of line
 
 * :kbd:`C-Home`/:kbd:`C-End` go to begin/end of file
 
-* Some :program:`Emacs` bindings may also work, including :kbd:`C-B`,
-  :kbd:`C-P`, :kbd:`C-A`, :kbd:`C-E`, :kbd:`C-D`, :kbd:`C-L`
+* Some useful Emacs bindings are inherited from Tcl/Tk:
+
+   * :kbd:`C-a` beginning of line
+
+   * :kbd:`C-e` end of line
+
+   * :kbd:`C-k` kill line (but doesn't put it in clipboard)
+
+   * :kbd:`C-l` center window around the insertion point
+
+   * :kbd:`C-b` go backwards one character without deleting (usually you can
+     also use the cursor key for this)
+
+   * :kbd:`C-f` go forward one character without deleting (usually you can
+     also use the cursor key for this)
+
+   * :kbd:`C-p` go up one line (usually you can also use the cursor key for
+     this)
+
+   * :kbd:`C-d` delete next character
+
+Standard keybindings (like :kbd:`C-c` to copy and :kbd:`C-v` to paste)
+may work.  Keybindings are selected in the Configure IDLE dialog.
 
 
 Automatic indentation
@@ -246,27 +377,75 @@
 After a block-opening statement, the next line is indented by 4 spaces (in the
 Python Shell window by one tab).  After certain keywords (break, return etc.)
 the next line is dedented.  In leading indentation, :kbd:`Backspace` deletes up
-to 4 spaces if they are there. :kbd:`Tab` inserts 1-4 spaces (in the Python
-Shell window one tab). See also the indent/dedent region commands in the edit
-menu.
+to 4 spaces if they are there. :kbd:`Tab` inserts spaces (in the Python
+Shell window one tab), number depends on Indent width. Currently tabs
+are restricted to four spaces due to Tcl/Tk limitations.
 
+See also the indent/dedent region commands in the edit menu.
+
+Completions
+^^^^^^^^^^^
+
+Completions are supplied for functions, classes, and attributes of classes,
+both built-in and user-defined. Completions are also provided for
+filenames.
+
+The AutoCompleteWindow (ACW) will open after a predefined delay (default is
+two seconds) after a '.' or (in a string) an os.sep is typed. If after one
+of those characters (plus zero or more other characters) a tab is typed
+the ACW will open immediately if a possible continuation is found.
+
+If there is only one possible completion for the characters entered, a
+:kbd:`Tab` will supply that completion without opening the ACW.
+
+'Show Completions' will force open a completions window, by default the
+:kbd:`C-space` will open a completions window. In an empty
+string, this will contain the files in the current directory. On a
+blank line, it will contain the built-in and user-defined functions and
+classes in the current name spaces, plus any modules imported. If some
+characters have been entered, the ACW will attempt to be more specific.
+
+If a string of characters is typed, the ACW selection will jump to the
+entry most closely matching those characters.  Entering a :kbd:`tab` will
+cause the longest non-ambiguous match to be entered in the Editor window or
+Shell.  Two :kbd:`tab` in a row will supply the current ACW selection, as
+will return or a double click.  Cursor keys, Page Up/Down, mouse selection,
+and the scroll wheel all operate on the ACW.
+
+"Hidden" attributes can be accessed by typing the beginning of hidden
+name after a '.', e.g. '_'. This allows access to modules with
+``__all__`` set, or to class-private attributes.
+
+Completions and the 'Expand Word' facility can save a lot of typing!
+
+Completions are currently limited to those in the namespaces. Names in
+an Editor window which are not via ``__main__`` and :data:`sys.modules` will
+not be found.  Run the module once with your imports to correct this situation.
+Note that IDLE itself places quite a few modules in sys.modules, so
+much can be found by default, e.g. the re module.
+
+If you don't like the ACW popping up unbidden, simply make the delay
+longer or disable the extension.  Or another option is the delay could
+be set to zero. Another alternative to preventing ACW popups is to
+disable the call tips extension.
 
 Python Shell window
 ^^^^^^^^^^^^^^^^^^^
 
-* :kbd:`C-C` interrupts executing command
+* :kbd:`C-c` interrupts executing command
 
-* :kbd:`C-D` sends end-of-file; closes window if typed at a ``>>>`` prompt
+* :kbd:`C-d` sends end-of-file; closes window if typed at a ``>>>`` prompt
 
-* :kbd:`Alt-p` retrieves previous command matching what you have typed
+* :kbd:`Alt-/` (Expand word) is also useful to reduce typing
 
-* :kbd:`Alt-n` retrieves next
+  Command history
 
-* :kbd:`Return` while on any previous command retrieves that command
+  * :kbd:`Alt-p` retrieves previous command matching what you have typed. On
+    OS X use :kbd:`C-p`.
 
-* :kbd:`Alt-/` (Expand word) is also useful here
+  * :kbd:`Alt-n` retrieves next. On OS X use :kbd:`C-n`.
 
-.. index:: single: indentation
+  * :kbd:`Return` while on any previous command retrieves that command
 
 
 Syntax colors
@@ -308,17 +487,17 @@
 
 Upon startup with the ``-s`` option, IDLE will execute the file referenced by
 the environment variables :envvar:`IDLESTARTUP` or :envvar:`PYTHONSTARTUP`.
-Idle first checks for ``IDLESTARTUP``; if ``IDLESTARTUP`` is present the file
-referenced is run.  If ``IDLESTARTUP`` is not present, Idle checks for
+IDLE first checks for ``IDLESTARTUP``; if ``IDLESTARTUP`` is present the file
+referenced is run.  If ``IDLESTARTUP`` is not present, IDLE checks for
 ``PYTHONSTARTUP``.  Files referenced by these environment variables are
-convenient places to store functions that are used frequently from the Idle
+convenient places to store functions that are used frequently from the IDLE
 shell, or for executing import statements to import common modules.
 
 In addition, ``Tk`` also loads a startup file if it is present.  Note that the
 Tk file is loaded unconditionally.  This additional file is ``.Idle.py`` and is
 looked for in the user's home directory.  Statements in this file will be
-executed in the Tk namespace, so this file is not useful for importing functions
-to be used from Idle's Python shell.
+executed in the Tk namespace, so this file is not useful for importing
+functions to be used from IDLE's Python shell.
 
 
 Command line usage
@@ -344,8 +523,71 @@
 
 #. Otherwise, if neither ``-e`` nor ``-c`` is used, the first
    argument is a script which is executed with the remaining arguments in
-   ``sys.argv[1:...]``  and ``sys.argv[0]`` set to the script name.  If the script
-   name is '-', no script is executed but an interactive Python session is started;
-   the arguments are still available in ``sys.argv``.
+   ``sys.argv[1:...]``  and ``sys.argv[0]`` set to the script name.  If the
+   script name is '-', no script is executed but an interactive Python session
+   is started;    the arguments are still available in ``sys.argv``.
+
+Running without a subprocess
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+If IDLE is started with the -n command line switch it will run in a
+single process and will not create the subprocess which runs the RPC
+Python execution server.  This can be useful if Python cannot create
+the subprocess or the RPC socket interface on your platform.  However,
+in this mode user code is not isolated from IDLE itself.  Also, the
+environment is not restarted when Run/Run Module (F5) is selected.  If
+your code has been modified, you must reload() the affected modules and
+re-import any specific items (e.g. from foo import baz) if the changes
+are to take effect.  For these reasons, it is preferable to run IDLE
+with the default subprocess if at all possible.
+
+.. deprecated:: 3.4
 
 
+Help and preferences
+--------------------
+
+Additional help sources
+^^^^^^^^^^^^^^^^^^^^^^^
+
+IDLE includes a help menu entry called "Python Docs" that will open the
+extensive sources of help, including tutorials, available at docs.python.org.
+Selected URLs can be added or removed from the help menu at any time using the
+Configure IDLE dialog. See the IDLE help option in the help menu of IDLE for
+more information.
+
+
+Setting preferences
+^^^^^^^^^^^^^^^^^^^
+
+The font preferences, highlighting, keys, and general preferences can be
+changed via Configure IDLE on the Option menu.  Keys can be user defined;
+IDLE ships with four built in key sets. In addition a user can create a
+custom key set in the Configure IDLE dialog under the keys tab.
+
+
+Extensions
+^^^^^^^^^^
+
+IDLE contains an extension facility.  Peferences for extensions can be
+changed with Configure Extensions. See the beginning of config-extensions.def
+in the idlelib directory for further information.  The default extensions
+are currently:
+
+* FormatParagraph
+
+* AutoExpand
+
+* ZoomHeight
+
+* ScriptBinding
+
+* CallTips
+
+* ParenMatch
+
+* AutoComplete
+
+* CodeContext
+
+* RstripExtension
diff --git a/Doc/library/json.rst b/Doc/library/json.rst
index caee953..db9df0a 100644
--- a/Doc/library/json.rst
+++ b/Doc/library/json.rst
@@ -8,9 +8,11 @@
 .. versionadded:: 2.6
 
 `JSON (JavaScript Object Notation) <http://json.org>`_, specified by
-:rfc:`4627`, is a lightweight data interchange format based on a subset of
-`JavaScript <http://en.wikipedia.org/wiki/JavaScript>`_ syntax (`ECMA-262 3rd
-edition <http://www.ecma-international.org/publications/files/ECMA-ST-ARCH/ECMA-262,%203rd%20edition,%20December%201999.pdf>`_).
+:rfc:`7159` (which obsoletes :rfc:`4627`) and by
+`ECMA-404 <http://www.ecma-international.org/publications/standards/Ecma-404.htm>`_,
+is a lightweight data interchange format inspired by
+`JavaScript <http://en.wikipedia.org/wiki/JavaScript>`_ object literal syntax
+(although it is not a strict subset of JavaScript [#rfc-errata]_ ).
 
 :mod:`json` exposes an API familiar to users of the standard library
 :mod:`marshal` and :mod:`pickle` modules.
@@ -485,18 +487,18 @@
                 mysocket.write(chunk)
 
 
-Standard Compliance
--------------------
+Standard Compliance and Interoperability
+----------------------------------------
 
-The JSON format is specified by :rfc:`4627`.  This section details this
-module's level of compliance with the RFC.  For simplicity,
-:class:`JSONEncoder` and :class:`JSONDecoder` subclasses, and parameters other
-than those explicitly mentioned, are not considered.
+The JSON format is specified by :rfc:`7159` and by
+`ECMA-404 <http://www.ecma-international.org/publications/standards/Ecma-404.htm>`_.
+This section details this module's level of compliance with the RFC.
+For simplicity, :class:`JSONEncoder` and :class:`JSONDecoder` subclasses, and
+parameters other than those explicitly mentioned, are not considered.
 
 This module does not comply with the RFC in a strict fashion, implementing some
 extensions that are valid JavaScript but not valid JSON.  In particular:
 
-- Top-level non-object, non-array values are accepted and output;
 - Infinite and NaN number values are accepted and output;
 - Repeated names within an object are accepted, and only the value of the last
   name-value pair is used.
@@ -508,48 +510,30 @@
 Character Encodings
 ^^^^^^^^^^^^^^^^^^^
 
-The RFC recommends that JSON be represented using either UTF-8, UTF-16, or
-UTF-32, with UTF-8 being the default.  Accordingly, this module uses UTF-8 as
-the default for its *encoding* parameter.
+The RFC requires that JSON be represented using either UTF-8, UTF-16, or
+UTF-32, with UTF-8 being the recommended default for maximum interoperability.
+Accordingly, this module uses UTF-8 as the default for its *encoding* parameter.
 
 This module's deserializer only directly works with ASCII-compatible encodings;
 UTF-16, UTF-32, and other ASCII-incompatible encodings require the use of
 workarounds described in the documentation for the deserializer's *encoding*
 parameter.
 
-The RFC also non-normatively describes a limited encoding detection technique
-for JSON texts; this module's deserializer does not implement this or any other
-kind of encoding detection.
-
 As permitted, though not required, by the RFC, this module's serializer sets
 *ensure_ascii=True* by default, thus escaping the output so that the resulting
 strings only contain ASCII characters.
 
+The RFC prohibits adding a byte order mark (BOM) to the start of a JSON text,
+and this module's serializer does not add a BOM to its output.
+The RFC permits, but does not require, JSON deserializers to ignore an initial
+BOM in their input.  This module's deserializer raises a :exc:`ValueError`
+when an initial BOM is present.
 
-Top-level Non-Object, Non-Array Values
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The RFC specifies that the top-level value of a JSON text must be either a
-JSON object or array (Python :class:`dict` or :class:`list`).  This module's
-deserializer also accepts input texts consisting solely of a
-JSON null, boolean, number, or string value::
-
-   >>> just_a_json_string = '"spam and eggs"'  # Not by itself a valid JSON text
-   >>> json.loads(just_a_json_string)
-   u'spam and eggs'
-
-This module itself does not include a way to request that such input texts be
-regarded as illegal.  Likewise, this module's serializer also accepts single
-Python :data:`None`, :class:`bool`, numeric, and :class:`str`
-values as input and will generate output texts consisting solely of a top-level
-JSON null, boolean, number, or string value without raising an exception::
-
-   >>> neither_a_list_nor_a_dict = u"spam and eggs"
-   >>> json.dumps(neither_a_list_nor_a_dict)  # The result is not a valid JSON text
-   '"spam and eggs"'
-
-This module's serializer does not itself include a way to enforce the
-aforementioned constraint.
+The RFC does not explicitly forbid JSON strings which contain byte sequences
+that don't correspond to valid Unicode characters (e.g. unpaired UTF-16
+surrogates), but it does note that they may cause interoperability problems.
+By default, this module accepts and outputs (when present in the original
+:class:`str`) codepoints for such sequences.
 
 
 Infinite and NaN Number Values
@@ -579,7 +563,7 @@
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 The RFC specifies that the names within a JSON object should be unique, but
-does not specify how repeated names in JSON objects should be handled.  By
+does not mandate how repeated names in JSON objects should be handled.  By
 default, this module does not raise an exception; instead, it ignores all but
 the last name-value pair for a given name::
 
@@ -588,3 +572,48 @@
    {u'x': 3}
 
 The *object_pairs_hook* parameter can be used to alter this behavior.
+
+
+Top-level Non-Object, Non-Array Values
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The old version of JSON specified by the obsolete :rfc:`4627` required that
+the top-level value of a JSON text must be either a JSON object or array
+(Python :class:`dict` or :class:`list`), and could not be a JSON null,
+boolean, number, or string value.  :rfc:`7159` removed that restriction, and
+this module does not and has never implemented that restriction in either its
+serializer or its deserializer.
+
+Regardless, for maximum interoperability, you may wish to voluntarily adhere
+to the restriction yourself.
+
+
+Implementation Limitations
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Some JSON deserializer implementations may set limits on:
+
+* the size of accepted JSON texts
+* the maximum level of nesting of JSON objects and arrays
+* the range and precision of JSON numbers
+* the content and maximum length of JSON strings
+
+This module does not impose any such limits beyond those of the relevant
+Python datatypes themselves or the Python interpreter itself.
+
+When serializing to JSON, beware any such limitations in applications that may
+consume your JSON.  In particular, it is common for JSON numbers to be
+deserialized into IEEE 754 double precision numbers and thus subject to that
+representation's range and precision limitations.  This is especially relevant
+when serializing Python :class:`int` values of extremely large magnitude, or
+when serializing instances of "exotic" numerical types such as
+:class:`decimal.Decimal`.
+
+
+.. rubric:: Footnotes
+
+.. [#rfc-errata] As noted in `the errata for RFC 7159
+   <http://www.rfc-editor.org/errata_search.php?rfc=7159>`_,
+   JSON permits literal U+2028 (LINE SEPARATOR) and
+   U+2029 (PARAGRAPH SEPARATOR) characters in strings, whereas JavaScript
+   (as of ECMAScript Edition 5.1) does not.
diff --git a/Doc/library/pydoc.rst b/Doc/library/pydoc.rst
index 494a48d..57521f7 100644
--- a/Doc/library/pydoc.rst
+++ b/Doc/library/pydoc.rst
@@ -53,6 +53,10 @@
    executed on that occasion.  Use an ``if __name__ == '__main__':`` guard to
    only execute code when a file is invoked as a script and not just imported.
 
+When printing output to the console, :program:`pydoc` attempts to paginate the
+output for easier reading.  If the :envvar:`PAGER` environment variable is set,
+:program:`pydoc` will use its value as a pagination program.
+
 Specifying a ``-w`` flag before the argument will cause HTML documentation
 to be written out to a file in the current directory, instead of displaying text
 on the console.
diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst
index e6398ae..1c2cbba 100644
--- a/Doc/library/ssl.rst
+++ b/Doc/library/ssl.rst
@@ -192,7 +192,7 @@
        ------------------------  ---------  ---------  ----------  ---------  -----------  -----------
         *SSLv2*                    yes        no         yes         no         no         no
         *SSLv3*                    no         yes        yes         no         no         no
-        *SSLv23*                   yes        no         yes         no         no         no
+        *SSLv23*                   no         yes        yes         yes        yes        yes
         *TLSv1*                    no         no         yes         yes        no         no
         *TLSv1.1*                  no         no         yes         no         yes        no
         *TLSv1.2*                  no         no         yes         no         no         yes
@@ -201,9 +201,8 @@
    .. note::
 
       Which connections succeed will vary depending on the version of
-      OpenSSL.  For example, beginning with OpenSSL 1.0.0, an SSLv23 client
-      will not actually attempt SSLv2 connections unless you explicitly
-      enable SSLv2 ciphers (which is not recommended, as SSLv2 is broken).
+      OpenSSL.  For example, before OpenSSL 1.0.0, an SSLv23 client
+      would always attempt SSLv2 connections.
 
    The *ciphers* parameter sets the available ciphers for this SSL object.
    It should be a string in the `OpenSSL cipher list format
diff --git a/Doc/library/zipfile.rst b/Doc/library/zipfile.rst
index 261747a..71cfe97 100644
--- a/Doc/library/zipfile.rst
+++ b/Doc/library/zipfile.rst
@@ -186,14 +186,8 @@
 
    .. note::
 
-      If the ZipFile was created by passing in a file-like object as the  first
-      argument to the constructor, then the object returned by :meth:`.open` shares the
-      ZipFile's file pointer.  Under these  circumstances, the object returned by
-      :meth:`.open` should not  be used after any additional operations are performed
-      on the  ZipFile object.  If the ZipFile was created by passing in a string (the
-      filename) as the first argument to the constructor, then  :meth:`.open` will
-      create a new file object that will be held by the ZipExtFile, allowing it to
-      operate independently of the  ZipFile.
+      Objects returned by :meth:`.open` can operate independently of the
+      ZipFile.
 
    .. note::
 
diff --git a/Lib/_abcoll.py b/Lib/_abcoll.py
index 3d567e3..0385627 100644
--- a/Lib/_abcoll.py
+++ b/Lib/_abcoll.py
@@ -548,23 +548,25 @@
             If E present and lacks .keys() method, does:     for (k, v) in E: D[k] = v
             In either case, this is followed by: for k, v in F.items(): D[k] = v
         '''
-        if len(args) > 2:
-            raise TypeError("update() takes at most 2 positional "
-                            "arguments ({} given)".format(len(args)))
-        elif not args:
-            raise TypeError("update() takes at least 1 argument (0 given)")
+        if not args:
+            raise TypeError("descriptor 'update' of 'MutableMapping' object "
+                            "needs an argument")
         self = args[0]
-        other = args[1] if len(args) >= 2 else ()
-
-        if isinstance(other, Mapping):
-            for key in other:
-                self[key] = other[key]
-        elif hasattr(other, "keys"):
-            for key in other.keys():
-                self[key] = other[key]
-        else:
-            for key, value in other:
-                self[key] = value
+        args = args[1:]
+        if len(args) > 1:
+            raise TypeError('update expected at most 1 arguments, got %d' %
+                            len(args))
+        if args:
+            other = args[0]
+            if isinstance(other, Mapping):
+                for key in other:
+                    self[key] = other[key]
+            elif hasattr(other, "keys"):
+                for key in other.keys():
+                    self[key] = other[key]
+            else:
+                for key, value in other:
+                    self[key] = value
         for key, value in kwds.items():
             self[key] = value
 
diff --git a/Lib/bsddb/test/test_all.py b/Lib/bsddb/test/test_all.py
index caef1ac..004e357 100644
--- a/Lib/bsddb/test/test_all.py
+++ b/Lib/bsddb/test/test_all.py
@@ -412,9 +412,6 @@
         def get_dbp(self) :
             return self._db
 
-    import string
-    string.letters=[chr(i) for i in xrange(65,91)]
-
     bsddb._db.DBEnv_orig = bsddb._db.DBEnv
     bsddb._db.DB_orig = bsddb._db.DB
     if bsddb.db.version() <= (4, 3) :
diff --git a/Lib/bsddb/test/test_basics.py b/Lib/bsddb/test/test_basics.py
index 3c57be4..1459d36 100644
--- a/Lib/bsddb/test/test_basics.py
+++ b/Lib/bsddb/test/test_basics.py
@@ -999,7 +999,7 @@
         for x in "The quick brown fox jumped over the lazy dog".split():
             d2.put(x, self.makeData(x))
 
-        for x in string.letters:
+        for x in string.ascii_letters:
             d3.put(x, x*70)
 
         d1.sync()
@@ -1047,7 +1047,7 @@
             if verbose:
                 print rec
             rec = c3.next()
-        self.assertEqual(count, len(string.letters))
+        self.assertEqual(count, len(string.ascii_letters))
 
 
         c1.close()
diff --git a/Lib/bsddb/test/test_dbshelve.py b/Lib/bsddb/test/test_dbshelve.py
index c3701e1..e5609c5 100644
--- a/Lib/bsddb/test/test_dbshelve.py
+++ b/Lib/bsddb/test/test_dbshelve.py
@@ -59,7 +59,7 @@
             return bytes(key, "iso8859-1")  # 8 bits
 
     def populateDB(self, d):
-        for x in string.letters:
+        for x in string.ascii_letters:
             d[self.mk('S' + x)] = 10 * x           # add a string
             d[self.mk('I' + x)] = ord(x)           # add an integer
             d[self.mk('L' + x)] = [x] * 10         # add a list
diff --git a/Lib/bsddb/test/test_get_none.py b/Lib/bsddb/test/test_get_none.py
index 8763b54..541044c 100644
--- a/Lib/bsddb/test/test_get_none.py
+++ b/Lib/bsddb/test/test_get_none.py
@@ -26,14 +26,14 @@
         d.open(self.filename, db.DB_BTREE, db.DB_CREATE)
         d.set_get_returns_none(1)
 
-        for x in string.letters:
+        for x in string.ascii_letters:
             d.put(x, x * 40)
 
         data = d.get('bad key')
         self.assertEqual(data, None)
 
-        data = d.get(string.letters[0])
-        self.assertEqual(data, string.letters[0]*40)
+        data = d.get(string.ascii_letters[0])
+        self.assertEqual(data, string.ascii_letters[0]*40)
 
         count = 0
         c = d.cursor()
@@ -43,7 +43,7 @@
             rec = c.next()
 
         self.assertEqual(rec, None)
-        self.assertEqual(count, len(string.letters))
+        self.assertEqual(count, len(string.ascii_letters))
 
         c.close()
         d.close()
@@ -54,14 +54,14 @@
         d.open(self.filename, db.DB_BTREE, db.DB_CREATE)
         d.set_get_returns_none(0)
 
-        for x in string.letters:
+        for x in string.ascii_letters:
             d.put(x, x * 40)
 
         self.assertRaises(db.DBNotFoundError, d.get, 'bad key')
         self.assertRaises(KeyError, d.get, 'bad key')
 
-        data = d.get(string.letters[0])
-        self.assertEqual(data, string.letters[0]*40)
+        data = d.get(string.ascii_letters[0])
+        self.assertEqual(data, string.ascii_letters[0]*40)
 
         count = 0
         exceptionHappened = 0
@@ -77,7 +77,7 @@
 
         self.assertNotEqual(rec, None)
         self.assertTrue(exceptionHappened)
-        self.assertEqual(count, len(string.letters))
+        self.assertEqual(count, len(string.ascii_letters))
 
         c.close()
         d.close()
diff --git a/Lib/bsddb/test/test_queue.py b/Lib/bsddb/test/test_queue.py
index d3a0c8b..5fa22ee 100644
--- a/Lib/bsddb/test/test_queue.py
+++ b/Lib/bsddb/test/test_queue.py
@@ -10,7 +10,6 @@
 
 #----------------------------------------------------------------------
 
-@unittest.skip("fails on Windows; see issue 22943")
 class SimpleQueueTestCase(unittest.TestCase):
     def setUp(self):
         self.filename = get_new_database_path()
@@ -37,17 +36,17 @@
             print "before appends" + '-' * 30
             pprint(d.stat())
 
-        for x in string.letters:
+        for x in string.ascii_letters:
             d.append(x * 40)
 
-        self.assertEqual(len(d), len(string.letters))
+        self.assertEqual(len(d), len(string.ascii_letters))
 
         d.put(100, "some more data")
         d.put(101, "and some more ")
         d.put(75,  "out of order")
         d.put(1,   "replacement data")
 
-        self.assertEqual(len(d), len(string.letters)+3)
+        self.assertEqual(len(d), len(string.ascii_letters)+3)
 
         if verbose:
             print "before close" + '-' * 30
@@ -108,17 +107,17 @@
             print "before appends" + '-' * 30
             pprint(d.stat())
 
-        for x in string.letters:
+        for x in string.ascii_letters:
             d.append(x * 40)
 
-        self.assertEqual(len(d), len(string.letters))
+        self.assertEqual(len(d), len(string.ascii_letters))
 
         d.put(100, "some more data")
         d.put(101, "and some more ")
         d.put(75,  "out of order")
         d.put(1,   "replacement data")
 
-        self.assertEqual(len(d), len(string.letters)+3)
+        self.assertEqual(len(d), len(string.ascii_letters)+3)
 
         if verbose:
             print "before close" + '-' * 30
diff --git a/Lib/bsddb/test/test_recno.py b/Lib/bsddb/test/test_recno.py
index fb6956a..b0e30de 100644
--- a/Lib/bsddb/test/test_recno.py
+++ b/Lib/bsddb/test/test_recno.py
@@ -4,12 +4,11 @@
 import os, sys
 import errno
 from pprint import pprint
+import string
 import unittest
 
 from test_all import db, test_support, verbose, get_new_environment_path, get_new_database_path
 
-letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
-
 
 #----------------------------------------------------------------------
 
@@ -39,7 +38,7 @@
 
         d.open(self.filename, db.DB_RECNO, db.DB_CREATE)
 
-        for x in letters:
+        for x in string.ascii_letters:
             recno = d.append(x * 60)
             self.assertIsInstance(recno, int)
             self.assertGreaterEqual(recno, 1)
@@ -270,7 +269,7 @@
         d.set_re_pad(45)  # ...test both int and char
         d.open(self.filename, db.DB_RECNO, db.DB_CREATE)
 
-        for x in letters:
+        for x in string.ascii_letters:
             d.append(x * 35)    # These will be padded
 
         d.append('.' * 40)      # this one will be exact
diff --git a/Lib/collections.py b/Lib/collections.py
index 8831f0b..1dcd233 100644
--- a/Lib/collections.py
+++ b/Lib/collections.py
@@ -35,12 +35,17 @@
     # The sentinel element never gets deleted (this simplifies the algorithm).
     # Each link is stored as a list of length three:  [PREV, NEXT, KEY].
 
-    def __init__(self, *args, **kwds):
+    def __init__(*args, **kwds):
         '''Initialize an ordered dictionary.  The signature is the same as
         regular dictionaries, but keyword arguments are not recommended because
         their insertion order is arbitrary.
 
         '''
+        if not args:
+            raise TypeError("descriptor '__init__' of 'OrderedDict' object "
+                            "needs an argument")
+        self = args[0]
+        args = args[1:]
         if len(args) > 1:
             raise TypeError('expected at most 1 arguments, got %d' % len(args))
         try:
@@ -438,7 +443,7 @@
     #   http://code.activestate.com/recipes/259174/
     #   Knuth, TAOCP Vol. II section 4.6.3
 
-    def __init__(self, iterable=None, **kwds):
+    def __init__(*args, **kwds):
         '''Create a new, empty Counter object.  And if given, count elements
         from an input iterable.  Or, initialize the count from another mapping
         of elements to their counts.
@@ -449,8 +454,15 @@
         >>> c = Counter(a=4, b=2)                   # a new counter from keyword args
 
         '''
+        if not args:
+            raise TypeError("descriptor '__init__' of 'Counter' object "
+                            "needs an argument")
+        self = args[0]
+        args = args[1:]
+        if len(args) > 1:
+            raise TypeError('expected at most 1 arguments, got %d' % len(args))
         super(Counter, self).__init__()
-        self.update(iterable, **kwds)
+        self.update(*args, **kwds)
 
     def __missing__(self, key):
         'The count of elements not in the Counter is zero.'
@@ -501,7 +513,7 @@
         raise NotImplementedError(
             'Counter.fromkeys() is undefined.  Use Counter(iterable) instead.')
 
-    def update(self, iterable=None, **kwds):
+    def update(*args, **kwds):
         '''Like dict.update() but add counts instead of replacing them.
 
         Source can be an iterable, a dictionary, or another Counter instance.
@@ -521,6 +533,14 @@
         # contexts.  Instead, we implement straight-addition.  Both the inputs
         # and outputs are allowed to contain zero and negative counts.
 
+        if not args:
+            raise TypeError("descriptor 'update' of 'Counter' object "
+                            "needs an argument")
+        self = args[0]
+        args = args[1:]
+        if len(args) > 1:
+            raise TypeError('expected at most 1 arguments, got %d' % len(args))
+        iterable = args[0] if args else None
         if iterable is not None:
             if isinstance(iterable, Mapping):
                 if self:
@@ -536,7 +556,7 @@
         if kwds:
             self.update(kwds)
 
-    def subtract(self, iterable=None, **kwds):
+    def subtract(*args, **kwds):
         '''Like dict.update() but subtracts counts instead of replacing them.
         Counts can be reduced below zero.  Both the inputs and outputs are
         allowed to contain zero and negative counts.
@@ -552,6 +572,14 @@
         -1
 
         '''
+        if not args:
+            raise TypeError("descriptor 'subtract' of 'Counter' object "
+                            "needs an argument")
+        self = args[0]
+        args = args[1:]
+        if len(args) > 1:
+            raise TypeError('expected at most 1 arguments, got %d' % len(args))
+        iterable = args[0] if args else None
         if iterable is not None:
             self_get = self.get
             if isinstance(iterable, Mapping):
diff --git a/Lib/hashlib.py b/Lib/hashlib.py
index 4a411bc..bbd06b9 100644
--- a/Lib/hashlib.py
+++ b/Lib/hashlib.py
@@ -187,7 +187,7 @@
 
         def prf(msg, inner=inner, outer=outer):
             # PBKDF2_HMAC uses the password as key. We can re-use the same
-            # digest objects and and just update copies to skip initialization.
+            # digest objects and just update copies to skip initialization.
             icpy = inner.copy()
             ocpy = outer.copy()
             icpy.update(msg)
diff --git a/Lib/httplib.py b/Lib/httplib.py
index 7c27906..1224989 100644
--- a/Lib/httplib.py
+++ b/Lib/httplib.py
@@ -1070,18 +1070,22 @@
             kwds["buffering"] = True;
         response = self.response_class(*args, **kwds)
 
-        response.begin()
-        assert response.will_close != _UNKNOWN
-        self.__state = _CS_IDLE
+        try:
+            response.begin()
+            assert response.will_close != _UNKNOWN
+            self.__state = _CS_IDLE
 
-        if response.will_close:
-            # this effectively passes the connection to the response
-            self.close()
-        else:
-            # remember this, so we can tell when it is complete
-            self.__response = response
+            if response.will_close:
+                # this effectively passes the connection to the response
+                self.close()
+            else:
+                # remember this, so we can tell when it is complete
+                self.__response = response
 
-        return response
+            return response
+        except:
+            response.close()
+            raise
 
 
 class HTTP:
diff --git a/Lib/pydoc.py b/Lib/pydoc.py
index dfa1f8e..0647d1e 100755
--- a/Lib/pydoc.py
+++ b/Lib/pydoc.py
@@ -17,7 +17,8 @@
 of all available modules.
 
 Run "pydoc -p <port>" to start an HTTP server on a given port on the
-local machine to generate documentation web pages.
+local machine to generate documentation web pages.  Port number 0 can be
+used to get an arbitrary unused port.
 
 For platforms without a command line, "pydoc -g" starts the HTTP server
 and also pops up a little window for controlling it.
@@ -1445,7 +1446,13 @@
         getchar = lambda: sys.stdin.readline()[:-1][:1]
 
     try:
-        r = inc = os.environ.get('LINES', 25) - 1
+        try:
+            h = int(os.environ.get('LINES', 0))
+        except ValueError:
+            h = 0
+        if h <= 1:
+            h = 25
+        r = inc = h - 1
         sys.stdout.write(join(lines[:inc], '\n') + '\n')
         while lines[r:]:
             sys.stdout.write('-- more --')
@@ -2098,7 +2105,6 @@
         def __init__(self, port, callback):
             host = 'localhost'
             self.address = (host, port)
-            self.url = 'http://%s:%d/' % (host, port)
             self.callback = callback
             self.base.__init__(self, self.address, self.handler)
 
@@ -2111,6 +2117,7 @@
 
         def server_activate(self):
             self.base.server_activate(self)
+            self.url = 'http://%s:%d/' % (self.address[0], self.server_port)
             if self.callback: self.callback(self)
 
     DocServer.base = BaseHTTPServer.HTTPServer
@@ -2384,7 +2391,8 @@
     Search for a keyword in the synopsis lines of all available modules.
 
 %s -p <port>
-    Start an HTTP server on the given port on the local machine.
+    Start an HTTP server on the given port on the local machine.  Port
+    number 0 can be used to get an arbitrary unused port.
 
 %s -g
     Pop up a graphical interface for finding and serving documentation.
diff --git a/Lib/shutil.py b/Lib/shutil.py
index e12f791..e78a575 100644
--- a/Lib/shutil.py
+++ b/Lib/shutil.py
@@ -362,7 +362,7 @@
     archive_name = base_name + '.tar' + compress_ext.get(compress, '')
     archive_dir = os.path.dirname(archive_name)
 
-    if not os.path.exists(archive_dir):
+    if archive_dir and not os.path.exists(archive_dir):
         if logger is not None:
             logger.info("creating %s", archive_dir)
         if not dry_run:
@@ -426,7 +426,7 @@
     zip_filename = base_name + ".zip"
     archive_dir = os.path.dirname(base_name)
 
-    if not os.path.exists(archive_dir):
+    if archive_dir and not os.path.exists(archive_dir):
         if logger is not None:
             logger.info("creating %s", archive_dir)
         if not dry_run:
diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py
index 20e0667..cd27227 100644
--- a/Lib/test/test_collections.py
+++ b/Lib/test/test_collections.py
@@ -905,6 +905,28 @@
         self.assertEqual(c.setdefault('e', 5), 5)
         self.assertEqual(c['e'], 5)
 
+    def test_init(self):
+        self.assertEqual(list(Counter(self=42).items()), [('self', 42)])
+        self.assertEqual(list(Counter(iterable=42).items()), [('iterable', 42)])
+        self.assertEqual(list(Counter(iterable=None).items()), [('iterable', None)])
+        self.assertRaises(TypeError, Counter, 42)
+        self.assertRaises(TypeError, Counter, (), ())
+        self.assertRaises(TypeError, Counter.__init__)
+
+    def test_update(self):
+        c = Counter()
+        c.update(self=42)
+        self.assertEqual(list(c.items()), [('self', 42)])
+        c = Counter()
+        c.update(iterable=42)
+        self.assertEqual(list(c.items()), [('iterable', 42)])
+        c = Counter()
+        c.update(iterable=None)
+        self.assertEqual(list(c.items()), [('iterable', None)])
+        self.assertRaises(TypeError, Counter().update, 42)
+        self.assertRaises(TypeError, Counter().update, {}, {})
+        self.assertRaises(TypeError, Counter.update)
+
     def test_copying(self):
         # Check that counters are copyable, deepcopyable, picklable, and
         #have a repr/eval round-trip
@@ -1006,6 +1028,16 @@
         c.subtract('aaaabbcce')
         self.assertEqual(c, Counter(a=-1, b=0, c=-1, d=1, e=-1))
 
+        c = Counter()
+        c.subtract(self=42)
+        self.assertEqual(list(c.items()), [('self', -42)])
+        c = Counter()
+        c.subtract(iterable=42)
+        self.assertEqual(list(c.items()), [('iterable', -42)])
+        self.assertRaises(TypeError, Counter().subtract, 42)
+        self.assertRaises(TypeError, Counter().subtract, {}, {})
+        self.assertRaises(TypeError, Counter.subtract)
+
 class TestOrderedDict(unittest.TestCase):
 
     def test_init(self):
@@ -1019,8 +1051,11 @@
                                           c=3, e=5).items()), pairs)                # mixed input
 
         # make sure no positional args conflict with possible kwdargs
-        self.assertEqual(inspect.getargspec(OrderedDict.__dict__['__init__']).args,
-                         ['self'])
+        self.assertEqual(list(OrderedDict(self=42).items()), [('self', 42)])
+        self.assertEqual(list(OrderedDict(other=42).items()), [('other', 42)])
+        self.assertRaises(TypeError, OrderedDict, 42)
+        self.assertRaises(TypeError, OrderedDict, (), ())
+        self.assertRaises(TypeError, OrderedDict.__init__)
 
         # Make sure that direct calls to __init__ do not clear previous contents
         d = OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 44), ('e', 55)])
@@ -1065,6 +1100,10 @@
         self.assertEqual(list(d.items()),
             [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5), ('f', 6), ('g', 7)])
 
+        self.assertRaises(TypeError, OrderedDict().update, 42)
+        self.assertRaises(TypeError, OrderedDict().update, (), ())
+        self.assertRaises(TypeError, OrderedDict.update)
+
     def test_abc(self):
         self.assertIsInstance(OrderedDict(), MutableMapping)
         self.assertTrue(issubclass(OrderedDict, MutableMapping))
diff --git a/Lib/test/test_docxmlrpc.py b/Lib/test/test_docxmlrpc.py
index 80d1803..a1a1fcf 100644
--- a/Lib/test/test_docxmlrpc.py
+++ b/Lib/test/test_docxmlrpc.py
@@ -10,7 +10,7 @@
 PORT = None
 
 def make_request_and_skipIf(condition, reason):
-    # If we skip the test, we have to make a request because the
+    # If we skip the test, we have to make a request because
     # the server created in setUp blocks expecting one to come in.
     if not condition:
         return lambda func: func
diff --git a/Lib/test/test_httplib.py b/Lib/test/test_httplib.py
index 3e7a57e..a73a28b 100644
--- a/Lib/test/test_httplib.py
+++ b/Lib/test/test_httplib.py
@@ -25,6 +25,7 @@
         self.text = text
         self.fileclass = fileclass
         self.data = ''
+        self.file_closed = False
         self.host = host
         self.port = port
 
@@ -34,7 +35,13 @@
     def makefile(self, mode, bufsize=None):
         if mode != 'r' and mode != 'rb':
             raise httplib.UnimplementedFileMode()
-        return self.fileclass(self.text)
+        # keep the file around so we can check how much was read from it
+        self.file = self.fileclass(self.text)
+        self.file.close = self.file_close #nerf close ()
+        return self.file
+
+    def file_close(self):
+        self.file_closed = True
 
     def close(self):
         pass
@@ -433,6 +440,22 @@
         self.assertEqual(resp.read(), '')
         self.assertTrue(resp.isclosed())
 
+    def test_error_leak(self):
+        # Test that the socket is not leaked if getresponse() fails
+        conn = httplib.HTTPConnection('example.com')
+        response = []
+        class Response(httplib.HTTPResponse):
+            def __init__(self, *pos, **kw):
+                response.append(self)  # Avoid garbage collector closing the socket
+                httplib.HTTPResponse.__init__(self, *pos, **kw)
+        conn.response_class = Response
+        conn.sock = FakeSocket('')  # Emulate server dropping connection
+        conn.request('GET', '/')
+        self.assertRaises(httplib.BadStatusLine, conn.getresponse)
+        self.assertTrue(response)
+        #self.assertTrue(response[0].closed)
+        self.assertTrue(conn.sock.file_closed)
+
 class OfflineTest(TestCase):
     def test_responses(self):
         self.assertEqual(httplib.responses[httplib.NOT_FOUND], "Not Found")
diff --git a/Lib/test/test_readline.py b/Lib/test/test_readline.py
index e009952..588043e 100644
--- a/Lib/test/test_readline.py
+++ b/Lib/test/test_readline.py
@@ -15,9 +15,9 @@
     That's why the tests cover only a small subset of the interface.
     """
 
-    @unittest.skipIf(not hasattr(readline, 'clear_history'),
-                     "The history update test cannot be run because the "
-                     "clear_history method is not available.")
+    @unittest.skipUnless(hasattr(readline, "clear_history"),
+                         "The history update test cannot be run because the "
+                         "clear_history method is not available.")
     def testHistoryUpdates(self):
         readline.clear_history()
 
diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py
index 0e81145..bcabe75 100644
--- a/Lib/test/test_shutil.py
+++ b/Lib/test/test_shutil.py
@@ -581,6 +581,29 @@
         finally:
             unregister_archive_format('xxx')
 
+    def test_make_tarfile_in_curdir(self):
+        # Issue #21280
+        root_dir = self.mkdtemp()
+        saved_dir = os.getcwd()
+        try:
+            os.chdir(root_dir)
+            self.assertEqual(make_archive('test', 'tar'), 'test.tar')
+            self.assertTrue(os.path.isfile('test.tar'))
+        finally:
+            os.chdir(saved_dir)
+
+    @unittest.skipUnless(zlib, "Requires zlib")
+    def test_make_zipfile_in_curdir(self):
+        # Issue #21280
+        root_dir = self.mkdtemp()
+        saved_dir = os.getcwd()
+        try:
+            os.chdir(root_dir)
+            self.assertEqual(make_archive('test', 'zip'), 'test.zip')
+            self.assertTrue(os.path.isfile('test.zip'))
+        finally:
+            os.chdir(saved_dir)
+
     def test_register_archive_format(self):
 
         self.assertRaises(TypeError, register_archive_format, 'xxx', 1)
diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py
index fbeda53..95d3536 100644
--- a/Lib/test/test_zipfile.py
+++ b/Lib/test/test_zipfile.py
@@ -14,7 +14,7 @@
 
 from StringIO import StringIO
 from tempfile import TemporaryFile
-from random import randint, random
+from random import randint, random, getrandbits
 from unittest import skipUnless
 
 from test.test_support import TESTFN, TESTFN_UNICODE, TESTFN_ENCODING, \
@@ -35,6 +35,20 @@
                    ('ziptest2dir/ziptest3dir/_ziptest3', 'azsxdcfvgb'),
                    ('ziptest2dir/ziptest3dir/ziptest4dir/_ziptest3', '6y7u8i9o0p')]
 
+def getrandbytes(size):
+    return getrandbits(8 * size).to_bytes(size, 'little')
+
+def getrandbytes(size):
+    return bytes(bytearray.fromhex('%0*x' % (2 * size, getrandbits(8 * size))))
+
+def get_files(test):
+    yield TESTFN2
+    with TemporaryFile() as f:
+        yield f
+        test.assertFalse(f.closed)
+    with io.BytesIO() as f:
+        yield f
+        test.assertFalse(f.closed)
 
 class TestsWithSourceFile(unittest.TestCase):
     def setUp(self):
@@ -1168,8 +1182,7 @@
         # than requested.
         for test_size in (1, 4095, 4096, 4097, 16384):
             file_size = test_size + 1
-            junk = b''.join(struct.pack('B', randint(0, 255))
-                            for x in range(file_size))
+            junk = getrandbytes(file_size)
             with zipfile.ZipFile(io.BytesIO(), "w", compression) as zipf:
                 zipf.writestr('foo', junk)
                 with zipf.open('foo', 'r') as fp:
@@ -1400,50 +1413,110 @@
 
 @skipUnless(zlib, "requires zlib")
 class TestsWithMultipleOpens(unittest.TestCase):
-    def setUp(self):
+    @classmethod
+    def setUpClass(cls):
+        cls.data1 = b'111' + getrandbytes(10000)
+        cls.data2 = b'222' + getrandbytes(10000)
+
+    def make_test_archive(self, f):
         # Create the ZIP archive
-        with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_DEFLATED) as zipfp:
-            zipfp.writestr('ones', '1'*FIXEDTEST_SIZE)
-            zipfp.writestr('twos', '2'*FIXEDTEST_SIZE)
+        with zipfile.ZipFile(f, "w", zipfile.ZIP_DEFLATED) as zipfp:
+            zipfp.writestr('ones', self.data1)
+            zipfp.writestr('twos', self.data2)
 
     def test_same_file(self):
         # Verify that (when the ZipFile is in control of creating file objects)
         # multiple open() calls can be made without interfering with each other.
-        with zipfile.ZipFile(TESTFN2, mode="r") as zipf:
-            with zipf.open('ones') as zopen1, zipf.open('ones') as zopen2:
-                data1 = zopen1.read(500)
-                data2 = zopen2.read(500)
-                data1 += zopen1.read(500)
-                data2 += zopen2.read(500)
-            self.assertEqual(data1, data2)
+        for f in get_files(self):
+            self.make_test_archive(f)
+            with zipfile.ZipFile(f, mode="r") as zipf:
+                with zipf.open('ones') as zopen1, zipf.open('ones') as zopen2:
+                    data1 = zopen1.read(500)
+                    data2 = zopen2.read(500)
+                    data1 += zopen1.read()
+                    data2 += zopen2.read()
+                self.assertEqual(data1, data2)
+                self.assertEqual(data1, self.data1)
 
     def test_different_file(self):
         # Verify that (when the ZipFile is in control of creating file objects)
         # multiple open() calls can be made without interfering with each other.
-        with zipfile.ZipFile(TESTFN2, mode="r") as zipf:
-            with zipf.open('ones') as zopen1, zipf.open('twos') as zopen2:
-                data1 = zopen1.read(500)
-                data2 = zopen2.read(500)
-                data1 += zopen1.read(500)
-                data2 += zopen2.read(500)
-            self.assertEqual(data1, '1'*FIXEDTEST_SIZE)
-            self.assertEqual(data2, '2'*FIXEDTEST_SIZE)
+        for f in get_files(self):
+            self.make_test_archive(f)
+            with zipfile.ZipFile(f, mode="r") as zipf:
+                with zipf.open('ones') as zopen1, zipf.open('twos') as zopen2:
+                    data1 = zopen1.read(500)
+                    data2 = zopen2.read(500)
+                    data1 += zopen1.read()
+                    data2 += zopen2.read()
+                self.assertEqual(data1, self.data1)
+                self.assertEqual(data2, self.data2)
 
     def test_interleaved(self):
         # Verify that (when the ZipFile is in control of creating file objects)
         # multiple open() calls can be made without interfering with each other.
-        with zipfile.ZipFile(TESTFN2, mode="r") as zipf:
-            with zipf.open('ones') as zopen1, zipf.open('twos') as zopen2:
+        for f in get_files(self):
+            self.make_test_archive(f)
+            with zipfile.ZipFile(f, mode="r") as zipf:
+                with zipf.open('ones') as zopen1, zipf.open('twos') as zopen2:
+                    data1 = zopen1.read(500)
+                    data2 = zopen2.read(500)
+                    data1 += zopen1.read()
+                    data2 += zopen2.read()
+                self.assertEqual(data1, self.data1)
+                self.assertEqual(data2, self.data2)
+
+    def test_read_after_close(self):
+        for f in get_files(self):
+            self.make_test_archive(f)
+            zopen1 = zopen2 = None
+            try:
+                with zipfile.ZipFile(f, 'r') as zipf:
+                    zopen1 = zipf.open('ones')
+                    zopen2 = zipf.open('twos')
                 data1 = zopen1.read(500)
                 data2 = zopen2.read(500)
-                data1 += zopen1.read(500)
-                data2 += zopen2.read(500)
-            self.assertEqual(data1, '1'*FIXEDTEST_SIZE)
-            self.assertEqual(data2, '2'*FIXEDTEST_SIZE)
+                data1 += zopen1.read()
+                data2 += zopen2.read()
+            finally:
+                if zopen1:
+                    zopen1.close()
+                if zopen2:
+                    zopen2.close()
+            self.assertEqual(data1, self.data1)
+            self.assertEqual(data2, self.data2)
+
+    def test_read_after_write(self):
+        for f in get_files(self):
+            with zipfile.ZipFile(f, 'w', zipfile.ZIP_DEFLATED) as zipf:
+                zipf.writestr('ones', self.data1)
+                zipf.writestr('twos', self.data2)
+                with zipf.open('ones') as zopen1:
+                    data1 = zopen1.read(500)
+            self.assertEqual(data1, self.data1[:500])
+            with zipfile.ZipFile(f, 'r') as zipf:
+                data1 = zipf.read('ones')
+                data2 = zipf.read('twos')
+            self.assertEqual(data1, self.data1)
+            self.assertEqual(data2, self.data2)
+
+    def test_write_after_read(self):
+        for f in get_files(self):
+            with zipfile.ZipFile(f, "w", zipfile.ZIP_DEFLATED) as zipf:
+                zipf.writestr('ones', self.data1)
+                with zipf.open('ones') as zopen1:
+                    zopen1.read(500)
+                    zipf.writestr('twos', self.data2)
+            with zipfile.ZipFile(f, 'r') as zipf:
+                data1 = zipf.read('ones')
+                data2 = zipf.read('twos')
+            self.assertEqual(data1, self.data1)
+            self.assertEqual(data2, self.data2)
 
     def test_many_opens(self):
         # Verify that read() and open() promptly close the file descriptor,
         # and don't rely on the garbage collector to free resources.
+        self.make_test_archive(TESTFN2)
         with zipfile.ZipFile(TESTFN2, mode="r") as zipf:
             for x in range(100):
                 zipf.read('ones')
diff --git a/Lib/zipfile.py b/Lib/zipfile.py
index b77e6c8..7619cfe 100644
--- a/Lib/zipfile.py
+++ b/Lib/zipfile.py
@@ -498,6 +498,25 @@
 }
 
 
+class _SharedFile:
+    def __init__(self, file, pos, close):
+        self._file = file
+        self._pos = pos
+        self._close = close
+
+    def read(self, n=-1):
+        self._file.seek(self._pos)
+        data = self._file.read(n)
+        self._pos = self._file.tell()
+        return data
+
+    def close(self):
+        if self._file is not None:
+            fileobj = self._file
+            self._file = None
+            self._close(fileobj)
+
+
 class ZipExtFile(io.BufferedIOBase):
     """File-like object for reading an archive member.
        Is returned by ZipFile.open().
@@ -743,7 +762,7 @@
         self.NameToInfo = {}    # Find file info given name
         self.filelist = []      # List of ZipInfo instances for archive
         self.compression = compression  # Method of compression
-        self.mode = key = mode.replace('b', '')[0]
+        self.mode = mode
         self.pwd = None
         self._comment = ''
 
@@ -751,28 +770,33 @@
         if isinstance(file, basestring):
             self._filePassed = 0
             self.filename = file
-            modeDict = {'r' : 'rb', 'w': 'wb', 'a' : 'r+b'}
-            try:
-                self.fp = open(file, modeDict[mode])
-            except IOError:
-                if mode == 'a':
-                    mode = key = 'w'
-                    self.fp = open(file, modeDict[mode])
-                else:
+            modeDict = {'r' : 'rb', 'w': 'w+b', 'a' : 'r+b',
+                        'r+b': 'w+b', 'w+b': 'wb'}
+            filemode = modeDict[mode]
+            while True:
+                try:
+                    self.fp = io.open(file, filemode)
+                except IOError:
+                    if filemode in modeDict:
+                        filemode = modeDict[filemode]
+                        continue
                     raise
+                break
         else:
             self._filePassed = 1
             self.fp = file
             self.filename = getattr(file, 'name', None)
+        self._fileRefCnt = 1
 
         try:
-            if key == 'r':
+            if mode == 'r':
                 self._RealGetContents()
-            elif key == 'w':
+            elif mode == 'w':
                 # set the modified flag so central directory gets written
                 # even if no files are added to the archive
                 self._didModify = True
-            elif key == 'a':
+                self.start_dir = 0
+            elif mode == 'a':
                 try:
                     # See if file is a zip file
                     self._RealGetContents()
@@ -785,13 +809,13 @@
                     # set the modified flag so central directory gets written
                     # even if no files are added to the archive
                     self._didModify = True
+                    self.start_dir = self.fp.tell()
             else:
                 raise RuntimeError('Mode must be "r", "w" or "a"')
         except:
             fp = self.fp
             self.fp = None
-            if not self._filePassed:
-                fp.close()
+            self._fpclose(fp)
             raise
 
     def __enter__(self):
@@ -942,26 +966,17 @@
             raise RuntimeError, \
                   "Attempt to read ZIP archive that was already closed"
 
-        # Only open a new file for instances where we were not
-        # given a file object in the constructor
-        if self._filePassed:
-            zef_file = self.fp
-            should_close = False
+        # Make sure we have an info object
+        if isinstance(name, ZipInfo):
+            # 'name' is already an info object
+            zinfo = name
         else:
-            zef_file = open(self.filename, 'rb')
-            should_close = True
+            # Get info object for name
+            zinfo = self.getinfo(name)
 
+        self._fileRefCnt += 1
+        zef_file = _SharedFile(self.fp, zinfo.header_offset, self._fpclose)
         try:
-            # Make sure we have an info object
-            if isinstance(name, ZipInfo):
-                # 'name' is already an info object
-                zinfo = name
-            else:
-                # Get info object for name
-                zinfo = self.getinfo(name)
-
-            zef_file.seek(zinfo.header_offset, 0)
-
             # Skip the file header:
             fheader = zef_file.read(sizeFileHeader)
             if len(fheader) != sizeFileHeader:
@@ -1006,11 +1021,9 @@
                 if ord(h[11]) != check_byte:
                     raise RuntimeError("Bad password for file", name)
 
-            return ZipExtFile(zef_file, mode, zinfo, zd,
-                    close_fileobj=should_close)
+            return ZipExtFile(zef_file, mode, zinfo, zd, True)
         except:
-            if should_close:
-                zef_file.close()
+            zef_file.close()
             raise
 
     def extract(self, member, path=None, pwd=None):
@@ -1141,6 +1154,7 @@
 
         zinfo.file_size = st.st_size
         zinfo.flag_bits = 0x00
+        self.fp.seek(self.start_dir, 0)
         zinfo.header_offset = self.fp.tell()    # Start of header bytes
 
         self._writecheck(zinfo)
@@ -1154,6 +1168,7 @@
             self.filelist.append(zinfo)
             self.NameToInfo[zinfo.filename] = zinfo
             self.fp.write(zinfo.FileHeader(False))
+            self.start_dir = self.fp.tell()
             return
 
         with open(filename, "rb") as fp:
@@ -1196,10 +1211,10 @@
                 raise RuntimeError('Compressed size larger than uncompressed size')
         # Seek backwards and write file header (which will now include
         # correct CRC and file sizes)
-        position = self.fp.tell()       # Preserve current position in file
+        self.start_dir = self.fp.tell()       # Preserve current position in file
         self.fp.seek(zinfo.header_offset, 0)
         self.fp.write(zinfo.FileHeader(zip64))
-        self.fp.seek(position, 0)
+        self.fp.seek(self.start_dir, 0)
         self.filelist.append(zinfo)
         self.NameToInfo[zinfo.filename] = zinfo
 
@@ -1228,6 +1243,7 @@
             zinfo.compress_type = compress_type
 
         zinfo.file_size = len(bytes)            # Uncompressed size
+        self.fp.seek(self.start_dir, 0)
         zinfo.header_offset = self.fp.tell()    # Start of header bytes
         self._writecheck(zinfo)
         self._didModify = True
@@ -1251,6 +1267,7 @@
             self.fp.write(struct.pack(fmt, zinfo.CRC, zinfo.compress_size,
                   zinfo.file_size))
         self.fp.flush()
+        self.start_dir = self.fp.tell()
         self.filelist.append(zinfo)
         self.NameToInfo[zinfo.filename] = zinfo
 
@@ -1266,7 +1283,7 @@
 
         try:
             if self.mode in ("w", "a") and self._didModify: # write ending records
-                pos1 = self.fp.tell()
+                self.fp.seek(self.start_dir, 0)
                 for zinfo in self.filelist:         # write central directory
                     dt = zinfo.date_time
                     dosdate = (dt[0] - 1980) << 9 | dt[1] << 5 | dt[2]
@@ -1329,8 +1346,8 @@
                 pos2 = self.fp.tell()
                 # Write end-of-zip-archive record
                 centDirCount = len(self.filelist)
-                centDirSize = pos2 - pos1
-                centDirOffset = pos1
+                centDirSize = pos2 - self.start_dir
+                centDirOffset = self.start_dir
                 requires_zip64 = None
                 if centDirCount > ZIP_FILECOUNT_LIMIT:
                     requires_zip64 = "Files count"
@@ -1366,8 +1383,13 @@
         finally:
             fp = self.fp
             self.fp = None
-            if not self._filePassed:
-                fp.close()
+            self._fpclose(fp)
+
+    def _fpclose(self, fp):
+        assert self._fileRefCnt > 0
+        self._fileRefCnt -= 1
+        if not self._fileRefCnt and not self._filePassed:
+            fp.close()
 
 
 class PyZipFile(ZipFile):
diff --git a/Misc/ACKS b/Misc/ACKS
index d44240f..5372ee7 100644
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -1010,6 +1010,7 @@
 Juan David Ibáñez Palomar
 Jan Palus
 Yongzhi Pan
+Martin Panter
 Mathias Panzenböck
 M. Papillon
 Peter Parente
diff --git a/Misc/NEWS b/Misc/NEWS
index 5e7a795..cb13dfd 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -2,6 +2,54 @@
 Python News
 +++++++++++
 
+What's New in Python 2.7.10?
+============================
+
+*Release date: XXXX-XX-XX*
+
+Core and Builtins
+-----------------
+
+Library
+-------
+
+- Issue #14099: ZipFile.open() no longer reopen the underlying file.  Objects
+  returned by ZipFile.open() can now operate independently of the ZipFile even
+  if the ZipFile was created by passing in a file-like object as the first
+  argument to the constructor.
+
+- Issue #21032. Fixed socket leak if HTTPConnection.getresponse() fails.
+  Original patch by Martin Panter.
+
+- Issue #22609: Constructors and update methods of mapping classes in the
+  collections module now accept the self keyword argument.
+
+Documentation
+-------------
+
+- Issue #21514: The documentation of the json module now refers to new JSON RFC
+  7159 instead of obsoleted RFC 4627.
+
+Tools/Demos
+-----------
+
+- Issue #22314: pydoc now works when the LINES environment variable is set.
+
+- Issue #18905: "pydoc -p 0" now outputs actually used port.  Based on patch by
+  Wieland Hoffmann.
+
+Tests
+-----
+
+- Issue #22943: bsddb tests are locale independend now.
+
+IDLE
+----
+
+- Issue #16893: Update Idle doc chapter to match current Idle and add new
+  information.
+
+
 What's New in Python 2.7.9?
 ===========================
 
@@ -100,7 +148,7 @@
 
 - Issue #22776: Brought excluded code into the scope of a try block in
   SysLogHandler.emit().
- 
+
 - Issue #17381: Fixed ranges handling in case-insensitive regular expressions.
 
 - Issue #19329: Optimized compiling charsets in regular expressions.
@@ -295,6 +343,23 @@
 IDLE
 ----
 
+- Issue #3068: Add Idle extension configuration dialog to Options menu.
+  Changes are written to HOME/.idlerc/config-extensions.cfg.
+  Original patch by Tal Einat.
+
+- Issue #16233: A module browser (File : Class Browser, Alt+C) requires a
+  editor window with a filename.  When Class Browser is requested otherwise,
+  from a shell, output window, or 'Untitled' editor, Idle no longer displays
+  an error box.  It now pops up an  Open Module box (Alt+M). If a valid name
+  is entered and a module is opened, a corresponding browser is also opened.
+
+- Issue #4832: Save As to type Python files automatically adds .py to the
+  name you enter (even if your system does not display it).  Some systems
+  automatically add .txt when type is Text files.
+
+- Issue #21986: Code objects are not normally pickled by the pickle module.
+  To match this, they are no longer pickled when running under Idle.
+
 - Issue #22221: IDLE now ignores the source encoding declaration on the second
   line if the first line contains anything except a comment.
 
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
index 4d0c8fa..379423c 100644
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -8496,7 +8496,7 @@
 
 
 /* This code is used to ensure that the tables of configuration value names
- * are in sorted order as required by conv_confname(), and also to build the
+ * are in sorted order as required by conv_confname(), and also to build
  * the exported dictionaries that are used to publish information about the
  * names available on the host platform.
  *
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index d0ac3ac..619ac9b 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -4798,7 +4798,7 @@
                      "%s.__new__(%s) is not safe, use %s.__new__()",
                      type->tp_name,
                      subtype->tp_name,
-                     staticbase == NULL ? "?" : staticbase->tp_name);
+                     staticbase->tp_name);
         return NULL;
     }
 
diff --git a/Python/pystrtod.c b/Python/pystrtod.c
index 859af43..ae6ab9c 100644
--- a/Python/pystrtod.c
+++ b/Python/pystrtod.c
@@ -324,7 +324,7 @@
 
    On overflow (e.g., when trying to convert '1e500' on an IEEE 754 machine),
    if overflow_exception is NULL then +-Py_HUGE_VAL is returned, and no Python
-   exception is raised.  Otherwise, overflow_exception should point to a
+   exception is raised.  Otherwise, overflow_exception should point to
    a Python exception, this exception will be raised, -1.0 will be returned,
    and *endptr will point just past the end of the converted value.
 
diff --git a/Python/random.c b/Python/random.c
index 0776bfc..1e5776d 100644
--- a/Python/random.c
+++ b/Python/random.c
@@ -274,7 +274,7 @@
 }
 
 /* Fill buffer with size pseudo-random bytes from the operating system random
-   number generator (RNG). It is suitable for for most cryptographic purposes
+   number generator (RNG). It is suitable for most cryptographic purposes
    except long living private keys for asymmetric encryption.
 
    Return 0 on success, raise an exception and return -1 on error. */
diff --git a/Python/thread.c b/Python/thread.c
index dd333e8..c54670d 100644
--- a/Python/thread.c
+++ b/Python/thread.c
@@ -271,7 +271,7 @@
         if (p->id == id && p->key == key)
             goto Done;
         /* Sanity check.  These states should never happen but if
-         * they do we must abort.  Otherwise we'll end up spinning in
+         * they do we must abort.  Otherwise we'll end up spinning
          * in a tight loop with the lock held.  A similar check is done
          * in pystate.c tstate_delete_common().  */
         if (p == prev_p)
diff --git a/Tools/msi/msi.py b/Tools/msi/msi.py
index 09105a2..074c9a5 100644
--- a/Tools/msi/msi.py
+++ b/Tools/msi/msi.py
@@ -912,9 +912,9 @@
                       ("Tk", "tk-8*", "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)
+        dirs = glob.glob(srcdir+"/externals/"+pat)
         if not dirs:
-            raise ValueError, "Could not find "+srcdir+"/../"+pat
+            raise ValueError, "Could not find "+srcdir+"/externals/"+pat
         if len(dirs) > 2:
             raise ValueError, "Multiple copies of "+pat
         dir = dirs[0]
@@ -1019,6 +1019,8 @@
         # Add additional files
         dirs[dir]=lib
         lib.glob("*.txt")
+        lib.glob("*.whl")
+        lib.glob("*.0")
         if dir=='site-packages':
             lib.add_file("README.txt", src="README")
             continue
@@ -1043,6 +1045,7 @@
             lib.add_file("check_soundcard.vbs")
             lib.add_file("empty.vbs")
             lib.add_file("Sine-1000Hz-300ms.aif")
+            lib.add_file("revocation.crl")
             lib.glob("*.uue")
             lib.glob("*.pem")
             lib.glob("*.pck")
@@ -1117,7 +1120,7 @@
             lib.start_component("TkDLLs", tcltk)
             lib.add_file("_tkinter.pyd")
             dlls.append("_tkinter.pyd")
-            tcldir = os.path.normpath(srcdir+("/../tcltk%s/bin" % tclsuffix))
+            tcldir = os.path.normpath(srcdir+("/externals/tcltk%s/bin" % tclsuffix))
             for f in glob.glob1(tcldir, "*.dll"):
                 lib.add_file(f, src=os.path.join(tcldir, f))
     # check whether there are any unknown extensions
@@ -1141,7 +1144,7 @@
         lib.add_file('libpython%s%s.a' % (major, minor))
     if have_tcl:
         # Add Tcl/Tk
-        tcldirs = [(root, '../tcltk%s/lib' % tclsuffix, 'tcl')]
+        tcldirs = [(root, 'externals/tcltk%s/lib' % tclsuffix, 'tcl')]
         tcltk.set_current()
         while tcldirs:
             parent, phys, dir = tcldirs.pop()
diff --git a/Tools/msi/uuids.py b/Tools/msi/uuids.py
index 2e4dc31..d8c426a 100644
--- a/Tools/msi/uuids.py
+++ b/Tools/msi/uuids.py
@@ -66,4 +66,6 @@
     '2.7.7121':'{5E0D187D-238B-4e96-9C75-C4CF141F5385}', # 2.7.7rc1
     '2.7.7150':'{049CA433-77A0-4e48-AC76-180A282C4E10}', # 2.7.7
     '2.7.8150':'{61121B12-88BD-4261-A6EE-AB32610A56DD}', # 2.7.8
+    '2.7.9121':'{AAB1E8FF-6D00-4409-8F13-BE365AB92FFE}', # 2.7.9rc1
+    '2.7.9150':'{79F081BF-7454-43DB-BD8F-9EE596813232}', # 2.7.9
 }