[Python-checkins] r66050 - in python/branches/tlee-ast-optimize: Doc/c-api/object.rst Doc/whatsnew/2.6.rst Include/abstract.h Include/object.h Lib/test/test_abc.py Lib/test/test_exceptions.py Lib/test/test_typechecks.py Misc/NEWS Objects/abstract.c Objects/typeobject.c Python/errors.c
thomas.lee
python-checkins at python.org
Wed Aug 27 11:15:25 CEST 2008
Author: thomas.lee
Date: Wed Aug 27 11:15:24 2008
New Revision: 66050
Log:
Merged revisions 66030-66049 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk
........
r66039 | benjamin.peterson | 2008-08-27 03:08:40 +1000 (Wed, 27 Aug 2008) | 1 line
sort of backport 66038 by aliasing PyObject_Bytes to PyObject_Str
........
r66043 | antoine.pitrou | 2008-08-27 08:42:08 +1000 (Wed, 27 Aug 2008) | 11 lines
Issue #2534: speed up isinstance() and issubclass() by 50-70%, so as to
match Python 2.5 speed despite the __instancecheck__ / __subclasscheck__
mechanism. In the process, fix a bug where isinstance() and issubclass(),
when given a tuple of classes as second argument, were looking up
__instancecheck__ / __subclasscheck__ on the tuple rather than on each
type object.
Reviewed by Benjamin Peterson and Raymond Hettinger.
........
r66045 | andrew.kuchling | 2008-08-27 10:27:18 +1000 (Wed, 27 Aug 2008) | 1 line
Trim whitespace; add a few updates
........
r66048 | andrew.kuchling | 2008-08-27 10:45:02 +1000 (Wed, 27 Aug 2008) | 1 line
Add an item and a note
........
r66049 | andrew.kuchling | 2008-08-27 12:12:18 +1000 (Wed, 27 Aug 2008) | 1 line
Add various items
........
Modified:
python/branches/tlee-ast-optimize/ (props changed)
python/branches/tlee-ast-optimize/Doc/c-api/object.rst
python/branches/tlee-ast-optimize/Doc/whatsnew/2.6.rst
python/branches/tlee-ast-optimize/Include/abstract.h
python/branches/tlee-ast-optimize/Include/object.h
python/branches/tlee-ast-optimize/Lib/test/test_abc.py
python/branches/tlee-ast-optimize/Lib/test/test_exceptions.py
python/branches/tlee-ast-optimize/Lib/test/test_typechecks.py
python/branches/tlee-ast-optimize/Misc/NEWS
python/branches/tlee-ast-optimize/Objects/abstract.c
python/branches/tlee-ast-optimize/Objects/typeobject.c
python/branches/tlee-ast-optimize/Python/errors.c
Modified: python/branches/tlee-ast-optimize/Doc/c-api/object.rst
==============================================================================
--- python/branches/tlee-ast-optimize/Doc/c-api/object.rst (original)
+++ python/branches/tlee-ast-optimize/Doc/c-api/object.rst Wed Aug 27 11:15:24 2008
@@ -130,6 +130,14 @@
by the :keyword:`print` statement.
+.. cfunction:: PyObject* PyObject_Bytes(PyObject *o)
+
+ .. index:: builtin: bytes
+
+ Compute a bytes representation of object *o*. In 2.x, this is just a alias
+ for :cfunc:`PyObject_Str`.
+
+
.. cfunction:: PyObject* PyObject_Unicode(PyObject *o)
.. index:: builtin: unicode
Modified: python/branches/tlee-ast-optimize/Doc/whatsnew/2.6.rst
==============================================================================
--- python/branches/tlee-ast-optimize/Doc/whatsnew/2.6.rst (original)
+++ python/branches/tlee-ast-optimize/Doc/whatsnew/2.6.rst Wed Aug 27 11:15:24 2008
@@ -529,15 +529,15 @@
The new :mod:`multiprocessing` package lets Python programs create new
processes that will perform a computation and return a result to the
parent. The parent and child processes can communicate using queues
-and pipes, synchronize their operations using locks and semaphores,
-and can share simple arrays of data.
+and pipes, synchronize their operations using locks and semaphores,
+and can share simple arrays of data.
The :mod:`multiprocessing` module started out as an exact emulation of
the :mod:`threading` module using processes instead of threads. That
goal was discarded along the path to Python 2.6, but the general
approach of the module is still similar. The fundamental class
-is the :class:`Process`, which is passed a callable object and
-a collection of arguments. The :meth:`start` method
+is the :class:`Process`, which is passed a callable object and
+a collection of arguments. The :meth:`start` method
sets the callable running in a subprocess, after which you can call
the :meth:`is_alive` method to check whether the subprocess is still running
and the :meth:`join` method to wait for the process to exit.
@@ -668,10 +668,10 @@
The documentation for the :mod:`multiprocessing` module.
:pep:`371` - Addition of the multiprocessing package
- PEP written by Jesse Noller and Richard Oudkerk;
+ PEP written by Jesse Noller and Richard Oudkerk;
implemented by Richard Oudkerk and Jesse Noller.
-
+
.. ======================================================================
.. _pep-3101:
@@ -918,15 +918,15 @@
print len(s) # 12 Unicode characters
-At the C level, Python 3.0 will rename the existing 8-bit
-string type, called :ctype:`PyStringObject` in Python 2.x,
+At the C level, Python 3.0 will rename the existing 8-bit
+string type, called :ctype:`PyStringObject` in Python 2.x,
to :ctype:`PyBytesObject`. Python 2.6 uses ``#define``
-to support using the names :cfunc:`PyBytesObject`,
+to support using the names :cfunc:`PyBytesObject`,
:cfunc:`PyBytes_Check`, :cfunc:`PyBytes_FromStringAndSize`,
and all the other functions and macros used with strings.
-Instances of the :class:`bytes` type are immutable just
-as strings are. A new :class:`bytearray` type stores a mutable
+Instances of the :class:`bytes` type are immutable just
+as strings are. A new :class:`bytearray` type stores a mutable
sequence of bytes::
>>> bytearray([65, 66, 67])
@@ -940,9 +940,9 @@
>>> unicode(str(b), 'utf-8')
u'\u31ef \u3244'
-Byte arrays support most of the methods of string types, such as
+Byte arrays support most of the methods of string types, such as
:meth:`startswith`/:meth:`endswith`, :meth:`find`/:meth:`rfind`,
-and some of the methods of lists, such as :meth:`append`,
+and some of the methods of lists, such as :meth:`append`,
:meth:`pop`, and :meth:`reverse`.
>>> b = bytearray('ABC')
@@ -951,6 +951,11 @@
>>> b
bytearray(b'ABCde')
+There's also a corresponding C API, with
+:cfunc:`PyByteArray_FromObject`,
+:cfunc:`PyByteArray_FromStringAndSize`,
+and various other functions.
+
.. seealso::
:pep:`3112` - Bytes literals in Python 3000
@@ -993,14 +998,14 @@
It supports all of the methods of :class:`RawIOBase`,
and adds a :attr:`raw` attribute holding the underlying raw object.
- There are four concrete classes implementing this ABC:
- :class:`BufferedWriter` and
- :class:`BufferedReader` for objects that only support
- writing or reading and don't support random access,
- :class:`BufferedRandom` for objects that support the :meth:`seek` method
- for random access,
- and :class:`BufferedRWPair` for objects such as TTYs that have
- both read and write operations that act upon unconnected streams of data.
+ There are five concrete classes implementing this ABC.
+ :class:`BufferedWriter` and :class:`BufferedReader` are for objects
+ that only support writing or reading and don't support random
+ access. :class:`BufferedRandom` adds the :meth:`seek` method for
+ random access, and :class:`BufferedRWPair` is for objects such as
+ TTYs that have both read and write operations that act upon
+ unconnected streams of data. The :class:`BytesIO`
+ class supports reading, writing, and seeking over an in-memory buffer.
* :class:`TextIOBase`: Provides functions for reading and writing
strings (remember, strings will be Unicode in Python 3.0),
@@ -1053,8 +1058,7 @@
of arrays so that callers can write data directly into an array instead
of going through a slower API. This PEP updates the buffer protocol in light of experience
from NumPy development, adding a number of new features
-such as indicating the shape of an array,
-locking memory .
+such as indicating the shape of an array or locking a memory region.
The most important new C API function is
``PyObject_GetBuffer(PyObject *obj, Py_buffer *view, int flags)``, which
@@ -1063,10 +1067,11 @@
about the object's memory representation. Objects
can use this operation to lock memory in place
while an external caller could be modifying the contents,
-so there's a corresponding
-``PyBuffer_Release(Py_buffer *view)`` to
+so there's a corresponding ``PyBuffer_Release(Py_buffer *view)`` to
indicate that the external caller is done.
+.. XXX PyObject_GetBuffer not documented in c-api
+
The **flags** argument to :cfunc:`PyObject_GetBuffer` specifies
constraints upon the memory returned. Some examples are:
@@ -1078,7 +1083,8 @@
requests a C-contiguous (last dimension varies the fastest) or
Fortran-contiguous (first dimension varies the fastest) layout.
-.. XXX this feature is not in 2.6 docs yet
+Two new argument codes for :cfunc:`PyArg_ParseTuple`,
+``s*`` and ``z*``, return locked buffer objects for a parameter.
.. seealso::
@@ -1436,6 +1442,18 @@
(Contributed by Alexander Belopolsky; :issue:`1686487`.)
+ It's also now legal to provide keyword arguments after a ``*args`` argument
+ to a function call.
+
+ >>> def f(*args, **kw):
+ ... print args, kw
+ ...
+ >>> f(1,2,3, *(4,5,6), keyword=13)
+ (1, 2, 3, 4, 5, 6) {'keyword': 13}
+
+ Previously this would have been a syntax error.
+ (Contributed by Amaury Forgeot d'Arc; :issue:`3473`.)
+
* A new built-in, ``next(*iterator*, [*default*])`` returns the next item
from the specified iterator. If the *default* argument is supplied,
it will be returned if *iterator* has been exhausted; otherwise,
@@ -1485,8 +1503,8 @@
self._x = value / 2
* Several methods of the built-in set types now accept multiple iterables:
- :meth:`intersection`,
- :meth:`intersection_update`,
+ :meth:`intersection`,
+ :meth:`intersection_update`,
:meth:`union`, :meth:`update`,
:meth:`difference` and :meth:`difference_update`.
@@ -1645,10 +1663,21 @@
(Original optimization implemented by Armin Rigo, updated for
Python 2.6 by Kevin Jacobs; :issue:`1700288`.)
+ By default, this change is only applied to types that are included with
+ the Python core. Extension modules may not necessarily be compatible with
+ this cache,
+ so they must explicitly add :cmacro:`Py_TPFLAGS_HAVE_VERSION_TAG`
+ to the module's ``tp_flags`` field to enable the method cache.
+ (To be compatible with the method cache, the extension module's code
+ must not directly access and modify the ``tp_dict`` member of
+ any of the types it implements. Most modules don't do this,
+ but it's impossible for the Python interpreter to determine that.
+ See :issue:`1878` for some discussion.)
+
* Function calls that use keyword arguments
are significantly faster thanks to a patch that does a quick pointer
comparison, usually saving the time of a full string comparison.
- (Contributed by Raymond Hettinger, after an initial implementation by
+ (Contributed by Raymond Hettinger, after an initial implementation by
Antoine Pitrou; :issue:`1819`.)
* All of the functions in the :mod:`struct` module have been rewritten in
@@ -1701,10 +1730,10 @@
The encoding used for standard input, output, and standard error can
be specified by setting the :envvar:`PYTHONIOENCODING` environment
-variable before running the interpreter. The value should be a string
-in the form ``**encoding**`` or ``**encoding**:**errorhandler**``.
+variable before running the interpreter. The value should be a string
+in the form ``**encoding**`` or ``**encoding**:**errorhandler**``.
The **encoding** part specifies the encoding's name, e.g. ``utf-8`` or
-``latin-1``; the optional **errorhandler** part specifies
+``latin-1``; the optional **errorhandler** part specifies
what to do with characters that can't be handled by the encoding,
and should be one of "error", "ignore", or "replace". (Contributed
by Martin von Loewis.)
@@ -1814,18 +1843,18 @@
:mod:`videoreader`,
:mod:`WAIT`.
-* The :mod:`asyncore` and :mod:`asynchat` modules are
- being actively maintained again, and a number of patches and bugfixes
- were applied. (Maintained by Josiah Carlson; see :issue:`1736190` for
+* The :mod:`asyncore` and :mod:`asynchat` modules are
+ being actively maintained again, and a number of patches and bugfixes
+ were applied. (Maintained by Josiah Carlson; see :issue:`1736190` for
one patch.)
* The :mod:`bsddb.dbshelve` module now uses the highest pickling protocol
available, instead of restricting itself to protocol 1.
(Contributed by W. Barnes; :issue:`1551443`.)
-* The :mod:`cgi` module will now read variables from the query string of an
- HTTP POST request. This makes it possible to use form actions with
- URLs such as "/cgi-bin/add.py?category=1". (Contributed by
+* The :mod:`cgi` module will now read variables from the query string of an
+ HTTP POST request. This makes it possible to use form actions with
+ URLs such as "/cgi-bin/add.py?category=1". (Contributed by
Alexandre Fiori and Nubis; :issue:`1817`.)
* The :mod:`cmath` module underwent an extensive set of revisions,
@@ -1973,7 +2002,7 @@
* When possible, the :mod:`getpass` module will now use
:file:`/dev/tty` (when available) to print
a prompting message and read the password, falling back to using
- standard error and standard input. If the password may be echoed to
+ standard error and standard input. If the password may be echoed to
the terminal, a warning is printed before the prompt is displayed.
(Contributed by Gregory P. Smith.)
@@ -1998,7 +2027,7 @@
:mod:`heapq` is now implemented to only use less-than comparison,
instead of the less-than-or-equal comparison it previously used.
- This makes :mod:`heapq`'s usage of a type match that of the
+ This makes :mod:`heapq`'s usage of a type match that of the
:meth:`list.sort` method.
(Contributed by Raymond Hettinger.)
@@ -2094,8 +2123,8 @@
is true, opening of the log file is deferred until the first
:meth:`emit` call is made. (Contributed by Vinay Sajip.)
- :class:`TimedRotatingFileHandler` also has a *utc* constructor
- parameter. If the argument is true, UTC time will be used
+ :class:`TimedRotatingFileHandler` also has a *utc* constructor
+ parameter. If the argument is true, UTC time will be used
in determining when midnight occurs and in generating filenames;
otherwise local time will be used.
@@ -2246,6 +2275,13 @@
time-consuming searches can now be interrupted.
(Contributed by Josh Hoyt and Ralf Schmitt; :issue:`846388`.)
+ The regular expression module is implemented by compiling bytecodes
+ for a tiny regex-specific virtual machine. Untrusted code
+ could create malicious strings of bytecode directly and cause crashes,
+ so Python 2.6 includes a verifier for the regex bytecode.
+ (Contributed by Guido van Rossum from work for Google App Engine;
+ :issue:`3487`.)
+
* The :mod:`rgbimg` module has been removed.
* The :mod:`rlcompleter` module's :meth:`Completer.complete()` method
@@ -2272,17 +2308,17 @@
* The :func:`shutil.copytree` function now has an optional **ignore** argument
that takes a callable object. This callable will receive each directory path
and a list of the directory's contents, and returns a list of names that
- will be ignored, not copied.
+ will be ignored, not copied.
The :mod:`shutil` module also provides an :func:`ignore_patterns`
function for use with this new parameter.
:func:`ignore_patterns` takes an arbitrary number of glob-style patterns
and will ignore any files and directories that match this pattern.
The following example copies a directory tree, but skip both SVN's internal
- :file:`.svn` directories and Emacs backup
+ :file:`.svn` directories and Emacs backup
files, which have names ending with '~'::
- shutil.copytree('Doc/library', '/tmp/library',
+ shutil.copytree('Doc/library', '/tmp/library',
ignore=shutil.ignore_patterns('*~', '.svn'))
(Contributed by Tarek Ziadé; :issue:`2663`.)
@@ -2395,10 +2431,10 @@
These attributes are all read-only.
(Contributed by Christian Heimes.)
- A new function, :func:`getsizeof`, takes a Python object and returns
+ A new function, :func:`getsizeof`, takes a Python object and returns
the amount of memory used by the object, measured in bytes. Built-in
objects return correct results; third-party extensions may not,
- but can define a :meth:`__sizeof__` method to return the
+ but can define a :meth:`__sizeof__` method to return the
object's size.
(Contributed by Robert Schuppenies; :issue:`2898`.)
@@ -2487,9 +2523,18 @@
(Contributed by Dwayne Bailey; :issue:`1581073`.)
-* The :mod:`threading` module's :class:`Thread` objects
- gained a :meth:`getIdent` method that returns the thread's
- identifier, a nonzero integer. (Contributed by Gregory P. Smith;
+* The :mod:`threading` module API is being changed for Python 3.0, to
+ use properties such as :attr:`daemon` instead of :meth:`setDaemon`
+ and :meth:`isDaemon` methods, and some methods have been renamed to
+ use underscores instead of camel-case; for example, the
+ :meth:`activeCount` method is renamed to :meth:`active_count`. The
+ 2.6 version of the module supports the same properties and renamed
+ methods, but doesn't remove the old methods. (Carried out by
+ various people, most notably Benjamin Peterson.)
+
+ The :mod:`threading` module's :class:`Thread` objects
+ gained an :attr:`ident` property that returns the thread's
+ identifier, a nonzero integer. (Contributed by Gregory P. Smith;
:issue:`2871`.)
* The :mod:`timeit` module now accepts callables as well as strings
@@ -2502,7 +2547,7 @@
:issue:`1533909`.)
* The :mod:`Tkinter` module now accepts lists and tuples for options,
- separating the elements by spaces before passing the resulting value to
+ separating the elements by spaces before passing the resulting value to
Tcl/Tk.
(Contributed by Guilherme Polo; :issue:`2906`.)
@@ -2510,18 +2555,18 @@
Gregor Lingl. New features in the module include:
* Better animation of turtle movement and rotation.
- * Control over turtle movement using the new delay(),
+ * Control over turtle movement using the new delay(),
tracer(), and speed() methods.
- * The ability to set new shapes for the turtle, and to
+ * The ability to set new shapes for the turtle, and to
define a new coordinate system.
* Turtles now have an undo() method that can roll back actions.
* Simple support for reacting to input events such as mouse and keyboard
activity, making it possible to write simple games.
- * A :file:`turtle.cfg` file can be used to customize the starting appearance
+ * A :file:`turtle.cfg` file can be used to customize the starting appearance
of the turtle's screen.
* The module's docstrings can be replaced by new docstrings that have been
translated into another language.
-
+
(:issue:`1513695`)
* An optional ``timeout`` parameter was added to the
@@ -2569,7 +2614,7 @@
dates before 1900 (contributed by Ralf Schmitt; :issue:`2014`)
and 64-bit integers represented by using ``<i8>`` in XML-RPC responses
(contributed by Riku Lindblad; :issue:`2985`).
-
+
* The :mod:`zipfile` module's :class:`ZipFile` class now has
:meth:`extract` and :meth:`extractall` methods that will unpack
a single file or all the files in the archive to the current directory, or
@@ -2585,14 +2630,14 @@
(Contributed by Alan McIntyre; :issue:`467924`.)
- The :meth:`open`, :meth:`read` and :meth:`extract` methods can now
+ The :meth:`open`, :meth:`read` and :meth:`extract` methods can now
take either a filename or a :class:`ZipInfo` object. This is useful when an
archive accidentally contains a duplicated filename.
(Contributed by Graham Horler; :issue:`1775025`.)
Finally, :mod:`zipfile` now supports using Unicode filenames
for archived files. (Contributed by Alexey Borzenkov; :issue:`1734346`.)
-
+
.. ======================================================================
.. whole new modules get described in subsections here
@@ -2603,7 +2648,7 @@
of Python code. For Python 2.6, Armin Ronacher contributed a set of
helper functions that perform various common tasks. These will be useful
for HTML templating packages, code analyzers, and similar tools that
-process Python code.
+process Python code.
The :func:`parse` function takes an expression and returns an AST.
The :func:`dump` function outputs a representation of a tree, suitable
@@ -2638,7 +2683,7 @@
representing a literal expression, one that contains a Python
expression containing only strings, numbers, dictionaries, etc. but no
statements or function calls, and returns the resulting value. If you
-need to unserialize an expression but need to worry about security
+need to unserialize an expression but need to worry about security
and can't risk using an :func:`eval` call, :func:`literal_eval` will
handle it safely::
@@ -2663,22 +2708,22 @@
Python 3.0 makes various changes to the repertoire of built-in
functions, and most of the changes can't be introduced in the Python
2.x series because they would break compatibility.
-The :mod:`future_builtins` module provides versions
-of these built-in functions that can be imported when writing
+The :mod:`future_builtins` module provides versions
+of these built-in functions that can be imported when writing
3.0-compatible code.
The functions in this module currently include:
-* ``ascii(**obj**)``: equivalent to :func:`repr`. In Python 3.0,
- :func:`repr` will return a Unicode string, while :func:`ascii` will
+* ``ascii(**obj**)``: equivalent to :func:`repr`. In Python 3.0,
+ :func:`repr` will return a Unicode string, while :func:`ascii` will
return a pure ASCII bytestring.
-* ``filter(**predicate**, **iterable**)``,
- ``map(**func**, **iterable1**, ...)``: the 3.0 versions
+* ``filter(**predicate**, **iterable**)``,
+ ``map(**func**, **iterable1**, ...)``: the 3.0 versions
return iterators, differing from the 2.x built-ins that return lists.
-* ``hex(**value**)``, ``oct(**value**)``: instead of calling the
- :meth:`__hex__` or :meth:`__oct__` methods, these versions will
+* ``hex(**value**)``, ``oct(**value**)``: instead of calling the
+ :meth:`__hex__` or :meth:`__oct__` methods, these versions will
call the :meth:`__index__` method and convert the result to hexadecimal
or octal.
@@ -2753,8 +2798,8 @@
ctypes Enhancements
--------------------------------------------------
-Thomas Heller continued to maintain and enhance the
-:mod:`ctypes` module.
+Thomas Heller continued to maintain and enhance the
+:mod:`ctypes` module.
:mod:`ctypes` now supports a :class:`c_bool` datatype
that represents the C99 ``bool`` type. (Contributed by David Remahl;
@@ -2767,6 +2812,13 @@
.. Revision 57769
+All :mod:`ctypes` data types now support
+:meth:`from_buffer` and :meth:`from_buffer_copy`
+methods that create a ctypes instance based on a
+provided buffer object. :meth:`from_buffer_copy` copies
+the contents of the object,
+while :meth:`from_buffer` will share the same memory area.
+
A new calling convention tells :mod:`ctypes` to clear the ``errno`` or
Win32 LastError variables at the outset of each wrapped call.
(Implemented by Thomas Heller; :issue:`1798`.)
@@ -2775,13 +2827,13 @@
you can supply ``use_errno=True`` as a keyword parameter
to the :func:`DLL` function
and then call the module-level methods :meth:`set_errno`
-and :meth:`get_errno` to set and retrieve the error value.
+and :meth:`get_errno` to set and retrieve the error value.
The Win32 LastError variable is supported similarly by
the :func:`DLL`, :func:`OleDLL`, and :func:`WinDLL` functions.
You supply ``use_last_error=True`` as a keyword parameter
and then call the module-level methods :meth:`set_last_error`
-and :meth:`get_last_error`.
+and :meth:`get_last_error`.
The :func:`byref` function, used to retrieve a pointer to a ctypes
instance, now has an optional **offset** parameter that is a byte
@@ -2823,7 +2875,7 @@
(Implemented by Christian Heimes.)
* On MacOS X, Python 2.6 can be compiled as a 4-way universal build.
- The :program:`configure` script
+ The :program:`configure` script
can take a :option:`--with-universal-archs=[32-bit|64-bit|all]`
switch, controlling whether the binaries are built for 32-bit
architectures (x86, PowerPC), 64-bit (x86-64 and PPC-64), or both.
@@ -2964,9 +3016,9 @@
registry reflection for 32-bit processes running on 64-bit systems.
(:issue:`1753245`)
-* The :mod:`msilib` module's :class:`Record` object
- gained :meth:`GetInteger` and :meth:`GetString` methods that
- return field values as an integer or a string.
+* The :mod:`msilib` module's :class:`Record` object
+ gained :meth:`GetInteger` and :meth:`GetString` methods that
+ return field values as an integer or a string.
(Contributed by Floris Bruynooghe; :issue:`2125`.)
* The new default compiler on Windows is Visual Studio 2008 (VS 9.0). The
@@ -2982,9 +3034,9 @@
Port-Specific Changes: MacOS X
-----------------------------------
-* When compiling a framework build of Python, you can now specify the
- framework name to be used by providing the
- :option:`--with-framework-name=` option to the
+* When compiling a framework build of Python, you can now specify the
+ framework name to be used by providing the
+ :option:`--with-framework-name=` option to the
:program:`configure` script.
.. ======================================================================
Modified: python/branches/tlee-ast-optimize/Include/abstract.h
==============================================================================
--- python/branches/tlee-ast-optimize/Include/abstract.h (original)
+++ python/branches/tlee-ast-optimize/Include/abstract.h Wed Aug 27 11:15:24 2008
@@ -1377,6 +1377,11 @@
/* issubclass(object, typeorclass) */
+PyAPI_FUNC(int) _PyObject_RealIsInstance(PyObject *inst, PyObject *cls);
+
+PyAPI_FUNC(int) _PyObject_RealIsSubclass(PyObject *derived, PyObject *cls);
+
+
#ifdef __cplusplus
}
#endif
Modified: python/branches/tlee-ast-optimize/Include/object.h
==============================================================================
--- python/branches/tlee-ast-optimize/Include/object.h (original)
+++ python/branches/tlee-ast-optimize/Include/object.h Wed Aug 27 11:15:24 2008
@@ -458,6 +458,7 @@
PyAPI_FUNC(PyObject *) PyObject_Repr(PyObject *);
PyAPI_FUNC(PyObject *) _PyObject_Str(PyObject *);
PyAPI_FUNC(PyObject *) PyObject_Str(PyObject *);
+#define PyObject_Bytes PyObject_Str
#ifdef Py_USING_UNICODE
PyAPI_FUNC(PyObject *) PyObject_Unicode(PyObject *);
#endif
Modified: python/branches/tlee-ast-optimize/Lib/test/test_abc.py
==============================================================================
--- python/branches/tlee-ast-optimize/Lib/test/test_abc.py (original)
+++ python/branches/tlee-ast-optimize/Lib/test/test_abc.py Wed Aug 27 11:15:24 2008
@@ -88,15 +88,21 @@
pass
b = B()
self.assertEqual(issubclass(B, A), False)
+ self.assertEqual(issubclass(B, (A,)), False)
self.assertEqual(isinstance(b, A), False)
+ self.assertEqual(isinstance(b, (A,)), False)
A.register(B)
self.assertEqual(issubclass(B, A), True)
+ self.assertEqual(issubclass(B, (A,)), True)
self.assertEqual(isinstance(b, A), True)
+ self.assertEqual(isinstance(b, (A,)), True)
class C(B):
pass
c = C()
self.assertEqual(issubclass(C, A), True)
+ self.assertEqual(issubclass(C, (A,)), True)
self.assertEqual(isinstance(c, A), True)
+ self.assertEqual(isinstance(c, (A,)), True)
def test_isinstance_invalidation(self):
class A:
@@ -105,20 +111,26 @@
pass
b = B()
self.assertEqual(isinstance(b, A), False)
+ self.assertEqual(isinstance(b, (A,)), False)
A.register(B)
self.assertEqual(isinstance(b, A), True)
+ self.assertEqual(isinstance(b, (A,)), True)
def test_registration_builtins(self):
class A:
__metaclass__ = abc.ABCMeta
A.register(int)
self.assertEqual(isinstance(42, A), True)
+ self.assertEqual(isinstance(42, (A,)), True)
self.assertEqual(issubclass(int, A), True)
+ self.assertEqual(issubclass(int, (A,)), True)
class B(A):
pass
B.register(basestring)
self.assertEqual(isinstance("", A), True)
+ self.assertEqual(isinstance("", (A,)), True)
self.assertEqual(issubclass(str, A), True)
+ self.assertEqual(issubclass(str, (A,)), True)
def test_registration_edge_cases(self):
class A:
@@ -141,29 +153,40 @@
class A:
__metaclass__ = abc.ABCMeta
self.failUnless(issubclass(A, A))
+ self.failUnless(issubclass(A, (A,)))
class B:
__metaclass__ = abc.ABCMeta
self.failIf(issubclass(A, B))
+ self.failIf(issubclass(A, (B,)))
self.failIf(issubclass(B, A))
+ self.failIf(issubclass(B, (A,)))
class C:
__metaclass__ = abc.ABCMeta
A.register(B)
class B1(B):
pass
self.failUnless(issubclass(B1, A))
+ self.failUnless(issubclass(B1, (A,)))
class C1(C):
pass
B1.register(C1)
self.failIf(issubclass(C, B))
+ self.failIf(issubclass(C, (B,)))
self.failIf(issubclass(C, B1))
+ self.failIf(issubclass(C, (B1,)))
self.failUnless(issubclass(C1, A))
+ self.failUnless(issubclass(C1, (A,)))
self.failUnless(issubclass(C1, B))
+ self.failUnless(issubclass(C1, (B,)))
self.failUnless(issubclass(C1, B1))
+ self.failUnless(issubclass(C1, (B1,)))
C1.register(int)
class MyInt(int):
pass
self.failUnless(issubclass(MyInt, A))
+ self.failUnless(issubclass(MyInt, (A,)))
self.failUnless(isinstance(42, A))
+ self.failUnless(isinstance(42, (A,)))
def test_all_new_methods_are_called(self):
class A:
Modified: python/branches/tlee-ast-optimize/Lib/test/test_exceptions.py
==============================================================================
--- python/branches/tlee-ast-optimize/Lib/test/test_exceptions.py (original)
+++ python/branches/tlee-ast-optimize/Lib/test/test_exceptions.py Wed Aug 27 11:15:24 2008
@@ -333,7 +333,19 @@
return g()
except ValueError:
return -1
- self.assertRaises(RuntimeError, g)
+
+ # The test prints an unraisable recursion error when
+ # doing "except ValueError", this is because subclass
+ # checking has recursion checking too.
+ with captured_output("stderr"):
+ try:
+ g()
+ except RuntimeError:
+ pass
+ except:
+ self.fail("Should have raised KeyError")
+ else:
+ self.fail("Should have raised KeyError")
def testUnicodeStrUsage(self):
# Make sure both instances and classes have a str and unicode
@@ -363,12 +375,20 @@
except KeyError:
pass
except:
- self.fail("Should have raised TypeError")
+ self.fail("Should have raised KeyError")
else:
- self.fail("Should have raised TypeError")
- self.assertEqual(stderr.getvalue(),
- "Exception ValueError: ValueError() in "
- "<type 'exceptions.KeyError'> ignored\n")
+ self.fail("Should have raised KeyError")
+
+ with captured_output("stderr") as stderr:
+ def g():
+ try:
+ return g()
+ except RuntimeError:
+ return sys.exc_info()
+ e, v, tb = g()
+ self.assert_(e is RuntimeError, e)
+ self.assert_("maximum recursion depth exceeded" in str(v), v)
+
def test_main():
run_unittest(ExceptionTests)
Modified: python/branches/tlee-ast-optimize/Lib/test/test_typechecks.py
==============================================================================
--- python/branches/tlee-ast-optimize/Lib/test/test_typechecks.py (original)
+++ python/branches/tlee-ast-optimize/Lib/test/test_typechecks.py Wed Aug 27 11:15:24 2008
@@ -41,26 +41,39 @@
def testIsSubclassBuiltin(self):
self.assertEqual(issubclass(int, Integer), True)
+ self.assertEqual(issubclass(int, (Integer,)), True)
self.assertEqual(issubclass(float, Integer), False)
+ self.assertEqual(issubclass(float, (Integer,)), False)
def testIsInstanceBuiltin(self):
self.assertEqual(isinstance(42, Integer), True)
+ self.assertEqual(isinstance(42, (Integer,)), True)
self.assertEqual(isinstance(3.14, Integer), False)
+ self.assertEqual(isinstance(3.14, (Integer,)), False)
def testIsInstanceActual(self):
self.assertEqual(isinstance(Integer(), Integer), True)
+ self.assertEqual(isinstance(Integer(), (Integer,)), True)
def testIsSubclassActual(self):
self.assertEqual(issubclass(Integer, Integer), True)
+ self.assertEqual(issubclass(Integer, (Integer,)), True)
def testSubclassBehavior(self):
self.assertEqual(issubclass(SubInt, Integer), True)
+ self.assertEqual(issubclass(SubInt, (Integer,)), True)
self.assertEqual(issubclass(SubInt, SubInt), True)
+ self.assertEqual(issubclass(SubInt, (SubInt,)), True)
self.assertEqual(issubclass(Integer, SubInt), False)
+ self.assertEqual(issubclass(Integer, (SubInt,)), False)
self.assertEqual(issubclass(int, SubInt), False)
+ self.assertEqual(issubclass(int, (SubInt,)), False)
self.assertEqual(isinstance(SubInt(), Integer), True)
+ self.assertEqual(isinstance(SubInt(), (Integer,)), True)
self.assertEqual(isinstance(SubInt(), SubInt), True)
+ self.assertEqual(isinstance(SubInt(), (SubInt,)), True)
self.assertEqual(isinstance(42, SubInt), False)
+ self.assertEqual(isinstance(42, (SubInt,)), False)
def testInfiniteRecursionCaughtProperly(self):
e = Evil()
Modified: python/branches/tlee-ast-optimize/Misc/NEWS
==============================================================================
--- python/branches/tlee-ast-optimize/Misc/NEWS (original)
+++ python/branches/tlee-ast-optimize/Misc/NEWS Wed Aug 27 11:15:24 2008
@@ -12,6 +12,13 @@
Core and Builtins
-----------------
+- Issue #2534: speed up isinstance() and issubclass() by 50-70%, so as to
+ match Python 2.5 speed despite the __instancecheck__ / __subclasscheck__
+ mechanism. In the process, fix a bug where isinstance() and issubclass(),
+ when given a tuple of classes as second argument, were looking up
+ __instancecheck__ / __subclasscheck__ on the tuple rather than on each
+ type object.
+
- Fix crashes on memory allocation failure found with failmalloc.
- Fix memory leaks found with valgrind and update suppressions file.
@@ -29,6 +36,11 @@
- Added warnings on the use of ``__getslice__``, ``__setslice__``, or
``__delslice__``.
+C-API
+-----
+
+- Aliased PyObject_Bytes to PyObject_Str.
+
Library
-------
Modified: python/branches/tlee-ast-optimize/Objects/abstract.c
==============================================================================
--- python/branches/tlee-ast-optimize/Objects/abstract.c (original)
+++ python/branches/tlee-ast-optimize/Objects/abstract.c Wed Aug 27 11:15:24 2008
@@ -2778,39 +2778,38 @@
static int
abstract_issubclass(PyObject *derived, PyObject *cls)
{
- PyObject *bases;
+ PyObject *bases = NULL;
Py_ssize_t i, n;
int r = 0;
-
- if (derived == cls)
- return 1;
-
- if (PyTuple_Check(cls)) {
- /* Not a general sequence -- that opens up the road to
- recursion and stack overflow. */
- n = PyTuple_GET_SIZE(cls);
+ while (1) {
+ if (derived == cls)
+ return 1;
+ bases = abstract_get_bases(derived);
+ if (bases == NULL) {
+ if (PyErr_Occurred())
+ return -1;
+ return 0;
+ }
+ n = PyTuple_GET_SIZE(bases);
+ if (n == 0) {
+ Py_DECREF(bases);
+ return 0;
+ }
+ /* Avoid recursivity in the single inheritance case */
+ if (n == 1) {
+ derived = PyTuple_GET_ITEM(bases, 0);
+ Py_DECREF(bases);
+ continue;
+ }
for (i = 0; i < n; i++) {
- if (derived == PyTuple_GET_ITEM(cls, i))
- return 1;
+ r = abstract_issubclass(PyTuple_GET_ITEM(bases, i), cls);
+ if (r != 0)
+ break;
}
+ Py_DECREF(bases);
+ return r;
}
- bases = abstract_get_bases(derived);
- if (bases == NULL) {
- if (PyErr_Occurred())
- return -1;
- return 0;
- }
- n = PyTuple_GET_SIZE(bases);
- for (i = 0; i < n; i++) {
- r = abstract_issubclass(PyTuple_GET_ITEM(bases, i), cls);
- if (r != 0)
- break;
- }
-
- Py_DECREF(bases);
-
- return r;
}
static int
@@ -2828,7 +2827,7 @@
}
static int
-recursive_isinstance(PyObject *inst, PyObject *cls, int recursion_depth)
+recursive_isinstance(PyObject *inst, PyObject *cls)
{
PyObject *icls;
static PyObject *__class__ = NULL;
@@ -2862,25 +2861,6 @@
}
}
}
- else if (PyTuple_Check(cls)) {
- Py_ssize_t i, n;
-
- if (!recursion_depth) {
- PyErr_SetString(PyExc_RuntimeError,
- "nest level of tuple too deep");
- return -1;
- }
-
- n = PyTuple_GET_SIZE(cls);
- for (i = 0; i < n; i++) {
- retval = recursive_isinstance(
- inst,
- PyTuple_GET_ITEM(cls, i),
- recursion_depth-1);
- if (retval != 0)
- break;
- }
- }
else {
if (!check_class(cls,
"isinstance() arg 2 must be a class, type,"
@@ -2910,6 +2890,24 @@
if (Py_TYPE(inst) == (PyTypeObject *)cls)
return 1;
+ if (PyTuple_Check(cls)) {
+ Py_ssize_t i;
+ Py_ssize_t n;
+ int r = 0;
+
+ if (Py_EnterRecursiveCall(" in __instancecheck__"))
+ return -1;
+ n = PyTuple_GET_SIZE(cls);
+ for (i = 0; i < n; ++i) {
+ PyObject *item = PyTuple_GET_ITEM(cls, i);
+ r = PyObject_IsInstance(inst, item);
+ if (r != 0)
+ /* either found it, or got an error */
+ break;
+ }
+ Py_LeaveRecursiveCall();
+ return r;
+ }
if (name == NULL) {
name = PyString_InternFromString("__instancecheck__");
if (name == NULL)
@@ -2934,47 +2932,28 @@
}
return ok;
}
- return recursive_isinstance(inst, cls, Py_GetRecursionLimit());
+ return recursive_isinstance(inst, cls);
}
static int
-recursive_issubclass(PyObject *derived, PyObject *cls, int recursion_depth)
+recursive_issubclass(PyObject *derived, PyObject *cls)
{
int retval;
+ if (PyType_Check(cls) && PyType_Check(derived)) {
+ /* Fast path (non-recursive) */
+ return PyType_IsSubtype(
+ (PyTypeObject *)derived, (PyTypeObject *)cls);
+ }
if (!PyClass_Check(derived) || !PyClass_Check(cls)) {
if (!check_class(derived,
"issubclass() arg 1 must be a class"))
return -1;
- if (PyTuple_Check(cls)) {
- Py_ssize_t i;
- Py_ssize_t n = PyTuple_GET_SIZE(cls);
-
- if (!recursion_depth) {
- PyErr_SetString(PyExc_RuntimeError,
- "nest level of tuple too deep");
- return -1;
- }
- for (i = 0; i < n; ++i) {
- retval = recursive_issubclass(
- derived,
- PyTuple_GET_ITEM(cls, i),
- recursion_depth-1);
- if (retval != 0) {
- /* either found it, or got an error */
- return retval;
- }
- }
- return 0;
- }
- else {
- if (!check_class(cls,
- "issubclass() arg 2 must be a class"
- " or tuple of classes"))
- return -1;
- }
-
+ if (!check_class(cls,
+ "issubclass() arg 2 must be a class"
+ " or tuple of classes"))
+ return -1;
retval = abstract_issubclass(derived, cls);
}
else {
@@ -2992,20 +2971,40 @@
static PyObject *name = NULL;
PyObject *t, *v, *tb;
PyObject *checker;
- PyErr_Fetch(&t, &v, &tb);
+ if (PyTuple_Check(cls)) {
+ Py_ssize_t i;
+ Py_ssize_t n;
+ int r = 0;
+
+ if (Py_EnterRecursiveCall(" in __subclasscheck__"))
+ return -1;
+ n = PyTuple_GET_SIZE(cls);
+ for (i = 0; i < n; ++i) {
+ PyObject *item = PyTuple_GET_ITEM(cls, i);
+ r = PyObject_IsSubclass(derived, item);
+ if (r != 0)
+ /* either found it, or got an error */
+ break;
+ }
+ Py_LeaveRecursiveCall();
+ return r;
+ }
if (name == NULL) {
name = PyString_InternFromString("__subclasscheck__");
if (name == NULL)
return -1;
}
+ PyErr_Fetch(&t, &v, &tb);
checker = PyObject_GetAttr(cls, name);
PyErr_Restore(t, v, tb);
if (checker != NULL) {
PyObject *res;
int ok = -1;
- if (Py_EnterRecursiveCall(" in __subclasscheck__"))
+ if (Py_EnterRecursiveCall(" in __subclasscheck__")) {
+ Py_DECREF(checker);
return ok;
+ }
res = PyObject_CallFunctionObjArgs(checker, derived, NULL);
Py_LeaveRecursiveCall();
Py_DECREF(checker);
@@ -3015,7 +3014,19 @@
}
return ok;
}
- return recursive_issubclass(derived, cls, Py_GetRecursionLimit());
+ return recursive_issubclass(derived, cls);
+}
+
+int
+_PyObject_RealIsInstance(PyObject *inst, PyObject *cls)
+{
+ return recursive_isinstance(inst, cls);
+}
+
+int
+_PyObject_RealIsSubclass(PyObject *derived, PyObject *cls)
+{
+ return recursive_issubclass(derived, cls);
}
Modified: python/branches/tlee-ast-optimize/Objects/typeobject.c
==============================================================================
--- python/branches/tlee-ast-optimize/Objects/typeobject.c (original)
+++ python/branches/tlee-ast-optimize/Objects/typeobject.c Wed Aug 27 11:15:24 2008
@@ -571,6 +571,49 @@
return result;
}
+static PyObject *
+type___instancecheck__(PyObject *type, PyObject *inst)
+{
+ switch (_PyObject_RealIsInstance(inst, type)) {
+ case -1:
+ return NULL;
+ case 0:
+ Py_RETURN_FALSE;
+ default:
+ Py_RETURN_TRUE;
+ }
+}
+
+
+static PyObject *
+type_get_instancecheck(PyObject *type, void *context)
+{
+ static PyMethodDef ml = {"__instancecheck__",
+ type___instancecheck__, METH_O };
+ return PyCFunction_New(&ml, type);
+}
+
+static PyObject *
+type___subclasscheck__(PyObject *type, PyObject *inst)
+{
+ switch (_PyObject_RealIsSubclass(inst, type)) {
+ case -1:
+ return NULL;
+ case 0:
+ Py_RETURN_FALSE;
+ default:
+ Py_RETURN_TRUE;
+ }
+}
+
+static PyObject *
+type_get_subclasscheck(PyObject *type, void *context)
+{
+ static PyMethodDef ml = {"__subclasscheck__",
+ type___subclasscheck__, METH_O };
+ return PyCFunction_New(&ml, type);
+}
+
static PyGetSetDef type_getsets[] = {
{"__name__", (getter)type_name, (setter)type_set_name, NULL},
{"__bases__", (getter)type_get_bases, (setter)type_set_bases, NULL},
@@ -579,6 +622,8 @@
(setter)type_set_abstractmethods, NULL},
{"__dict__", (getter)type_dict, NULL, NULL},
{"__doc__", (getter)type_get_doc, NULL, NULL},
+ {"__instancecheck__", (getter)type_get_instancecheck, NULL, NULL},
+ {"__subclasscheck__", (getter)type_get_subclasscheck, NULL, NULL},
{0}
};
Modified: python/branches/tlee-ast-optimize/Python/errors.c
==============================================================================
--- python/branches/tlee-ast-optimize/Python/errors.c (original)
+++ python/branches/tlee-ast-optimize/Python/errors.c Wed Aug 27 11:15:24 2008
@@ -113,7 +113,6 @@
/* This function must not fail, so print the error here */
if (res == -1) {
PyErr_WriteUnraisable(err);
- /* issubclass did not succeed */
res = 0;
}
PyErr_Restore(exception, value, tb);
More information about the Python-checkins
mailing list