summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/c-api/arg.rst10
-rw-r--r--Doc/c-api/exceptions.rst9
-rw-r--r--Doc/distutils/apiref.rst29
-rw-r--r--Doc/howto/unicode.rst2
-rw-r--r--Doc/library/email.mime.rst15
-rw-r--r--Doc/library/json.rst4
-rw-r--r--Doc/library/logging.rst12
-rw-r--r--Doc/library/multiprocessing.rst6
-rw-r--r--Doc/library/new.rst4
-rw-r--r--Doc/library/pydoc.rst7
-rw-r--r--Doc/library/socketserver.rst2
-rw-r--r--Doc/library/urllib2.rst61
-rw-r--r--Doc/library/webbrowser.rst2
-rw-r--r--Doc/library/winsound.rst9
-rw-r--r--Doc/library/xml.etree.elementtree.rst10
-rw-r--r--Include/unicodeobject.h16
-rw-r--r--Lib/distutils/util.py8
-rw-r--r--Lib/inspect.py5
-rwxr-xr-xLib/pydoc.py57
-rw-r--r--Lib/re.py6
-rw-r--r--Lib/test/test_deque.py21
-rw-r--r--Lib/test/test_dict.py14
-rw-r--r--Lib/test/test_file.py13
-rw-r--r--Lib/test/test_fileio.py1
-rw-r--r--Lib/test/test_set.py17
-rw-r--r--Lib/test/test_struct.py7
-rw-r--r--Lib/textwrap.py26
-rw-r--r--Misc/NEWS32
-rw-r--r--Modules/_collectionsmodule.c23
-rw-r--r--Modules/_fileio.c8
-rw-r--r--Modules/_struct.c12
-rw-r--r--Objects/dictobject.c25
-rw-r--r--Objects/fileobject.c4
-rw-r--r--Objects/setobject.c16
-rw-r--r--Tools/pybench/Lists.py55
35 files changed, 438 insertions, 110 deletions
diff --git a/Doc/c-api/arg.rst b/Doc/c-api/arg.rst
index 5dc28af..144a365 100644
--- a/Doc/c-api/arg.rst
+++ b/Doc/c-api/arg.rst
@@ -136,8 +136,9 @@ variable(s) whose address should be passed.
them. Instead, the implementation assumes that the string object uses the
encoding passed in as parameter.
-``b`` (integer) [char]
- Convert a Python integer to a tiny int, stored in a C :ctype:`char`.
+``b`` (integer) [unsigned char]
+ Convert a nonnegative Python integer to an unsigned tiny int, stored in a C
+ :ctype:`unsigned char`.
``B`` (integer) [unsigned char]
Convert a Python integer to a tiny int without overflow checking, stored in a C
@@ -533,3 +534,8 @@ and the following format units are left untouched.
If there is an error in the format string, the :exc:`SystemError` exception is
set and *NULL* returned.
+
+.. cfunction:: PyObject* Py_VaBuildValue(const char *format, va_list vargs)
+
+ Identical to :cfunc:`Py_BuildValue`, except that it accepts a va_list
+ rather than a variable number of arguments.
diff --git a/Doc/c-api/exceptions.rst b/Doc/c-api/exceptions.rst
index 2998521..536b123 100644
--- a/Doc/c-api/exceptions.rst
+++ b/Doc/c-api/exceptions.rst
@@ -73,11 +73,10 @@ is a separate error indicator for each thread.
.. cfunction:: int PyErr_GivenExceptionMatches(PyObject *given, PyObject *exc)
- Return true if the *given* exception matches the exception in *exc*. If *exc*
- is a class object, this also returns true when *given* is an instance of a
- subclass. If *exc* is a tuple, all exceptions in the tuple (and recursively in
- subtuples) are searched for a match. If *given* is *NULL*, a memory access
- violation will occur.
+ Return true if the *given* exception matches the exception in *exc*. If
+ *exc* is a class object, this also returns true when *given* is an instance
+ of a subclass. If *exc* is a tuple, all exceptions in the tuple (and
+ recursively in subtuples) are searched for a match.
.. cfunction:: void PyErr_NormalizeException(PyObject**exc, PyObject**val, PyObject**tb)
diff --git a/Doc/distutils/apiref.rst b/Doc/distutils/apiref.rst
index a8f7461..4a0d354 100644
--- a/Doc/distutils/apiref.rst
+++ b/Doc/distutils/apiref.rst
@@ -88,9 +88,9 @@ setup script). Indirectly provides the :class:`distutils.dist.Distribution` and
| *options* | default options for the setup | a string |
| | script | |
+--------------------+--------------------------------+-------------------------------------------------------------+
- | *license* | The license for the package | |
+ | *license* | The license for the package | a string |
+--------------------+--------------------------------+-------------------------------------------------------------+
- | *keywords* | Descriptive meta-data. See | |
+ | *keywords* | Descriptive meta-data, see | |
| | :pep:`314` | |
+--------------------+--------------------------------+-------------------------------------------------------------+
| *platforms* | | |
@@ -98,6 +98,13 @@ setup script). Indirectly provides the :class:`distutils.dist.Distribution` and
| *cmdclass* | A mapping of command names to | a dictionary |
| | :class:`Command` subclasses | |
+--------------------+--------------------------------+-------------------------------------------------------------+
+ | *data_files* | A list of data files to | a list |
+ | | install | |
+ +--------------------+--------------------------------+-------------------------------------------------------------+
+ | *package_dir* | A mapping of package to | a dictionary |
+ | | directory names | |
+ +--------------------+--------------------------------+-------------------------------------------------------------+
+
.. function:: run_setup(script_name[, script_args=None, stop_after='run'])
@@ -1100,6 +1107,24 @@ other utility module.
For non-POSIX platforms, currently just returns ``sys.platform``.
+ For MacOS X systems the OS version reflects the minimal version on which
+ binaries will run (that is, the value of ``MACOSX_DEPLOYMENT_TARGET``
+ during the build of Python), not the OS version of the current system.
+
+ For universal binary builds on MacOS X the architecture value reflects
+ the univeral binary status instead of the architecture of the current
+ processor. For 32-bit universal binaries the architecture is ``fat``,
+ for 64-bit universal binaries the architecture is ``fat64``, and
+ for 4-way universal binaries the architecture is ``universal``.
+
+ Examples of returned values on MacOS X:
+
+ * ``macosx-10.3-ppc``
+
+ * ``macosx-10.3-fat``
+
+ * ``macosx-10.5-universal``
+
.. % XXX isn't this also provided by some other non-distutils module?
diff --git a/Doc/howto/unicode.rst b/Doc/howto/unicode.rst
index 561ce29..d5dec63 100644
--- a/Doc/howto/unicode.rst
+++ b/Doc/howto/unicode.rst
@@ -30,7 +30,7 @@ For a while people just wrote programs that didn't display accents. I remember
looking at Apple ][ BASIC programs, published in French-language publications in
the mid-1980s, that had lines like these::
- PRINT "FICHER EST COMPLETE."
+ PRINT "FICHIER EST COMPLETE."
PRINT "CARACTERE NON ACCEPTE."
Those messages should contain accents, and they just look wrong to someone who
diff --git a/Doc/library/email.mime.rst b/Doc/library/email.mime.rst
index 6f1b0ae..415a682 100644
--- a/Doc/library/email.mime.rst
+++ b/Doc/library/email.mime.rst
@@ -19,6 +19,7 @@ things easier.
Here are the classes:
+.. currentmodule:: email.mime.base
.. class:: MIMEBase(_maintype, _subtype, **_params)
@@ -39,6 +40,8 @@ Here are the classes:
:mailheader:`MIME-Version` header (always set to ``1.0``).
+.. currentmodule:: email.mime.nonmultipart
+
.. class:: MIMENonMultipart()
Module: :mod:`email.mime.nonmultipart`
@@ -52,6 +55,8 @@ Here are the classes:
.. versionadded:: 2.2.2
+.. currentmodule:: email.mime.multipart
+
.. class:: MIMEMultipart([subtype[, boundary[, _subparts[, _params]]]])
Module: :mod:`email.mime.multipart`
@@ -77,6 +82,8 @@ Here are the classes:
.. versionadded:: 2.2.2
+.. currentmodule:: email.mime.application
+
.. class:: MIMEApplication(_data[, _subtype[, _encoder[, **_params]]])
Module: :mod:`email.mime.application`
@@ -99,6 +106,8 @@ Here are the classes:
.. versionadded:: 2.5
+.. currentmodule:: email.mime.audio
+
.. class:: MIMEAudio(_audiodata[, _subtype[, _encoder[, **_params]]])
Module: :mod:`email.mime.audio`
@@ -122,6 +131,8 @@ Here are the classes:
*_params* are passed straight through to the base class constructor.
+.. currentmodule:: email.mime.image
+
.. class:: MIMEImage(_imagedata[, _subtype[, _encoder[, **_params]]])
Module: :mod:`email.mime.image`
@@ -145,6 +156,8 @@ Here are the classes:
*_params* are passed straight through to the :class:`MIMEBase` constructor.
+.. currentmodule:: email.mime.message
+
.. class:: MIMEMessage(_msg[, _subtype])
Module: :mod:`email.mime.message`
@@ -158,6 +171,8 @@ Here are the classes:
:mimetype:`rfc822`.
+.. currentmodule:: email.mime.text
+
.. class:: MIMEText(_text[, _subtype[, _charset]])
Module: :mod:`email.mime.text`
diff --git a/Doc/library/json.rst b/Doc/library/json.rst
index bff779b..cf6138e 100644
--- a/Doc/library/json.rst
+++ b/Doc/library/json.rst
@@ -166,7 +166,7 @@ Basic Usage
:func:`dump`.
-.. function load(fp[, encoding[, cls[, object_hook[, parse_float[, parse_int[, parse_constant[, **kw]]]]]]])
+.. function:: load(fp[, encoding[, cls[, object_hook[, parse_float[, parse_int[, parse_constant[, **kw]]]]]]])
Deserialize *fp* (a ``.read()``-supporting file-like object containing a JSON
document) to a Python object.
@@ -202,7 +202,7 @@ Basic Usage
class.
-.. function loads(s[, encoding[, cls[, object_hook[, parse_float[, parse_int[, parse_constant[, **kw]]]]]]])
+.. function:: loads(s[, encoding[, cls[, object_hook[, parse_float[, parse_int[, parse_constant[, **kw]]]]]]])
Deserialize *s* (a :class:`str` or :class:`unicode` instance containing a JSON
document) to a Python object.
diff --git a/Doc/library/logging.rst b/Doc/library/logging.rst
index dac6aeb1..3e54422 100644
--- a/Doc/library/logging.rst
+++ b/Doc/library/logging.rst
@@ -553,10 +553,10 @@ provided:
#. :class:`HTTPHandler` instances send error messages to an HTTP server using
either ``GET`` or ``POST`` semantics.
-The :class:`StreamHandler` and :class:`FileHandler` classes are defined in the
-core logging package. The other handlers are defined in a sub- module,
-:mod:`logging.handlers`. (There is also another sub-module,
-:mod:`logging.config`, for configuration functionality.)
+The :class:`NullHandler`, :class:`StreamHandler` and :class:`FileHandler`
+classes are defined in the core logging package. The other handlers are
+defined in a sub- module, :mod:`logging.handlers`. (There is also another
+sub-module, :mod:`logging.config`, for configuration functionality.)
Logged messages are formatted for presentation through instances of the
:class:`Formatter` class. They are initialized with a format string suitable for
@@ -1544,6 +1544,8 @@ subclasses. However, the :meth:`__init__` method in subclasses needs to call
StreamHandler
^^^^^^^^^^^^^
+.. module:: logging.handlers
+
The :class:`StreamHandler` class, located in the core :mod:`logging` package,
sends logging output to streams such as *sys.stdout*, *sys.stderr* or any
file-like object (or, more precisely, any object which supports :meth:`write`
@@ -2050,6 +2052,8 @@ supports sending logging messages to a Web server, using either ``GET`` or
Formatter Objects
-----------------
+.. currentmodule:: logging
+
:class:`Formatter`\ s have the following attributes and methods. They are
responsible for converting a :class:`LogRecord` to (usually) a string which can
be interpreted by either a human or an external system. The base
diff --git a/Doc/library/multiprocessing.rst b/Doc/library/multiprocessing.rst
index 8297e9f..6f4a3f1 100644
--- a/Doc/library/multiprocessing.rst
+++ b/Doc/library/multiprocessing.rst
@@ -358,7 +358,7 @@ The :mod:`multiprocessing` package mostly replicates the API of the
.. attribute:: daemon
- The process's daemon flag, a Boolean value. This must be called before
+ The process's daemon flag, a Boolean value. This must be set before
:meth:`start` is called.
The initial value is inherited from the creating process.
@@ -1810,9 +1810,9 @@ Address Formats
filesystem.
* An ``'AF_PIPE'`` address is a string of the form
- ``r'\\\\.\\pipe\\PipeName'``. To use :func:`Client` to connect to a named
+ :samp:`r'\\\\.\\pipe\\{PipeName}'`. To use :func:`Client` to connect to a named
pipe on a remote computer called ServerName* one should use an address of the
- form ``r'\\\\ServerName\\pipe\\PipeName'`` instead.
+ form :samp:`r'\\\\{ServerName}\\pipe\\{PipeName}'`` instead.
Note that any string beginning with two backslashes is assumed by default to be
an ``'AF_PIPE'`` address rather than an ``'AF_UNIX'`` address.
diff --git a/Doc/library/new.rst b/Doc/library/new.rst
index d8e455c..670d3d7 100644
--- a/Doc/library/new.rst
+++ b/Doc/library/new.rst
@@ -1,4 +1,3 @@
-
:mod:`new` --- Creation of runtime internal objects
===================================================
@@ -7,7 +6,8 @@
:deprecated:
.. deprecated:: 2.6
- The :mod:`new` module has been removed in Python 3.0.
+ The :mod:`new` module has been removed in Python 3.0. Use the :mod:`types`
+ module's classes instead.
.. sectionauthor:: Moshe Zadka <moshez@zadka.site.co.il>
diff --git a/Doc/library/pydoc.rst b/Doc/library/pydoc.rst
index 6d4986e..3784515 100644
--- a/Doc/library/pydoc.rst
+++ b/Doc/library/pydoc.rst
@@ -36,6 +36,13 @@ it contains the path separator for your operating system, such as a slash in
Unix), and refers to an existing Python source file, then documentation is
produced for that file.
+.. note::
+
+ In order to find objects and their documentation, :mod:`pydoc` imports the
+ module(s) to be documented. Therefore, any code on module level will be
+ 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.
+
Specifying a :option:`-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/socketserver.rst b/Doc/library/socketserver.rst
index 7f4daad..786632e 100644
--- a/Doc/library/socketserver.rst
+++ b/Doc/library/socketserver.rst
@@ -448,7 +448,7 @@ This is the server side::
if __name__ == "__main__":
HOST, PORT = "localhost", 9999
- server = SocketServer.UDPServer((HOST, PORT), BaseUDPRequestHandler)
+ server = SocketServer.UDPServer((HOST, PORT), MyUDPHandler)
server.serve_forever()
This is the client side::
diff --git a/Doc/library/urllib2.rst b/Doc/library/urllib2.rst
index 18f5af7..4c7c582 100644
--- a/Doc/library/urllib2.rst
+++ b/Doc/library/urllib2.rst
@@ -391,23 +391,23 @@ OpenerDirector Objects
.. method:: OpenerDirector.add_handler(handler)
- *handler* should be an instance of :class:`BaseHandler`. The following methods
- are searched, and added to the possible chains (note that HTTP errors are a
- special case).
+ *handler* should be an instance of :class:`BaseHandler`. The following
+ methods are searched, and added to the possible chains (note that HTTP errors
+ are a special case).
- * :meth:`protocol_open` --- signal that the handler knows how to open *protocol*
- URLs.
+ * :samp:`{protocol}_open` --- signal that the handler knows how to open
+ *protocol* URLs.
- * :meth:`http_error_type` --- signal that the handler knows how to handle HTTP
- errors with HTTP error code *type*.
+ * :samp:`http_error_{type}` --- signal that the handler knows how to handle
+ HTTP errors with HTTP error code *type*.
- * :meth:`protocol_error` --- signal that the handler knows how to handle errors
- from (non-\ ``http``) *protocol*.
+ * :samp:`{protocol}_error` --- signal that the handler knows how to handle
+ errors from (non-\ ``http``) *protocol*.
- * :meth:`protocol_request` --- signal that the handler knows how to pre-process
- *protocol* requests.
+ * :samp:`{protocol}_request` --- signal that the handler knows how to
+ pre-process *protocol* requests.
- * :meth:`protocol_response` --- signal that the handler knows how to
+ * :samp:`{protocol}_response` --- signal that the handler knows how to
post-process *protocol* responses.
@@ -441,24 +441,24 @@ OpenerDirector objects open URLs in three stages:
The order in which these methods are called within each stage is determined by
sorting the handler instances.
-#. Every handler with a method named like :meth:`protocol_request` has that
+#. Every handler with a method named like :samp:`{protocol}_request` has that
method called to pre-process the request.
-#. Handlers with a method named like :meth:`protocol_open` are called to handle
+#. Handlers with a method named like :samp:`{protocol}_open` are called to handle
the request. This stage ends when a handler either returns a non-\ :const:`None`
value (ie. a response), or raises an exception (usually :exc:`URLError`).
Exceptions are allowed to propagate.
In fact, the above algorithm is first tried for methods named
- :meth:`default_open`. If all such methods return :const:`None`, the algorithm
- is repeated for methods named like :meth:`protocol_open`. If all such methods
- return :const:`None`, the algorithm is repeated for methods named
- :meth:`unknown_open`.
+ :meth:`default_open`. If all such methods return :const:`None`, the
+ algorithm is repeated for methods named like :samp:`{protocol}_open`. If all
+ such methods return :const:`None`, the algorithm is repeated for methods
+ named :meth:`unknown_open`.
Note that the implementation of these methods may involve calls of the parent
:class:`OpenerDirector` instance's :meth:`.open` and :meth:`.error` methods.
-#. Every handler with a method named like :meth:`protocol_response` has that
+#. Every handler with a method named like :samp:`{protocol}_response` has that
method called to post-process the response.
@@ -514,8 +514,10 @@ The following members and methods should only be used by classes derived from
.. method:: BaseHandler.protocol_open(req)
:noindex:
+ ("protocol" is to be replaced by the protocol name.)
+
This method is *not* defined in :class:`BaseHandler`, but subclasses should
- define it if they want to handle URLs with the given protocol.
+ define it if they want to handle URLs with the given *protocol*.
This method, if defined, will be called by the parent :class:`OpenerDirector`.
Return values should be the same as for :meth:`default_open`.
@@ -563,8 +565,10 @@ The following members and methods should only be used by classes derived from
.. method:: BaseHandler.protocol_request(req)
:noindex:
+ ("protocol" is to be replaced by the protocol name.)
+
This method is *not* defined in :class:`BaseHandler`, but subclasses should
- define it if they want to pre-process requests of the given protocol.
+ define it if they want to pre-process requests of the given *protocol*.
This method, if defined, will be called by the parent :class:`OpenerDirector`.
*req* will be a :class:`Request` object. The return value should be a
@@ -574,8 +578,10 @@ The following members and methods should only be used by classes derived from
.. method:: BaseHandler.protocol_response(req, response)
:noindex:
+ ("protocol" is to be replaced by the protocol name.)
+
This method is *not* defined in :class:`BaseHandler`, but subclasses should
- define it if they want to post-process responses of the given protocol.
+ define it if they want to post-process responses of the given *protocol*.
This method, if defined, will be called by the parent :class:`OpenerDirector`.
*req* will be a :class:`Request` object. *response* will be an object
@@ -660,7 +666,9 @@ ProxyHandler Objects
.. method:: ProxyHandler.protocol_open(request)
:noindex:
- The :class:`ProxyHandler` will have a method :meth:`protocol_open` for every
+ ("protocol" is to be replaced by the protocol name.)
+
+ The :class:`ProxyHandler` will have a method :samp:`{protocol}_open` for every
*protocol* which has a proxy in the *proxies* dictionary given in the
constructor. The method will modify requests to go through the proxy, by
calling ``request.set_proxy()``, and call the next handler in the chain to
@@ -865,9 +873,10 @@ HTTPErrorProcessor Objects
For 200 error codes, the response object is returned immediately.
For non-200 error codes, this simply passes the job on to the
- :meth:`protocol_error_code` handler methods, via :meth:`OpenerDirector.error`.
- Eventually, :class:`urllib2.HTTPDefaultErrorHandler` will raise an
- :exc:`HTTPError` if no other handler handles the error.
+ :samp:`{protocol}_error_code` handler methods, via
+ :meth:`OpenerDirector.error`. Eventually,
+ :class:`urllib2.HTTPDefaultErrorHandler` will raise an :exc:`HTTPError` if no
+ other handler handles the error.
.. _urllib2-examples:
diff --git a/Doc/library/webbrowser.rst b/Doc/library/webbrowser.rst
index 13cd8c7..d340b8a 100644
--- a/Doc/library/webbrowser.rst
+++ b/Doc/library/webbrowser.rst
@@ -172,7 +172,7 @@ Here are some simple examples::
Browser Controller Objects
--------------------------
-Browser controllers provide two methods which parallel two of the module-level
+Browser controllers provide these methods which parallel two of the module-level
convenience functions:
diff --git a/Doc/library/winsound.rst b/Doc/library/winsound.rst
index f9709fe..b4a3391 100644
--- a/Doc/library/winsound.rst
+++ b/Doc/library/winsound.rst
@@ -30,8 +30,9 @@ provided by Windows platforms. It includes functions and several constants.
Call the underlying :cfunc:`PlaySound` function from the Platform API. The
*sound* parameter may be a filename, audio data as a string, or ``None``. Its
interpretation depends on the value of *flags*, which can be a bitwise ORed
- combination of the constants described below. If the system indicates an error,
- :exc:`RuntimeError` is raised.
+ combination of the constants described below. If the *sound* parameter is
+ ``None``, any currently playing waveform sound is stopped. If the system
+ indicates an error, :exc:`RuntimeError` is raised.
.. function:: MessageBeep([type=MB_OK])
@@ -108,6 +109,10 @@ provided by Windows platforms. It includes functions and several constants.
Stop playing all instances of the specified sound.
+ .. note::
+
+ This flag is not supported on modern Windows platforms.
+
.. data:: SND_ASYNC
diff --git a/Doc/library/xml.etree.elementtree.rst b/Doc/library/xml.etree.elementtree.rst
index cdc774e..b17d510 100644
--- a/Doc/library/xml.etree.elementtree.rst
+++ b/Doc/library/xml.etree.elementtree.rst
@@ -94,6 +94,16 @@ Functions
*events* is a list of events to report back. If omitted, only "end" events are
reported. Returns an :term:`iterator` providing ``(event, elem)`` pairs.
+ .. note::
+
+ :func:`iterparse` only guarantees that it has seen the ">"
+ character of a starting tag when it emits a "start" event, so the
+ attributes are defined, but the contents of the text and tail attributes
+ are undefined at that point. The same applies to the element children;
+ they may or may not be present.
+
+ If you need a fully populated element, look for "end" events instead.
+
.. function:: parse(source[, parser])
diff --git a/Include/unicodeobject.h b/Include/unicodeobject.h
index ee9fec1..cff0ac3 100644
--- a/Include/unicodeobject.h
+++ b/Include/unicodeobject.h
@@ -153,6 +153,7 @@ typedef PY_UNICODE_TYPE Py_UNICODE;
# define PyUnicode_AsUnicode PyUnicodeUCS2_AsUnicode
# define PyUnicode_AsUnicodeEscapeString PyUnicodeUCS2_AsUnicodeEscapeString
# define PyUnicode_AsWideChar PyUnicodeUCS2_AsWideChar
+# define PyUnicode_ClearFreeList PyUnicodeUCS2_ClearFreelist
# define PyUnicode_Compare PyUnicodeUCS2_Compare
# define PyUnicode_Concat PyUnicodeUCS2_Concat
# define PyUnicode_Contains PyUnicodeUCS2_Contains
@@ -182,13 +183,13 @@ typedef PY_UNICODE_TYPE Py_UNICODE;
# define PyUnicode_Find PyUnicodeUCS2_Find
# define PyUnicode_Format PyUnicodeUCS2_Format
# define PyUnicode_FromEncodedObject PyUnicodeUCS2_FromEncodedObject
+# define PyUnicode_FromFormat PyUnicodeUCS2_FromFormat
+# define PyUnicode_FromFormatV PyUnicodeUCS2_FromFormatV
# define PyUnicode_FromObject PyUnicodeUCS2_FromObject
# define PyUnicode_FromOrdinal PyUnicodeUCS2_FromOrdinal
-# define PyUnicode_FromUnicode PyUnicodeUCS2_FromUnicode
# define PyUnicode_FromString PyUnicodeUCS2_FromString
# define PyUnicode_FromStringAndSize PyUnicodeUCS2_FromStringAndSize
-# define PyUnicode_FromFormatV PyUnicodeUCS2_FromFormatV
-# define PyUnicode_FromFormat PyUnicodeUCS2_FromFormat
+# define PyUnicode_FromUnicode PyUnicodeUCS2_FromUnicode
# define PyUnicode_FromWideChar PyUnicodeUCS2_FromWideChar
# define PyUnicode_GetDefaultEncoding PyUnicodeUCS2_GetDefaultEncoding
# define PyUnicode_GetMax PyUnicodeUCS2_GetMax
@@ -209,7 +210,6 @@ typedef PY_UNICODE_TYPE Py_UNICODE;
# define _PyUnicode_AsDefaultEncodedString _PyUnicodeUCS2_AsDefaultEncodedString
# define _PyUnicode_Fini _PyUnicodeUCS2_Fini
# define _PyUnicode_Init _PyUnicodeUCS2_Init
-# define PyUnicode_ClearFreeList PyUnicodeUCS2_ClearFreelist
# define _PyUnicode_IsAlpha _PyUnicodeUCS2_IsAlpha
# define _PyUnicode_IsDecimalDigit _PyUnicodeUCS2_IsDecimalDigit
# define _PyUnicode_IsDigit _PyUnicodeUCS2_IsDigit
@@ -240,6 +240,7 @@ typedef PY_UNICODE_TYPE Py_UNICODE;
# define PyUnicode_AsUnicode PyUnicodeUCS4_AsUnicode
# define PyUnicode_AsUnicodeEscapeString PyUnicodeUCS4_AsUnicodeEscapeString
# define PyUnicode_AsWideChar PyUnicodeUCS4_AsWideChar
+# define PyUnicode_ClearFreeList PyUnicodeUCS4_ClearFreelist
# define PyUnicode_Compare PyUnicodeUCS4_Compare
# define PyUnicode_Concat PyUnicodeUCS4_Concat
# define PyUnicode_Contains PyUnicodeUCS4_Contains
@@ -269,13 +270,13 @@ typedef PY_UNICODE_TYPE Py_UNICODE;
# define PyUnicode_Find PyUnicodeUCS4_Find
# define PyUnicode_Format PyUnicodeUCS4_Format
# define PyUnicode_FromEncodedObject PyUnicodeUCS4_FromEncodedObject
+# define PyUnicode_FromFormat PyUnicodeUCS4_FromFormat
+# define PyUnicode_FromFormatV PyUnicodeUCS4_FromFormatV
# define PyUnicode_FromObject PyUnicodeUCS4_FromObject
# define PyUnicode_FromOrdinal PyUnicodeUCS4_FromOrdinal
-# define PyUnicode_FromUnicode PyUnicodeUCS4_FromUnicode
# define PyUnicode_FromString PyUnicodeUCS4_FromString
# define PyUnicode_FromStringAndSize PyUnicodeUCS4_FromStringAndSize
-# define PyUnicode_FromFormatV PyUnicodeUCS4_FromFormatV
-# define PyUnicode_FromFormat PyUnicodeUCS4_FromFormat
+# define PyUnicode_FromUnicode PyUnicodeUCS4_FromUnicode
# define PyUnicode_FromWideChar PyUnicodeUCS4_FromWideChar
# define PyUnicode_GetDefaultEncoding PyUnicodeUCS4_GetDefaultEncoding
# define PyUnicode_GetMax PyUnicodeUCS4_GetMax
@@ -296,7 +297,6 @@ typedef PY_UNICODE_TYPE Py_UNICODE;
# define _PyUnicode_AsDefaultEncodedString _PyUnicodeUCS4_AsDefaultEncodedString
# define _PyUnicode_Fini _PyUnicodeUCS4_Fini
# define _PyUnicode_Init _PyUnicodeUCS4_Init
-# define PyUnicode_ClearFreeList PyUnicodeUCS2_ClearFreelist
# define _PyUnicode_IsAlpha _PyUnicodeUCS4_IsAlpha
# define _PyUnicode_IsDecimalDigit _PyUnicodeUCS4_IsDecimalDigit
# define _PyUnicode_IsDigit _PyUnicodeUCS4_IsDigit
diff --git a/Lib/distutils/util.py b/Lib/distutils/util.py
index 48cc17f..e9d29ff 100644
--- a/Lib/distutils/util.py
+++ b/Lib/distutils/util.py
@@ -140,9 +140,13 @@ def get_platform ():
# 'universal' instead of 'fat'.
machine = 'fat'
+ cflags = get_config_vars().get('CFLAGS')
- if '-arch x86_64' in get_config_vars().get('CFLAGS'):
- machine = 'universal'
+ if '-arch x86_64' in cflags:
+ if '-arch i386' in cflags:
+ machine = 'universal'
+ else:
+ machine = 'fat64'
elif machine in ('PowerPC', 'Power_Macintosh'):
# Pick a sane name for the PPC architecture.
diff --git a/Lib/inspect.py b/Lib/inspect.py
index d3d946d..1685bfc 100644
--- a/Lib/inspect.py
+++ b/Lib/inspect.py
@@ -158,9 +158,8 @@ def isgeneratorfunction(object):
Generator function objects provides same attributes as functions.
See isfunction.__doc__ for attributes listing."""
- if (isfunction(object) or ismethod(object)) and \
- object.func_code.co_flags & CO_GENERATOR:
- return True
+ return bool((isfunction(object) or ismethod(object)) and
+ object.func_code.co_flags & CO_GENERATOR)
def isgenerator(object):
"""Return true if the object is a generator.
diff --git a/Lib/pydoc.py b/Lib/pydoc.py
index 179026b..dda0208 100755
--- a/Lib/pydoc.py
+++ b/Lib/pydoc.py
@@ -1574,6 +1574,42 @@ class Helper:
'with': ('with', 'CONTEXTMANAGERS EXCEPTIONS yield'),
'yield': ('yield', ''),
}
+ # Either add symbols to this dictionary or to the symbols dictionary
+ # directly: Whichever is easier. They are merged later.
+ _symbols_inverse = {
+ 'STRINGS' : ("'", "'''", "r'", "u'", '"""', '"', 'r"', 'u"'),
+ 'OPERATORS' : ('+', '-', '*', '**', '/', '//', '%', '<<', '>>', '&',
+ '|', '^', '~', '<', '>', '<=', '>=', '==', '!=', '<>'),
+ 'COMPARISON' : ('<', '>', '<=', '>=', '==', '!=', '<>'),
+ 'UNARY' : ('-', '~'),
+ 'AUGMENTEDASSIGNMENT' : ('+=', '-=', '*=', '/=', '%=', '&=', '|=',
+ '^=', '<<=', '>>=', '**=', '//='),
+ 'BITWISE' : ('<<', '>>', '&', '|', '^', '~'),
+ 'COMPLEX' : ('j', 'J')
+ }
+ symbols = {
+ '%': 'OPERATORS FORMATTING',
+ '**': 'POWER',
+ ',': 'TUPLES LISTS FUNCTIONS',
+ '.': 'ATTRIBUTES FLOAT MODULES OBJECTS',
+ '...': 'ELLIPSIS',
+ ':': 'SLICINGS DICTIONARYLITERALS',
+ '@': 'def class',
+ '\\': 'STRINGS',
+ '_': 'PRIVATENAMES',
+ '__': 'PRIVATENAMES SPECIALMETHODS',
+ '`': 'BACKQUOTES',
+ '(': 'TUPLES FUNCTIONS CALLS',
+ ')': 'TUPLES FUNCTIONS CALLS',
+ '[': 'LISTS SUBSCRIPTS SLICINGS',
+ ']': 'LISTS SUBSCRIPTS SLICINGS'
+ }
+ for topic, symbols_ in _symbols_inverse.iteritems():
+ for symbol in symbols_:
+ topics = symbols.get(symbol, topic)
+ if topic not in topics:
+ topics = topics + ' ' + topic
+ symbols[symbol] = topics
topics = {
'TYPES': ('types', 'STRINGS UNICODE NUMBERS SEQUENCES MAPPINGS '
@@ -1717,10 +1753,12 @@ has the same effect as typing a particular string at the help> prompt.
if type(request) is type(''):
if request == 'help': self.intro()
elif request == 'keywords': self.listkeywords()
+ elif request == 'symbols': self.listsymbols()
elif request == 'topics': self.listtopics()
elif request == 'modules': self.listmodules()
elif request[:8] == 'modules ':
self.listmodules(split(request)[1])
+ elif request in self.symbols: self.showsymbol(request)
elif request in self.keywords: self.showtopic(request)
elif request in self.topics: self.showtopic(request)
elif request: doc(request, 'Help on %s:')
@@ -1766,6 +1804,14 @@ Here is a list of the Python keywords. Enter any keyword to get more help.
''')
self.list(self.keywords.keys())
+ def listsymbols(self):
+ self.output.write('''
+Here is a list of the punctuation symbols which Python assigns special meaning
+to. Enter any symbol to get more help.
+
+''')
+ self.list(self.symbols.keys())
+
def listtopics(self):
self.output.write('''
Here is a list of available topics. Enter any topic name to get more help.
@@ -1773,7 +1819,7 @@ Here is a list of available topics. Enter any topic name to get more help.
''')
self.list(self.topics.keys())
- def showtopic(self, topic):
+ def showtopic(self, topic, more_xrefs=''):
try:
import pydoc_topics
except ImportError:
@@ -1787,7 +1833,7 @@ module "pydoc_topics" could not be found.
self.output.write('no documentation found for %s\n' % repr(topic))
return
if type(target) is type(''):
- return self.showtopic(target)
+ return self.showtopic(target, more_xrefs)
label, xrefs = target
try:
@@ -1796,6 +1842,8 @@ module "pydoc_topics" could not be found.
self.output.write('no documentation found for %s\n' % repr(topic))
return
pager(strip(doc) + '\n')
+ if more_xrefs:
+ xrefs = (xrefs or '') + ' ' + more_xrefs
if xrefs:
import StringIO, formatter
buffer = StringIO.StringIO()
@@ -1803,6 +1851,11 @@ module "pydoc_topics" could not be found.
'Related help topics: ' + join(split(xrefs), ', ') + '\n')
self.output.write('\n%s\n' % buffer.getvalue())
+ def showsymbol(self, symbol):
+ target = self.symbols[symbol]
+ topic, _, xrefs = target.partition(' ')
+ self.showtopic(topic, xrefs)
+
def listmodules(self, key=''):
if key:
self.output.write('''
diff --git a/Lib/re.py b/Lib/re.py
index ee962bb..2cf7132 100644
--- a/Lib/re.py
+++ b/Lib/re.py
@@ -145,7 +145,8 @@ def sub(pattern, repl, string, count=0):
"""Return the string obtained by replacing the leftmost
non-overlapping occurrences of the pattern in string by the
replacement repl. repl can be either a string or a callable;
- if a callable, it's passed the match object and must return
+ if a string, backslash escapes in it are processed. If it is
+ a callable, it's passed the match object and must return
a replacement string to be used."""
return _compile(pattern, 0).sub(repl, string, count)
@@ -155,7 +156,8 @@ def subn(pattern, repl, string, count=0):
non-overlapping occurrences of the pattern in the source
string by the replacement repl. number is the number of
substitutions that were made. repl can be either a string or a
- callable; if a callable, it's passed the match object and must
+ callable; if a string, backslash escapes in it are processed.
+ If it is a callable, it's passed the match object and must
return a replacement string to be used."""
return _compile(pattern, 0).subn(repl, string, count)
diff --git a/Lib/test/test_deque.py b/Lib/test/test_deque.py
index 0f0d098..4e2de3d 100644
--- a/Lib/test/test_deque.py
+++ b/Lib/test/test_deque.py
@@ -1,7 +1,8 @@
from collections import deque
import unittest
from test import test_support, seq_tests
-from weakref import proxy
+import gc
+import weakref
import copy
import cPickle as pickle
import random
@@ -418,6 +419,22 @@ class TestBasic(unittest.TestCase):
d.append(1)
gc.collect()
+ def test_container_iterator(self):
+ # Bug # XXX: tp_traverse was not implemented for deque iterator objects
+ class C(object):
+ pass
+ for i in range(2):
+ obj = C()
+ ref = weakref.ref(obj)
+ if i == 0:
+ container = deque([obj, 1])
+ else:
+ container = reversed(deque([obj, 1]))
+ obj.x = iter(container)
+ del obj, container
+ gc.collect()
+ self.assert_(ref() is None, "Cycle was not collected")
+
class TestVariousIteratorArgs(unittest.TestCase):
def test_constructor(self):
@@ -528,7 +545,7 @@ class TestSubclass(unittest.TestCase):
def test_weakref(self):
d = deque('gallahad')
- p = proxy(d)
+ p = weakref.proxy(d)
self.assertEqual(str(p), str(d))
d = None
self.assertRaises(ReferenceError, str, p)
diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py
index f715657..14d62f5 100644
--- a/Lib/test/test_dict.py
+++ b/Lib/test/test_dict.py
@@ -2,6 +2,7 @@ import unittest
from test import test_support
import UserDict, random, string
+import gc, weakref
class DictTest(unittest.TestCase):
@@ -554,6 +555,19 @@ class DictTest(unittest.TestCase):
pass
d = {}
+ def test_container_iterator(self):
+ # Bug # XXX: tp_traverse was not implemented for dictiter objects
+ class C(object):
+ pass
+ iterators = (dict.iteritems, dict.itervalues, dict.iterkeys)
+ for i in iterators:
+ obj = C()
+ ref = weakref.ref(obj)
+ container = {obj: 1}
+ obj.x = i(container)
+ del obj, container
+ gc.collect()
+ self.assert_(ref() is None, "Cycle was not collected")
from test import mapping_tests
diff --git a/Lib/test/test_file.py b/Lib/test/test_file.py
index 96f6da2..b4f494b 100644
--- a/Lib/test/test_file.py
+++ b/Lib/test/test_file.py
@@ -125,6 +125,19 @@ class AutoFileTests(unittest.TestCase):
class OtherFileTests(unittest.TestCase):
+ def testOpenDir(self):
+ this_dir = os.path.dirname(__file__)
+ for mode in (None, "w"):
+ try:
+ if mode:
+ f = open(this_dir, mode)
+ else:
+ f = open(this_dir)
+ except IOError as e:
+ self.assertEqual(e.filename, this_dir)
+ else:
+ self.fail("opening a directory didn't raise an IOError")
+
def testModeStrings(self):
# check invalid mode strings
for mode in ("", "aU", "wU+"):
diff --git a/Lib/test/test_fileio.py b/Lib/test/test_fileio.py
index c978779..d8cf415 100644
--- a/Lib/test/test_fileio.py
+++ b/Lib/test/test_fileio.py
@@ -109,6 +109,7 @@ class AutoFileTests(unittest.TestCase):
_fileio._FileIO('.', 'r')
except IOError as e:
self.assertNotEqual(e.errno, 0)
+ self.assertEqual(e.filename, ".")
else:
self.fail("Should have raised IOError")
diff --git a/Lib/test/test_set.py b/Lib/test/test_set.py
index d38a675..8d05712 100644
--- a/Lib/test/test_set.py
+++ b/Lib/test/test_set.py
@@ -1,6 +1,7 @@
import unittest
from test import test_support
-from weakref import proxy
+import gc
+import weakref
import operator
import copy
import pickle
@@ -322,6 +323,18 @@ class TestJointOps(unittest.TestCase):
self.assertEqual(sum(elem.hash_count for elem in d), n)
self.assertEqual(d3, dict.fromkeys(d, 123))
+ def test_container_iterator(self):
+ # Bug # XXX: tp_traverse was not implemented for set iterator object
+ class C(object):
+ pass
+ obj = C()
+ ref = weakref.ref(obj)
+ container = set([obj, 1])
+ obj.x = iter(container)
+ del obj, container
+ gc.collect()
+ self.assert_(ref() is None, "Cycle was not collected")
+
class TestSet(TestJointOps):
thetype = set
@@ -538,7 +551,7 @@ class TestSet(TestJointOps):
def test_weakref(self):
s = self.thetype('gallahad')
- p = proxy(s)
+ p = weakref.proxy(s)
self.assertEqual(str(p), str(s))
s = None
self.assertRaises(ReferenceError, str, p)
diff --git a/Lib/test/test_struct.py b/Lib/test/test_struct.py
index 232bffc..7f5f08b 100644
--- a/Lib/test/test_struct.py
+++ b/Lib/test/test_struct.py
@@ -2,6 +2,8 @@ import array
import unittest
import struct
import warnings
+warnings.filterwarnings("ignore", "struct integer overflow masking is deprecated",
+ DeprecationWarning)
from functools import wraps
from test.test_support import TestFailed, verbose, run_unittest
@@ -461,6 +463,11 @@ class StructTest(unittest.TestCase):
self.check_float_coerce(endian + fmt, 1.0)
self.check_float_coerce(endian + fmt, 1.5)
+ def test_issue4228(self):
+ # Packing a long may yield either 32 or 64 bits
+ x = struct.pack('L', -1)[:4]
+ self.assertEqual(x, '\xff'*4)
+
def test_unpack_from(self):
test_string = 'abcd01234'
fmt = '4s'
diff --git a/Lib/textwrap.py b/Lib/textwrap.py
index 192b43b..64a5b97 100644
--- a/Lib/textwrap.py
+++ b/Lib/textwrap.py
@@ -84,7 +84,7 @@ class TextWrapper:
# splits into
# Hello/ /there/ /--/ /you/ /goof-/ball,/ /use/ /the/ /-b/ /option!
# (after stripping out empty strings).
- wordsep_re = (
+ wordsep_re = re.compile(
r'(\s+|' # any whitespace
r'[^\s\w]*\w+[^0-9\W]-(?=\w+[^0-9\W])|' # hyphenated words
r'(?<=[\w\!\"\'\&\.\,\?])-{2,}(?=\w))') # em-dash
@@ -93,7 +93,7 @@ class TextWrapper:
# "Hello there -- you goof-ball, use the -b option!"
# splits into
# Hello/ /there/ /--/ /you/ /goof-ball,/ /use/ /the/ /-b/ /option!/
- wordsep_simple_re = r'(\s+)'
+ 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)
@@ -124,6 +124,13 @@ class TextWrapper:
self.drop_whitespace = drop_whitespace
self.break_on_hyphens = break_on_hyphens
+ # recompile the regexes for Unicode mode -- done in this clumsy way for
+ # backwards compatibility because it's rather common to monkey-patch
+ # the TextWrapper class' wordsep_re attribute.
+ self.wordsep_re_uni = re.compile(self.wordsep_re.pattern, re.U)
+ self.wordsep_simple_re_uni = re.compile(
+ self.wordsep_simple_re.pattern, re.U)
+
# -- Private methods -----------------------------------------------
# (possibly useful for subclasses to override)
@@ -160,12 +167,17 @@ class TextWrapper:
'use', ' ', 'the', ' ', '-b', ' ', option!'
otherwise.
"""
- flags = re.UNICODE if isinstance(text, unicode) else 0
- if self.break_on_hyphens:
- pat = self.wordsep_re
+ if isinstance(text, unicode):
+ if self.break_on_hyphens:
+ pat = self.wordsep_re_uni
+ else:
+ pat = self.wordsep_simple_re_uni
else:
- pat = self.wordsep_simple_re
- chunks = re.compile(pat, flags).split(text)
+ if self.break_on_hyphens:
+ pat = self.wordsep_re
+ else:
+ pat = self.wordsep_simple_re
+ chunks = pat.split(text)
chunks = filter(None, chunks) # remove empty chunks
return chunks
diff --git a/Misc/NEWS b/Misc/NEWS
index 9bdd262..84f5772 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -12,9 +12,21 @@ What's New in Python 2.6.2
Core and Builtins
-----------------
+- Issue #3680: Reference cycles created through a dict, set or deque iterator
+ did not get collected.
+
- Issue #4701: PyObject_Hash now implicitly calls PyType_Ready on types
where the tp_hash and tp_dict slots are both NULL.
+- Issue #4764: With io.open, IOError.filename is set when trying to open a
+ directory on POSIX systems.
+
+- Issue #4764: IOError.filename is set when trying to open a directory on POSIX
+ systems.
+
+- Issue #4759: None is now allowed as the first argument of
+ bytearray.translate(). It was always allowed for bytes.translate().
+
- Issue #4759: fix a segfault for bytearray.translate(x, None).
- Added test case to ensure attempts to read from a file opened for writing
@@ -138,9 +150,18 @@ Core and Builtins
Library
-------
+- Issue #4795: inspect.isgeneratorfunction() returns False instead of None when
+ the function is not a generator.
+
- Issue #4702: Throwing a DistutilsPlatformError instead of IOError in case
no MSVC compiler is found under Windows. Original patch by Philip Jenvey.
+ - Issue #4739: Add pydoc help topics for symbols, so that e.g. help('@')
+ works as expected in the interactive environment.
+
+- Issue #4756: zipfile.is_zipfile() now supports file-like objects. Patch by
+ Gabriel Genellina.
+
- Issue #4646: distutils was choking on empty options arg in the setup
function. Original patch by Thomas Heller.
@@ -206,9 +227,16 @@ Library
- Issue #4730: Fixed the cPickle module to handle correctly astral characters
when protocol 0 is used.
+Tools/Demos
+-----------
+
+- Issue #4677: add two list comprehension tests to pybench.
+
Build
-----
+- Issues #4728 and #4060: WORDS_BIGEDIAN is now correct in Universal builds.
+
- Issue #4389: Add icon to the uninstall entry in "add-and-remove-programs".
- Issue #4289: Remove Cancel button from AdvancedDlg.
@@ -239,6 +267,10 @@ C-API
Extension Modules
-----------------
+- Issue #4228: Pack negative values the same way as 2.4 in struct's L format.
+
+- Issue #1040026: Fix os.times result on systems where HZ is incorrect.
+
- Issues #3167, #3682: Fix test_math failures for log, log10 on Solaris,
OpenBSD.
diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c
index da000d0..37633d2 100644
--- a/Modules/_collectionsmodule.c
+++ b/Modules/_collectionsmodule.c
@@ -958,7 +958,7 @@ deque_iter(dequeobject *deque)
{
dequeiterobject *it;
- it = PyObject_New(dequeiterobject, &dequeiter_type);
+ it = PyObject_GC_New(dequeiterobject, &dequeiter_type);
if (it == NULL)
return NULL;
it->b = deque->leftblock;
@@ -967,14 +967,22 @@ deque_iter(dequeobject *deque)
it->deque = deque;
it->state = deque->state;
it->counter = deque->len;
+ _PyObject_GC_TRACK(it);
return (PyObject *)it;
}
+static int
+dequeiter_traverse(dequeiterobject *dio, visitproc visit, void *arg)
+{
+ Py_VISIT(dio->deque);
+ return 0;
+}
+
static void
dequeiter_dealloc(dequeiterobject *dio)
{
Py_XDECREF(dio->deque);
- Py_TYPE(dio)->tp_free(dio);
+ PyObject_GC_Del(dio);
}
static PyObject *
@@ -1039,9 +1047,9 @@ static PyTypeObject dequeiter_type = {
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT, /* tp_flags */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
0, /* tp_doc */
- 0, /* tp_traverse */
+ (traverseproc)dequeiter_traverse, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
@@ -1060,7 +1068,7 @@ deque_reviter(dequeobject *deque)
{
dequeiterobject *it;
- it = PyObject_New(dequeiterobject, &dequereviter_type);
+ it = PyObject_GC_New(dequeiterobject, &dequereviter_type);
if (it == NULL)
return NULL;
it->b = deque->rightblock;
@@ -1069,6 +1077,7 @@ deque_reviter(dequeobject *deque)
it->deque = deque;
it->state = deque->state;
it->counter = deque->len;
+ _PyObject_GC_TRACK(it);
return (PyObject *)it;
}
@@ -1121,9 +1130,9 @@ static PyTypeObject dequereviter_type = {
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT, /* tp_flags */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
0, /* tp_doc */
- 0, /* tp_traverse */
+ (traverseproc)dequeiter_traverse, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
diff --git a/Modules/_fileio.c b/Modules/_fileio.c
index 65cc99d..ca12822 100644
--- a/Modules/_fileio.c
+++ b/Modules/_fileio.c
@@ -98,7 +98,7 @@ fileio_new(PyTypeObject *type, PyObject *args, PyObject *kews)
directories, so we need a check. */
static int
-dircheck(PyFileIOObject* self)
+dircheck(PyFileIOObject* self, char *name)
{
#if defined(HAVE_FSTAT) && defined(S_IFDIR) && defined(EISDIR)
struct stat buf;
@@ -109,8 +109,8 @@ dircheck(PyFileIOObject* self)
PyObject *exc;
internal_close(self);
- exc = PyObject_CallFunction(PyExc_IOError, "(is)",
- EISDIR, msg);
+ exc = PyObject_CallFunction(PyExc_IOError, "(iss)",
+ EISDIR, msg, name);
PyErr_SetObject(PyExc_IOError, exc);
Py_XDECREF(exc);
return -1;
@@ -271,7 +271,7 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds)
#endif
goto error;
}
- if(dircheck(self) < 0)
+ if(dircheck(self, name) < 0)
goto error;
}
diff --git a/Modules/_struct.c b/Modules/_struct.c
index 30feaa6..b8f1525 100644
--- a/Modules/_struct.c
+++ b/Modules/_struct.c
@@ -663,7 +663,7 @@ np_int(char *p, PyObject *v, const formatdef *f)
return -1;
#if (SIZEOF_LONG > SIZEOF_INT)
if ((x < ((long)INT_MIN)) || (x > ((long)INT_MAX)))
- return _range_error(f, 0);
+ RANGE_ERROR(x, f, 0, -1);
#endif
y = (int)x;
memcpy(p, (char *)&y, sizeof y);
@@ -675,12 +675,12 @@ np_uint(char *p, PyObject *v, const formatdef *f)
{
unsigned long x;
unsigned int y;
- if (get_ulong(v, &x) < 0)
- return _range_error(f, 1);
+ if (get_wrapped_ulong(v, &x) < 0)
+ return -1;
y = (unsigned int)x;
#if (SIZEOF_LONG > SIZEOF_INT)
if (x > ((unsigned long)UINT_MAX))
- return _range_error(f, 1);
+ RANGE_ERROR(y, f, 1, -1);
#endif
memcpy(p, (char *)&y, sizeof y);
return 0;
@@ -700,8 +700,8 @@ static int
np_ulong(char *p, PyObject *v, const formatdef *f)
{
unsigned long x;
- if (get_ulong(v, &x) < 0)
- return _range_error(f, 1);
+ if (get_wrapped_ulong(v, &x) < 0)
+ return -1;
memcpy(p, (char *)&x, sizeof x);
return 0;
}
diff --git a/Objects/dictobject.c b/Objects/dictobject.c
index f2ef4b0..f4d8683 100644
--- a/Objects/dictobject.c
+++ b/Objects/dictobject.c
@@ -2331,7 +2331,7 @@ static PyObject *
dictiter_new(PyDictObject *dict, PyTypeObject *itertype)
{
dictiterobject *di;
- di = PyObject_New(dictiterobject, itertype);
+ di = PyObject_GC_New(dictiterobject, itertype);
if (di == NULL)
return NULL;
Py_INCREF(dict);
@@ -2348,6 +2348,7 @@ dictiter_new(PyDictObject *dict, PyTypeObject *itertype)
}
else
di->di_result = NULL;
+ _PyObject_GC_TRACK(di);
return (PyObject *)di;
}
@@ -2356,7 +2357,15 @@ dictiter_dealloc(dictiterobject *di)
{
Py_XDECREF(di->di_dict);
Py_XDECREF(di->di_result);
- PyObject_Del(di);
+ PyObject_GC_Del(di);
+}
+
+static int
+dictiter_traverse(dictiterobject *di, visitproc visit, void *arg)
+{
+ Py_VISIT(di->di_dict);
+ Py_VISIT(di->di_result);
+ return 0;
}
static PyObject *
@@ -2435,9 +2444,9 @@ PyTypeObject PyDictIterKey_Type = {
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT, /* tp_flags */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
0, /* tp_doc */
- 0, /* tp_traverse */
+ (traverseproc)dictiter_traverse, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
@@ -2507,9 +2516,9 @@ PyTypeObject PyDictIterValue_Type = {
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT, /* tp_flags */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
0, /* tp_doc */
- 0, /* tp_traverse */
+ (traverseproc)dictiter_traverse, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
@@ -2593,9 +2602,9 @@ PyTypeObject PyDictIterItem_Type = {
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT, /* tp_flags */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
0, /* tp_doc */
- 0, /* tp_traverse */
+ (traverseproc)dictiter_traverse, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
diff --git a/Objects/fileobject.c b/Objects/fileobject.c
index b2051d7..e01f38e 100644
--- a/Objects/fileobject.c
+++ b/Objects/fileobject.c
@@ -132,8 +132,8 @@ dircheck(PyFileObject* f)
if (fstat(fileno(f->f_fp), &buf) == 0 &&
S_ISDIR(buf.st_mode)) {
char *msg = strerror(EISDIR);
- PyObject *exc = PyObject_CallFunction(PyExc_IOError, "(is)",
- EISDIR, msg);
+ PyObject *exc = PyObject_CallFunction(PyExc_IOError, "(isO)",
+ EISDIR, msg, f->f_name);
PyErr_SetObject(PyExc_IOError, exc);
Py_XDECREF(exc);
return NULL;
diff --git a/Objects/setobject.c b/Objects/setobject.c
index ea3970e..a55bbb7 100644
--- a/Objects/setobject.c
+++ b/Objects/setobject.c
@@ -810,7 +810,14 @@ static void
setiter_dealloc(setiterobject *si)
{
Py_XDECREF(si->si_set);
- PyObject_Del(si);
+ PyObject_GC_Del(si);
+}
+
+static int
+setiter_traverse(setiterobject *si, visitproc visit, void *arg)
+{
+ Py_VISIT(si->si_set);
+ return 0;
}
static PyObject *
@@ -888,9 +895,9 @@ static PyTypeObject PySetIter_Type = {
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT, /* tp_flags */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
0, /* tp_doc */
- 0, /* tp_traverse */
+ (traverseproc)setiter_traverse, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
@@ -903,7 +910,7 @@ static PyTypeObject PySetIter_Type = {
static PyObject *
set_iter(PySetObject *so)
{
- setiterobject *si = PyObject_New(setiterobject, &PySetIter_Type);
+ setiterobject *si = PyObject_GC_New(setiterobject, &PySetIter_Type);
if (si == NULL)
return NULL;
Py_INCREF(so);
@@ -911,6 +918,7 @@ set_iter(PySetObject *so)
si->si_used = so->used;
si->si_pos = 0;
si->len = so->used;
+ _PyObject_GC_TRACK(si);
return (PyObject *)si;
}
diff --git a/Tools/pybench/Lists.py b/Tools/pybench/Lists.py
index 67760db..6c297a3 100644
--- a/Tools/pybench/Lists.py
+++ b/Tools/pybench/Lists.py
@@ -293,3 +293,58 @@ class SmallLists(Test):
for i in xrange(self.rounds):
pass
+
+class SimpleListComprehensions(Test):
+
+ version = 2.0
+ operations = 6
+ rounds = 20000
+
+ def test(self):
+
+ n = range(10) * 10
+
+ for i in xrange(self.rounds):
+ l = [x for x in n]
+ l = [x for x in n if x]
+ l = [x for x in n if not x]
+
+ l = [x for x in n]
+ l = [x for x in n if x]
+ l = [x for x in n if not x]
+
+ def calibrate(self):
+
+ n = range(10) * 10
+
+ for i in xrange(self.rounds):
+ pass
+
+class NestedListComprehensions(Test):
+
+ version = 2.0
+ operations = 6
+ rounds = 20000
+
+ def test(self):
+
+ m = range(10)
+ n = range(10)
+
+ for i in xrange(self.rounds):
+ l = [x for x in n for y in m]
+ l = [y for x in n for y in m]
+
+ l = [x for x in n for y in m if y]
+ l = [y for x in n for y in m if x]
+
+ l = [x for x in n for y in m if not y]
+ l = [y for x in n for y in m if not x]
+
+ def calibrate(self):
+
+ m = range(10)
+ n = range(10)
+
+ for i in xrange(self.rounds):
+ pass