Merged revisions 62998-63003,63005-63006,63009-63012,63014-63017,63019-63020,63022-63024,63026-63029,63031-63041,63043-63045,63047-63054,63056-63062 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk

........
  r62998 | andrew.kuchling | 2008-05-10 15:51:55 -0400 (Sat, 10 May 2008) | 7 lines

  #1858 from Tarek Ziade:
  Allow multiple repositories in .pypirc; see http://wiki.python.org/moin/EnhancedPyPI
  for discussion.

  The patch is slightly revised from Tarek's last patch: I've simplified
  the PyPIRCCommand.finalize_options() method to not look at sys.argv.
  Tests still pass.
........
  r63000 | alexandre.vassalotti | 2008-05-10 15:59:16 -0400 (Sat, 10 May 2008) | 5 lines

  Cleaned up io._BytesIO.write().

  I am amazed that the old code, for inserting null-bytes, actually
  worked. Who wrote that thing? Oh, it is me... doh.
........
  r63002 | brett.cannon | 2008-05-10 16:52:01 -0400 (Sat, 10 May 2008) | 2 lines

  Revert r62998 as it broke the build (seems distutils.config is missing).
........
  r63014 | andrew.kuchling | 2008-05-10 18:12:38 -0400 (Sat, 10 May 2008) | 1 line

  #1858: add distutils.config module
........
  r63027 | brett.cannon | 2008-05-10 21:09:32 -0400 (Sat, 10 May 2008) | 2 lines

  Flesh out the 3.0 deprecation to suggest using the ctypes module.
........
  r63028 | skip.montanaro | 2008-05-10 22:59:30 -0400 (Sat, 10 May 2008) | 4 lines

  Copied two versions of the example from the interactive session.  Delete
  one.
........
  r63037 | georg.brandl | 2008-05-11 03:02:17 -0400 (Sun, 11 May 2008) | 2 lines

  reload() takes the module itself.
........
  r63038 | alexandre.vassalotti | 2008-05-11 03:06:04 -0400 (Sun, 11 May 2008) | 4 lines

  Added test framework for handling module renames.
  Factored the import guard in test_py3kwarn.TestStdlibRemovals into
  a context manager, namely test_support.CleanImport.
........
  r63039 | georg.brandl | 2008-05-11 03:06:05 -0400 (Sun, 11 May 2008) | 2 lines

  #2742: ``''`` is not converted to NULL in getaddrinfo.
........
  r63040 | alexandre.vassalotti | 2008-05-11 03:08:12 -0400 (Sun, 11 May 2008) | 2 lines

  Fixed typo in a comment of test_support.CleanImport.
........
  r63041 | alexandre.vassalotti | 2008-05-11 03:10:25 -0400 (Sun, 11 May 2008) | 2 lines

  Removed a dead line of code.
........
  r63043 | georg.brandl | 2008-05-11 04:47:53 -0400 (Sun, 11 May 2008) | 2 lines

  #2812: document property.getter/setter/deleter.
........
  r63049 | georg.brandl | 2008-05-11 05:06:30 -0400 (Sun, 11 May 2008) | 2 lines

  #1153769: document PEP 237 changes to string formatting.
........
  r63050 | georg.brandl | 2008-05-11 05:11:40 -0400 (Sun, 11 May 2008) | 2 lines

  #2809: elaborate str.split docstring a bit.
........
  r63051 | georg.brandl | 2008-05-11 06:13:59 -0400 (Sun, 11 May 2008) | 2 lines

  Fix typo.
........
  r63052 | georg.brandl | 2008-05-11 06:33:27 -0400 (Sun, 11 May 2008) | 2 lines

  #2709: clarification.
........
  r63053 | georg.brandl | 2008-05-11 06:42:28 -0400 (Sun, 11 May 2008) | 2 lines

  #2659: add ``break_on_hyphens`` to TextWrapper.
........
  r63057 | georg.brandl | 2008-05-11 06:59:39 -0400 (Sun, 11 May 2008) | 2 lines

  #2741: clarification of value range for address_family.
........
  r63058 | georg.brandl | 2008-05-11 07:09:35 -0400 (Sun, 11 May 2008) | 2 lines

  #2452: timeout is used for all blocking operations.
........
  r63059 | andrew.kuchling | 2008-05-11 09:33:56 -0400 (Sun, 11 May 2008) | 2 lines

  #1792: Improve performance of marshal.dumps() on large objects by increasing
  the size of the buffer more quickly.
........
  r63060 | andrew.kuchling | 2008-05-11 10:00:00 -0400 (Sun, 11 May 2008) | 1 line

  #1858: re-apply patch for this, adding the missing files
........
  r63061 | benjamin.peterson | 2008-05-11 10:13:25 -0400 (Sun, 11 May 2008) | 2 lines

  Add the "until" command to pdb
........
  r63062 | georg.brandl | 2008-05-11 10:17:13 -0400 (Sun, 11 May 2008) | 2 lines

  Add some sentence endings.
........
diff --git a/Doc/distutils/packageindex.rst b/Doc/distutils/packageindex.rst
index 8242012..ef81d64 100644
--- a/Doc/distutils/packageindex.rst
+++ b/Doc/distutils/packageindex.rst
@@ -55,11 +55,40 @@
 
 The format of the :file:`.pypirc` file is as follows::
 
-   [server-login]
+   [distutils]
+   index-servers =
+     pypi
+
+   [pypi]
    repository: <repository-url>
    username: <username>
    password: <password>
 
 *repository* can be omitted and defaults to ``http://www.python.org/pypi``.
 
+If you want to define another server a new section can be created::
 
+   [distutils]
+   index-servers =
+     pypi
+     other
+ 
+   [pypi]
+   repository: <repository-url>
+   username: <username>
+   password: <password>
+
+   [other]
+   repository: http://example.com/pypi
+   username: <username>
+   password: <password>
+
+The command can then be called with the -r option::
+
+   python setup.py register -r http://example.com/pypi
+
+Or even with the section name::
+
+   python setup.py register -r other
+
+ 
diff --git a/Doc/distutils/uploading.rst b/Doc/distutils/uploading.rst
index 5be4130..d960656 100644
--- a/Doc/distutils/uploading.rst
+++ b/Doc/distutils/uploading.rst
@@ -22,14 +22,20 @@
 from the :file:`$HOME/.pypirc` file (see section :ref:`pypirc` for more on this
 file).
 
+You can specify another PyPI server with the :option:`--repository=*url*` option::
+
+   python setup.py sdist bdist_wininst upload -r http://example.com/pypi
+
+See section :ref:`pypirc` for more on defining several servers.
+
 You can use the :option:`--sign` option to tell :command:`upload` to sign each
 uploaded file using GPG (GNU Privacy Guard).  The  :program:`gpg` program must
 be available for execution on the system :envvar:`PATH`.  You can also specify
 which key to use for signing using the :option:`--identity=*name*` option.
 
