merge heads

This commit is contained in:
Benjamin Peterson 2012-10-09 11:16:26 -04:00
commit 455fa0a314
85 changed files with 8070 additions and 6993 deletions

View File

@ -53,7 +53,7 @@ checkout:
fi
@if [ ! -d tools/pygments ]; then \
echo "Checking out Pygments..."; \
svn checkout $(SVNROOT)/external/Pygments-1.3.1/pygments tools/pygments; \
svn checkout $(SVNROOT)/external/Pygments-1.5dev-20120930/pygments tools/pygments; \
fi
update: clean checkout

View File

@ -1083,8 +1083,6 @@ These are the UTF-32 codec APIs:
After completion, *\*byteorder* is set to the current byte order at the end
of input data.
In a narrow build codepoints outside the BMP will be decoded as surrogate pairs.
If *byteorder* is *NULL*, the codec starts in native order mode.
Return *NULL* if an exception was raised by the codec.

View File

@ -660,7 +660,7 @@ Glossary
sequence
An :term:`iterable` which supports efficient element access using integer
indices via the :meth:`__getitem__` special method and defines a
:meth:`len` method that returns the length of the sequence.
:meth:`__len__` method that returns the length of the sequence.
Some built-in sequence types are :class:`list`, :class:`str`,
:class:`tuple`, and :class:`bytes`. Note that :class:`dict` also
supports :meth:`__getitem__` and :meth:`__len__`, but is considered a

View File

@ -1,7 +1,7 @@
.. _ipaddress-howto:
***************************************
An Introduction to the ipaddress module
An introduction to the ipaddress module
***************************************
:author: Peter Moody
@ -47,7 +47,12 @@ Addresses, often referred to as "host addresses" are the most basic unit
when working with IP addressing. The simplest way to create addresses is
to use the :func:`ipaddress.ip_address` factory function, which automatically
determines whether to create an IPv4 or IPv6 address based on the passed in
value::
value:
.. testsetup::
>>> import ipaddress
::
>>> ipaddress.ip_address('192.0.2.1')
IPv4Address('192.0.2.1')
@ -142,7 +147,7 @@ address.
>>> ipaddress.ip_interface('192.0.2.1/24')
IPv4Interface('192.0.2.1/24')
>>> ipaddress.ip_network('2001:db8::1/96')
>>> ipaddress.ip_interface('2001:db8::1/96')
IPv6Interface('2001:db8::1/96')
Integer inputs are accepted (as with networks), and use of a particular IP
@ -177,22 +182,22 @@ Obtaining the network from an interface::
Finding out how many individual addresses are in a network::
>>> net4 = ipaddress.ip_network('192.0.2.0/24')
>>> net4.numhosts
>>> net4.num_addresses
256
>>> net6 = ipaddress.ip_network('2001:db8::0/96')
>>> net6.numhosts
>>> net6.num_addresses
4294967296
Iterating through the "usable" addresses on a network::
>>> net4 = ipaddress.ip_network('192.0.2.0/24')
>>> for x in net4.hosts():
print(x)
... print(x) # doctest: +ELLIPSIS
192.0.2.1
192.0.2.2
192.0.2.3
192.0.2.4
<snip>
...
192.0.2.252
192.0.2.253
192.0.2.254
@ -216,9 +221,9 @@ the hostmask (any bits that are not part of the netmask):
Exploding or compressing the address::
>>> addr6.exploded
'2001:0db8:0000:0000:0000:0000:0000:0000'
'2001:0db8:0000:0000:0000:0000:0000:0001'
>>> addr6.compressed
'2001:db8::'
'2001:db8::1'
>>> net6.exploded
'2001:0db8:0000:0000:0000:0000:0000:0000/96'
>>> net6.compressed
@ -241,9 +246,9 @@ to index them like this::
>>> net4[-1]
IPv4Address('192.0.2.255')
>>> net6[1]
IPv6Address('2001::1')
IPv6Address('2001:db8::1')
>>> net6[-1]
IPv6Address('2001::ffff:ffff')
IPv6Address('2001:db8::ffff:ffff')
It also means that network objects lend themselves to using the list

View File

@ -144,7 +144,7 @@ This is done as follows::
>>> data['location'] = 'Northampton'
>>> data['language'] = 'Python'
>>> url_values = urllib.parse.urlencode(data)
>>> print(url_values)
>>> print(url_values) # The order may differ from below. #doctest: +SKIP
name=Somebody+Here&language=Python&location=Northampton
>>> url = 'http://www.example.com/example.cgi'
>>> full_url = url + '?' + url_values
@ -214,9 +214,9 @@ e.g. ::
>>> req = urllib.request.Request('http://www.pretend_server.org')
>>> try: urllib.request.urlopen(req)
>>> except urllib.error.URLError as e:
>>> print(e.reason)
>>>
... except urllib.error.URLError as e:
... print(e.reason) #doctest: +SKIP
...
(4, 'getaddrinfo failed')
@ -322,18 +322,17 @@ geturl, and info, methods as returned by the ``urllib.response`` module::
>>> req = urllib.request.Request('http://www.python.org/fish.html')
>>> try:
>>> urllib.request.urlopen(req)
>>> except urllib.error.HTTPError as e:
>>> print(e.code)
>>> print(e.read())
>>>
... urllib.request.urlopen(req)
... except urllib.error.HTTPError as e:
... print(e.code)
... print(e.read()) #doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
...
404
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<?xml-stylesheet href="./css/ht2html.css"
type="text/css"?>
<html><head><title>Error 404: File Not Found</title>
...... etc...
b'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n\n\n<html
...
<title>Page Not Found</title>\n
...
Wrapping it Up
--------------

View File

@ -159,7 +159,7 @@ contexts::
d['x'] # Get first key in the chain of contexts
d['x'] = 1 # Set value in current context
del['x'] # Delete from current context
del d['x'] # Delete from current context
list(d) # All nested values
k in d # Check all nested values
len(d) # Number of nested values

View File

@ -15,6 +15,7 @@ multitasking) Here's an overview:
threading.rst
multiprocessing.rst
concurrent.rst
concurrent.futures.rst
subprocess.rst
sched.rst

View File

@ -0,0 +1,6 @@
The :mod:`concurrent` package
=============================
Currently, there is only one module in this package:
* :mod:`concurrent.futures` -- Launching parallel tasks

View File

@ -770,9 +770,9 @@ An example of writing to a configuration file::
# values using the mapping protocol or ConfigParser's set() does not allow
# such assignments to take place.
config.add_section('Section1')
config.set('Section1', 'int', '15')
config.set('Section1', 'bool', 'true')
config.set('Section1', 'float', '3.1415')
config.set('Section1', 'an_int', '15')
config.set('Section1', 'a_bool', 'true')
config.set('Section1', 'a_float', '3.1415')
config.set('Section1', 'baz', 'fun')
config.set('Section1', 'bar', 'Python')
config.set('Section1', 'foo', '%(bar)s is %(baz)s!')
@ -790,13 +790,13 @@ An example of reading the configuration file again::
# getfloat() raises an exception if the value is not a float
# getint() and getboolean() also do this for their respective types
float = config.getfloat('Section1', 'float')
int = config.getint('Section1', 'int')
print(float + int)
a_float = config.getfloat('Section1', 'a_float')
an_int = config.getint('Section1', 'an_int')
print(a_float + an_int)
# Notice that the next output does not interpolate '%(bar)s' or '%(baz)s'.
# This is because we are using a RawConfigParser().
if config.getboolean('Section1', 'bool'):
if config.getboolean('Section1', 'a_bool'):
print(config.get('Section1', 'foo'))
To get interpolation, use :class:`ConfigParser`::

View File

@ -650,7 +650,16 @@ above.
An example's doctest directives modify doctest's behavior for that single
example. Use ``+`` to enable the named behavior, or ``-`` to disable it.
For example, this test passes::
.. note::
Due to an `unfortunate limitation`_ of our current documentation
publishing process, syntax highlighting has been disabled in the examples
below in order to ensure the doctest directives are correctly displayed.
.. _unfortunate limitation: http://bugs.python.org/issue12947
For example, this test passes:
.. code-block:: text
>>> print(list(range(20))) #doctest: +NORMALIZE_WHITESPACE
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
@ -659,18 +668,25 @@ For example, this test passes::
Without the directive it would fail, both because the actual output doesn't have
two blanks before the single-digit list elements, and because the actual output
is on a single line. This test also passes, and also requires a directive to do
so::
so:
.. code-block:: text
>>> print(list(range(20))) # doctest: +ELLIPSIS
[0, 1, ..., 18, 19]
Multiple directives can be used on a single physical line, separated by commas::
Multiple directives can be used on a single physical line, separated by
commas:
.. code-block:: text
>>> print(list(range(20))) # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
[0, 1, ..., 18, 19]
If multiple directive comments are used for a single example, then they are
combined::
combined:
.. code-block:: text
>>> print(list(range(20))) # doctest: +ELLIPSIS
... # doctest: +NORMALIZE_WHITESPACE
@ -678,7 +694,9 @@ combined::
As the previous example shows, you can add ``...`` lines to your example
containing only directives. This can be useful when an example is too long for
a directive to comfortably fit on the same line::
a directive to comfortably fit on the same line:
.. code-block:: text
>>> print(list(range(5)) + list(range(10, 20)) + list(range(30, 40)))
... # doctest: +ELLIPSIS

View File

@ -17,7 +17,7 @@ Suggested usage is::
try:
import threading
except ImportError:
import dummy_threading
import dummy_threading as threading
Be careful to not use this module where deadlock might occur from a thread being
created that blocks waiting for another thread to be created. This often occurs

View File

@ -270,12 +270,12 @@ followed by ``lines`` for the text version or ``binary`` for the binary version.
.. method:: FTP.storbinary(cmd, file, blocksize=8192, callback=None, rest=None)
Store a file in binary transfer mode. *cmd* should be an appropriate
``STOR`` command: ``"STOR filename"``. *file* is an open :term:`file object`
which is read until EOF using its :meth:`read` method in blocks of size
*blocksize* to provide the data to be stored. The *blocksize* argument
defaults to 8192. *callback* is an optional single parameter callable that
is called on each block of data after it is sent. *rest* means the same thing
as in the :meth:`transfercmd` method.
``STOR`` command: ``"STOR filename"``. *file* is a :term:`file object`
(opened in binary mode) which is read until EOF using its :meth:`read`
method in blocks of size *blocksize* to provide the data to be stored.
The *blocksize* argument defaults to 8192. *callback* is an optional single
parameter callable that is called on each block of data after it is sent.
*rest* means the same thing as in the :meth:`transfercmd` method.
.. versionchanged:: 3.2
*rest* parameter added.
@ -285,9 +285,9 @@ followed by ``lines`` for the text version or ``binary`` for the binary version.
Store a file in ASCII transfer mode. *cmd* should be an appropriate
``STOR`` command (see :meth:`storbinary`). Lines are read until EOF from the
open :term:`file object` *file* using its :meth:`readline` method to provide
the data to be stored. *callback* is an optional single parameter callable
that is called on each line after it is sent.
:term:`file object` *file* (opened in binary mode) using its :meth:`readline`
method to provide the data to be stored. *callback* is an optional single
parameter callable that is called on each line after it is sent.
.. method:: FTP.transfercmd(cmd, rest=None)

View File

@ -1203,7 +1203,8 @@ are always available. They are listed here in alphabetical order.
.. _func-str:
.. function:: str([object[, encoding[, errors]]])
.. function:: str(object='')
str(object[, encoding[, errors]])
Return a string version of an object, using one of the following modes:

View File

@ -189,13 +189,13 @@ values but should not rebind them):
after collection. The callbacks will be called with two arguments,
*phase* and *info*.
*phase* can one of two values:
*phase* can be one of two values:
"start": The garbage collection is about to start.
"stop": The garbage collection has finished.
*info* provides more information for the callback. The following
*info* is a dict providing more information for the callback. The following
keys are currently defined:
"generation": The oldest generation being collected.
@ -203,7 +203,7 @@ values but should not rebind them):
"collected": When *phase* is "stop", the number of objects
successfully collected.
"uncollectable": when *phase* is "stop", the number of objects
"uncollectable": When *phase* is "stop", the number of objects
that could not be collected and were put in :data:`garbage`.
Applications can add their own callbacks to this list. The primary

View File

@ -19,3 +19,10 @@ This module defines utilities to manipulate HTML.
attribute value delimited by quotes, as in ``<a href="...">``.
.. versionadded:: 3.2
--------------
Submodules in the ``html`` package are:
* :mod:`html.parser` -- HTML/XHTML parser with lenient parsing mode
* :mod:`html.entities` -- HTML entity definitions

11
Doc/library/http.rst Normal file
View File

@ -0,0 +1,11 @@
:mod:`http` --- HTTP modules
============================
``http`` is a package that collects several modules for working with the
HyperText Transfer Protocol:
* :mod:`http.client` is a low-level HTTP protocol client; for high-level URL
opening use :mod:`urllib.request`
* :mod:`http.server` contains basic HTTP server classes based on :mod:`socketserver`
* :mod:`http.cookies` has utilities for implementing state management with cookies
* :mod:`http.cookiejar` provides persistence of cookies

View File

@ -23,10 +23,12 @@ is currently supported on most popular platforms. Here is an overview:
cgi.rst
cgitb.rst
wsgiref.rst
urllib.rst
urllib.request.rst
urllib.parse.rst
urllib.error.rst
urllib.robotparser.rst
http.rst
http.client.rst
ftplib.rst
poplib.rst
@ -40,6 +42,7 @@ is currently supported on most popular platforms. Here is an overview:
http.server.rst
http.cookies.rst
http.cookiejar.rst
xmlrpc.rst
xmlrpc.client.rst
xmlrpc.server.rst
ipaddress.rst

View File

@ -42,8 +42,15 @@ IP addresses, networks and interfaces:
Return an :class:`IPv4Address` or :class:`IPv6Address` object depending on
the IP address passed as argument. Either IPv4 or IPv6 addresses may be
supplied; integers less than 2**32 will be considered to be IPv4 by default.
A :exc:`ValueError` is raised if *address* does not represent a valid IPv4 or
IPv6 address.
A :exc:`ValueError` is raised if *address* does not represent a valid IPv4
or IPv6 address.
.. testsetup::
>>> import ipaddress
>>> from ipaddress import (ip_network, IPv4Address, IPv4Interface,
... IPv4Network)
::
>>> ipaddress.ip_address('192.168.0.1')
IPv4Address('192.168.0.1')
@ -111,7 +118,7 @@ write code that handles both IP versions correctly.
>>> ipaddress.IPv4Address('192.168.0.1')
IPv4Address('192.168.0.1')
>>> ipaddress.IPv4Address(3221225985)
>>> ipaddress.IPv4Address(3232235521)
IPv4Address('192.168.0.1')
>>> ipaddress.IPv4Address(b'\xC0\xA8\x00\x01')
IPv4Address('192.168.0.1')
@ -437,7 +444,7 @@ so to avoid duplication they are only documented for :class:`IPv4Network`.
hosts are all the IP addresses that belong to the network, except the
network address itself and the network broadcast address.
>>> list(ip_network('192.0.2.0/29').hosts())
>>> list(ip_network('192.0.2.0/29').hosts()) #doctest: +NORMALIZE_WHITESPACE
[IPv4Address('192.0.2.1'), IPv4Address('192.0.2.2'),
IPv4Address('192.0.2.3'), IPv4Address('192.0.2.4'),
IPv4Address('192.0.2.5'), IPv4Address('192.0.2.6')]
@ -456,7 +463,7 @@ so to avoid duplication they are only documented for :class:`IPv4Network`.
>>> n1 = ip_network('192.0.2.0/28')
>>> n2 = ip_network('192.0.2.1/32')
>>> list(n1.address_exclude(n2))
>>> list(n1.address_exclude(n2)) #doctest: +NORMALIZE_WHITESPACE
[IPv4Network('192.0.2.8/29'), IPv4Network('192.0.2.4/30'),
IPv4Network('192.0.2.2/31'), IPv4Network('192.0.2.0/32')]
@ -471,10 +478,10 @@ so to avoid duplication they are only documented for :class:`IPv4Network`.
>>> list(ip_network('192.0.2.0/24').subnets())
[IPv4Network('192.0.2.0/25'), IPv4Network('192.0.2.128/25')]
>>> list(ip_network('192.0.2.0/24').subnets(prefixlen_diff=2))
>>> list(ip_network('192.0.2.0/24').subnets(prefixlen_diff=2)) #doctest: +NORMALIZE_WHITESPACE
[IPv4Network('192.0.2.0/26'), IPv4Network('192.0.2.64/26'),
IPv4Network('192.0.2.128/26'), IPv4Network('192.0.2.192/26')]
>>> list(ip_network('192.0.2.0/24').subnets(new_prefix=26))
>>> list(ip_network('192.0.2.0/24').subnets(new_prefix=26)) #doctest: +NORMALIZE_WHITESPACE
[IPv4Network('192.0.2.0/26'), IPv4Network('192.0.2.64/26'),
IPv4Network('192.0.2.128/26'), IPv4Network('192.0.2.192/26')]
>>> list(ip_network('192.0.2.0/24').subnets(new_prefix=23))

View File