-Other :command:`upload` options include  :option:`--repository=*url*` (which
-lets you override the repository setting from :file:`$HOME/.pypirc`), and
+Other :command:`upload` options include  :option:`--repository=*url*` 
+or :option:`--repository=*section*` where `url` is the url of the server
+and `section` the name of the section in :file:`$HOME/.pypirc`, and
 :option:`--show-response` (which displays the full response text from the PyPI
 server for help in debugging upload problems).
 
-
diff --git a/Doc/library/bdb.rst b/Doc/library/bdb.rst
index f04b671..fefb2ad 100644
--- a/Doc/library/bdb.rst
+++ b/Doc/library/bdb.rst
@@ -207,6 +207,11 @@
 
       Stop when returning from the given frame.
 
+   .. method:: set_until(frame)
+
+      Stop when the line with the line no greater than the current one is
+      reached or when returning from current frame
+
    .. method:: set_trace([frame])
 
       Start debugging from *frame*.  If *frame* is not specified, debugging
diff --git a/Doc/library/ftplib.rst b/Doc/library/ftplib.rst
index 41bdcd8..99aae0d 100644
--- a/Doc/library/ftplib.rst
+++ b/Doc/library/ftplib.rst
@@ -40,11 +40,12 @@
 .. class:: FTP([host[, user[, passwd[, acct[, timeout]]]]])
 
    Return a new instance of the :class:`FTP` class.  When *host* is given, the
-   method call ``connect(host)`` is made.  When *user* is given, additionally 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 the connection attempt (if is not specified,
-   or passed as None, the global default timeout setting will be used).
+   method call ``connect(host)`` is made.  When *user* is given, additionally
+   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).
 
 
    .. attribute:: all_errors
@@ -122,9 +123,10 @@
    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 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.
 
 
 .. method:: FTP.getwelcome()
diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst
index 129aa3c..9ccc59c 100644
--- a/Doc/library/functions.rst
+++ b/Doc/library/functions.rst
@@ -848,10 +848,15 @@
    use is to define a managed attribute x::
 
       class C(object):
-          def __init__(self): self._x = None
-          def getx(self): return self._x
-          def setx(self, value): self._x = value
-          def delx(self): del self._x
+          def __init__(self):
+              self._x = None
+
+          def getx(self):
+              return self._x
+          def setx(self, value):
+              self._x = value
+          def delx(self):
+              del self._x
           x = property(getx, setx, delx, "I'm the 'x' property.")
 
    If given, *doc* will be the docstring of the property attribute. Otherwise, the
@@ -867,8 +872,36 @@
               """Get the current voltage."""
               return self._voltage
 
-   turns the :meth:`voltage` method into a "getter" for a read-only attribute with
-   the same name.
+   turns the :meth:`voltage` method into a "getter" for a read-only attribute
+   with the same name.
+
+   A property object has :attr:`getter`, :attr:`setter`, and :attr:`deleter`
+   methods usable as decorators that create a copy of the property with the
+   corresponding accessor function set to the decorated function.  This is
+   best explained with an example::
+
+      class C(object):
+          def __init__(self): self._x = None
+
+          @property
+          def x(self):
+              """I'm the 'x' property."""
+              return self._x
+
+          @x.setter
+          def x(self, value):
+              self._x = value
+
+          @x.deleter
+          def x(self):
+              del self._x
+
+   This code is exactly equivalent to the first example.  Be sure to give the
+   additional functions the same name as the original property (``x`` in this
+   case.)
+
+   The returned property also has the attributes ``fget``, ``fset``, and
+   ``fdel`` corresponding to the constructor arguments.
 
 
 .. XXX does accept objects with __index__ too
diff --git a/Doc/library/httplib.rst b/Doc/library/httplib.rst
index 03fe681..16b74ee 100644
--- a/Doc/library/httplib.rst
+++ b/Doc/library/httplib.rst
@@ -27,14 +27,14 @@
 .. class:: HTTPConnection(host[, port[, strict[, timeout]]])
 
    An :class:`HTTPConnection` instance represents one transaction with an HTTP
-   server.  It should be instantiated passing it a host and optional port number.
-   If no port number is passed, the port is extracted from the host string if it
-   has the form ``host:port``, else the default HTTP port (80) is used.  When True,
-   the optional parameter *strict* causes ``BadStatusLine`` to be raised if the
-   status line can't be parsed as a valid HTTP/1.0 or 1.1 status line.  If the
-   optional *timeout* parameter is given, connection attempts will timeout after
-   that many seconds (if it is not given or ``None``, the global default  timeout
-   setting is used).
+   server.  It should be instantiated passing it a host and optional port
+   number.  If no port number is passed, the port is extracted from the host
+   string if it has the form ``host:port``, else the default HTTP port (80) is
+   used.  When True, the optional parameter *strict* causes ``BadStatusLine`` to
+   be raised if the status line can't be parsed as a valid HTTP/1.0 or 1.1
+   status line.  If the optional *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).
 
    For example, the following calls all create instances that connect to the server
    at the same host and port::
diff --git a/Doc/library/pdb.rst b/Doc/library/pdb.rst
index df8cf6c..ba6c1b5 100644
--- a/Doc/library/pdb.rst
+++ b/Doc/library/pdb.rst
@@ -261,6 +261,12 @@
    inside a called function, while ``next`` executes called functions at (nearly)
    full speed, only stopping at the next line in the current function.)
 
+unt(il)
+   Continue execution until the line with the the line number greater than the
+   current one is reached or when returning from current frame.
+
+   .. versionadded:: 2.6
+
 r(eturn)
    Continue execution until the current function returns.
 
diff --git a/Doc/library/smtplib.rst b/Doc/library/smtplib.rst
index d4dd43f..602edb6 100644
--- a/Doc/library/smtplib.rst
+++ b/Doc/library/smtplib.rst
@@ -19,13 +19,14 @@
 
 .. class:: SMTP([host[, port[, local_hostname[, timeout]]]])
 
-   A :class:`SMTP` instance encapsulates an SMTP connection.  It has methods that
-   support a full repertoire of SMTP and ESMTP operations. If the optional host and
-   port parameters are given, the SMTP :meth:`connect` method is called 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 the connection attempt (if not specified, or
-   passed as None, the global default timeout setting will be used).
+   A :class:`SMTP` instance encapsulates an SMTP connection.  It has methods
+   that support a full repertoire of SMTP and ESMTP operations. If the optional
+   host and port parameters are given, the SMTP :meth:`connect` method is called
+   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).
 
    For normal use, you should only require the initialization/connect,
    :meth:`sendmail`, and :meth:`quit` methods.  An example is included below.
@@ -35,13 +36,14 @@
 
    A :class:`SMTP_SSL` instance behaves exactly the same as instances of
    :class:`SMTP`. :class:`SMTP_SSL` should be used for situations where SSL is
-   required from  the beginning of the connection and using :meth:`starttls` is not
-   appropriate. If *host* is not specified, the local host is used. If *port* is
-   omitted, the standard SMTP-over-SSL port (465) is used. *keyfile* and *certfile*
-   are also optional, 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 the connection attempt (if not specified, or passed as
-   None, the global default timeout setting will be used).
+   required from the beginning of the connection and using :meth:`starttls` is
+   not appropriate. If *host* is not specified, the local host is used. If
+   *port* is omitted, the standard SMTP-over-SSL port (465) is used. *keyfile*
+   and *certfile* are also optional, 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).
 
 
 .. class:: LMTP([host[, port[, local_hostname]]])
diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst
index d7164da..8fefce6 100644
--- a/Doc/library/socket.rst
+++ b/Doc/library/socket.rst
@@ -213,9 +213,9 @@
    service name (like ``'http'``), a numeric port number or ``None``.
 
    The rest of the arguments are optional and must be numeric if specified.  For
-   *host* and *port*, by passing either an empty string or ``None``, you can pass
-   ``NULL`` to the C API.  The :func:`getaddrinfo` function returns a list of
-   5-tuples with the following structure:
+   *host* and *port*, by passing ``None``, you can pass ``NULL`` to the C API.
+   The :func:`getaddrinfo` function returns a list of 5-tuples with the following
+   structure:
 
    ``(family, socktype, proto, canonname, sockaddr)``
 
@@ -785,7 +785,7 @@
    import socket
    import sys
 
-   HOST = ''                 # Symbolic name meaning all available interfaces
+   HOST = None               # Symbolic name meaning all available interfaces
    PORT = 50007              # Arbitrary non-privileged port
    s = None
    for res in socket.getaddrinfo(HOST, PORT, socket.AF_UNSPEC, socket.SOCK_STREAM, 0, socket.AI_PASSIVE):
@@ -847,7 +847,7 @@
 
    
 The last example shows how to write a very simple network sniffer with raw
-sockets on Windows. The example requires administrator priviliges to modify
+sockets on Windows. The example requires administrator privileges to modify
 the interface::
 
    import socket
diff --git a/Doc/library/socketserver.rst b/Doc/library/socketserver.rst
index b7ce818..e24b429 100644
--- a/Doc/library/socketserver.rst
+++ b/Doc/library/socketserver.rst
@@ -155,7 +155,7 @@
 .. data:: address_family
 
    The family of protocols to which the server's socket belongs.
-   :const:`socket.AF_INET` and :const:`socket.AF_UNIX` are two possible values.
+   Common examples are :const:`socket.AF_INET` and :const:`socket.AF_UNIX`.
 
 
 .. data:: RequestHandlerClass
@@ -199,7 +199,7 @@
 .. data:: socket_type
 
    The type of socket used by the server; :const:`socket.SOCK_STREAM` and
-   :const:`socket.SOCK_DGRAM` are two possible values.
+   :const:`socket.SOCK_DGRAM` are two common values.
 
 .. data:: timeout
 
diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst
index ce6aab3..09549ad 100644
--- a/Doc/library/stdtypes.rst
+++ b/Doc/library/stdtypes.rst
@@ -1114,7 +1114,7 @@
 +---------+---------------------------------------------------------------------+
 
 A length modifier (``h``, ``l``, or ``L``) may be present, but is ignored as it
-is not necessary for Python.
+is not necessary for Python -- so e.g. ``%ld`` is identical to ``%d``.
 
 The conversion types are:
 
@@ -1125,13 +1125,13 @@
 +------------+-----------------------------------------------------+-------+
 | ``'i'``    | Signed integer decimal.                             |       |
 +------------+-----------------------------------------------------+-------+
-| ``'o'``    | Unsigned octal.                                     | \(1)  |
+| ``'o'``    | Signed octal value.                                 | \(1)  |
 +------------+-----------------------------------------------------+-------+
-| ``'u'``    | Unsigned decimal.                                   |       |
+| ``'u'``    | Obselete type -- it is identical to ``'d'``.        | \(7)  |
 +------------+-----------------------------------------------------+-------+
-| ``'x'``    | Unsigned hexadecimal (lowercase).                   | \(2)  |
+| ``'x'``    | Signed hexadecimal (lowercase).                     | \(2)  |
 +------------+-----------------------------------------------------+-------+
-| ``'X'``    | Unsigned hexadecimal (uppercase).                   | \(2)  |
+| ``'X'``    | Signed hexadecimal (uppercase).                     | \(2)  |
 +------------+-----------------------------------------------------+-------+
 | ``'e'``    | Floating point exponential format (lowercase).      | \(3)  |
 +------------+-----------------------------------------------------+-------+
@@ -1193,6 +1193,9 @@
    The precision determines the maximal number of characters used.
 
 
+(7)
+   See :pep:`237`.
+
 Since Python strings have an explicit length, ``%s`` conversions do not assume
 that ``'\0'`` is the end of the string.
 
diff --git a/Doc/library/telnetlib.rst b/Doc/library/telnetlib.rst
index 4c8ce45..8c8ddbb 100644
--- a/Doc/library/telnetlib.rst
+++ b/Doc/library/telnetlib.rst
@@ -27,11 +27,12 @@
 
    :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 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 the connection attempt (if not
-   specified, or passed as None, the global default timeout setting will be used).
+   establish a connection.  Alternatively, the host name and optional port
+   number can be passed to the constructor, to, in which case the connection to
+   the server will be established before the constructor returns. The optional
+   *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).
 
    Do not reopen an already connected instance.
 
@@ -121,8 +122,9 @@
 
    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 the connection attempt (if not specified, or
-   passed as None, the global default timeout setting will be used).
+   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).
 
    Do not try to reopen an already connected instance.
 
diff --git a/Doc/library/tempfile.rst b/Doc/library/tempfile.rst
index 25d5acb..69b05ce 100644
--- a/Doc/library/tempfile.rst
+++ b/Doc/library/tempfile.rst
@@ -156,11 +156,6 @@
       :func:`NamedTemporaryFile`, passing it the  `delete=False` parameter::
 
          >>> f = NamedTemporaryFile(delete=False)
-         >>> print f.name
-         >>> f.write("Hello World!\n")
-         >>> f.close()
-         >>> os.unlink(f.name)
-         >>> f = NamedTemporaryFile(delete=False)
          >>> f
          <open file '<fdopen>', mode 'w+b' at 0x384698>
          >>> f.name
diff --git a/Doc/library/textwrap.rst b/Doc/library/textwrap.rst
index 243e43c..a18a801 100644
--- a/Doc/library/textwrap.rst
+++ b/Doc/library/textwrap.rst
@@ -39,6 +39,10 @@
 applications that wrap/fill many text strings, it will be more efficient for you
 to create your own :class:`TextWrapper` object.
 
+Text is preferably wrapped on whitespaces and right after the hyphens in
+hyphenated words; only then will long words be broken if necessary, unless
+:attr:`TextWrapper.break_long_words` is set to false.
+
 An additional utility function, :func:`dedent`, is provided to remove
 indentation from strings that have unwanted whitespace to the left of the text.
 
@@ -167,10 +171,22 @@
       than :attr:`width`.  (Long words will be put on a line by themselves, in
       order to minimize the amount by which :attr:`width` is exceeded.)
 
+
+   .. attribute:: break_on_hyphens
+
+      (default: ``True``) If true, wrapping will occur preferably on whitespaces
+      and right after hyphens in compound words, as it is customary in English.
+      If false, only whitespaces will be considered as potentially good places
+      for line breaks, but you need to set :attr:`break_long_words` to false if
+      you want truly insecable words.  Default behaviour in previous versions
+      was to always allow breaking hyphenated words.
+
+      .. versionadded:: 2.6
+
+
    :class:`TextWrapper` also provides two public methods, analogous to the
    module-level convenience functions:
 
-
    .. method:: wrap(text)
 
       Wraps the single paragraph in *text* (a string) so every line is at most
diff --git a/Doc/library/tk.rst b/Doc/library/tk.rst
index 3e2f100..8451f6d 100644
--- a/Doc/library/tk.rst
+++ b/Doc/library/tk.rst
@@ -23,7 +23,8 @@
 
 :mod:`Tkinter`'s chief virtues are that it is fast, and that it usually comes
 bundled with Python. Although it has been used to create some very good
-applications, including IDLE, it has weak documentation and an outdated look and
+applications, including IDLE, its standard documentation is weak (but there
+are some good books and tutorials), and it has an outdated look and
 feel. For more modern, better documented, and much more extensive GUI
 libraries, see the :ref:`other-gui-packages` section.
 
diff --git a/Doc/library/urllib2.rst b/Doc/library/urllib2.rst
index 7987007..143fe50 100644
--- a/Doc/library/urllib2.rst
+++ b/Doc/library/urllib2.rst
@@ -26,10 +26,10 @@
    :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 the
-   connection attempt (if not specified, or passed as None, the global default
-   timeout setting will be used). This actually only work for HTTP, HTTPS, FTP and
-   FTPS connections.
+   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.
 
    This function returns a file-like object with two additional methods:
 
@@ -399,12 +399,13 @@
 .. 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 the connection  attempt (if not
-   specified, or passed as None, the global default timeout  setting will be used;
-   this actually only work for HTTP, HTTPS, FTP and FTPS connections).
+   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, or passed as
+   ``None``, the global default timeout setting will be used; this actually only
+   works for HTTP, HTTPS, FTP and FTPS connections).
 
 
 .. method:: OpenerDirector.error(proto[, arg[, ...]])
diff --git a/Doc/tutorial/modules.rst b/Doc/tutorial/modules.rst
index 4d06df2..68e0258 100644
--- a/Doc/tutorial/modules.rst
+++ b/Doc/tutorial/modules.rst
@@ -111,7 +111,7 @@
    For efficiency reasons, each module is only imported once per interpreter
    session.  Therefore, if you change your modules, you must restart the
    interpreter -- or, if it's just one module you want to test interactively,
-   use :func:`reload`, e.g. ``reload('modulename')``.
+   use :func:`reload`, e.g. ``reload(modulename)``.
 
 
 .. _tut-modulesasscripts:
diff --git a/Lib/bdb.py b/Lib/bdb.py
index e55031e..b8a20ec 100644
--- a/Lib/bdb.py
+++ b/Lib/bdb.py
@@ -37,9 +37,7 @@
         import linecache
         linecache.checkcache()
         self.botframe = None
-        self.stopframe = None
-        self.returnframe = None
-        self.quitting = 0
+        self._set_stopinfo(None, None)
 
     def trace_dispatch(self, frame, event, arg):
         if self.quitting:
@@ -100,7 +98,7 @@
         # (CT) stopframe may now also be None, see dispatch_call.
         # (CT) the former test for None is therefore removed from here.
         if frame is self.stopframe:
-            return True
+            return frame.f_lineno >= self.stoplineno
         while frame is not None and frame is not self.stopframe:
             if frame is self.botframe:
                 return True
@@ -156,26 +154,31 @@
         but only if we are to stop at or just below this level."""
         pass
 
+    def _set_stopinfo(self, stopframe, returnframe, stoplineno=-1):
+        self.stopframe = stopframe
+        self.returnframe = returnframe
+        self.quitting = 0
+        self.stoplineno = stoplineno
+
     # Derived classes and clients can call the following methods
     # to affect the stepping state.
 
+    def set_until(self, frame): #the name "until" is borrowed from gdb
+        """Stop when the line with the line no greater than the current one is
+        reached or when returning from current frame"""
+        self._set_stopinfo(frame, frame, frame.f_lineno+1)
+
     def set_step(self):
         """Stop after one line of code."""
-        self.stopframe = None
-        self.returnframe = None
-        self.quitting = 0
+        self._set_stopinfo(None,None)
 
     def set_next(self, frame):
         """Stop on the next line in or below the given frame."""
-        self.stopframe = frame
-        self.returnframe = None
-        self.quitting = 0
+        self._set_stopinfo(frame, None)
 
     def set_return(self, frame):
         """Stop when returning from the given frame."""
-        self.stopframe = frame.f_back
-        self.returnframe = frame
-        self.quitting = 0
+        self._set_stopinfo(frame.f_back, frame)
 
     def set_trace(self, frame=None):
         """Start debugging from `frame`.
@@ -194,9 +197,7 @@
 
     def set_continue(self):
         # Don't stop except at breakpoints or when finished
-        self.stopframe = self.botframe
-        self.returnframe = None
-        self.quitting = 0
+        self._set_stopinfo(self.botframe, None)
         if not self.breaks:
             # no breakpoints; run without debugger overhead
             sys.settrace(None)
diff --git a/Lib/distutils/command/register.py b/Lib/distutils/command/register.py
index b6a36f5..89cb2d4 100644
--- a/Lib/distutils/command/register.py
+++ b/Lib/distutils/command/register.py
@@ -8,42 +8,34 @@
 __revision__ = "$Id$"
 
 import os, string, urllib2, getpass, urlparse
-import io, configparser
+import io
 
-from distutils.core import Command
+from distutils.core import PyPIRCCommand
 from distutils.errors import *
+from distutils import log
 
 def raw_input(prompt):
     sys.stdout.write(prompt)
     sys.stdout.flush()
     return sys.stdin.readline()
 
-class register(Command):
+class register(PyPIRCCommand):
 
     description = ("register the distribution with the Python package index")
-
-    DEFAULT_REPOSITORY = 'http://pypi.python.org/pypi'
-
-    user_options = [
-        ('repository=', 'r',
-         "url of repository [default: %s]"%DEFAULT_REPOSITORY),
+    user_options = PyPIRCCommand.user_options + [
         ('list-classifiers', None,
          'list the valid Trove classifiers'),
-        ('show-response', None,
-         'display full response text from server'),
         ]
-    boolean_options = ['verify', 'show-response', 'list-classifiers']
+    boolean_options = PyPIRCCommand.boolean_options + [
+        'verify', 'list-classifiers']
 
     def initialize_options(self):
-        self.repository = None
-        self.show_response = 0
+        PyPIRCCommand.initialize_options(self)
         self.list_classifiers = 0
 
-    def finalize_options(self):
-        if self.repository is None:
-            self.repository = self.DEFAULT_REPOSITORY
-
     def run(self):
+        self.finalize_options()
+        self._set_config()
         self.check_metadata()
         if self.dry_run:
             self.verify_metadata()
@@ -82,6 +74,23 @@
                       "or (maintainer and maintainer_email) " +
                       "must be supplied")
 
+    def _set_config(self):
+        ''' Reads the configuration file and set attributes.
+        '''
+        config = self._read_pypirc()
+        if config != {}:
+            self.username = config['username']
+            self.password = config['password']
+            self.repository = config['repository']
+            self.realm = config['realm']
+            self.has_config = True
+        else:
+            if self.repository not in ('pypi', self.DEFAULT_REPOSITORY):
+                raise ValueError('%s not found in .pypirc' % self.repository)
+            if self.repository == 'pypi':
+                self.repository = self.DEFAULT_REPOSITORY
+            self.has_config = False
+
     def classifiers(self):
         ''' Fetch the list of classifiers from the server.
         '''
@@ -95,6 +104,7 @@
         (code, result) = self.post_to_server(self.build_post_data('verify'))
         print('Server response (%s): %s'%(code, result))
 
+
     def send_metadata(self):
         ''' Send the metadata to the package index server.
 
@@ -104,10 +114,14 @@
 
             First we try to read the username/password from $HOME/.pypirc,
             which is a ConfigParser-formatted file with a section
-            [server-login] containing username and password entries (both
+            [distutils] containing username and password entries (both
             in clear text). Eg:
 
-                [server-login]
+                [distutils]
+                index-servers =
+                    pypi
+
+                [pypi]
                 username: fred
                 password: sekrit
 
@@ -119,21 +133,15 @@
              3. set the password to a random string and email the user.
 
         '''
-        choice = 'x'
-        username = password = ''
-
         # see if we can short-cut and get the username/password from the
         # config
-        config = None
-        if 'HOME' in os.environ:
-            rc = os.path.join(os.environ['HOME'], '.pypirc')
-            if os.path.exists(rc):
-                print('Using PyPI login from %s'%rc)
-                config = ConfigParser.ConfigParser()
-                config.read(rc)
-                username = config.get('server-login', 'username')
-                password = config.get('server-login', 'password')
-                choice = '1'
+        if self.has_config:
+            choice = '1'
+            username = self.username
+            password = self.password
+        else:
+            choice = 'x'
+            username = password = ''
 
         # get the user's login info
         choices = '1 2 3 4'.split()
@@ -160,32 +168,24 @@
             # set up the authentication
             auth = urllib2.HTTPPasswordMgr()
             host = urlparse.urlparse(self.repository)[1]
-            auth.add_password('pypi', host, username, password)
-
+            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'),
                 auth)
             print('Server response (%s): %s'%(code, result))
 
             # possibly save the login
-            if 'HOME' in os.environ and config is None and code == 200:
-                rc = os.path.join(os.environ['HOME'], '.pypirc')
+            if not self.has_config and code == 200:
                 print('I can store your PyPI login so future submissions will be faster.')
-                print('(the login will be stored in %s)'%rc)
+                print('(the login will be stored in %s)' % self._get_rc_file())
                 choice = 'X'
                 while choice.lower() not in 'yn':
                     choice = raw_input('Save your login (y/N)?')
                     if not choice:
                         choice = 'n'
                 if choice.lower() == 'y':
-                    f = open(rc, 'w')
-                    f.write('[server-login]\nusername:%s\npassword:%s\n'%(
-                        username, password))
-                    f.close()
-                    try:
-                        os.chmod(rc, 0o600)
-                    except:
-                        pass
+                    self._store_pypirc(username, password)
+
         elif choice == '2':
             data = {':action': 'user'}
             data['name'] = data['password'] = data['email'] = ''
@@ -248,7 +248,8 @@
     def post_to_server(self, data, auth=None):
         ''' Post a query to the server, and return a string response.
         '''
-
+        self.announce('Registering %s to %s' % (data['name'],
+                                                self.repository), log.INFO)
         # Build up the MIME payload for the urllib2 POST data
         boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254'
         sep_boundary = '\n--' + boundary
diff --git a/Lib/distutils/command/upload.py b/Lib/distutils/command/upload.py
index 23999ae..603336c 100644
--- a/Lib/distutils/command/upload.py
+++ b/Lib/distutils/command/upload.py
@@ -3,7 +3,7 @@
 Implements the Distutils 'upload' subcommand (upload package to PyPI)."""
 
 from distutils.errors import *
-from distutils.core import Command
+from distutils.core import PyPIRCCommand
 from distutils.spawn import spawn
 from distutils import log
 from hashlib import md5
@@ -15,53 +15,38 @@
 import base64
 import urlparse
 
-class upload(Command):
+class upload(PyPIRCCommand):
 
     description = "upload binary package to PyPI"
 
-    DEFAULT_REPOSITORY = 'http://pypi.python.org/pypi'
-
-    user_options = [
-        ('repository=', 'r',
-         "url of repository [default: %s]" % DEFAULT_REPOSITORY),
-        ('show-response', None,
-         'display full response text from server'),
+    user_options = PyPIRCCommand.user_options + [
         ('sign', 's',
          'sign files to upload using gpg'),
         ('identity=', 'i', 'GPG identity used to sign files'),
         ]
-    boolean_options = ['show-response', 'sign']
+
+    boolean_options = PyPIRCCommand.boolean_options + ['sign']
 
     def initialize_options(self):
+        PyPIRCCommand.initialize_options(self)
         self.username = ''
         self.password = ''
-        self.repository = ''
         self.show_response = 0
         self.sign = False
         self.identity = None
 
     def finalize_options(self):
+        PyPIRCCommand.finalize_options(self)
         if self.identity and not self.sign:
             raise DistutilsOptionError(
                 "Must use --sign for --identity to have meaning"
             )
-        if 'HOME' in os.environ:
-            rc = os.path.join(os.environ['HOME'], '.pypirc')
-            if os.path.exists(rc):
-                self.announce('Using PyPI login from %s' % rc)
-                config = ConfigParser.ConfigParser({
-                        'username':'',
-                        'password':'',
-                        'repository':''})
-                config.read(rc)
-                if not self.repository:
-                    self.repository = config.get('server-login', 'repository')
-                if not self.username:
-                    self.username = config.get('server-login', 'username')
-                if not self.password:
-                    self.password = config.get('server-login', 'password')
-        if not self.repository:
-            self.repository = self.DEFAULT_REPOSITORY
+        config = self._read_pypirc()
+        if config != {}:
+            self.username = config['username']
+            self.password = config['password']
+            self.repository = config['repository']
+            self.realm = config['realm']
 
     def run(self):
         if not self.distribution.dist_files:
diff --git a/Lib/distutils/config.py b/Lib/distutils/config.py
index e9ba402..a625aec 100644
--- a/Lib/distutils/config.py
+++ b/Lib/distutils/config.py
@@ -49,7 +49,7 @@
         finally:
             f.close()
         try:
-            os.chmod(rc, 0600)
+            os.chmod(rc, 0o600)
         except OSError:
             # should do something better here
             pass
@@ -58,7 +58,7 @@
         """Reads the .pypirc file."""
         rc = self._get_rc_file()
         if os.path.exists(rc):
-            print 'Using PyPI login from %s' % rc
+            print('Using PyPI login from %s' % rc)
             repository = self.repository or self.DEFAULT_REPOSITORY
             realm = self.realm or self.DEFAULT_REALM
 
diff --git a/Lib/distutils/core.py b/Lib/distutils/core.py
index a4c5e18..6e48920 100644
--- a/Lib/distutils/core.py
+++ b/Lib/distutils/core.py
@@ -17,6 +17,7 @@
 # Mainly import these so setup scripts can "from distutils.core import" them.
 from distutils.dist import Distribution
 from distutils.cmd import Command
+from distutils.config import PyPIRCCommand
 from distutils.extension import Extension
 
 # This is a barebones help message generated displayed when the user
diff --git a/Lib/distutils/dist.py b/Lib/distutils/dist.py
index 847eb90..ddde909 100644
--- a/Lib/distutils/dist.py
+++ b/Lib/distutils/dist.py
@@ -334,10 +334,9 @@
             user_filename = "pydistutils.cfg"
 
         # And look for the user config file
-        if 'HOME' in os.environ:
-            user_file = os.path.join(os.environ.get('HOME'), user_filename)
-            if os.path.isfile(user_file):
-                files.append(user_file)
+        user_file = os.path.join(os.path.expanduser('~'), user_filename)
+        if os.path.isfile(user_file):
+            files.append(user_file)
 
         # All platforms support local setup.cfg
         local_file = "setup.cfg"
diff --git a/Lib/distutils/tests/test_config.py b/Lib/distutils/tests/test_config.py
new file mode 100644
index 0000000..016ba4c
--- /dev/null
+++ b/Lib/distutils/tests/test_config.py
@@ -0,0 +1,103 @@
+"""Tests for distutils.pypirc.pypirc."""
+import sys
+import os
+import unittest
+
+from distutils.core import PyPIRCCommand
+from distutils.core import Distribution
+
+from distutils.tests import support
+
+PYPIRC = """\
+[distutils]
+
+index-servers =
+    server1
+    server2
+
+[server1]
+username:me
+password:secret
+
+[server2]
+username:meagain
+password: secret
+realm:acme
+repository:http://another.pypi/
+"""
+
+PYPIRC_OLD = """\
+[server-login]
+username:tarek
+password:secret
+"""
+
+class PyPIRCCommandTestCase(support.TempdirManager, unittest.TestCase):
+
+    def setUp(self):
+        """Patches the environment."""
+        if 'HOME' in os.environ:
+            self._old_home = os.environ['HOME']
+        else:
+            self._old_home = None
+        curdir = os.path.dirname(__file__)
+        os.environ['HOME'] = curdir
+        self.rc = os.path.join(curdir, '.pypirc')
+        self.dist = Distribution()
+
+        class command(PyPIRCCommand):
+            def __init__(self, dist):
+                PyPIRCCommand.__init__(self, dist)
+            def initialize_options(self):
+                pass
+            finalize_options = initialize_options
+
+        self._cmd = command
+
+    def tearDown(self):
+        """Removes the patch."""
+        if self._old_home is None:
+            del os.environ['HOME']
+        else:
+            os.environ['HOME'] = self._old_home
+        if os.path.exists(self.rc):
+            os.remove(self.rc)
+
+    def test_server_registration(self):
+        # This test makes sure PyPIRCCommand knows how to:
+        # 1. handle several sections in .pypirc
+        # 2. handle the old format
+
+        # new format
+        f = open(self.rc, 'w')
+        try:
+            f.write(PYPIRC)
+        finally:
+            f.close()
+
+        cmd = self._cmd(self.dist)
+        config = cmd._read_pypirc()
+
+        config = list(sorted(config.items()))
+        waited = [('password', 'secret'), ('realm', 'pypi'),
+                  ('repository', 'http://pypi.python.org/pypi'),
+                  ('server', 'server1'), ('username', 'me')]
+        self.assertEquals(config, waited)
+
+        # old format
+        f = open(self.rc, 'w')
+        f.write(PYPIRC_OLD)
+        f.close()
+
+        config = cmd._read_pypirc()
+        config = list(sorted(config.items()))
+        waited = [('password', 'secret'), ('realm', 'pypi'),
+                  ('repository', 'http://pypi.python.org/pypi'),
+                  ('server', 'server-login'), ('username', 'tarek')]
+        self.assertEquals(config, waited)
+
+def test_suite():
+    return unittest.makeSuite(PyPIRCCommandTestCase)
+
+if __name__ == "__main__":
+    unittest.main(defaultTest="test_suite")
diff --git a/Lib/distutils/tests/test_dist.py b/Lib/distutils/tests/test_dist.py
index 91acf45..81459ac 100644
--- a/Lib/distutils/tests/test_dist.py
+++ b/Lib/distutils/tests/test_dist.py
@@ -55,6 +55,7 @@
         self.assertEqual(d.get_command_packages(), ["distutils.command"])
 
     def test_command_packages_cmdline(self):
+        from distutils.tests.test_dist import test_dist
         sys.argv.extend(["--command-packages",
                          "foo.bar,distutils.tests",
                          "test_dist",
@@ -179,9 +180,54 @@
         dist.metadata.write_pkg_file(sio)
         return sio.getvalue()
 
+    def test_custom_pydistutils(self):
+        # fixes #2166
+        # make sure pydistutils.cfg is found
+        old = {}
+        for env in ('HOME', 'HOMEPATH', 'HOMEDRIVE'):
+            value = os.environ.get(env)
+            old[env] = value
+            if value is not None:
+                del os.environ[env]
+
+        if os.name == 'posix':
+            user_filename = ".pydistutils.cfg"
+        else:
+            user_filename = "pydistutils.cfg"
+
+        curdir = os.path.dirname(__file__)
+        user_filename = os.path.join(curdir, user_filename)
+        f = open(user_filename, 'w')
+        f.write('.')
+        f.close()
+
+        try:
+            dist = distutils.dist.Distribution()
+
+            # linux-style
+            if sys.platform in ('linux', 'darwin'):
+                os.environ['HOME'] = curdir
+                files = dist.find_config_files()
+                self.assert_(user_filename in files)
+
+            # win32-style
+            if sys.platform == 'win32':
+                # home drive should be found
+                os.environ['HOMEPATH'] = curdir
+                files = dist.find_config_files()
+                self.assert_(user_filename in files)
+        finally:
+            for key, value in old.items():
+                if value is None:
+                    continue
+                os.environ[key] = value
+            os.remove(user_filename)
 
 def test_suite():
     suite = unittest.TestSuite()
     suite.addTest(unittest.makeSuite(DistributionTestCase))
     suite.addTest(unittest.makeSuite(MetadataTestCase))
     return suite
+
+if __name__ == "__main__":
+    unittest.main(defaultTest="test_suite")
diff --git a/Lib/distutils/tests/test_upload.py b/Lib/distutils/tests/test_upload.py
new file mode 100644
index 0000000..b05ab1f
--- /dev/null
+++ b/Lib/distutils/tests/test_upload.py
@@ -0,0 +1,34 @@
+"""Tests for distutils.command.upload."""
+import sys
+import os
+import unittest
+
+from distutils.command.upload import upload
+from distutils.core import Distribution
+
+from distutils.tests import support
+from distutils.tests.test_config import PYPIRC, PyPIRCCommandTestCase
+
+class uploadTestCase(PyPIRCCommandTestCase):
+
+    def test_finalize_options(self):
+
+        # new format
+        f = open(self.rc, 'w')
+        f.write(PYPIRC)
+        f.close()
+
+        dist = Distribution()
+        cmd = upload(dist)
+        cmd.finalize_options()
+        for attr, waited in (('username', 'me'), ('password', 'secret'),
+                             ('realm', 'pypi'),
+                             ('repository', 'http://pypi.python.org/pypi')):
+            self.assertEquals(getattr(cmd, attr), waited)
+
+
+def test_suite():
+    return unittest.makeSuite(uploadTestCase)
+
+if __name__ == "__main__":
+    unittest.main(defaultTest="test_suite")
diff --git a/Lib/io.py b/Lib/io.py
index d5c8dfe..207e428 100644
--- a/Lib/io.py
+++ b/Lib/io.py
@@ -813,14 +813,14 @@
         n = len(b)
         if n == 0:
             return 0
-        newpos = self._pos + n
-        if newpos > len(self._buffer):
+        pos = self._pos
+        if pos > len(self._buffer):
             # Inserts null bytes between the current end of the file
             # and the new write position.
-            padding = b'\x00' * (newpos - len(self._buffer) - n)
-            self._buffer[self._pos:newpos - n] = padding
-        self._buffer[self._pos:newpos] = b
-        self._pos = newpos
+            padding = b'\x00' * (pos - len(self._buffer))
+            self._buffer += padding
+        self._buffer[pos:pos + n] = b
+        self._pos += n
         return n
 
     def seek(self, pos, whence=0):
diff --git a/Lib/pdb.doc b/Lib/pdb.doc
index c513954..0d32800 100644
--- a/Lib/pdb.doc
+++ b/Lib/pdb.doc
@@ -128,6 +128,10 @@
         Continue execution until the next line in the current function
         is reached or it returns.
 
+unt(il)
+        Continue execution until the line with a number greater than the 
+        current one is reached or until the current frame returns.
+
 r(eturn)
         Continue execution until the current function returns.
 
diff --git a/Lib/pdb.py b/Lib/pdb.py
index d77ea28..7e1edb5 100755
--- a/Lib/pdb.py
+++ b/Lib/pdb.py
@@ -611,6 +611,11 @@
             self.lineno = None
     do_d = do_down
 
+    def do_until(self, arg):
+        self.set_until(self.curframe)
+        return 1
+    do_unt = do_until
+
     def do_step(self, arg):
         self.set_step()
         return 1
@@ -958,6 +963,14 @@
 Execute the current line, stop at the first possible occasion
 (either in a function that is called or in the current function).""", file=self.stdout)
 
+    def help_until(self):
+        self.help_unt()
+
+    def help_unt(self):
+        print("""unt(il)
+Continue execution until the line with a number greater than the current
+one is reached or until the current frame returns""")
+
     def help_next(self):
         self.help_n()
 
diff --git a/Lib/test/test_marshal.py b/Lib/test/test_marshal.py
index 66545e0..838207a 100644
--- a/Lib/test/test_marshal.py
+++ b/Lib/test/test_marshal.py
@@ -199,6 +199,14 @@
             subtyp = type('subtyp', (typ,), {})
             self.assertRaises(ValueError, marshal.dumps, subtyp())
 
+    # Issue #1792 introduced a change in how marshal increases the size of its
+    # internal buffer; this test ensures that the new code is exercised.
+    def test_large_marshal(self):
+        size = int(1e6)
+        testString = 'abc' * size
+        marshal.dumps(testString)
+
+
 def test_main():
     test_support.run_unittest(IntTestCase,
                               FloatTestCase,
diff --git a/Lib/test/test_support.py b/Lib/test/test_support.py
index 27a01ea..c4084bb 100644
--- a/Lib/test/test_support.py
+++ b/Lib/test/test_support.py
@@ -409,6 +409,39 @@
         module.showwarning = original_showwarning
         module.filters = original_filters
 
+
+class CleanImport(object):
+    """Context manager to force import to return a new module reference.
+
+    This is useful for testing module-level behaviours, such as
+    the emission of a DepreciationWarning on import.
+
+    Use like this:
+
+        with CleanImport("foo"):
+            __import__("foo") # new reference
+    """
+
+    def __init__(self, *module_names):
+        self.original_modules = sys.modules.copy()
+        for module_name in module_names:
+            if module_name in sys.modules:
+                module = sys.modules[module_name]
+                # It is possible that module_name is just an alias for
+                # another module (e.g. stub for modules renamed in 3.x).
+                # In that case, we also need delete the real module to clear
+                # the import cache.
+                if module.__name__ != module_name:
+                    del sys.modules[module.__name__]
+                del sys.modules[module_name]
+
+    def __enter__(self):
+        return self
+
+    def __exit__(self, *ignore_exc):
+        sys.modules.update(self.original_modules)
+
+
 class EnvironmentVarGuard(object):
 
     """Class to help protect the environment variable properly.  Can be used as
diff --git a/Lib/test/test_textwrap.py b/Lib/test/test_textwrap.py
index dc97d40..1a9761a 100644
--- a/Lib/test/test_textwrap.py
+++ b/Lib/test/test_textwrap.py
@@ -351,6 +351,14 @@
              ["Hello", " ", "there", " ", "--", " ", "you", " ", "goof-",
               "ball,", " ", "use", " ", "the", " ", "-b", " ",  "option!"])
 
+    def test_break_on_hyphens(self):
+        # Ensure that the break_on_hyphens attributes work
+        text = "yaba daba-doo"
+        self.check_wrap(text, 10, ["yaba daba-", "doo"],
+                        break_on_hyphens=True)
+        self.check_wrap(text, 10, ["yaba", "daba-doo"],
+                        break_on_hyphens=False)
+
     def test_bad_width(self):
         # Ensure that width <= 0 is caught.
         text = "Whatever, it doesn't matter."
diff --git a/Lib/textwrap.py b/Lib/textwrap.py
index b5f87efc..6a2021d 100644
--- a/Lib/textwrap.py
+++ b/Lib/textwrap.py
@@ -55,6 +55,10 @@
       break_long_words (default: true)
         Break words longer than 'width'.  If false, those words will not
         be broken, and some lines might be longer than 'width'.
+      break_on_hyphens (default: true)
+        Allow breaking hyphenated words. If true, wrapping will occur
+        preferably on whitespaces and right after hyphens part of
+        compound words.
       drop_whitespace (default: true)
         Drop leading and trailing whitespace from lines.
     """
@@ -75,11 +79,18 @@
         r'[^\s\w]*\w+[a-zA-Z]-(?=\w+[a-zA-Z])|'   # hyphenated words
         r'(?<=[\w\!\"\'\&\.\,\?])-{2,}(?=\w))')   # em-dash
 
-    # XXX this is not locale-aware
+    # This less funky little regex just split on recognized spaces. E.g.
+    #   "Hello there -- you goof-ball, use the -b option!"
+    # splits into
+    #   Hello/ /there/ /--/ /you/ /goof-ball,/ /use/ /the/ /-b/ /option!/
+    wordsep_simple_re = re.compile(r'(\s+)')
+
+    # XXX this is not locale- or charset-aware -- string.lowercase
+    # is US-ASCII only (and therefore English-only)
     sentence_end_re = re.compile(r'[a-z]'             # lowercase letter
                                  r'[\.\!\?]'          # sentence-ending punct.
                                  r'[\"\']?'           # optional end-of-quote
-                                 r'\Z')                # end of chunk
+                                 r'\Z')               # end of chunk
 
 
     def __init__(self,
@@ -90,7 +101,8 @@
                  replace_whitespace=True,
                  fix_sentence_endings=False,
                  break_long_words=True,
-                 drop_whitespace=True):
+                 drop_whitespace=True,
+                 break_on_hyphens=True):
         self.width = width
         self.initial_indent = initial_indent
         self.subsequent_indent = subsequent_indent
@@ -99,6 +111,7 @@
         self.fix_sentence_endings = fix_sentence_endings
         self.break_long_words = break_long_words
         self.drop_whitespace = drop_whitespace
+        self.break_on_hyphens = break_on_hyphens
 
 
     # -- Private methods -----------------------------------------------
@@ -128,8 +141,15 @@
         breaks into the following chunks:
           'Look,', ' ', 'goof-', 'ball', ' ', '--', ' ',
           'use', ' ', 'the', ' ', '-b', ' ', 'option!'
+        if break_on_hyphens is True, or in:
+          'Look,', ' ', 'goof-ball', ' ', '--', ' ',
+          'use', ' ', 'the', ' ', '-b', ' ', option!'
+        otherwise.
         """
-        chunks = self.wordsep_re.split(text)
+        if self.break_on_hyphens is True:
+            chunks = self.wordsep_re.split(text)
+        else:
+            chunks = self.wordsep_simple_re.split(text)
         chunks = [c for c in chunks if c]
         return chunks
 
diff --git a/Misc/ACKS b/Misc/ACKS
index 4aa0101..19210a0 100644
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -588,6 +588,7 @@
 Hajime Saitou
 Rich Salz
 Kevin Samborn
+Ilya Sandler
 Ty Sarna
 Ben Sayer
 Michael Scharf
@@ -757,3 +758,4 @@
 Uwe Zessin
 Amaury Forgeot d'Arc
 Peter Åstrand
+Tarek ZiadĀŽ
diff --git a/Misc/NEWS b/Misc/NEWS
index 31b2678..3208a69 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -28,13 +28,15 @@
 Library
 -------
 
-- The ConfigParser module has been renamed to configparser.
+- #2659: Added ``break_on_hyphens`` option to textwrap TextWrapper class.
 
 - Issue #2487: change the semantics of math.ldexp(x, n) when n is too
   large to fit in a C long.  ldexp(x, n) now returns a zero (with
   suitable sign) if n is large and negative; previously, it raised
   OverflowError.
 
+- The ConfigParser module has been renamed to configparser.
+
 - Issue 2865: webbrowser.open() works again in a KDE environment.
 
 - The multifile module has been removed.
@@ -71,6 +73,8 @@
 
 - os.path.walk has been removed in favor of os.walk
 
+- pdb gained the "until" command.
+
 Build
 -----
 
diff --git a/Objects/stringobject.c b/Objects/stringobject.c
index 3aee28e..0cc48c3 100644
--- a/Objects/stringobject.c
+++ b/Objects/stringobject.c
@@ -1134,8 +1134,8 @@
 "B.split([sep[, maxsplit]]) -> list of bytes\n\
 \n\
 Return a list of the sections in B, using sep as the delimiter.\n\
-If sep is not given, B is split on ASCII whitespace characters\n\
-(space, tab, return, newline, formfeed, vertical tab).\n\
+If sep is not specified or is None, B is split on ASCII whitespace\n\
+characters (space, tab, return, newline, formfeed, vertical tab).\n\
 If maxsplit is given, at most maxsplit splits are done.");
 
 static PyObject *
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index 08e832f..9ea9a88 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -7729,8 +7729,9 @@
 \n\
 Return a list of the words in S, using sep as the\n\
 delimiter string.  If maxsplit is given, at most maxsplit\n\
-splits are done. If sep is not specified or is None,\n\
-any whitespace string is a separator.");
+splits are done. If sep is not specified or is None, any\n\
+whitespace string is a separator and leading and trailing\n\
+whitespace is stripped before splitting.");
 
 static PyObject*
 unicode_split(PyUnicodeObject *self, PyObject *args)
diff --git a/Python/marshal.c b/Python/marshal.c
index 22f84a8..ce828da 100644
--- a/Python/marshal.c
+++ b/Python/marshal.c
@@ -68,7 +68,10 @@
 	if (p->str == NULL)
 		return; /* An error already occurred */
 	size = PyString_Size(p->str);
-	newsize = size + 1024;
+	newsize = size + size + 1024;
+	if (newsize > 32*1024*1024) {
+		newsize = size + 1024*1024;
+	}
 	if (_PyString_Resize(&p->str, newsize) != 0) {
 		p->ptr = p->end = NULL;
 	}