@ -9,20 +9,13 @@ data markup. This includes modules to work with the Standard Generalized Markup
Language (SGML) and the Hypertext Markup Language (HTML), and several interfaces
for working with the Extensible Markup Language (XML).
It is important to note that modules in the :mod:`xml` package require that
there be at least one SAX-compliant XML parser available. The Expat parser is
included with Python, so the :mod:`xml.parsers.expat` module will always be
available.
The documentation for the :mod:`xml.dom` and :mod:`xml.sax` packages are the
definition of the Python bindings for the DOM and SAX interfaces.
.. toctree::
html.rst
html.parser.rst
html.entities.rst
xml.rst
xml.etree.elementtree.rst
xml.dom.rst
xml.dom.minidom.rst

View File

@ -29,7 +29,7 @@ Windows.
Functionality within this package requires that the ``__main__`` module be
importable by the children. This is covered in :ref:`multiprocessing-programming`
however it is worth pointing out here. This means that some examples, such
as the :class:`multiprocessing.Pool` examples will not work in the
as the :class:`multiprocessing.pool.Pool` examples will not work in the
interactive interpreter. For example::
>>> from multiprocessing import Pool
@ -916,7 +916,7 @@ object -- see :ref:`multiprocessing-managers`.
.. class:: Condition([lock])
A condition variable: a clone of :class:`threading.Condition`.
A condition variable: an alias for :class:`threading.Condition`.
If *lock* is specified then it should be a :class:`Lock` or :class:`RLock`
object from :mod:`multiprocessing`.
@ -1638,7 +1638,7 @@ Process Pools
One can create a pool of processes which will carry out tasks submitted to it
with the :class:`Pool` class.
.. class:: multiprocessing.Pool([processes[, initializer[, initargs[, maxtasksperchild]]]])
.. class:: Pool([processes[, initializer[, initargs[, maxtasksperchild]]]])
A process pool object which controls a pool of worker processes to which jobs
can be submitted. It supports asynchronous results with timeouts and

View File

@ -1555,18 +1555,21 @@ features:
single: UNC paths; and os.makedirs()
Recursive directory creation function. Like :func:`mkdir`, but makes all
intermediate-level directories needed to contain the leaf directory. If
the target directory with the same mode as specified already exists,
raises an :exc:`OSError` exception if *exist_ok* is False, otherwise no
exception is raised. If the directory cannot be created in other cases,
raises an :exc:`OSError` exception. The default *mode* is ``0o777`` (octal).
On some systems, *mode* is ignored. Where it is used, the current umask
value is first masked out.
intermediate-level directories needed to contain the leaf directory.
The default *mode* is ``0o777`` (octal). On some systems, *mode* is
ignored. Where it is used, the current umask value is first masked out.
If *exists_ok* is ``False`` (the default), an :exc:`OSError` is raised if
the target directory already exists. If *exists_ok* is ``True`` an
:exc:`OSError` is still raised if the umask-masked *mode* is different from
the existing mode, on systems where the mode is used. :exc:`OSError` will
also be raised if the directory creation fails.
.. note::
:func:`makedirs` will become confused if the path elements to create
include :data:`pardir`.
include :data:`pardir` (eg. ".." on UNIX systems).
This function handles UNC paths correctly.

View File

@ -153,20 +153,22 @@ Server Objects
.. method:: BaseServer.serve_forever(poll_interval=0.5)
Handle requests until an explicit :meth:`shutdown` request.
Poll for shutdown every *poll_interval* seconds. Ignores :attr:`self.timeout`. It also calls
:meth:`service_actions` which may be used by a subclass or Mixin to provide
various cleanup actions. For e.g. ForkingMixin class uses
:meth:`service_actions` to cleanup the zombie child processes.
Handle requests until an explicit :meth:`shutdown` request. Poll for
shutdown every *poll_interval* seconds. Ignores :attr:`self.timeout`. It
also calls :meth:`service_actions`, which may be used by a subclass or mixin
to provide actions specific to a given service. For example, the
:class:`ForkingMixIn` class uses :meth:`service_actions` to clean up zombie
child processes.
.. versionchanged:: 3.3
Added service_actions call to the serve_forever method.
Added ``service_actions`` call to the ``serve_forever`` method.
.. method:: BaseServer.service_actions()
This is called by the serve_forever loop. This method is can be overridden
by Mixin's to add cleanup or service specific actions.
This is called in the :meth:`serve_forever` loop. This method is can be
overridden by subclasses or mixin classes to perform actions specific to
a given service, such as cleanup actions.
.. versionadded:: 3.3

View File

@ -222,64 +222,64 @@ Connection Objects
A SQLite database connection has the following attributes and methods:
.. attribute:: Connection.isolation_level
.. attribute:: isolation_level
Get or set the current isolation level. :const:`None` for autocommit mode or
one of "DEFERRED", "IMMEDIATE" or "EXCLUSIVE". See section
:ref:`sqlite3-controlling-transactions` for a more detailed explanation.
.. attribute:: Connection.in_transaction
.. attribute:: in_transaction
:const:`True` if a transaction is active (there are uncommitted changes),
:const:`False` otherwise. Read-only attribute.
.. versionadded:: 3.2
.. method:: Connection.cursor([cursorClass])
.. method:: cursor([cursorClass])
The cursor method accepts a single optional parameter *cursorClass*. If
supplied, this must be a custom cursor class that extends
:class:`sqlite3.Cursor`.
.. method:: Connection.commit()
.. method:: commit()
This method commits the current transaction. If you don't call this method,
anything you did since the last call to ``commit()`` is not visible from
other database connections. If you wonder why you don't see the data you've
written to the database, please check you didn't forget to call this method.
.. method:: Connection.rollback()
.. method:: rollback()
This method rolls back any changes to the database since the last call to
:meth:`commit`.
.. method:: Connection.close()
.. method:: close()
This closes the database connection. Note that this does not automatically
call :meth:`commit`. If you just close your database connection without
calling :meth:`commit` first, your changes will be lost!
.. method:: Connection.execute(sql, [parameters])
.. method:: execute(sql, [parameters])
This is a nonstandard shortcut that creates an intermediate cursor object by
calling the cursor method, then calls the cursor's :meth:`execute
<Cursor.execute>` method with the parameters given.
.. method:: Connection.executemany(sql, [parameters])
.. method:: executemany(sql, [parameters])
This is a nonstandard shortcut that creates an intermediate cursor object by
calling the cursor method, then calls the cursor's :meth:`executemany
<Cursor.executemany>` method with the parameters given.
.. method:: Connection.executescript(sql_script)
.. method:: executescript(sql_script)
This is a nonstandard shortcut that creates an intermediate cursor object by
calling the cursor method, then calls the cursor's :meth:`executescript
<Cursor.executescript>` method with the parameters given.
.. method:: Connection.create_function(name, num_params, func)
.. method:: create_function(name, num_params, func)
Creates a user-defined function that you can later use from within SQL
statements under the function name *name*. *num_params* is the number of
@ -294,7 +294,7 @@ Connection Objects
.. literalinclude:: ../includes/sqlite3/md5func.py
.. method:: Connection.create_aggregate(name, num_params, aggregate_class)
.. method:: create_aggregate(name, num_params, aggregate_class)
Creates a user-defined aggregate function.
@ -310,7 +310,7 @@ Connection Objects
.. literalinclude:: ../includes/sqlite3/mysumaggr.py
.. method:: Connection.create_collation(name, callable)
.. method:: create_collation(name, callable)
Creates a collation with the specified *name* and *callable*. The callable will
be passed two string arguments. It should return -1 if the first is ordered
@ -330,14 +330,14 @@ Connection Objects
con.create_collation("reverse", None)
.. method:: Connection.interrupt()
.. method:: interrupt()
You can call this method from a different thread to abort any queries that might
be executing on the connection. The query will then abort and the caller will
get an exception.
.. method:: Connection.set_authorizer(authorizer_callback)
.. method:: set_authorizer(authorizer_callback)
This routine registers a callback. The callback is invoked for each attempt to
access a column of a table in the database. The callback should return
@ -358,7 +358,7 @@ Connection Objects
one. All necessary constants are available in the :mod:`sqlite3` module.
.. method:: Connection.set_progress_handler(handler, n)
.. method:: set_progress_handler(handler, n)
This routine registers a callback. The callback is invoked for every *n*
instructions of the SQLite virtual machine. This is useful if you want to
@ -369,7 +369,7 @@ Connection Objects
method with :const:`None` for *handler*.
.. method:: Connection.set_trace_callback(trace_callback)
.. method:: set_trace_callback(trace_callback)
Registers *trace_callback* to be called for each SQL statement that is
actually executed by the SQLite backend.
@ -385,7 +385,7 @@ Connection Objects
.. versionadded:: 3.3
.. method:: Connection.enable_load_extension(enabled)
.. method:: enable_load_extension(enabled)
This routine allows/disallows the SQLite engine to load SQLite extensions
from shared libraries. SQLite extensions can define new functions,
@ -398,7 +398,7 @@ Connection Objects
.. literalinclude:: ../includes/sqlite3/load_extension.py
.. method:: Connection.load_extension(path)
.. method:: load_extension(path)
This routine loads a SQLite extension from a shared library. You have to
enable extension loading with :meth:`enable_load_extension` before you can
@ -408,7 +408,7 @@ Connection Objects
.. versionadded:: 3.2
.. attribute:: Connection.row_factory
.. attribute:: row_factory
You can change this attribute to a callable that accepts the cursor and the
original row as a tuple and will return the real result row. This way, you can
@ -429,13 +429,17 @@ Connection Objects
.. XXX what's a db_row-based solution?
.. attribute:: Connection.text_factory
.. attribute:: text_factory
Using this attribute you can control what objects are returned for the ``TEXT``
data type. By default, this attribute is set to :class:`str` and the
:mod:`sqlite3` module will return Unicode objects for ``TEXT``. If you want to
return bytestrings instead, you can set it to :class:`bytes`.
For efficiency reasons, there's also a way to return :class:`str` objects
only for non-ASCII data, and :class:`bytes` otherwise. To activate it, set
this attribute to :const:`sqlite3.OptimizedUnicode`.
You can also set it to any other callable that accepts a single bytestring
parameter and returns the resulting object.
@ -444,13 +448,13 @@ Connection Objects
.. literalinclude:: ../includes/sqlite3/text_factory.py
.. attribute:: Connection.total_changes
.. attribute:: total_changes
Returns the total number of database rows that have been modified, inserted, or
deleted since the database connection was opened.
.. attribute:: Connection.iterdump
.. attribute:: iterdump
Returns an iterator to dump the database in an SQL text format. Useful when
saving an in-memory database for later restoration. This function provides
@ -477,7 +481,7 @@ Cursor Objects
A :class:`Cursor` instance has the following attributes and methods.
.. method:: Cursor.execute(sql, [parameters])
.. method:: execute(sql, [parameters])
Executes an SQL statement. The SQL statement may be parametrized (i. e.
placeholders instead of SQL literals). The :mod:`sqlite3` module supports two
@ -494,7 +498,7 @@ Cursor Objects
call.
.. method:: Cursor.executemany(sql, seq_of_parameters)
.. method:: executemany(sql, seq_of_parameters)
Executes an SQL command against all parameter sequences or mappings found in
the sequence *sql*. The :mod:`sqlite3` module also allows using an
@ -507,7 +511,7 @@ Cursor Objects
.. literalinclude:: ../includes/sqlite3/executemany_2.py
.. method:: Cursor.executescript(sql_script)
.. method:: executescript(sql_script)
This is a nonstandard convenience method for executing multiple SQL statements
at once. It issues a ``COMMIT`` statement first, then executes the SQL script it
@ -520,13 +524,13 @@ Cursor Objects
.. literalinclude:: ../includes/sqlite3/executescript.py
.. method:: Cursor.fetchone()
.. method:: fetchone()
Fetches the next row of a query result set, returning a single sequence,
or :const:`None` when no more data is available.
.. method:: Cursor.fetchmany(size=cursor.arraysize)
.. method:: fetchmany(size=cursor.arraysize)
Fetches the next set of rows of a query result, returning a list. An empty
list is returned when no more rows are available.
@ -542,14 +546,14 @@ Cursor Objects
If the *size* parameter is used, then it is best for it to retain the same
value from one :meth:`fetchmany` call to the next.
.. method:: Cursor.fetchall()
.. method:: fetchall()
Fetches all (remaining) rows of a query result, returning a list. Note that
the cursor's arraysize attribute can affect the performance of this operation.
An empty list is returned when no rows are available.
.. attribute:: Cursor.rowcount
.. attribute:: rowcount
Although the :class:`Cursor` class of the :mod:`sqlite3` module implements this
attribute, the database engine's own support for the determination of "rows
@ -567,14 +571,14 @@ Cursor Objects
With SQLite versions before 3.6.5, :attr:`rowcount` is set to 0 if
you make a ``DELETE FROM table`` without any condition.
.. attribute:: Cursor.lastrowid
.. attribute:: lastrowid
This read-only attribute provides the rowid of the last modified row. It is
only set if you issued a ``INSERT`` statement using the :meth:`execute`
method. For operations other than ``INSERT`` or when :meth:`executemany` is
called, :attr:`lastrowid` is set to :const:`None`.
.. attribute:: Cursor.description
.. attribute:: description
This read-only attribute provides the column names of the last query. To
remain compatible with the Python DB API, it returns a 7-tuple for each

View File

@ -358,20 +358,15 @@ functions.
Arguments are:
*args* should be a string, or a sequence of program arguments. The program
to execute is normally the first item in the args sequence or the string if
a string is given, but can be explicitly set by using the *executable*
argument. When *executable* is given, the first item in the args sequence
is still treated by most programs as the command name, which can then be
different from the actual executable name. On Unix, it becomes the display
name for the executing program in utilities such as :program:`ps`.
*args* should be a sequence of program arguments or else a single string.
By default, the program to execute is the first item in *args* if *args* is
a sequence and the string itself if *args* is a string. However, see the
*shell* and *executable* arguments for differences from this behavior.
On Unix, with *shell=False* (default): In this case, the Popen class uses
:meth:`os.execvp` like behavior to execute the child program.
*args* should normally be a
sequence. If a string is specified for *args*, it will be used as the name
or path of the program to execute; this will only work if the program is
being given no arguments.
On Unix, the :class:`Popen` class uses :meth:`os.execvp`-like behavior to
execute the child program. If *args* is a string, the string is
interpreted as the name or path of the program to execute; this only works
if the program is being given no arguments.
.. note::
@ -392,13 +387,23 @@ functions.
used in the shell (such as filenames containing spaces or the *echo* command
shown above) are single list elements.
On Unix, with *shell=True*: If args is a string, it specifies the command
string to execute through the shell. This means that the string must be
On Windows, the :class:`Popen` class uses ``CreateProcess()`` to
execute the child program, which operates on strings. If *args* is a
sequence, it will be converted to a string in a manner described in
:ref:`converting-argument-sequence`.
The *shell* argument (which defaults to *False*) specifies whether to use
the shell as the program to execute. It is recommended to pass *args* as a
sequence if *shell* is *False* and as a string if *shell* is *True*.
On Unix with ``shell=True``, the shell defaults to :file:`/bin/sh`. If
*args* is a string, the string specifies the command
to execute through the shell. This means that the string must be
formatted exactly as it would be when typed at the shell prompt. This
includes, for example, quoting or backslash escaping filenames with spaces in
them. If *args* is a sequence, the first item specifies the command string, and
any additional items will be treated as additional arguments to the shell
itself. That is to say, *Popen* does the equivalent of::
itself. That is to say, :class:`Popen` does the equivalent of::
Popen(['/bin/sh', '-c', args[0], args[1], ...])
@ -408,10 +413,11 @@ functions.
input. See the warning under :ref:`frequently-used-arguments`
for details.
On Windows: the :class:`Popen` class uses CreateProcess() to execute the
child program, which operates on strings. If *args* is a sequence, it will
be converted to a string in a manner described in
:ref:`converting-argument-sequence`.
On Windows with ``shell=True``, the :envvar:`COMSPEC` environment variable
specifies the default shell. The only time you need to specify
``shell=True`` on Windows is when the command you wish to execute is built
into the shell (e.g. :command:`dir` or :command:`copy`). You do not need
``shell=True`` to run a batch file or console-based executable.
*bufsize*, if given, has the same meaning as the corresponding argument to the
built-in open() function: :const:`0` means unbuffered, :const:`1` means line
@ -425,15 +431,14 @@ functions.
enable buffering by setting *bufsize* to either -1 or a large enough
positive value (such as 4096).
The *executable* argument specifies the program to execute. It is very seldom
needed: Usually, the program to execute is defined by the *args* argument. If
``shell=True``, the *executable* argument specifies which shell to use. On Unix,
the default shell is :file:`/bin/sh`. On Windows, the default shell is
specified by the :envvar:`COMSPEC` environment variable. The only reason you
would need to specify ``shell=True`` on Windows is where the command you
wish to execute is actually built in to the shell, eg ``dir``, ``copy``.
You don't need ``shell=True`` to run a batch file, nor to run a console-based
executable.
The *executable* argument specifies a replacement program to execute. It
is very seldom needed. When ``shell=False``, *executable* replaces the
program to execute specified by *args*. However, the *args* program is
still treated by most programs as the command name, which can then be
different from the program actually executed. On Unix, the *args* name
becomes the display name for the executable in utilities such as
:program:`ps`. If ``shell=True``, on Unix the *executable* argument
specifies a replacement shell for the default :file:`/bin/sh`.
*stdin*, *stdout* and *stderr* specify the executed program's standard input,
standard output and standard error file handles, respectively. Valid values
@ -484,10 +489,10 @@ functions.
.. versionadded:: 3.2
The *pass_fds* parameter was added.
If *cwd* is not ``None``, the child's current directory will be changed to *cwd*
before it is executed. Note that this directory is not considered when
searching the executable, so you can't specify the program's path relative to
*cwd*.
If *cwd* is not ``None``, the function changes the working directory to
*cwd* before executing the child. In particular, the function looks for
*executable* (or for the first item in *args*) relative to *cwd* if the
executable path is a relative path.
If *restore_signals* is True (the default) all signals that Python has set to
SIG_IGN are restored to SIG_DFL in the child process before the exec.

View File

@ -86,6 +86,9 @@ The module defines the following user-callable items:
whether :func:`rollover` has been called. This file-like object can be
used in a :keyword:`with` statement, just like a normal file.
.. versionchanged:: 3.3
the truncate method now accepts a ``size`` argument.
.. function:: TemporaryDirectory(suffix='', prefix='tmp', dir=None)

View File

@ -21,7 +21,7 @@ The :mod:`dummy_threading` module is provided for situations where
supported by this module.
This module defines the following functions and objects:
This module defines the following functions:
.. function:: active_count()
@ -30,16 +30,6 @@ This module defines the following functions and objects:
count is equal to the length of the list returned by :func:`.enumerate`.
.. function:: Condition()
:noindex:
A factory function that returns a new condition variable object. A condition
variable allows one or more threads to wait until they are notified by another
thread.
See :ref:`condition-objects`.
.. function:: current_thread()
Return the current :class:`Thread` object, corresponding to the caller's thread
@ -67,88 +57,6 @@ This module defines the following functions and objects:
and threads that have not yet been started.
.. function:: Event()
:noindex:
A factory function that returns a new event object. An event manages a flag
that can be set to true with the :meth:`~Event.set` method and reset to false
with the :meth:`clear` method. The :meth:`wait` method blocks until the flag
is true.
See :ref:`event-objects`.
.. class:: local
A class that represents thread-local data. Thread-local data are data whose
values are thread specific. To manage thread-local data, just create an
instance of :class:`local` (or a subclass) and store attributes on it::
mydata = threading.local()
mydata.x = 1
The instance's values will be different for separate threads.
For more details and extensive examples, see the documentation string of the
:mod:`_threading_local` module.
.. function:: Lock()
A factory function that returns a new primitive lock object. Once a thread has
acquired it, subsequent attempts to acquire it block, until it is released; any
thread may release it.
See :ref:`lock-objects`.
.. function:: RLock()
A factory function that returns a new reentrant lock object. A reentrant lock
must be released by the thread that acquired it. Once a thread has acquired a
reentrant lock, the same thread may acquire it again without blocking; the
thread must release it once for each time it has acquired it.
See :ref:`rlock-objects`.
.. function:: Semaphore(value=1)
:noindex:
A factory function that returns a new semaphore object. A semaphore manages a
counter representing the number of :meth:`release` calls minus the number of
:meth:`acquire` calls, plus an initial value. The :meth:`acquire` method blocks
if necessary until it can return without making the counter negative. If not
given, *value* defaults to 1.
See :ref:`semaphore-objects`.
.. function:: BoundedSemaphore(value=1)
A factory function that returns a new bounded semaphore object. A bounded
semaphore checks to make sure its current value doesn't exceed its initial
value. If it does, :exc:`ValueError` is raised. In most situations semaphores
are used to guard resources with limited capacity. If the semaphore is released
too many times it's a sign of a bug. If not given, *value* defaults to 1.
.. class:: Thread
A class that represents a thread of control. This class can be safely
subclassed in a limited fashion.
See :ref:`thread-objects`.
.. class:: Timer
:noindex:
A thread that executes a function after a specified interval has passed.
See :ref:`timer-objects`.
.. function:: settrace(func)
.. index:: single: trace function
@ -197,7 +105,8 @@ This module also defines the following constant:
.. versionadded:: 3.2
Detailed interfaces for the objects are documented below.
This module defines a number of classes, which are detailed in the sections
below.
The design of this module is loosely based on Java's threading model. However,
where Java makes locks and condition variables basic behavior of every object,
@ -210,17 +119,38 @@ when implemented, are mapped to module-level functions.
All of the methods described below are executed atomically.
Thread-Local Data
-----------------
Thread-local data is data whose values are thread specific. To manage
thread-local data, just create an instance of :class:`local` (or a
subclass) and store attributes on it::
mydata = threading.local()
mydata.x = 1
The instance's values will be different for separate threads.
.. class:: local()
A class that represents thread-local data.
For more details and extensive examples, see the documentation string of the
:mod:`_threading_local` module.
.. _thread-objects:
Thread Objects
--------------
This class represents an activity that is run in a separate thread of control.
There are two ways to specify the activity: by passing a callable object to the
constructor, or by overriding the :meth:`~Thread.run` method in a subclass.
No other methods (except for the constructor) should be overridden in a
subclass. In other words, *only* override the :meth:`~Thread.__init__`
and :meth:`~Thread.run` methods of this class.
The :class:`Thread` class represents an activity that is run in a separate
thread of control. There are two ways to specify the activity: by passing a
callable object to the constructor, or by overriding the :meth:`~Thread.run`
method in a subclass. No other methods (except for the constructor) should be
overridden in a subclass. In other words, *only* override the
:meth:`~Thread.__init__` and :meth:`~Thread.run` methods of this class.
Once a thread object is created, its activity must be started by calling the
thread's :meth:`~Thread.start` method. This invokes the :meth:`~Thread.run`
@ -419,7 +349,17 @@ is not defined, and may vary across implementations.
All methods are executed atomically.
.. method:: Lock.acquire(blocking=True, timeout=-1)
.. class:: Lock()
The class implementing primitive lock objects. Once a thread has acquired a
lock, subsequent attempts to acquire it block, until it is released; any
thread may release it.
.. versionchanged:: 3.3
Changed from a factory function to a class.
.. method:: acquire(blocking=True, timeout=-1)
Acquire a lock, blocking or non-blocking.
@ -446,7 +386,7 @@ All methods are executed atomically.
Lock acquires can now be interrupted by signals on POSIX.
.. method:: Lock.release()
.. method:: release()
Release a lock. This can be called from any thread, not only the thread
which has acquired the lock.
@ -481,7 +421,19 @@ allows another thread blocked in :meth:`~Lock.acquire` to proceed.
Reentrant locks also support the :ref:`context manager protocol <with-locks>`.
.. method:: RLock.acquire(blocking=True, timeout=-1)
.. class:: RLock()
This class implements reentrant lock objects. A reentrant lock must be
released by the thread that acquired it. Once a thread has acquired a
reentrant lock, the same thread may acquire it again without blocking; the
thread must release it once for each time it has acquired it.
Note that ``RLock`` is actually a factory function which returns an instance
of the most efficient version of the concrete RLock class that is supported
by the platform.
.. method:: acquire(blocking=True, timeout=-1)
Acquire a lock, blocking or non-blocking.
@ -509,7 +461,7 @@ Reentrant locks also support the :ref:`context manager protocol <with-locks>`.
The *timeout* parameter is new.
.. method:: RLock.release()
.. method:: release()
Release a lock, decrementing the recursion level. If after the decrement it is
zero, reset the lock to unlocked (not owned by any thread), and if any other
@ -556,10 +508,6 @@ not return from their :meth:`~Condition.wait` call immediately, but only when
the thread that called :meth:`~Condition.notify` or :meth:`~Condition.notify_all`
finally relinquishes ownership of the lock.
Usage
^^^^^
The typical programming style using condition variables uses the lock to
synchronize access to some shared state; threads that are interested in a
particular change of state call :meth:`~Condition.wait` repeatedly until they
@ -598,15 +546,18 @@ waiting threads. E.g. in a typical producer-consumer situation, adding one
item to the buffer only needs to wake up one consumer thread.
Interface
^^^^^^^^^
.. class:: Condition(lock=None)
This class implements condition variable objects. A condition variable
allows one or more threads to wait until they are notified by another thread.
If the *lock* argument is given and not ``None``, it must be a :class:`Lock`
or :class:`RLock` object, and it is used as the underlying lock. Otherwise,
a new :class:`RLock` object is created and used as the underlying lock.
.. versionchanged:: 3.3
changed from a factory function to a class.
.. method:: acquire(*args)
Acquire the underlying lock. This method calls the corresponding method on
@ -716,10 +667,19 @@ Semaphores also support the :ref:`context manager protocol <with-locks>`.
.. class:: Semaphore(value=1)
This class implements semaphore objects. A semaphore manages a counter
representing the number of :meth:`release` calls minus the number of
:meth:`acquire` calls, plus an initial value. The :meth:`acquire` method
blocks if necessary until it can return without making the counter negative.
If not given, *value* defaults to 1.
The optional argument gives the initial *value* for the internal counter; it
defaults to ``1``. If the *value* given is less than 0, :exc:`ValueError` is
raised.
.. versionchanged:: 3.3
changed from a factory function to a class.
.. method:: acquire(blocking=True, timeout=None)
Acquire a semaphore.
@ -752,6 +712,18 @@ Semaphores also support the :ref:`context manager protocol <with-locks>`.
than zero again, wake up that thread.
.. class:: BoundedSemaphore(value=1)
Class implementing bounded semaphore objects. A bounded semaphore checks to
make sure its current value doesn't exceed its initial value. If it does,
:exc:`ValueError` is raised. In most situations semaphores are used to guard
resources with limited capacity. If the semaphore is released too many times
it's a sign of a bug. If not given, *value* defaults to 1.
.. versionchanged:: 3.3
changed from a factory function to a class.
.. _semaphore-examples:
:class:`Semaphore` Example
@ -763,7 +735,7 @@ you should use a bounded semaphore. Before spawning any worker threads, your
main thread would initialize the semaphore::
maxconnections = 5
...
# ...
pool_sema = BoundedSemaphore(value=maxconnections)
Once spawned, worker threads call the semaphore's acquire and release methods
@ -772,7 +744,7 @@ when they need to connect to the server::
with pool_sema:
conn = connectdb()
try:
... use connection ...
# ... use connection ...
finally:
conn.close()
@ -795,7 +767,13 @@ method. The :meth:`~Event.wait` method blocks until the flag is true.
.. class:: Event()
The internal flag is initially false.
Class implementing event objects. An event manages a flag that can be set to
true with the :meth:`~Event.set` method and reset to false with the
:meth:`clear` method. The :meth:`wait` method blocks until the flag is true.
The flag is initially false.
.. versionchanged:: 3.3
changed from a factory function to a class.
.. method:: is_set()
@ -860,6 +838,9 @@ For example::
Create a timer that will run *function* with arguments *args* and keyword
arguments *kwargs*, after *interval* seconds have passed.
.. versionchanged:: 3.3
changed from a factory function to a class.
.. method:: cancel()
Stop the timer, and cancel the execution of the timer's action. This will

View File

@ -557,7 +557,7 @@ The module defines the following functions and data items:
:exc:`TypeError` is raised.
.. versionchanged:: 3.3
:attr:`tm_gmtoff` and :attr:`tm_zone` attributes are avaliable on platforms
:attr:`tm_gmtoff` and :attr:`tm_zone` attributes are available on platforms
with C library supporting the corresponding fields in ``struct tm``.
.. function:: time()

View File

@ -14,25 +14,83 @@
--------------
This module provides a simple way to time small bits of Python code. It has both
command line as well as callable interfaces. It avoids a number of common traps
for measuring execution times. See also Tim Peters' introduction to the
"Algorithms" chapter in the Python Cookbook, published by O'Reilly.
a :ref:`command-line-interface` as well as a :ref:`callable <python-interface>`
one. It avoids a number of common traps for measuring execution times.
See also Tim Peters' introduction to the "Algorithms" chapter in the *Python
Cookbook*, published by O'Reilly.
The module defines the following public class:
Basic Examples
--------------
The following example shows how the :ref:`command-line-interface`
can be used to compare three different expressions:
.. code-block:: sh
$ python -m timeit '"-".join(str(n) for n in range(100))'
10000 loops, best of 3: 40.3 usec per loop
$ python -m timeit '"-".join([str(n) for n in range(100)])'
10000 loops, best of 3: 33.4 usec per loop
$ python -m timeit '"-".join(map(str, range(100)))'
10000 loops, best of 3: 25.2 usec per loop
This can be achieved from the :ref:`python-interface` with::
>>> import timeit
>>> timeit.timeit('"-".join(str(n) for n in range(100))', number=10000)
0.8187260627746582
>>> timeit.timeit('"-".join([str(n) for n in range(100)])', number=10000)
0.7288308143615723
>>> timeit.timeit('"-".join(map(str, range(100)))', number=10000)
0.5858950614929199
Note however that :mod:`timeit` will automatically determine the number of
repetitions only when the command-line interface is used. In the
:ref:`timeit-examples` section you can find more advanced examples.
.. _python-interface:
Python Interface
----------------
The module defines three convenience functions and a public class:
.. function:: timeit(stmt='pass', setup='pass', timer=<default timer>, number=1000000)
Create a :class:`Timer` instance with the given statement, *setup* code and
*timer* function and run its :meth:`.timeit` method with *number* executions.
.. function:: repeat(stmt='pass', setup='pass', timer=<default timer>, repeat=3, number=1000000)
Create a :class:`Timer` instance with the given statement, *setup* code and
*timer* function and run its :meth:`.repeat` method with the given *repeat*
count and *number* executions.
.. function:: default_timer()
The default timer, which is always :func:`time.perf_counter`.
.. versionchanged:: 3.3
:func:`time.perf_counter` is now the default timer.
.. class:: Timer(stmt='pass', setup='pass', timer=<timer function>)
Class for timing execution speed of small code snippets.
The constructor takes a statement to be timed, an additional statement used for
setup, and a timer function. Both statements default to ``'pass'``; the timer
function is platform-dependent (see the module doc string). *stmt* and *setup*
may also contain multiple statements separated by ``;`` or newlines, as long as
they don't contain multi-line string literals.
The constructor takes a statement to be timed, an additional statement used
for setup, and a timer function. Both statements default to ``'pass'``;
the timer function is platform-dependent (see the module doc string).
*stmt* and *setup* may also contain multiple statements separated by ``;``
or newlines, as long as they don't contain multi-line string literals.
To measure the execution time of the first statement, use the :meth:`Timer.timeit`
method. The :meth:`repeat` method is a convenience to call :meth:`.timeit`
To measure the execution time of the first statement, use the :meth:`.timeit`
method. The :meth:`.repeat` method is a convenience to call :meth:`.timeit`
multiple times and return a list of results.
The *stmt* and *setup* parameters can also take objects that are callable
@ -41,6 +99,49 @@ The module defines the following public class:
little larger in this case because of the extra function calls.
.. method:: Timer.timeit(number=1000000)
Time *number* executions of the main statement. This executes the setup
statement once, and then returns the time it takes to execute the main
statement a number of times, measured in seconds as a float.
The argument is the number of times through the loop, defaulting to one
million. The main statement, the setup statement and the timer function
to be used are passed to the constructor.
.. note::
By default, :meth:`.timeit` temporarily turns off :term:`garbage
collection` during the timing. The advantage of this approach is that
it makes independent timings more comparable. This disadvantage is
that GC may be an important component of the performance of the
function being measured. If so, GC can be re-enabled as the first
statement in the *setup* string. For example::
timeit.Timer('for i in range(10): oct(i)', 'gc.enable()').timeit()
.. method:: Timer.repeat(repeat=3, number=1000000)
Call :meth:`.timeit` a few times.
This is a convenience function that calls the :meth:`.timeit` repeatedly,
returning a list of results. The first argument specifies how many times
to call :meth:`.timeit`. The second argument specifies the *number*
argument for :meth:`.timeit`.
.. note::
It's tempting to calculate mean and standard deviation from the result
vector and report these. However, this is not very useful.
In a typical case, the lowest value gives a lower bound for how fast
your machine can run the given code snippet; higher values in the
result vector are typically not caused by variability in Python's
speed, but by other processes interfering with your timing accuracy.
So the :func:`min` of the result is probably the only number you
should be interested in. After that, you should look at the entire
vector and apply common sense rather than statistics.
.. method:: Timer.print_exc(file=None)
Helper to print a traceback from the timed code.
@ -53,74 +154,14 @@ The module defines the following public class:
except:
t.print_exc()
The advantage over the standard traceback is that source lines in the compiled
template will be displayed. The optional *file* argument directs where the
traceback is sent; it defaults to ``sys.stderr``.
The advantage over the standard traceback is that source lines in the
compiled template will be displayed. The optional *file* argument directs
where the traceback is sent; it defaults to :data:`sys.stderr`.
.. method:: Timer.repeat(repeat=3, number=1000000)
.. _command-line-interface:
Call :meth:`.timeit` a few times.
This is a convenience function that calls the :meth:`.timeit` repeatedly,
returning a list of results. The first argument specifies how many times to
call :meth:`.timeit`. The second argument specifies the *number* argument for
:meth:`.timeit`.
.. note::
It's tempting to calculate mean and standard deviation from the result vector
and report these. However, this is not very useful. In a typical case, the
lowest value gives a lower bound for how fast your machine can run the given
code snippet; higher values in the result vector are typically not caused by
variability in Python's speed, but by other processes interfering with your
timing accuracy. So the :func:`min` of the result is probably the only number
you should be interested in. After that, you should look at the entire vector
and apply common sense rather than statistics.
.. method:: Timer.timeit(number=1000000)
Time *number* executions of the main statement. This executes the setup
statement once, and then returns the time it takes to execute the main statement
a number of times, measured in seconds as a float. The argument is the number
of times through the loop, defaulting to one million. The main statement, the
setup statement and the timer function to be used are passed to the constructor.
.. note::
By default, :meth:`.timeit` temporarily turns off :term:`garbage collection`
during the timing. The advantage of this approach is that it makes
independent timings more comparable. This disadvantage is that GC may be
an important component of the performance of the function being measured.
If so, GC can be re-enabled as the first statement in the *setup* string.
For example::
timeit.Timer('for i in range(10): oct(i)', 'gc.enable()').timeit()
The module also defines three convenience functions:
.. function:: default_timer()
The default timer, which is always :func:`time.perf_counter`.
.. function:: repeat(stmt='pass', setup='pass', timer=<default timer>, repeat=3, number=1000000)
Create a :class:`Timer` instance with the given statement, setup code and timer
function and run its :meth:`repeat` method with the given repeat count and
*number* executions.
.. function:: timeit(stmt='pass', setup='pass', timer=<default timer>, number=1000000)
Create a :class:`Timer` instance with the given statement, setup code and timer
function and run its :meth:`.timeit` method with *number* executions.
Command Line Interface
Command-Line Interface
----------------------
When called as a program from the command line, the following form is used::
@ -184,25 +225,53 @@ most cases. You can use :func:`time.process_time` to measure CPU time.
There is a certain baseline overhead associated with executing a pass statement.
The code here doesn't try to hide it, but you should be aware of it. The
baseline overhead can be measured by invoking the program without arguments.
baseline overhead can be measured by invoking the program without arguments,
and it might differ between Python versions.
The baseline overhead differs between Python versions! Also, to fairly compare
older Python versions to Python 2.3, you may want to use Python's :option:`-O`
option for the older versions to avoid timing ``SET_LINENO`` instructions.
.. _timeit-examples:
Examples
--------
Here are two example sessions (one using the command line, one using the module
interface) that compare the cost of using :func:`hasattr` vs.
:keyword:`try`/:keyword:`except` to test for missing and present object
attributes. ::
It is possible to provide a setup statement that is executed only once at the beginning:
.. code-block:: sh
$ python -m timeit -s 'text = "sample string"; char = "g"' 'char in text'
10000000 loops, best of 3: 0.0877 usec per loop
$ python -m timeit -s 'text = "sample string"; char = "g"' 'text.find(char)'
1000000 loops, best of 3: 0.342 usec per loop
::
>>> import timeit
>>> timeit.timeit('char in text', setup='text = "sample string"; char = "g"')
0.41440500499993504
>>> timeit.timeit('text.find(char)', setup='text = "sample string"; char = "g"')
1.7246671520006203
The same can be done using the :class:`Timer` class and its methods::
>>> import timeit
>>> t = timeit.Timer('char in text', setup='text = "sample string"; char = "g"')
>>> t.timeit()
0.3955516149999312
>>> t.repeat()
[0.40193588800002544, 0.3960157959998014, 0.39594301399984033]
The following examples show how to time expressions that contain multiple lines.
Here we compare the cost of using :func:`hasattr` vs. :keyword:`try`/:keyword:`except`
to test for missing and present object attributes:
.. code-block:: sh
$ python -m timeit 'try:' ' str.__bool__' 'except AttributeError:' ' pass'
100000 loops, best of 3: 15.7 usec per loop
$ python -m timeit 'if hasattr(str, "__bool__"): pass'
100000 loops, best of 3: 4.26 usec per loop
$ python -m timeit 'try:' ' int.__bool__' 'except AttributeError:' ' pass'
1000000 loops, best of 3: 1.43 usec per loop
$ python -m timeit 'if hasattr(int, "__bool__"): pass'
@ -211,36 +280,32 @@ attributes. ::
::
>>> import timeit
>>> # attribute is missing
>>> s = """\
... try:
... str.__bool__
... except AttributeError:
... pass
... """
>>> t = timeit.Timer(stmt=s)
>>> print("%.2f usec/pass" % (1000000 * t.timeit(number=100000)/100000))
17.09 usec/pass
>>> s = """\
... if hasattr(str, '__bool__'): pass
... """
>>> t = timeit.Timer(stmt=s)
>>> print("%.2f usec/pass" % (1000000 * t.timeit(number=100000)/100000))
4.85 usec/pass
>>> timeit.timeit(stmt=s, number=100000)
0.9138244460009446
>>> s = "if hasattr(str, '__bool__'): pass"
>>> timeit.timeit(stmt=s, number=100000)
0.5829014980008651
>>>
>>> # attribute is present
>>> s = """\
... try:
... int.__bool__
... except AttributeError:
... pass
... """
>>> t = timeit.Timer(stmt=s)
>>> print("%.2f usec/pass" % (1000000 * t.timeit(number=100000)/100000))
1.97 usec/pass
>>> s = """\
... if hasattr(int, '__bool__'): pass
... """
>>> t = timeit.Timer(stmt=s)
>>> print("%.2f usec/pass" % (1000000 * t.timeit(number=100000)/100000))
3.15 usec/pass
>>> timeit.timeit(stmt=s, number=100000)
0.04215312199994514
>>> s = "if hasattr(int, '__bool__'): pass"
>>> timeit.timeit(stmt=s, number=100000)
0.08588060699912603
To give the :mod:`timeit` module access to functions you define, you can pass a
*setup* parameter which contains an import statement::
@ -250,7 +315,5 @@ To give the :mod:`timeit` module access to functions you define, you can pass a
L = [i for i in range(100)]
if __name__ == '__main__':
from timeit import Timer
t = Timer("test()", "from __main__ import test")
print(t.timeit())
import timeit
print(timeit.timeit("test()", setup="from __main__ import test"))

9
Doc/library/urllib.rst Normal file
View File

@ -0,0 +1,9 @@
:mod:`urllib` --- URL handling modules
======================================
``urllib`` is a package that collects several modules for working with URLs:
* :mod:`urllib.request` for opening and reading URLs
* :mod:`urllib.error` containing the exceptions raised by :mod:`urllib.request`
* :mod:`urllib.parse` for parsing URLs
* :mod:`urllib.robotparser` for parsing ``robots.txt`` files

View File

@ -291,7 +291,9 @@ Supported XPath syntax
| | current element. For example, ``.//egg`` selects |
| | all ``egg`` elements in the entire tree. |
+-----------------------+------------------------------------------------------+
| ``..`` | Selects the parent element. |
| ``..`` | Selects the parent element. Returns ``None`` if the |
| | path attempts to reach the ancestors of the start |
| | element (the element ``find`` was called on). |
+-----------------------+------------------------------------------------------+
| ``[@attrib]`` | Selects all elements that have the given attribute. |
+-----------------------+------------------------------------------------------+
@ -431,9 +433,9 @@ Functions
Generates a string representation of an XML element, including all
subelements. *element* is an :class:`Element` instance. *encoding* [1]_ is
the output encoding (default is US-ASCII). Use ``encoding="unicode"`` to
generate a Unicode string. *method* is either ``"xml"``,
``"html"`` or ``"text"`` (default is ``"xml"``). Returns an (optionally)
encoded string containing the XML data.
generate a Unicode string (otherwise, a bytestring is generated). *method*
is either ``"xml"``, ``"html"`` or ``"text"`` (default is ``"xml"``).
Returns an (optionally) encoded string containing the XML data.
.. function:: tostringlist(element, encoding="us-ascii", method="xml")
@ -441,11 +443,11 @@ Functions
Generates a string representation of an XML element, including all
subelements. *element* is an :class:`Element` instance. *encoding* [1]_ is
the output encoding (default is US-ASCII). Use ``encoding="unicode"`` to
generate a Unicode string. *method* is either ``"xml"``,
``"html"`` or ``"text"`` (default is ``"xml"``). Returns a list of
(optionally) encoded strings containing the XML data. It does not guarantee
any specific sequence, except that ``"".join(tostringlist(element)) ==
tostring(element)``.
generate a Unicode string (otherwise, a bytestring is generated). *method*
is either ``"xml"``, ``"html"`` or ``"text"`` (default is ``"xml"``).
Returns a list of (optionally) encoded strings containing the XML data.
It does not guarantee any specific sequence, except that
``"".join(tostringlist(element)) == tostring(element)``.
.. versionadded:: 3.2
@ -521,7 +523,7 @@ Element Objects
.. method:: clear()
Resets an element. This function removes all subelements, clears all
attributes, and sets the text and tail attributes to None.
attributes, and sets the text and tail attributes to ``None``.
.. method:: get(key, default=None)

29
Doc/library/xml.rst Normal file
View File

@ -0,0 +1,29 @@
.. _xml:
XML Processing Modules
======================
Python's interfaces for processing XML are grouped in the ``xml`` package.
It is important to note that modules in the :mod:`xml` package require that
there be at least one SAX-compliant XML parser available. The Expat parser is
included with Python, so the :mod:`xml.parsers.expat` module will always be
available.
The documentation for the :mod:`xml.dom` and :mod:`xml.sax` packages are the
definition of the Python bindings for the DOM and SAX interfaces.
The XML handling submodules are:
* :mod:`xml.etree.ElementTree`: the ElementTree API, a simple and lightweight
..
* :mod:`xml.dom`: the DOM API definition
* :mod:`xml.dom.minidom`: a lightweight DOM implementation
* :mod:`xml.dom.pulldom`: support for building partial DOM trees
..
* :mod:`xml.sax`: SAX2 base classes and convenience functions
* :mod:`xml.parsers.expat`: the Expat parser binding

12
Doc/library/xmlrpc.rst Normal file
View File

@ -0,0 +1,12 @@
:mod:`xmlrpc` --- XMLRPC server and client modules
==================================================
XML-RPC is a Remote Procedure Call method that uses XML passed via HTTP as a
transport. With it, a client can call methods with parameters on a remote
server (the server is named by a URI) and get back structured data.
``xmlrpc`` is a package that collects server and client modules implementing
XML-RPC. The modules are:
* :mod:`xmlrpc.client`
* :mod:`xmlrpc.server`

View File

@ -61,7 +61,7 @@ The module defines the following items:
.. class:: ZipInfo(filename='NoName', date_time=(1980,1,1,0,0,0))
Class used to represent information about a member of an archive. Instances
of this class are returned by the :meth:`getinfo` and :meth:`infolist`
of this class are returned by the :meth:`.getinfo` and :meth:`.infolist`
methods of :class:`ZipFile` objects. Most users of the :mod:`zipfile` module
will not need to create these, but only use those created by this
module. *filename* should be the full name of the archive member, and
@ -87,20 +87,20 @@ The module defines the following items:
.. data:: ZIP_DEFLATED
The numeric constant for the usual ZIP compression method. This requires the
zlib module.
:mod:`zlib` module.
.. data:: ZIP_BZIP2
The numeric constant for the BZIP2 compression method. This requires the
bz2 module.
:mod:`bz2` module.
.. versionadded:: 3.3
.. data:: ZIP_LZMA
The numeric constant for the LZMA compression method. This requires the
lzma module.
:mod:`lzma` module.
.. versionadded:: 3.3
@ -155,7 +155,7 @@ ZipFile Objects
these extensions.
If the file is created with mode ``'a'`` or ``'w'`` and then
:meth:`close`\ d without adding any files to the archive, the appropriate
:meth:`closed <close>` without adding any files to the archive, the appropriate
ZIP structures for an empty archive will be written to the file.
ZipFile is also a context manager and therefore supports the
@ -169,7 +169,7 @@ ZipFile Objects
Added the ability to use :class:`ZipFile` as a context manager.
.. versionchanged:: 3.3
Added support for :mod:`bzip2` and :mod:`lzma` compression.
Added support for :mod:`bzip2 <bz2>` and :mod:`lzma` compression.
.. method:: ZipFile.close()
@ -207,7 +207,7 @@ ZipFile Objects
*mode* parameter, if included, must be one of the following: ``'r'`` (the
default), ``'U'``, or ``'rU'``. Choosing ``'U'`` or ``'rU'`` will enable
:term:`universal newlines` support in the read-only object. *pwd* is the
password used for encrypted files. Calling :meth:`open` on a closed
password used for encrypted files. Calling :meth:`.open` on a closed
ZipFile will raise a :exc:`RuntimeError`.
.. note::
@ -229,7 +229,7 @@ ZipFile Objects
.. note::
The :meth:`open`, :meth:`read` and :meth:`extract` methods can take a filename
The :meth:`.open`, :meth:`read` and :meth:`extract` methods can take a filename
or a :class:`ZipInfo` object. You will appreciate this when trying to read a
ZIP file that contains members with duplicate names.
@ -335,7 +335,7 @@ ZipFile Objects
:class:`ZipInfo` constructor sets this member to :const:`ZIP_STORED`.
.. versionchanged:: 3.2
The *compression_type* argument.
The *compress_type* argument.
The following data attributes are also available:
@ -351,7 +351,7 @@ The following data attributes are also available:
The comment text associated with the ZIP file. If assigning a comment to a
:class:`ZipFile` instance created with mode 'a' or 'w', this should be a
string no longer than 65535 bytes. Comments longer than this will be
truncated in the written archive when :meth:`ZipFile.close` is called.
truncated in the written archive when :meth:`close` is called.
.. _pyzipfile-objects:
@ -407,8 +407,8 @@ The :class:`PyZipFile` constructor takes the same parameters as the
ZipInfo Objects
---------------
Instances of the :class:`ZipInfo` class are returned by the :meth:`getinfo` and
:meth:`infolist` methods of :class:`ZipFile` objects. Each object stores
Instances of the :class:`ZipInfo` class are returned by the :meth:`.getinfo` and
:meth:`.infolist` methods of :class:`ZipFile` objects. Each object stores
information about a single member of the ZIP archive.
Instances have the following attributes:

View File

@ -37,7 +37,7 @@ goto end
svn co %SVNROOT%/external/Sphinx-1.0.7/sphinx tools/sphinx
svn co %SVNROOT%/external/docutils-0.6/docutils tools/docutils
svn co %SVNROOT%/external/Jinja-2.3.1/jinja2 tools/jinja2
svn co %SVNROOT%/external/Pygments-1.3.1/pygments tools/pygments
svn co %SVNROOT%/external/Pygments-1.5dev-20120930/pygments tools/pygments
goto end
:update

View File

@ -312,7 +312,7 @@ Sequences
A bytes object is an immutable array. The items are 8-bit bytes,
represented by integers in the range 0 <= x < 256. Bytes literals
(like ``b'abc'`` and the built-in function :func:`bytes` can be used to
(like ``b'abc'``) and the built-in function :func:`bytes` can be used to
construct bytes objects. Also, bytes objects can be decoded to strings
via the :meth:`decode` method.

View File

@ -1094,16 +1094,10 @@ Comparison of objects of the same type depends on the type:
another one is made arbitrarily but consistently within one execution of a
program.
Comparison of objects of the differing types depends on whether either
of the types provide explicit support for the comparison. Most numeric types
can be compared with one another, but comparisons of :class:`float` and
:class:`Decimal` are not supported to avoid the inevitable confusion arising
from representation issues such as ``float('1.1')`` being inexactly represented
and therefore not exactly equal to ``Decimal('1.1')`` which is. When
cross-type comparison is not supported, the comparison method returns
``NotImplemented``. This can create the illusion of non-transitivity between
supported cross-type comparisons and unsupported comparisons. For example,
``Decimal(2) == 2`` and ``2 == float(2)`` but ``Decimal(2) != float(2)``.
Comparison of objects of the differing types depends on whether either of the
types provide explicit support for the comparison. Most numeric types can be
compared with one another. When cross-type comparison is not supported, the
comparison method returns ``NotImplemented``.
.. _membership-test-details:

View File

@ -538,9 +538,7 @@ Notes:
this escape sequence. Exactly four hex digits are required.
(6)
Any Unicode character can be encoded this way, but characters outside the Basic
Multilingual Plane (BMP) will be encoded using a surrogate pair if Python is
compiled to use 16-bit code units (the default). Exactly eight hex digits
Any Unicode character can be encoded this way. Exactly eight hex digits
are required.

View File

@ -3,7 +3,7 @@
<h3>Docs for other versions</h3>
<ul>
<li><a href="http://docs.python.org/2.7/">Python 2.7 (stable)</a></li>
<li><a href="http://docs.python.org/3.2/">Python 3.2 (stable)</a></li>
<li><a href="http://docs.python.org/3.4/">Python 3.4 (in development)</a></li>
<li><a href="http://www.python.org/doc/versions/">Old versions</a></li>
</ul>

View File

@ -8,6 +8,63 @@
{% block extrahead %}
<link rel="shortcut icon" type="image/png" href="{{ pathto('_static/py.png', 1) }}" />
{% if not embedded %}<script type="text/javascript" src="{{ pathto('_static/copybutton.js', 1) }}"></script>{% endif %}
{% if pagename == 'whatsnew/changelog' %}
<script type="text/javascript">
$(document).ready(function() {
// add the search form and bind the events
$('h1').after([
'<p>Filter entries by content:',
'<input type="text" value="" id="searchbox" style="width: 50%">',
'<input type="submit" id="searchbox-submit" value="Filter"></p>'
].join('\n'));
function dofilter() {
try {
var query = new RegExp($('#searchbox').val(), 'i');
}
catch (e) {
return; // not a valid regex (yet)
}
// find headers for the versions (What's new in Python X.Y.Z?)
$('#changelog h2').each(function(index1, h2) {
var h2_parent = $(h2).parent();
var sections_found = 0;
// find headers for the sections (Core, Library, etc.)
h2_parent.find('h3').each(function(index2, h3) {
var h3_parent = $(h3).parent();
var entries_found = 0;
// find all the entries
h3_parent.find('li').each(function(index3, li) {
var li = $(li);
// check if the query matches the entry
if (query.test(li.text())) {
li.show();
entries_found++;
}
else {
li.hide();
}
});
// if there are entries, show the section, otherwise hide it
if (entries_found > 0) {
h3_parent.show();
sections_found++;
}
else {
h3_parent.hide();
}
});
if (sections_found > 0)
h2_parent.show();
else
h2_parent.hide();
});
}
$('#searchbox').keyup(dofilter);
$('#searchbox-submit').click(dofilter);
});
</script>
{% endif %}
{{ super() }}
{% endblock %}
{% block footer %}

View File

@ -145,6 +145,47 @@ class DeprecatedRemoved(Directive):
return ret
# Support for including Misc/NEWS
import re
import codecs
issue_re = re.compile('([Ii])ssue #([0-9]+)')
whatsnew_re = re.compile(r"(?im)^what's new in (.*?)\??$")
class MiscNews(Directive):
has_content = False
required_arguments = 1
optional_arguments = 0
final_argument_whitespace = False
option_spec = {}
def run(self):
fname = self.arguments[0]
source = self.state_machine.input_lines.source(
self.lineno - self.state_machine.input_offset - 1)
source_dir = path.dirname(path.abspath(source))
fpath = path.join(source_dir, fname)
self.state.document.settings.record_dependencies.add(fpath)
try:
fp = codecs.open(fpath, encoding='utf-8')
try:
content = fp.read()
finally:
fp.close()
except Exception:
text = 'The NEWS file is not available.'
node = nodes.strong(text, text)
return [node]
content = issue_re.sub(r'`\1ssue #\2 <http://bugs.python.org/\2>`__',
content)
content = whatsnew_re.sub(r'\1', content)
# remove first 3 lines as they are the main heading
lines = ['.. default-role:: obj', ''] + content.splitlines()[3:]
self.state_machine.insert_input(lines, fname)
return []
# Support for building "topic help" for pydoc
pydoc_topic_labels = [
@ -276,3 +317,4 @@ def setup(app):
app.add_description_unit('2to3fixer', '2to3fixer', '%s (2to3 fixer)')
app.add_directive_to_domain('py', 'decorator', PyDecoratorFunction)
app.add_directive_to_domain('py', 'decoratormethod', PyDecoratorMethod)
app.add_directive('miscnews', MiscNews)

View File

@ -357,3 +357,15 @@ whatsnew/3.2,,:location,... zope9-location = ${zope9:location}
whatsnew/3.2,,:location,zope9-location = ${zope9:location}
whatsnew/3.2,,:prefix,... zope-conf = ${custom:prefix}/etc/zope.conf
whatsnew/3.2,,:prefix,zope-conf = ${custom:prefix}/etc/zope.conf
whatsnew/news,,:platform,:platform:
whatsnew/news,,:password,: Unquote before b64encoding user:password during Basic
whatsnew/news,,:close,Connection:close header.
whatsnew/news,,:PythonCmd,"With Tk < 8.5 _tkinter.c:PythonCmd() raised UnicodeDecodeError, caused"
whatsnew/news,,:close,: Connection:close header is sent by requests using URLOpener
whatsnew/news,,::,": Fix FTP tests for IPv6, bind to ""::1"" instead of ""localhost""."
whatsnew/news,,:test,: test_subprocess:test_leaking_fds_on_error no longer gives a
whatsnew/news,,:test,: Fix test_posix:test_getgroups failure under Solaris. Patch
whatsnew/news,,:Olimit,Drop -OPT:Olimit compiler option.
whatsnew/news,,:MAXYEAR,timedelta from date or datetime falls outside of the MINYEAR:MAXYEAR range.
whatsnew/news,,:bz2,with mode 'r' or 'r:bz2' and a fileobj argument that contained no data or
whatsnew/news,,:db2,: Add configure option --with-dbmliborder=db1:db2:... to specify

1 c-api/arg :ref PyArg_ParseTuple(args, "O|O:ref", &object, &callback)
357 whatsnew/3.2 :location zope9-location = ${zope9:location}
358 whatsnew/3.2 :prefix ... zope-conf = ${custom:prefix}/etc/zope.conf
359 whatsnew/3.2 :prefix zope-conf = ${custom:prefix}/etc/zope.conf
360 whatsnew/news :platform :platform:
361 whatsnew/news :password : Unquote before b64encoding user:password during Basic
362 whatsnew/news :close Connection:close header.
363 whatsnew/news :PythonCmd With Tk < 8.5 _tkinter.c:PythonCmd() raised UnicodeDecodeError, caused
364 whatsnew/news :close : Connection:close header is sent by requests using URLOpener
365 whatsnew/news :: : Fix FTP tests for IPv6, bind to "::1" instead of "localhost".
366 whatsnew/news :test : test_subprocess:test_leaking_fds_on_error no longer gives a
367 whatsnew/news :test : Fix test_posix:test_getgroups failure under Solaris. Patch
368 whatsnew/news :Olimit Drop -OPT:Olimit compiler option.
369 whatsnew/news :MAXYEAR timedelta from date or datetime falls outside of the MINYEAR:MAXYEAR range.
370 whatsnew/news :bz2 with mode 'r' or 'r:bz2' and a fileobj argument that contained no data or
371 whatsnew/news :db2 : Add configure option --with-dbmliborder=db1:db2:... to specify

View File

@ -132,6 +132,8 @@ Consult :command:`set /?` for details on this behaviour.
Setting Environment variables, Louis J. Farrugia
.. _windows-path-mod:
Finding the Python executable
-----------------------------

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,6 @@
+++++++++
Changelog
+++++++++
.. miscnews:: ../../Misc/NEWS

View File

@ -23,3 +23,11 @@ anyone wishing to stay up-to-date after a new release.
2.2.rst
2.1.rst
2.0.rst
The "Changelog" is a HTML version of the file :source:`Misc/NEWS` which
contains *all* nontrivial changes to Python for the current version.
.. toctree::
:maxdepth: 2
changelog.rst

View File

@ -1022,8 +1022,7 @@ PyAPI_FUNC(void*) _PyUnicode_AsKind(PyObject *s, unsigned int kind);
/* Create a Unicode Object from the given Unicode code point ordinal.
The ordinal must be in range(0x10000) on narrow Python builds
(UCS2), and range(0x110000) on wide builds (UCS4). A ValueError is
The ordinal must be in range(0x110000). A ValueError is
raised in case it is not.
*/

View File

@ -79,7 +79,8 @@ class BZ2File(io.BufferedIOBase):
mode = "rb"
mode_code = _MODE_READ
self._decompressor = BZ2Decompressor()
self._buffer = None
self._buffer = b""
self._buffer_offset = 0
elif mode in ("w", "wb"):
mode = "wb"
mode_code = _MODE_WRITE
@ -124,7 +125,8 @@ class BZ2File(io.BufferedIOBase):
self._fp = None
self._closefp = False
self._mode = _MODE_CLOSED
self._buffer = None
self._buffer = b""
self._buffer_offset = 0
@property
def closed(self):
@ -157,15 +159,18 @@ class BZ2File(io.BufferedIOBase):
raise ValueError("I/O operation on closed file")
def _check_can_read(self):
if not self.readable():
if self._mode not in (_MODE_READ, _MODE_READ_EOF):
self._check_not_closed()
raise io.UnsupportedOperation("File not open for reading")
def _check_can_write(self):
if not self.writable():
if self._mode != _MODE_WRITE:
self._check_not_closed()
raise io.UnsupportedOperation("File not open for writing")
def _check_can_seek(self):
if not self.readable():
if self._mode not in (_MODE_READ, _MODE_READ_EOF):
self._check_not_closed()
raise io.UnsupportedOperation("Seeking is only supported "
"on files open for reading")
if not self._fp.seekable():
@ -174,16 +179,13 @@ class BZ2File(io.BufferedIOBase):
# Fill the readahead buffer if it is empty. Returns False on EOF.
def _fill_buffer(self):
if self._mode == _MODE_READ_EOF:
return False
# Depending on the input data, our call to the decompressor may not
# return any data. In this case, try again after reading another block.
while True:
if self._buffer:
return True
if self._decompressor.unused_data:
rawblock = self._decompressor.unused_data
else:
rawblock = self._fp.read(_BUFFER_SIZE)
while self._buffer_offset == len(self._buffer):
rawblock = (self._decompressor.unused_data or
self._fp.read(_BUFFER_SIZE))
if not rawblock:
if self._decompressor.eof:
@ -199,30 +201,48 @@ class BZ2File(io.BufferedIOBase):
self._decompressor = BZ2Decompressor()
self._buffer = self._decompressor.decompress(rawblock)
self._buffer_offset = 0
return True
# Read data until EOF.
# If return_data is false, consume the data without returning it.
def _read_all(self, return_data=True):
# The loop assumes that _buffer_offset is 0. Ensure that this is true.
self._buffer = self._buffer[self._buffer_offset:]
self._buffer_offset = 0
blocks = []
while self._fill_buffer():
if return_data:
blocks.append(self._buffer)
self._pos += len(self._buffer)
self._buffer = None
self._buffer = b""
if return_data:
return b"".join(blocks)
# Read a block of up to n bytes.
# If return_data is false, consume the data without returning it.
def _read_block(self, n, return_data=True):
# If we have enough data buffered, return immediately.
end = self._buffer_offset + n
if end <= len(self._buffer):
data = self._buffer[self._buffer_offset : end]
self._buffer_offset = end
self._pos += len(data)
return data if return_data else None
# The loop assumes that _buffer_offset is 0. Ensure that this is true.
self._buffer = self._buffer[self._buffer_offset:]
self._buffer_offset = 0
blocks = []
while n > 0 and self._fill_buffer():
if n < len(self._buffer):
data = self._buffer[:n]
self._buffer = self._buffer[n:]
self._buffer_offset = n
else:
data = self._buffer
self._buffer = None
self._buffer = b""
if return_data:
blocks.append(data)
self._pos += len(data)
@ -238,9 +258,9 @@ class BZ2File(io.BufferedIOBase):
"""
with self._lock:
self._check_can_read()
if self._mode == _MODE_READ_EOF or not self._fill_buffer():
if not self._fill_buffer():
return b""
return self._buffer
return self._buffer[self._buffer_offset:]
def read(self, size=-1):
"""Read up to size uncompressed bytes from the file.
@ -250,7 +270,7 @@ class BZ2File(io.BufferedIOBase):
"""
with self._lock:
self._check_can_read()
if self._mode == _MODE_READ_EOF or size == 0:
if size == 0:
return b""
elif size < 0:
return self._read_all()
@ -268,15 +288,19 @@ class BZ2File(io.BufferedIOBase):
# In this case we make multiple reads, to avoid returning b"".
with self._lock:
self._check_can_read()
if (size == 0 or self._mode == _MODE_READ_EOF or
not self._fill_buffer()):
if (size == 0 or
# Only call _fill_buffer() if the buffer is actually empty.
# This gives a significant speedup if *size* is small.
(self._buffer_offset == len(self._buffer) and not self._fill_buffer())):
return b""
if 0 < size < len(self._buffer):
data = self._buffer[:size]
self._buffer = self._buffer[size:]
if size > 0:
data = self._buffer[self._buffer_offset :
self._buffer_offset + size]
self._buffer_offset += len(data)
else:
data = self._buffer
self._buffer = None
data = self._buffer[self._buffer_offset:]
self._buffer = b""
self._buffer_offset = 0
self._pos += len(data)
return data
@ -295,10 +319,20 @@ class BZ2File(io.BufferedIOBase):
non-negative, no more than size bytes will be read (in which
case the line may be incomplete). Returns b'' if already at EOF.
"""
if not isinstance(size, int):
if not hasattr(size, "__index__"):
raise TypeError("Integer argument expected")
size = size.__index__()
with self._lock:
self._check_can_read()
# Shortcut for the common case - the whole line is in the buffer.
if size < 0:
end = self._buffer.find(b"\n", self._buffer_offset) + 1
if end > 0:
line = self._buffer[self._buffer_offset : end]
self._buffer_offset = end
self._pos += len(line)
return line
return io.BufferedIOBase.readline(self, size)
def readlines(self, size=-1):
@ -308,6 +342,7 @@ class BZ2File(io.BufferedIOBase):
further lines will be read once the total size of the lines read
so far equals or exceeds size.
"""
if not isinstance(size, int):
if not hasattr(size, "__index__"):
raise TypeError("Integer argument expected")
size = size.__index__()
@ -345,7 +380,8 @@ class BZ2File(io.BufferedIOBase):
self._mode = _MODE_READ
self._pos = 0
self._decompressor = BZ2Decompressor()
self._buffer = None
self._buffer = b""
self._buffer_offset = 0
def seek(self, offset, whence=0):
"""Change the file position.
@ -385,7 +421,6 @@ class BZ2File(io.BufferedIOBase):
offset -= self._pos
# Read and discard data until we reach the desired position.
if self._mode != _MODE_READ_EOF:
self._read_block(offset, return_data=False)
return self._pos

View File

@ -461,7 +461,7 @@ class StreamReader(Codec):
# read until we get the required number of characters (if available)
while True:
# can the request can be satisfied from the character buffer?
# can the request be satisfied from the character buffer?
if chars < 0:
if size < 0:
if self.charbuffer:

View File

@ -456,7 +456,7 @@ if _os.name in ("nt", "ce"):
code = GetLastError()
if descr is None:
descr = FormatError(code).strip()
return WindowsError(code, descr)
return WindowsError(None, descr, None, code)
if sizeof(c_uint) == sizeof(c_void_p):
c_size_t = c_uint

View File

@ -67,6 +67,28 @@ if sys.platform == "win32":
self.assertEqual(ex.text, "text")
self.assertEqual(ex.details, ("details",))
class TestWinError(unittest.TestCase):
def test_winerror(self):
# see Issue 16169
import errno
ERROR_INVALID_PARAMETER = 87
msg = FormatError(ERROR_INVALID_PARAMETER).strip()
args = (errno.EINVAL, msg, None, ERROR_INVALID_PARAMETER)
e = WinError(ERROR_INVALID_PARAMETER)
self.assertEqual(e.args, args)
self.assertEqual(e.errno, errno.EINVAL)
self.assertEqual(e.winerror, ERROR_INVALID_PARAMETER)
windll.kernel32.SetLastError(ERROR_INVALID_PARAMETER)
try:
raise WinError()
except OSError as exc:
e = exc
self.assertEqual(e.args, args)
self.assertEqual(e.errno, errno.EINVAL)
self.assertEqual(e.winerror, ERROR_INVALID_PARAMETER)
class Structures(unittest.TestCase):
def test_struct_by_value(self):

View File

@ -46,6 +46,8 @@ zoom-height=<Alt-Key-2>
[ScriptBinding]
enable=1
enable_shell=0
enable_editor=1
[ScriptBinding_cfgBindings]
run-module=<Key-F5>
check-module=<Alt-Key-x>

View File

@ -206,8 +206,9 @@ def summarize_address_range(first, last):
"""Summarize a network range given the first and last IP addresses.
Example:
>>> summarize_address_range(IPv4Address('192.0.2.0'),
IPv4Address('192.0.2.130'))
>>> list(summarize_address_range(IPv4Address('192.0.2.0'),
... IPv4Address('192.0.2.130')))
... #doctest: +NORMALIZE_WHITESPACE
[IPv4Network('192.0.2.0/25'), IPv4Network('192.0.2.128/31'),
IPv4Network('192.0.2.130/32')]

View File

@ -794,13 +794,7 @@ class SysLogHandler(logging.Handler):
self.formatter = None
def _connect_unixsocket(self, address):
self.socket = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
# syslog may require either DGRAM or STREAM sockets
try:
self.socket.connect(address)
except socket.error:
self.socket.close()
self.socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
self.socket = socket.socket(socket.AF_UNIX, self.socktype)
try:
self.socket.connect(address)
except socket.error:

View File

@ -112,7 +112,7 @@ __copyright__ = """
__version__ = '1.0.7'
import collections
import sys, os, re
import sys, os, re, subprocess
### Globals & Constants
@ -922,13 +922,15 @@ def _syscmd_file(target,default=''):
if sys.platform in ('dos','win32','win16','os2'):
# XXX Others too ?
return default
target = _follow_symlinks(target).replace('"', '\\"')
target = _follow_symlinks(target)
try:
f = os.popen('file -b "%s" 2> %s' % (target, DEV_NULL))
proc = subprocess.Popen(['file', target],
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
except (AttributeError,os.error):
return default
output = f.read().strip()
rc = f.close()
output = proc.communicate()[0].decode('latin-1')
rc = proc.wait()
if not output or rc:
return default
else:

View File

@ -159,15 +159,19 @@ class Stats:
# along with some printable description
sort_arg_dict_default = {
"calls" : (((1,-1), ), "call count"),
"ncalls" : (((1,-1), ), "call count"),
"cumtime" : (((3,-1), ), "cumulative time"),
"cumulative": (((3,-1), ), "cumulative time"),
"file" : (((4, 1), ), "file name"),
"filename" : (((4, 1), ), "file name"),
"line" : (((5, 1), ), "line number"),
"module" : (((4, 1), ), "file name"),
"name" : (((6, 1), ), "function name"),
"nfl" : (((6, 1),(4, 1),(5, 1),), "name/file/line"),
"pcalls" : (((0,-1), ), "call count"),
"pcalls" : (((0,-1), ), "primitive call count"),
"stdname" : (((7, 1), ), "standard name"),
"time" : (((2,-1), ), "internal time"),
"tottime" : (((2,-1), ), "internal time"),
}
def get_sort_arg_defs(self):

View File

@ -562,7 +562,7 @@ class ForkingMixIn:
self.collect_children()
def service_actions(self):
"""Collect the zombie child processes regularly in the ForkingMixin.
"""Collect the zombie child processes regularly in the ForkingMixIn.
service_actions is called in the BaseServer's serve_forver loop.
"""

View File

@ -1445,9 +1445,16 @@ class Popen(object):
pid, sts = _waitpid(self.pid, _WNOHANG)
if pid == self.pid:
self._handle_exitstatus(sts)
except _os_error:
except _os_error as e:
if _deadstate is not None:
self.returncode = _deadstate
elif e.errno == errno.ECHILD:
# This happens if SIGCLD is set to be ignored or
# waiting for child processes has otherwise been
# disabled for our process. This child is dead, we
# can't get the status.
# http://bugs.python.org/issue15756
self.returncode = 0
return self.returncode

View File

@ -1,6 +1,15 @@
import signal, subprocess, sys
import signal, subprocess, sys, time
# On Linux this causes os.waitpid to fail with OSError as the OS has already
# reaped our child process. The wait() passing the OSError on to the caller
# and causing us to exit with an error is what we are testing against.
signal.signal(signal.SIGCHLD, signal.SIG_IGN)
subprocess.Popen([sys.executable, '-c', 'print("albatross")']).wait()
# Also ensure poll() handles an errno.ECHILD appropriately.
p = subprocess.Popen([sys.executable, '-c', 'print("albatross")'])
num_polls = 0
while p.poll() is None:
# Waiting for the process to finish.
time.sleep(0.01) # Avoid being a CPU busy loop.
num_polls += 1
if num_polls > 3000:
raise RuntimeError('poll should have returned 0 within 30 seconds')

View File

@ -316,6 +316,17 @@ class SkipitemTest(unittest.TestCase):
c, i, when_skipped, when_not_skipped))
self.assertIs(when_skipped, when_not_skipped, message)
def test_parse_tuple_and_keywords(self):
# parse_tuple_and_keywords error handling tests
self.assertRaises(TypeError, _testcapi.parse_tuple_and_keywords,
(), {}, 42, [])
self.assertRaises(ValueError, _testcapi.parse_tuple_and_keywords,
(), {}, b'', 42)
self.assertRaises(ValueError, _testcapi.parse_tuple_and_keywords,
(), {}, b'', [''] * 42)
self.assertRaises(ValueError, _testcapi.parse_tuple_and_keywords,
(), {}, b'', [42])
def test_main():
support.run_unittest(CAPITest, TestPendingCalls,
Test6012, EmbeddingTest, SkipitemTest)

View File

@ -62,6 +62,7 @@ class BaseTestCase(unittest.TestCase):
def tearDown(self):
self.thread.stop()
self.thread = None
os.environ.__exit__()
support.threading_cleanup(*self._threads)

View File

@ -1,4 +1,5 @@
import unittest
from test import script_helper
from test import support
import subprocess
import sys
@ -191,15 +192,134 @@ class ProcessTestCase(BaseTestCase):
p.wait()
self.assertEqual(p.stderr, None)
def _assert_python(self, pre_args, **kwargs):
# We include sys.exit() to prevent the test runner from hanging
# whenever python is found.
args = pre_args + ["import sys; sys.exit(47)"]
p = subprocess.Popen(args, **kwargs)
p.wait()
self.assertEqual(47, p.returncode)
# TODO: make this test work on Linux.
# This may be failing on Linux because of issue #7774.
@unittest.skipIf(sys.platform not in ('win32', 'darwin'),
"possible bug using executable argument on Linux")
def test_executable(self):
# Check that the executable argument works.
self._assert_python(["doesnotexist", "-c"], executable=sys.executable)
def test_executable_takes_precedence(self):
# Check that the executable argument takes precedence over args[0].
#
# Verify first that the call succeeds without the executable arg.
pre_args = [sys.executable, "-c"]
self._assert_python(pre_args)
self.assertRaises(FileNotFoundError, self._assert_python, pre_args,
executable="doesnotexist")
@unittest.skipIf(mswindows, "executable argument replaces shell")
def test_executable_replaces_shell(self):
# Check that the executable argument replaces the default shell
# when shell=True.
self._assert_python([], executable=sys.executable, shell=True)
# For use in the test_cwd* tests below.
def _normalize_cwd(self, cwd):
# Normalize an expected cwd (for Tru64 support).
# We can't use os.path.realpath since it doesn't expand Tru64 {memb}
# strings. See bug #1063571.
original_cwd = os.getcwd()
os.chdir(cwd)
cwd = os.getcwd()
os.chdir(original_cwd)
return cwd
# For use in the test_cwd* tests below.
def _split_python_path(self):
# Return normalized (python_dir, python_base).
python_path = os.path.realpath(sys.executable)
return os.path.split(python_path)
# For use in the test_cwd* tests below.
def _assert_cwd(self, expected_cwd, python_arg, **kwargs):
# Invoke Python via Popen, and assert that (1) the call succeeds,
# and that (2) the current working directory of the child process
# matches *expected_cwd*.
p = subprocess.Popen([python_arg, "-c",
"import os, sys; "
"sys.stdout.write(os.getcwd()); "
"sys.exit(47)"],
stdout=subprocess.PIPE,
**kwargs)
self.addCleanup(p.stdout.close)
p.wait()
self.assertEqual(47, p.returncode)
normcase = os.path.normcase
self.assertEqual(normcase(expected_cwd),
normcase(p.stdout.read().decode("utf-8")))
def test_cwd(self):
# Check that cwd changes the cwd for the child process.
temp_dir = tempfile.gettempdir()
temp_dir = self._normalize_cwd(temp_dir)
self._assert_cwd(temp_dir, sys.executable, cwd=temp_dir)
@unittest.skipIf(mswindows, "pending resolution of issue #15533")
def test_cwd_with_relative_arg(self):
# Check that Popen looks for args[0] relative to cwd if args[0]
# is relative.
python_dir, python_base = self._split_python_path()
rel_python = os.path.join(os.curdir, python_base)
with support.temp_cwd() as wrong_dir:
# Before calling with the correct cwd, confirm that the call fails
# without cwd and with the wrong cwd.
self.assertRaises(FileNotFoundError, subprocess.Popen,
[rel_python])
self.assertRaises(FileNotFoundError, subprocess.Popen,
[rel_python], cwd=wrong_dir)
python_dir = self._normalize_cwd(python_dir)
self._assert_cwd(python_dir, rel_python, cwd=python_dir)
@unittest.skipIf(mswindows, "pending resolution of issue #15533")
def test_cwd_with_relative_executable(self):
# Check that Popen looks for executable relative to cwd if executable
# is relative (and that executable takes precedence over args[0]).
python_dir, python_base = self._split_python_path()
rel_python = os.path.join(os.curdir, python_base)
doesntexist = "somethingyoudonthave"
with support.temp_cwd() as wrong_dir:
# Before calling with the correct cwd, confirm that the call fails
# without cwd and with the wrong cwd.
self.assertRaises(FileNotFoundError, subprocess.Popen,
[doesntexist], executable=rel_python)
self.assertRaises(FileNotFoundError, subprocess.Popen,
[doesntexist], executable=rel_python,
cwd=wrong_dir)
python_dir = self._normalize_cwd(python_dir)
self._assert_cwd(python_dir, doesntexist, executable=rel_python,
cwd=python_dir)
def test_cwd_with_absolute_arg(self):
# Check that Popen can find the executable when the cwd is wrong
# if args[0] is an absolute path.
python_dir, python_base = self._split_python_path()
abs_python = os.path.join(python_dir, python_base)
rel_python = os.path.join(os.curdir, python_base)
with script_helper.temp_dir() as wrong_dir:
# Before calling with an absolute path, confirm that using a
# relative path fails.
self.assertRaises(FileNotFoundError, subprocess.Popen,
[rel_python], cwd=wrong_dir)
wrong_dir = self._normalize_cwd(wrong_dir)
self._assert_cwd(wrong_dir, abs_python, cwd=wrong_dir)
@unittest.skipIf(sys.base_prefix != sys.prefix,
'Test is not venv-compatible')
def test_executable_with_cwd(self):
python_dir = os.path.dirname(os.path.realpath(sys.executable))
p = subprocess.Popen(["somethingyoudonthave", "-c",
"import sys; sys.exit(47)"],
python_dir, python_base = self._split_python_path()
python_dir = self._normalize_cwd(python_dir)
self._assert_cwd(python_dir, "somethingyoudonthave",
executable=sys.executable, cwd=python_dir)
p.wait()
self.assertEqual(p.returncode, 47)
@unittest.skipIf(sys.base_prefix != sys.prefix,
'Test is not venv-compatible')
@ -208,11 +328,7 @@ class ProcessTestCase(BaseTestCase):
def test_executable_without_cwd(self):
# For a normal installation, it should work without 'cwd'
# argument. For test runs in the build directory, see #7774.
p = subprocess.Popen(["somethingyoudonthave", "-c",
"import sys; sys.exit(47)"],
executable=sys.executable)
p.wait()
self.assertEqual(p.returncode, 47)
self._assert_cwd('', "somethingyoudonthave", executable=sys.executable)
def test_stdin_pipe(self):
# stdin redirection
@ -369,24 +485,6 @@ class ProcessTestCase(BaseTestCase):
p.wait()
self.assertEqual(p.stdin, None)
def test_cwd(self):
tmpdir = tempfile.gettempdir()
# We cannot use os.path.realpath to canonicalize the path,
# since it doesn't expand Tru64 {memb} strings. See bug 1063571.
cwd = os.getcwd()
os.chdir(tmpdir)
tmpdir = os.getcwd()
os.chdir(cwd)
p = subprocess.Popen([sys.executable, "-c",
'import sys,os;'
'sys.stdout.write(os.getcwd())'],
stdout=subprocess.PIPE,
cwd=tmpdir)
self.addCleanup(p.stdout.close)
normcase = os.path.normcase
self.assertEqual(normcase(p.stdout.read().decode("utf-8")),
normcase(tmpdir))
def test_env(self):
newenv = os.environ.copy()
newenv["FRUIT"] = "orange"

View File

@ -225,11 +225,9 @@ class ThreadedImportTests(unittest.TestCase):
@reap_threads
def test_main():
old_switchinterval = None
# Issue #15599: FreeBSD/KVM cannot handle gil_interval == 1.
new_switchinterval = 0.00001 if 'freebsd' in sys.platform else 0.00000001
try:
old_switchinterval = sys.getswitchinterval()
sys.setswitchinterval(new_switchinterval)
sys.setswitchinterval(1e-5)
except AttributeError:
pass
try:

View File

@ -1893,10 +1893,23 @@ class TreeBuilderTest(unittest.TestCase):
sample1 = ('<!DOCTYPE html PUBLIC'
' "-//W3C//DTD XHTML 1.0 Transitional//EN"'
' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'
'<html>text</html>')
'<html>text<div>subtext</div>tail</html>')
sample2 = '''<toplevel>sometext</toplevel>'''
def _check_sample1_element(self, e):
self.assertEqual(e.tag, 'html')
self.assertEqual(e.text, 'text')
self.assertEqual(e.tail, None)
self.assertEqual(e.attrib, {})
children = list(e)
self.assertEqual(len(children), 1)
child = children[0]
self.assertEqual(child.tag, 'div')
self.assertEqual(child.text, 'subtext')
self.assertEqual(child.tail, 'tail')
self.assertEqual(child.attrib, {})
def test_dummy_builder(self):
class BaseDummyBuilder:
def close(self):
@ -1929,7 +1942,7 @@ class TreeBuilderTest(unittest.TestCase):
parser.feed(self.sample1)
e = parser.close()
self.assertEqual(e.tag, 'html')
self._check_sample1_element(e)
def test_element_factory(self):
lst = []
@ -1945,6 +1958,33 @@ class TreeBuilderTest(unittest.TestCase):
self.assertEqual(lst, ['toplevel'])
def _check_element_factory_class(self, cls):
tb = ET.TreeBuilder(element_factory=cls)
parser = ET.XMLParser(target=tb)
parser.feed(self.sample1)
e = parser.close()
self.assertIsInstance(e, cls)
self._check_sample1_element(e)
def test_element_factory_subclass(self):
class MyElement(ET.Element):
pass
self._check_element_factory_class(MyElement)
def test_element_factory_pure_python_subclass(self):
# Mimick SimpleTAL's behaviour (issue #16089): both versions of
# TreeBuilder should be able to cope with a subclass of the
# pure Python Element class.
base = ET._Element
# Not from a C extension
self.assertEqual(base.__module__, 'xml.etree.ElementTree')
# Force some multiple inheritance with a C class to make things
# more interesting.
class MyElement(base, ValueError):
pass
self._check_element_factory_class(MyElement)
def test_doctype(self):
class DoctypeParser:
_doctype = None

View File

@ -303,7 +303,9 @@ class Element:
self._children.insert(index, element)
def _assert_is_element(self, e):
if not isinstance(e, Element):
# Need to refer to the actual Python implementation, not the
# shadowing C implementation.
if not isinstance(e, _Element):
raise TypeError('expected an Element, not %s' % type(e).__name__)
##

View File

@ -49,9 +49,9 @@ Jason Asbahr
David Ascher
Chris AtLee
Aymeric Augustin
Jesús Cea Avión
John Aycock
Donovan Baarda
Arne Babenhauserheide
Attila Babo
Marcin Bachry
Alfonso Baciero
@ -94,6 +94,7 @@ Ben Bell
Thomas Bellman
Alexander “Саша” Belopolsky
Eli Bendersky
David Benjamin
Andrew Bennetts
Andy Bensky
Bennett Benson
@ -101,6 +102,7 @@ Ezra Berch
Michel Van den Bergh
Julian Berman
Brice Berna
Olivier Bernard
Eric Beser
Steven Bethard
Stephen Bevan
@ -183,6 +185,7 @@ Terry Carroll
Lorenzo M. Catucci
Donn Cave
Charles Cazabon
Jesús Cea Avión
Per Cederqvist
Matej Cepl
Carl Cerecke
@ -246,6 +249,7 @@ Christopher A. Craig
Jeremy Craven
Laura Creighton
Simon Cross
Felipe Cruz
Drew Csillag
Joaquin Cuenca Abela
John Cugini

File diff suppressed because it is too large Load Diff

5889
Misc/NEWS

File diff suppressed because it is too large Load Diff

View File

@ -177,12 +177,12 @@ escape_encode(PyObject *self,
return NULL;
size = PyBytes_GET_SIZE(str);
newsize = 4*size;
if (newsize > PY_SSIZE_T_MAX || newsize / 4 != size) {
if (size > PY_SSIZE_T_MAX / 4) {
PyErr_SetString(PyExc_OverflowError,
"string is too large to encode");
return NULL;
}
newsize = 4*size;
v = PyBytes_FromStringAndSize(NULL, newsize);
if (v == NULL) {

View File

@ -1265,14 +1265,13 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
assert(ptoappend != NULL);
assert(ntoappend > 0);
while (usednew + ntoappend > totalnew) {
size_t bigger = totalnew << 1;
if ((bigger >> 1) != totalnew) { /* overflow */
if (totalnew > (PY_SSIZE_T_MAX >> 1)) { /* overflow */
PyErr_NoMemory();
goto Done;
}
if (_PyBytes_Resize(&newfmt, bigger) < 0)
totalnew <<= 1;
if (_PyBytes_Resize(&newfmt, totalnew) < 0)
goto Done;
totalnew = bigger;
pnew = PyBytes_AsString(newfmt) + usednew;
}
memcpy(pnew, ptoappend, ntoappend);

View File

@ -207,7 +207,7 @@ _mpd_mul_words(mpd_uint_t *hi, mpd_uint_t *lo, mpd_uint_t a, mpd_uint_t b)
{
mpd_uint_t h, l;
asm ( "mulq %3\n\t"
__asm__ ( "mulq %3\n\t"
: "=d" (h), "=a" (l)
: "%a" (a), "rm" (b)
: "cc"
@ -223,7 +223,7 @@ _mpd_div_words(mpd_uint_t *q, mpd_uint_t *r, mpd_uint_t hi, mpd_uint_t lo,
{
mpd_uint_t qq, rr;
asm ( "divq %4\n\t"
__asm__ ( "divq %4\n\t"
: "=a" (qq), "=d" (rr)
: "a" (lo), "d" (hi), "rm" (d)
: "cc"
@ -464,7 +464,7 @@ _mpd_mul_words(mpd_uint_t *hi, mpd_uint_t *lo, mpd_uint_t a, mpd_uint_t b)
{
mpd_uint_t h, l;
asm ( "mull %3\n\t"
__asm__ ( "mull %3\n\t"
: "=d" (h), "=a" (l)
: "%a" (a), "rm" (b)
: "cc"
@ -480,7 +480,7 @@ _mpd_div_words(mpd_uint_t *q, mpd_uint_t *r, mpd_uint_t hi, mpd_uint_t lo,
{
mpd_uint_t qq, rr;
asm ( "divl %4\n\t"
__asm__ ( "divl %4\n\t"
: "=a" (qq), "=d" (rr)
: "a" (lo), "d" (hi), "rm" (d)
: "cc"

View File

@ -402,7 +402,7 @@ ppro_mulmod(mpd_uint_t a, mpd_uint_t b, double *dmod, uint32_t *dinvmod)
{
mpd_uint_t retval;
asm (
__asm__ (
"fildl %2\n\t"
"fildl %1\n\t"
"fmulp %%st, %%st(1)\n\t"
@ -432,7 +432,7 @@ static inline void
ppro_mulmod2c(mpd_uint_t *a0, mpd_uint_t *a1, mpd_uint_t w,
double *dmod, uint32_t *dinvmod)
{
asm (
__asm__ (
"fildl %2\n\t"
"fildl (%1)\n\t"
"fmul %%st(1), %%st\n\t"
@ -471,7 +471,7 @@ static inline void
ppro_mulmod2(mpd_uint_t *a0, mpd_uint_t b0, mpd_uint_t *a1, mpd_uint_t b1,
double *dmod, uint32_t *dinvmod)
{
asm (
__asm__ (
"fildl %3\n\t"
"fildl (%2)\n\t"
"fmulp %%st, %%st(1)\n\t"

View File

@ -18,8 +18,13 @@ except ImportError:
C = import_fresh_module('decimal', fresh=['_decimal'])
P = import_fresh_module('decimal', blocked=['_decimal'])
# Pi function from the decimal.py documentation
#
# NOTE: This is the pi function from the decimal documentation, modified
# for benchmarking purposes. Since floats do not have a context, the higher
# intermediate precision from the original is NOT used, so the modified
# algorithm only gives an approximation to the correctly rounded result.
# For serious use, refer to the documentation or the appropriate literature.
#
def pi_float():
"""native float"""
lasts, t, s, n, na, d, da = 0, 3.0, 3, 1, 0, 0, 24

View File

@ -123,17 +123,11 @@ deepcopy(PyObject* object, PyObject* memo)
return NULL;
}
args = PyTuple_New(2);
args = PyTuple_Pack(2, object, memo);
if (!args)
return NULL;
Py_INCREF(object); PyTuple_SET_ITEM(args, 0, (PyObject*) object);
Py_INCREF(memo); PyTuple_SET_ITEM(args, 1, (PyObject*) memo);
result = PyObject_CallObject(elementtree_deepcopy_obj, args);
Py_DECREF(args);
return result;
}
@ -141,48 +135,16 @@ LOCAL(PyObject*)
list_join(PyObject* list)
{
/* join list elements (destroying the list in the process) */
PyObject* joiner;
PyObject* function;
PyObject* args;
PyObject* result;
switch (PyList_GET_SIZE(list)) {
case 0:
Py_DECREF(list);
return PyBytes_FromString("");
case 1:
result = PyList_GET_ITEM(list, 0);
Py_INCREF(result);
Py_DECREF(list);
return result;
}
/* two or more elements: slice out a suitable separator from the
first member, and use that to join the entire list */
joiner = PySequence_GetSlice(PyList_GET_ITEM(list, 0), 0, 0);
joiner = PyUnicode_FromStringAndSize("", 0);
if (!joiner)
return NULL;
function = PyObject_GetAttrString(joiner, "join");
if (!function) {
result = PyUnicode_Join(joiner, list);
Py_DECREF(joiner);
return NULL;
}
args = PyTuple_New(1);
if (!args)
return NULL;
PyTuple_SET_ITEM(args, 0, list);
result = PyObject_CallObject(function, args);
Py_DECREF(args); /* also removes list */
Py_DECREF(function);
Py_DECREF(joiner);
if (result)
Py_DECREF(list);
return result;
}
@ -399,6 +361,7 @@ element_init(PyObject *self, PyObject *args, PyObject *kwds)
return -1;
if (kwds) {
if (PyDict_Update(attrib, kwds) < 0) {
Py_DECREF(attrib);
return -1;
}
}
@ -407,38 +370,34 @@ element_init(PyObject *self, PyObject *args, PyObject *kwds)
attrib = get_attrib_from_keywords(kwds);
if (!attrib)
return -1;
} else {
/* no attrib arg, no kwds, so no attributes */
Py_INCREF(Py_None);
attrib = Py_None;
}
self_elem = (ElementObject *)self;
if (attrib != Py_None && !is_empty_dict(attrib)) {
if (attrib != NULL && !is_empty_dict(attrib)) {
if (create_extra(self_elem, attrib) < 0) {
PyObject_Del(self_elem);
Py_DECREF(attrib);
return -1;
}
}
/* We own a reference to attrib here and it's no longer needed. */
Py_DECREF(attrib);
Py_XDECREF(attrib);
/* Replace the objects already pointed to by tag, text and tail. */
tmp = self_elem->tag;
self_elem->tag = tag;
Py_INCREF(tag);
self_elem->tag = tag;
Py_DECREF(tmp);
tmp = self_elem->text;
self_elem->text = Py_None;
Py_INCREF(Py_None);
self_elem->text = Py_None;
Py_DECREF(JOIN_OBJ(tmp));
tmp = self_elem->tail;
self_elem->tail = Py_None;
Py_INCREF(Py_None);
self_elem->tail = Py_None;
Py_DECREF(JOIN_OBJ(tmp));
return 0;
@ -520,11 +479,11 @@ element_get_attrib(ElementObject* self)
PyObject* res = self->extra->attrib;
if (res == Py_None) {
Py_DECREF(res);
/* create missing dictionary */
res = PyDict_New();
if (!res)
return NULL;
Py_DECREF(Py_None);
self->extra->attrib = res;
}
@ -824,7 +783,7 @@ element_deepcopy(ElementObject* self, PyObject* args)
}
/* add object to memo dictionary (so deepcopy won't visit it again) */
id = PyLong_FromLong((Py_uintptr_t) self);
id = PyLong_FromSsize_t((Py_uintptr_t) self);
if (!id)
goto error;
@ -2038,8 +1997,8 @@ typedef struct {
PyObject *root; /* root node (first created node) */
ElementObject *this; /* current node */
ElementObject *last; /* most recently created node */
PyObject *this; /* current node */
PyObject *last; /* most recently created node */
PyObject *data; /* data collector (string or list), or NULL */
@ -2071,9 +2030,9 @@ treebuilder_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
t->root = NULL;
Py_INCREF(Py_None);
t->this = (ElementObject *)Py_None;
t->this = Py_None;
Py_INCREF(Py_None);
t->last = (ElementObject *)Py_None;
t->last = Py_None;
t->data = NULL;
t->element_factory = NULL;
@ -2081,6 +2040,7 @@ treebuilder_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
if (!t->stack) {
Py_DECREF(t->this);
Py_DECREF(t->last);
Py_DECREF((PyObject *) t);
return NULL;
}
t->index = 0;
@ -2098,6 +2058,7 @@ treebuilder_init(PyObject *self, PyObject *args, PyObject *kwds)
static char *kwlist[] = {"element_factory", 0};
PyObject *element_factory = NULL;
TreeBuilderObject *self_tb = (TreeBuilderObject *)self;
PyObject *tmp;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:TreeBuilder", kwlist,
&element_factory)) {
@ -2106,8 +2067,9 @@ treebuilder_init(PyObject *self, PyObject *args, PyObject *kwds)
if (element_factory) {
Py_INCREF(element_factory);
Py_XDECREF(self_tb->element_factory);
tmp = self_tb->element_factory;
self_tb->element_factory = element_factory;
Py_XDECREF(tmp);
}
return 0;
@ -2128,17 +2090,17 @@ treebuilder_gc_traverse(TreeBuilderObject *self, visitproc visit, void *arg)
static int
treebuilder_gc_clear(TreeBuilderObject *self)
{
Py_XDECREF(self->end_ns_event_obj);
Py_XDECREF(self->start_ns_event_obj);
Py_XDECREF(self->end_event_obj);
Py_XDECREF(self->start_event_obj);
Py_XDECREF(self->events);
Py_DECREF(self->stack);
Py_XDECREF(self->data);
Py_DECREF(self->last);
Py_DECREF(self->this);
Py_CLEAR(self->end_ns_event_obj);
Py_CLEAR(self->start_ns_event_obj);
Py_CLEAR(self->end_event_obj);
Py_CLEAR(self->start_event_obj);
Py_CLEAR(self->events);
Py_CLEAR(self->stack);
Py_CLEAR(self->data);
Py_CLEAR(self->last);
Py_CLEAR(self->this);
Py_CLEAR(self->element_factory);
Py_XDECREF(self->root);
Py_CLEAR(self->root);
return 0;
}
@ -2150,6 +2112,64 @@ treebuilder_dealloc(TreeBuilderObject *self)
Py_TYPE(self)->tp_free((PyObject *)self);
}
/* -------------------------------------------------------------------- */
/* helpers for handling of arbitrary element-like objects */
static int
treebuilder_set_element_text_or_tail(PyObject *element, PyObject *data,
PyObject **dest, _Py_Identifier *name)
{
if (Element_CheckExact(element)) {
Py_DECREF(JOIN_OBJ(*dest));
*dest = JOIN_SET(data, PyList_CheckExact(data));
return 0;
}
else {
PyObject *joined = list_join(data);
int r;
if (joined == NULL)
return -1;
r = _PyObject_SetAttrId(element, name, joined);
Py_DECREF(joined);
return r;
}
}
/* These two functions steal a reference to data */
static int
treebuilder_set_element_text(PyObject *element, PyObject *data)
{
_Py_IDENTIFIER(text);
return treebuilder_set_element_text_or_tail(
element, data, &((ElementObject *) element)->text, &PyId_text);
}
static int
treebuilder_set_element_tail(PyObject *element, PyObject *data)
{
_Py_IDENTIFIER(tail);
return treebuilder_set_element_text_or_tail(
element, data, &((ElementObject *) element)->tail, &PyId_tail);
}
static int
treebuilder_add_subelement(PyObject *element, PyObject *child)
{
_Py_IDENTIFIER(append);
if (Element_CheckExact(element)) {
ElementObject *elem = (ElementObject *) element;
return element_add_subelement(elem, child);
}
else {
PyObject *res;
res = _PyObject_CallMethodId(element, &PyId_append, "O", child);
if (res == NULL)
return -1;
Py_DECREF(res);
return 0;
}
}
/* -------------------------------------------------------------------- */
/* handlers */
@ -2162,15 +2182,12 @@ treebuilder_handle_start(TreeBuilderObject* self, PyObject* tag,
if (self->data) {
if (self->this == self->last) {
Py_DECREF(JOIN_OBJ(self->last->text));
self->last->text = JOIN_SET(
self->data, PyList_CheckExact(self->data)
);
} else {
Py_DECREF(JOIN_OBJ(self->last->tail));
self->last->tail = JOIN_SET(
self->data, PyList_CheckExact(self->data)
);
if (treebuilder_set_element_text(self->last, self->data))
return NULL;
}
else {
if (treebuilder_set_element_tail(self->last, self->data))
return NULL;
}
self->data = NULL;
}
@ -2184,10 +2201,10 @@ treebuilder_handle_start(TreeBuilderObject* self, PyObject* tag,
return NULL;
}
this = (PyObject*) self->this;
this = self->this;
if (this != Py_None) {
if (element_add_subelement((ElementObject*) this, node) < 0)
if (treebuilder_add_subelement(this, node) < 0)
goto error;
} else {
if (self->root) {
@ -2213,19 +2230,17 @@ treebuilder_handle_start(TreeBuilderObject* self, PyObject* tag,
Py_DECREF(this);
Py_INCREF(node);
self->this = (ElementObject*) node;
self->this = node;
Py_DECREF(self->last);
Py_INCREF(node);
self->last = (ElementObject*) node;
self->last = node;
if (self->start_event_obj) {
PyObject* res;
PyObject* action = self->start_event_obj;
res = PyTuple_New(2);
res = PyTuple_Pack(2, action, node);
if (res) {
Py_INCREF(action); PyTuple_SET_ITEM(res, 0, (PyObject*) action);
Py_INCREF(node); PyTuple_SET_ITEM(res, 1, (PyObject*) node);
PyList_Append(self->events, res);
Py_DECREF(res);
} else
@ -2243,7 +2258,7 @@ LOCAL(PyObject*)
treebuilder_handle_data(TreeBuilderObject* self, PyObject* data)
{
if (!self->data) {
if (self->last == (ElementObject*) Py_None) {
if (self->last == Py_None) {
/* ignore calls to data before the first call to start */
Py_RETURN_NONE;
}
@ -2253,6 +2268,7 @@ treebuilder_handle_data(TreeBuilderObject* self, PyObject* data)
/* more than one item; use a list to collect items */
if (PyBytes_CheckExact(self->data) && Py_REFCNT(self->data) == 1 &&
PyBytes_CheckExact(data) && PyBytes_GET_SIZE(data) == 1) {
/* XXX this code path unused in Python 3? */
/* expat often generates single character data sections; handle
the most common case by resizing the existing string... */
Py_ssize_t size = PyBytes_GET_SIZE(self->data);
@ -2282,15 +2298,11 @@ treebuilder_handle_end(TreeBuilderObject* self, PyObject* tag)
if (self->data) {
if (self->this == self->last) {
Py_DECREF(JOIN_OBJ(self->last->text));
self->last->text = JOIN_SET(
self->data, PyList_CheckExact(self->data)
);
if (treebuilder_set_element_text(self->last, self->data))
return NULL;
} else {
Py_DECREF(JOIN_OBJ(self->last->tail));
self->last->tail = JOIN_SET(
self->data, PyList_CheckExact(self->data)
);
if (treebuilder_set_element_tail(self->last, self->data))
return NULL;
}
self->data = NULL;
}
@ -2310,17 +2322,15 @@ treebuilder_handle_end(TreeBuilderObject* self, PyObject* tag)
Py_DECREF(self->last);
self->last = (ElementObject*) self->this;
self->this = (ElementObject*) item;
self->last = self->this;
self->this = item;
if (self->end_event_obj) {
PyObject* res;
PyObject* action = self->end_event_obj;
PyObject* node = (PyObject*) self->last;
res = PyTuple_New(2);
res = PyTuple_Pack(2, action, node);
if (res) {
Py_INCREF(action); PyTuple_SET_ITEM(res, 0, (PyObject*) action);
Py_INCREF(node); PyTuple_SET_ITEM(res, 1, (PyObject*) node);
PyList_Append(self->events, res);
Py_DECREF(res);
} else
@ -2366,9 +2376,13 @@ treebuilder_handle_namespace(TreeBuilderObject* self, int start,
PyTuple_SET_ITEM(res, 1, parcel);
PyList_Append(self->events, res);
Py_DECREF(res);
} else
}
else {
Py_DECREF(action);
Py_DECREF(parcel);
PyErr_Clear(); /* FIXME: propagate error */
}
}
/* -------------------------------------------------------------------- */
/* methods (in alphabetical order) */
@ -2526,7 +2540,7 @@ makeuniversal(XMLParserObject* self, const char* string)
/* convert a UTF-8 tag/attribute name from the expat parser
to a universal name string */
int size = strlen(string);
Py_ssize_t size = (Py_ssize_t) strlen(string);
PyObject* key;
PyObject* value;
@ -2545,7 +2559,7 @@ makeuniversal(XMLParserObject* self, const char* string)
PyObject* tag;
char* p;
int i;
Py_ssize_t i;
/* look for namespace separator */
for (i = 0; i < size; i++)
@ -2717,13 +2731,7 @@ expat_start_handler(XMLParserObject* self, const XML_Char* tag_in,
attrib_in += 2;
}
} else {
Py_INCREF(Py_None);
attrib = Py_None;
}
/* If we get None, pass an empty dictionary on */
if (attrib == Py_None) {
Py_DECREF(attrib);
/* Pass an empty dictionary on */
attrib = PyDict_New();
if (!attrib)
return;
@ -3015,14 +3023,14 @@ xmlparser_init(PyObject *self, PyObject *args, PyObject *kwds)
self_xp->names = PyDict_New();
if (!self_xp->names) {
Py_XDECREF(self_xp->entity);
Py_CLEAR(self_xp->entity);
return -1;
}
self_xp->parser = EXPAT(ParserCreate_MM)(encoding, &ExpatMemoryHandler, "}");
if (!self_xp->parser) {
Py_XDECREF(self_xp->entity);
Py_XDECREF(self_xp->names);
Py_CLEAR(self_xp->entity);
Py_CLEAR(self_xp->names);
PyErr_NoMemory();
return -1;
}
@ -3032,8 +3040,8 @@ xmlparser_init(PyObject *self, PyObject *args, PyObject *kwds)
} else {
target = treebuilder_new(&TreeBuilder_Type, NULL, NULL);
if (!target) {
Py_XDECREF(self_xp->entity);
Py_XDECREF(self_xp->names);
Py_CLEAR(self_xp->entity);
Py_CLEAR(self_xp->names);
EXPAT(ParserFree)(self_xp->parser);
return -1;
}
@ -3109,17 +3117,17 @@ xmlparser_gc_clear(XMLParserObject *self)
{
EXPAT(ParserFree)(self->parser);
Py_XDECREF(self->handle_close);
Py_XDECREF(self->handle_pi);
Py_XDECREF(self->handle_comment);
Py_XDECREF(self->handle_end);
Py_XDECREF(self->handle_data);
Py_XDECREF(self->handle_start);
Py_XDECREF(self->handle_doctype);
Py_CLEAR(self->handle_close);
Py_CLEAR(self->handle_pi);
Py_CLEAR(self->handle_comment);
Py_CLEAR(self->handle_end);
Py_CLEAR(self->handle_data);
Py_CLEAR(self->handle_start);
Py_CLEAR(self->handle_doctype);
Py_XDECREF(self->target);
Py_XDECREF(self->entity);
Py_XDECREF(self->names);
Py_CLEAR(self->target);
Py_CLEAR(self->entity);
Py_CLEAR(self->names);
return 0;
}
@ -3227,17 +3235,12 @@ xmlparser_parse(XMLParserObject* self, PyObject* args)
break;
}
temp = PyUnicode_AsEncodedString(buffer, "utf-8", "surrogatepass");
Py_DECREF(buffer);
if (!temp) {
/* Propagate exception from PyUnicode_AsEncodedString */
Py_DECREF(buffer);
Py_DECREF(reader);
return NULL;
}
/* Here we no longer need the original buffer since it contains
* unicode. Make it point to the encoded bytes object.
*/
Py_DECREF(buffer);
buffer = temp;
}
else if (!PyBytes_CheckExact(buffer) || PyBytes_GET_SIZE(buffer) == 0) {
@ -3307,10 +3310,10 @@ xmlparser_setevents(XMLParserObject *self, PyObject* args)
target->events = events;
/* clear out existing events */
Py_XDECREF(target->start_event_obj); target->start_event_obj = NULL;
Py_XDECREF(target->end_event_obj); target->end_event_obj = NULL;
Py_XDECREF(target->start_ns_event_obj); target->start_ns_event_obj = NULL;
Py_XDECREF(target->end_ns_event_obj); target->end_ns_event_obj = NULL;
Py_CLEAR(target->start_event_obj);
Py_CLEAR(target->end_event_obj);
Py_CLEAR(target->start_ns_event_obj);
Py_CLEAR(target->end_ns_event_obj);
if (event_set == Py_None) {
/* default is "end" only */

View File

@ -284,7 +284,8 @@ random_seed(RandomObject *self, PyObject *args)
n = newn;
if (keyused >= keymax) {
unsigned long bigger = keymax << 1;
if ((bigger >> 1) != keymax) {
if ((bigger >> 1) != keymax ||
bigger > PY_SSIZE_T_MAX / sizeof(*key)) {
PyErr_NoMemory();
goto Done;
}

View File

@ -1238,7 +1238,7 @@ parse_tuple_and_keywords(PyObject *self, PyObject *args)
o = PySequence_Fast_GET_ITEM(sub_keywords, i);
if (!PyUnicode_FSConverter(o, (void *)(converted + i))) {
PyErr_Format(PyExc_ValueError,
"parse_tuple_and_keywords: could not convert keywords[%s] to narrow string", i);
"parse_tuple_and_keywords: could not convert keywords[%zd] to narrow string", i);
goto exit;
}
keywords[i] = PyBytes_AS_STRING(converted[i]);

View File

@ -483,11 +483,11 @@ newarrayobject(PyTypeObject *type, Py_ssize_t size, struct arraydescr *descr)
return NULL;
}
nbytes = size * descr->itemsize;
/* Check for overflow */
if (nbytes / descr->itemsize != (size_t)size) {
if (size > PY_SSIZE_T_MAX / descr->itemsize) {
return PyErr_NoMemory();
}
nbytes = size * descr->itemsize;
op = (arrayobject *) type->tp_alloc(type, 0);
if (op == NULL) {
return NULL;
@ -1251,11 +1251,15 @@ array_fromfile(arrayobject *self, PyObject *args)
if (!PyArg_ParseTuple(args, "On:fromfile", &f, &n))
return NULL;
nbytes = n * itemsize;
if (nbytes < 0 || nbytes/itemsize != n) {
if (n < 0) {
PyErr_SetString(PyExc_ValueError, "negative count");
return NULL;
}
if (n > PY_SSIZE_T_MAX / itemsize) {
PyErr_NoMemory();
return NULL;
}
nbytes = n * itemsize;
b = _PyObject_CallMethodId(f, &PyId_read, "n", nbytes);
if (b == NULL)

View File

@ -1108,8 +1108,7 @@ audioop_ratecv(PyObject *self, PyObject *args)
PyErr_SetString(AudioopError, "# of channels should be >= 1");
return NULL;
}
bytes_per_frame = size * nchannels;
if (bytes_per_frame / nchannels != size) {
if (size > INT_MAX / nchannels) {
/* This overflow test is rigorously correct because
both multiplicands are >= 1. Use the argument names
from the docs for the error msg. */
@ -1117,6 +1116,7 @@ audioop_ratecv(PyObject *self, PyObject *args)
"width * nchannels too big for a C int");
return NULL;
}
bytes_per_frame = size * nchannels;
if (weightA < 1 || weightB < 0) {
PyErr_SetString(AudioopError,
"weightA should be >= 1, weightB should be >= 0");

View File

@ -875,7 +875,12 @@ read_directory(PyObject *archive)
PyErr_Format(ZipImportError, "can't open Zip file: %R", archive);
return NULL;
}
fseek(fp, -22, SEEK_END);
if (fseek(fp, -22, SEEK_END) == -1) {
fclose(fp);
PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
return NULL;
}
header_position = ftell(fp);
if (fread(endof_central_dir, 1, 22, fp) != 22) {
fclose(fp);
@ -904,11 +909,13 @@ read_directory(PyObject *archive)
PyObject *t;
int err;
fseek(fp, header_offset, 0); /* Start of file header */
if (fseek(fp, header_offset, 0) == -1) /* Start of file header */
goto fseek_error;
l = PyMarshal_ReadLongFromFile(fp);
if (l != 0x02014B50)
break; /* Bad: Central Dir File Header */
fseek(fp, header_offset + 8, 0);
if (fseek(fp, header_offset + 8, 0) == -1)
goto fseek_error;
flags = (unsigned short)PyMarshal_ReadShortFromFile(fp);
compress = PyMarshal_ReadShortFromFile(fp);
time = PyMarshal_ReadShortFromFile(fp);
@ -920,7 +927,8 @@ read_directory(PyObject *archive)
header_size = 46 + name_size +
PyMarshal_ReadShortFromFile(fp) +
PyMarshal_ReadShortFromFile(fp);
fseek(fp, header_offset + 42, 0);
if (fseek(fp, header_offset + 42, 0) == -1)
goto fseek_error;
file_offset = PyMarshal_ReadLongFromFile(fp) + arc_offset;
if (name_size > MAXPATHLEN)
name_size = MAXPATHLEN;
@ -980,6 +988,12 @@ read_directory(PyObject *archive)
PySys_FormatStderr("# zipimport: found %ld names in %R\n",
count, archive);
return files;
fseek_error:
fclose(fp);
Py_XDECREF(files);
Py_XDECREF(nameobj);
PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
return NULL;
error:
fclose(fp);
Py_XDECREF(files);
@ -1050,7 +1064,12 @@ get_data(PyObject *archive, PyObject *toc_entry)
}
/* Check to make sure the local file header is correct */
fseek(fp, file_offset, 0);
if (fseek(fp, file_offset, 0) == -1) {
fclose(fp);
PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
return NULL;
}
l = PyMarshal_ReadLongFromFile(fp);
if (l != 0x04034B50) {
/* Bad: Local File Header */
@ -1060,7 +1079,12 @@ get_data(PyObject *archive, PyObject *toc_entry)
fclose(fp);
return NULL;
}
fseek(fp, file_offset + 26, 0);
if (fseek(fp, file_offset + 26, 0) == -1) {
fclose(fp);
PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
return NULL;
}
l = 30 + PyMarshal_ReadShortFromFile(fp) +
PyMarshal_ReadShortFromFile(fp); /* local header size */
file_offset += l; /* Start of file data */
@ -1077,8 +1101,13 @@ get_data(PyObject *archive, PyObject *toc_entry)
buf = PyBytes_AsString(raw_data);
err = fseek(fp, file_offset, 0);
if (err == 0)
if (err == 0) {
bytes_read = fread(buf, 1, data_size, fp);
} else {
fclose(fp);
PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
return NULL;
}
fclose(fp);
if (err || bytes_read != data_size) {
PyErr_SetString(PyExc_IOError,

View File

@ -668,10 +668,9 @@ _PyLong_NumBits(PyObject *vv)
assert(ndigits == 0 || v->ob_digit[ndigits - 1] != 0);
if (ndigits > 0) {
digit msd = v->ob_digit[ndigits - 1];
result = (ndigits - 1) * PyLong_SHIFT;
if (result / PyLong_SHIFT != (size_t)(ndigits - 1))
if ((size_t)(ndigits - 1) > PY_SIZE_MAX / (size_t)PyLong_SHIFT)
goto Overflow;
result = (size_t)(ndigits - 1) * (size_t)PyLong_SHIFT;
do {
++result;
if (result == 0)
@ -4849,13 +4848,20 @@ static PyGetSetDef long_getset[] = {
};
PyDoc_STRVAR(long_doc,
"int(x[, base]) -> integer\n\
"int(x=0) -> integer\n\
int(x, base=10) -> integer\n\
\n\
Convert a string or number to an integer, if possible. A floating\n\
point argument will be truncated towards zero (this does not include a\n\
string representation of a floating point number!) When converting a\n\
string, use the optional base. It is an error to supply a base when\n\
converting a non-string.");
Convert a number or string to an integer, or return 0 if no arguments\n\
are given. If x is a number, return x.__int__(). For floating point\n\
numbers, this truncates towards zero.\n\
\n\
If x is not a number or if base is given, then x must be a string,\n\
bytes, or bytearray instance representing an integer literal in the\n\
given base. The literal can be preceded by '+' or '-' and be surrounded\n\
by whitespace. The base defaults to 10. Valid bases are 0 and 2-36.\n\
Base 0 means to interpret the base from the string as an integer literal.\n\
>>> int('0b100', base=0)\n\
4");
static PyNumberMethods long_as_number = {
(binaryfunc)long_add, /*nb_add*/

View File

@ -136,7 +136,8 @@ range_new(PyTypeObject *type, PyObject *args, PyObject *kw)
}
PyDoc_STRVAR(range_doc,
"range([start,] stop[, step]) -> range object\n\
"range(stop) -> range object\n\
range(start, stop[, step]) -> range object\n\
\n\
Returns a virtual sequence of numbers from start to stop by step.");

View File

@ -269,7 +269,8 @@ slice_new(PyTypeObject *type, PyObject *args, PyObject *kw)
}
PyDoc_STRVAR(slice_doc,
"slice([start,] stop[, step])\n\
"slice(stop)\n\
slice(start, stop[, step])\n\
\n\
Create a slice object. This is used for extended slicing (e.g. a[0:10:2]).");

View File

@ -96,15 +96,11 @@ PyTuple_New(register Py_ssize_t size)
else
#endif
{
Py_ssize_t nbytes = size * sizeof(PyObject *);
/* Check for overflow */
if (nbytes / sizeof(PyObject *) != (size_t)size ||
(nbytes > PY_SSIZE_T_MAX - sizeof(PyTupleObject) - sizeof(PyObject *)))
{
if (size > (PY_SSIZE_T_MAX - sizeof(PyTupleObject) -
sizeof(PyObject *)) / sizeof(PyObject *)) {
return PyErr_NoMemory();
}
/* nbytes += sizeof(PyTupleObject) - sizeof(PyObject *); */
op = PyObject_GC_NewVar(PyTupleObject, &PyTuple_Type, size);
if (op == NULL)
return NULL;
@ -481,9 +477,9 @@ tuplerepeat(PyTupleObject *a, Py_ssize_t n)
if (Py_SIZE(a) == 0)
return PyTuple_New(0);
}
size = Py_SIZE(a) * n;
if (size/Py_SIZE(a) != n)
if (n > PY_SSIZE_T_MAX / Py_SIZE(a))
return PyErr_NoMemory();
size = Py_SIZE(a) * n;
np = (PyTupleObject *) PyTuple_New(size);
if (np == NULL)
return NULL;

View File

@ -4492,7 +4492,6 @@ _PyUnicode_EncodeUTF7(PyObject *str,
void *data;
Py_ssize_t len;
PyObject *v;
Py_ssize_t allocated;
int inShift = 0;
Py_ssize_t i;
unsigned int base64bits = 0;
@ -4510,11 +4509,9 @@ _PyUnicode_EncodeUTF7(PyObject *str,
return PyBytes_FromStringAndSize(NULL, 0);
/* It might be possible to tighten this worst case */
allocated = 8 * len;
if (allocated / 8 != len)
if (len > PY_SSIZE_T_MAX / 8)
return PyErr_NoMemory();
v = PyBytes_FromStringAndSize(NULL, allocated);
v = PyBytes_FromStringAndSize(NULL, len * 8);
if (v == NULL)
return NULL;
@ -5092,7 +5089,7 @@ _PyUnicode_EncodeUTF32(PyObject *str,
Py_ssize_t len;
PyObject *v;
unsigned char *p;
Py_ssize_t nsize, bytesize, i;
Py_ssize_t nsize, i;
/* Offsets from p for storing byte pairs in the right order. */
#ifdef BYTEORDER_IS_LITTLE_ENDIAN
int iorder[] = {0, 1, 2, 3};
@ -5120,10 +5117,9 @@ _PyUnicode_EncodeUTF32(PyObject *str,
len = PyUnicode_GET_LENGTH(str);
nsize = len + (byteorder == 0);
bytesize = nsize * 4;
if (bytesize / 4 != nsize)
if (nsize > PY_SSIZE_T_MAX / 4)
return PyErr_NoMemory();
v = PyBytes_FromStringAndSize(NULL, bytesize);
v = PyBytes_FromStringAndSize(NULL, nsize * 4);
if (v == NULL)
return NULL;
@ -5772,18 +5768,12 @@ PyUnicode_AsUnicodeEscapeString(PyObject *unicode)
void *data;
Py_ssize_t expandsize = 0;
/* Initial allocation is based on the longest-possible unichr
/* Initial allocation is based on the longest-possible character
escape.
In wide (UTF-32) builds '\U00xxxxxx' is 10 chars per source
unichr, so in this case it's the longest unichr escape. In
narrow (UTF-16) builds this is five chars per source unichr
since there are two unichrs in the surrogate pair, so in narrow
(UTF-16) builds it's not the longest unichr escape.
In wide or narrow builds '\uxxxx' is 6 chars per source unichr,
so in the narrow (UTF-16) build case it's the longest unichr
escape.
For UCS1 strings it's '\xxx', 4 bytes per source character.
For UCS2 strings it's '\uxxxx', 6 bytes per source character.
For UCS4 strings it's '\U00xxxxxx', 10 bytes per source character.
*/
if (!PyUnicode_Check(unicode)) {
@ -10165,7 +10155,7 @@ replace(PyObject *self, PyObject *str1,
}
else {
Py_ssize_t n, i, j, ires;
Py_ssize_t product, new_size;
Py_ssize_t new_size;
int rkind = skind;
char *res;
@ -10197,19 +10187,18 @@ replace(PyObject *self, PyObject *str1,
}
/* new_size = PyUnicode_GET_LENGTH(self) + n * (PyUnicode_GET_LENGTH(str2) -
PyUnicode_GET_LENGTH(str1))); */
product = n * (len2-len1);
if ((product / (len2-len1)) != n) {
if (len2 > len1 && len2 - len1 > (PY_SSIZE_T_MAX - slen) / n) {
PyErr_SetString(PyExc_OverflowError,
"replace string is too long");
goto error;
}
new_size = slen + product;
new_size = slen + n * (len2 - len1);
if (new_size == 0) {
Py_INCREF(unicode_empty);
u = unicode_empty;
goto done;
}
if (new_size < 0 || new_size > (PY_SSIZE_T_MAX >> (rkind-1))) {
if (new_size > (PY_SSIZE_T_MAX >> (rkind-1))) {
PyErr_SetString(PyExc_OverflowError,
"replace string is too long");
goto error;
@ -13442,8 +13431,10 @@ PyUnicode_Format(PyObject *format, PyObject *args)
uformat = PyUnicode_FromObject(format);
if (uformat == NULL)
return NULL;
if (PyUnicode_READY(uformat) == -1)
if (PyUnicode_READY(uformat) == -1) {
Py_DECREF(uformat);
return NULL;
}
fmt = PyUnicode_DATA(uformat);
fmtkind = PyUnicode_KIND(uformat);
@ -14083,7 +14074,8 @@ onError:
}
PyDoc_STRVAR(unicode_doc,
"str(object[, encoding[, errors]]) -> str\n\
"str(object='') -> str\n\
str(bytes_or_buffer[, encoding[, errors]]) -> str\n\
\n\
Create a new string object from the given object. If encoding or\n\
errors is specified, then the object must expose a data buffer\n\

View File

@ -1064,7 +1064,7 @@ class ObjVisitor(PickleVisitor):
self.emit("case %s:" % t.name, 2)
self.emit("Py_INCREF(%s_singleton);" % t.name, 3)
self.emit("return %s_singleton;" % t.name, 3)
self.emit("default:" % name, 2)
self.emit("default:", 2)
self.emit('/* should never happen, but just in case ... */', 3)
code = "PyErr_Format(PyExc_SystemError, \"unknown %s found\");" % name
self.emit(code, 3, reflow=False)

View File

@ -1985,6 +1985,7 @@ class PyBuildExt(build_ext):
# solaris: problems with register allocation.
# icc >= 11.0 works as well.
define_macros = config['ppro']
extra_compile_args.append('-Wno-unknown-pragmas')
else:
define_macros = config['ansi32']
else: