Kaydet (Commit) ae5360b3 authored tarafından Benjamin Peterson's avatar Benjamin Peterson

Merged revisions…

Merged revisions 66141,66145,66150,66180,66211,66217,66219,66226,66231,66244,66246,66249-66250,66264,66268,66272,66294,66306 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk

........
  r66141 | gregory.p.smith | 2008-09-02 00:29:51 -0500 (Tue, 02 Sep 2008) | 3 lines

  Issue #3678: Correctly pass LDFLAGS and LDLAST to the linker on shared
  library targets in the Makefile.
........
  r66145 | marc-andre.lemburg | 2008-09-02 05:32:34 -0500 (Tue, 02 Sep 2008) | 5 lines

  Add quotes around the file name to avoid issues with spaces.

  Closes #3719.
........
  r66150 | marc-andre.lemburg | 2008-09-02 07:11:19 -0500 (Tue, 02 Sep 2008) | 3 lines

  Add news item for #3719.
........
  r66180 | vinay.sajip | 2008-09-03 04:20:05 -0500 (Wed, 03 Sep 2008) | 1 line

  Issue #3726: Allowed spaces in separators in logging configuration files.
........
  r66211 | vinay.sajip | 2008-09-04 02:31:21 -0500 (Thu, 04 Sep 2008) | 1 line

  Issue #3772: Fixed regression problem in StreamHandler.emit().
........
  r66217 | andrew.kuchling | 2008-09-04 08:26:24 -0500 (Thu, 04 Sep 2008) | 1 line

  #3671: various corrections and markup fixes noted by Kent Johnson
........
  r66219 | hirokazu.yamamoto | 2008-09-04 09:25:30 -0500 (Thu, 04 Sep 2008) | 1 line

  Added NEWS
........
  r66226 | benjamin.peterson | 2008-09-04 18:31:27 -0500 (Thu, 04 Sep 2008) | 1 line

  flesh out the documentation on using 2to3
........
  r66231 | andrew.kuchling | 2008-09-05 10:15:56 -0500 (Fri, 05 Sep 2008) | 1 line

  #3671: Typo fix
........
  r66244 | jesse.noller | 2008-09-05 20:20:11 -0500 (Fri, 05 Sep 2008) | 2 lines

  Fix typo in multiprocessing doc, cancel_join_thread was missing _thread
........
  r66246 | benjamin.peterson | 2008-09-05 22:00:00 -0500 (Fri, 05 Sep 2008) | 1 line

  actually tell the name of the flag to use
........
  r66249 | andrew.kuchling | 2008-09-06 07:50:05 -0500 (Sat, 06 Sep 2008) | 1 line

  Various corrections
........
  r66250 | andrew.kuchling | 2008-09-06 08:04:02 -0500 (Sat, 06 Sep 2008) | 1 line

  #3040: include 'dest' argument in example; trim some trailing whitespace
........
  r66264 | benjamin.peterson | 2008-09-06 14:42:39 -0500 (Sat, 06 Sep 2008) | 1 line

  docs are pretty good about new-style classes these days
........
  r66268 | andrew.kuchling | 2008-09-06 15:28:01 -0500 (Sat, 06 Sep 2008) | 1 line

  #3669 from Robert Lehmann: simplify use of iterator in example
........
  r66272 | andrew.kuchling | 2008-09-06 16:26:02 -0500 (Sat, 06 Sep 2008) | 1 line

  #1317: describe the does_esmtp, ehlo_resp, esmtp_features, and helo_resp attributes
........
  r66294 | georg.brandl | 2008-09-07 12:00:17 -0500 (Sun, 07 Sep 2008) | 2 lines

  Add a new howto about Python and the web, by Marek Kubica.
........
  r66306 | mark.summerfield | 2008-09-08 09:45:37 -0500 (Mon, 08 Sep 2008) | 3 lines

  Added xrefs to each other.
........
üst e5b4ca6c
...@@ -21,4 +21,5 @@ Currently, the HOWTOs are: ...@@ -21,4 +21,5 @@ Currently, the HOWTOs are:
sockets.rst sockets.rst
unicode.rst unicode.rst
urllib2.rst urllib2.rst
webservers.rst
This diff is collapsed.
...@@ -7,15 +7,21 @@ ...@@ -7,15 +7,21 @@
2to3 is a Python program that reads Python 2.x source code and applies a series 2to3 is a Python program that reads Python 2.x source code and applies a series
of *fixers* to transform it into valid Python 3.x code. The standard library of *fixers* to transform it into valid Python 3.x code. The standard library
contains a rich set of fixers that will handle almost all code. It is, however, contains a rich set of fixers that will handle almost all code. 2to3 supporting
possible to write your own fixers. library :mod:`lib2to3` is, however, a flexible and generic library, so it is
possible to write your own fixers for 2to3. :mod:`lib2to3` could also be
adapted to custom applications in which Python code needs to be edited
automatically.
Using 2to3 Using 2to3
---------- ----------
2to3 can be run with a list of files to transform or a directory to recursively 2to3 will usually be installed with the Python interpreter as a script. It is
traverse looking for files with the ``.py`` extension. also located in the :file:`Tools/scripts` directory of the Python root.
2to3's basic arguments are a list of files or directories to transform. The
directories are to recursively traversed for Python sources.
Here is a sample Python 2.x source file, :file:`example.py`:: Here is a sample Python 2.x source file, :file:`example.py`::
...@@ -29,13 +35,14 @@ It can be converted to Python 3.x code via 2to3 on the command line:: ...@@ -29,13 +35,14 @@ It can be converted to Python 3.x code via 2to3 on the command line::
$ 2to3 example.py $ 2to3 example.py
A diff against the original source file will be printed. 2to3 can also write A diff against the original source file is printed. 2to3 can also write the
the needed modifications right back to the source file. (A backup of the needed modifications right back to the source file. (Of course, a backup of the
original file will also be made.) This is done with the :option:`-w` flag:: original is also be made.) Writing the changes back is enabled with the
:option:`-w` flag::
$ 2to3 -w example.py $ 2to3 -w example.py
:file:`example.py` will now look like this:: After transformation, :file:`example.py` looks like this::
def greet(name): def greet(name):
print("Hello, {0}!".format(name)) print("Hello, {0}!".format(name))
...@@ -43,10 +50,10 @@ original file will also be made.) This is done with the :option:`-w` flag:: ...@@ -43,10 +50,10 @@ original file will also be made.) This is done with the :option:`-w` flag::
name = input() name = input()
greet(name) greet(name)
Comments and and exact indentation will be preserved throughout the translation Comments and and exact indentation are preserved throughout the translation
process. process.
By default, 2to3 will run a set of predefined fixers. The :option:`-l` flag By default, 2to3 runs a set of predefined fixers. The :option:`-l` flag
lists all avaible fixers. An explicit set of fixers to run can be given by use lists all avaible fixers. An explicit set of fixers to run can be given by use
of the :option:`-f` flag. The following example runs only the ``imports`` and of the :option:`-f` flag. The following example runs only the ``imports`` and
``has_key`` fixers:: ``has_key`` fixers::
...@@ -54,16 +61,30 @@ of the :option:`-f` flag. The following example runs only the ``imports`` and ...@@ -54,16 +61,30 @@ of the :option:`-f` flag. The following example runs only the ``imports`` and
$ 2to3 -f imports -f has_key example.py $ 2to3 -f imports -f has_key example.py
Some fixers are *explicit*, meaning they aren't run be default and must be Some fixers are *explicit*, meaning they aren't run be default and must be
listed on the command line. Here, in addition to the default fixers, the listed on the command line to be run. Here, in addition to the default fixers,
``idioms`` fixer is run:: the ``idioms`` fixer is run::
$ 2to3 -f all -f idioms example.py $ 2to3 -f all -f idioms example.py
Notice how ``all`` enables all default fixers. Notice how passing ``all`` enables all default fixers.
Sometimes 2to3 will find will find a place in your source code that needs to be Sometimes 2to3 will find will find a place in your source code that needs to be
changed, but 2to3 cannot fix automatically. In this case, 2to3 will print a changed, but 2to3 cannot fix automatically. In this case, 2to3 will print a
warning beneath the diff for a file. warning beneath the diff for a file. You should address the warning in order to
have compliant 3.x code.
2to3 can also refactor doctests. To enable this mode, use the :option:`-d`
flag. Note that *only* doctests will be refactored.
The :option:`-v` option enables the output of more information on the
translation process.
When the :option:`-p` is passed to it, 2to3 treats ``print`` as a function
instead of a statement. This is useful when ``from __future__ import
print_function`` is being used. If this option is not given, the print fixer
will surround print calls in an extra set of parentheses because it cannot
differentiate between the and print statement with parentheses (such as ``print
("a" + "b" + "c")``) and a true function call.
:mod:`lib2to3` - 2to3's library :mod:`lib2to3` - 2to3's library
......
...@@ -11,7 +11,12 @@ This module helps scripts to parse the command line arguments in ``sys.argv``. ...@@ -11,7 +11,12 @@ This module helps scripts to parse the command line arguments in ``sys.argv``.
It supports the same conventions as the Unix :cfunc:`getopt` function (including It supports the same conventions as the Unix :cfunc:`getopt` function (including
the special meanings of arguments of the form '``-``' and '``--``'). Long the special meanings of arguments of the form '``-``' and '``--``'). Long
options similar to those supported by GNU software may be used as well via an options similar to those supported by GNU software may be used as well via an
optional third argument. This module provides two functions and an optional third argument.
A more convenient, flexible, and powerful alternative is the
:mod:`optparse` module.
This module provides two functions and an
exception: exception:
......
...@@ -1859,7 +1859,7 @@ Joining processes that use queues ...@@ -1859,7 +1859,7 @@ Joining processes that use queues
Bear in mind that a process that has put items in a queue will wait before Bear in mind that a process that has put items in a queue will wait before
terminating until all the buffered items are fed by the "feeder" thread to terminating until all the buffered items are fed by the "feeder" thread to
the underlying pipe. (The child process can call the the underlying pipe. (The child process can call the
:meth:`Queue.cancel_join` method of the queue to avoid this behaviour.) :meth:`Queue.cancel_join_thread` method of the queue to avoid this behaviour.)
This means that whenever you use a queue you need to make sure that all This means that whenever you use a queue you need to make sure that all
items which have been put on the queue will eventually be removed before the items which have been put on the queue will eventually be removed before the
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
``optparse`` is a more convenient, flexible, and powerful library for parsing ``optparse`` is a more convenient, flexible, and powerful library for parsing
command-line options than ``getopt``. ``optparse`` uses a more declarative command-line options than the old :mod:`getopt` module. ``optparse`` uses a more declarative
style of command-line parsing: you create an instance of :class:`OptionParser`, style of command-line parsing: you create an instance of :class:`OptionParser`,
populate it with options, and parse the command line. ``optparse`` allows users populate it with options, and parse the command line. ``optparse`` allows users
to specify options in the conventional GNU/POSIX syntax, and additionally to specify options in the conventional GNU/POSIX syntax, and additionally
...@@ -92,7 +92,7 @@ argument ...@@ -92,7 +92,7 @@ argument
``sys.argv[1:]``, or of some other list provided as a substitute for ``sys.argv[1:]``, or of some other list provided as a substitute for
``sys.argv[1:]``". ``sys.argv[1:]``".
option option
an argument used to supply extra information to guide or customize the execution an argument used to supply extra information to guide or customize the execution
of a program. There are many different syntaxes for options; the traditional of a program. There are many different syntaxes for options; the traditional
Unix syntax is a hyphen ("-") followed by a single letter, e.g. ``"-x"`` or Unix syntax is a hyphen ("-") followed by a single letter, e.g. ``"-x"`` or
...@@ -464,7 +464,7 @@ user-friendly (documented) options:: ...@@ -464,7 +464,7 @@ user-friendly (documented) options::
action="store_true", dest="verbose", default=True, action="store_true", dest="verbose", default=True,
help="make lots of noise [default]") help="make lots of noise [default]")
parser.add_option("-q", "--quiet", parser.add_option("-q", "--quiet",
action="store_false", dest="verbose", action="store_false", dest="verbose",
help="be vewwy quiet (I'm hunting wabbits)") help="be vewwy quiet (I'm hunting wabbits)")
parser.add_option("-f", "--filename", parser.add_option("-f", "--filename",
metavar="FILE", help="write output to FILE"), metavar="FILE", help="write output to FILE"),
...@@ -1632,7 +1632,7 @@ arguments:: ...@@ -1632,7 +1632,7 @@ arguments::
setattr(parser.values, option.dest, value) setattr(parser.values, option.dest, value)
[...] [...]
parser.add_option("-c", "--callback", parser.add_option("-c", "--callback", dest="vararg_attr",
action="callback", callback=vararg_callback) action="callback", callback=vararg_callback)
The main weakness with this particular implementation is that negative numbers The main weakness with this particular implementation is that negative numbers
......
...@@ -171,6 +171,8 @@ An :class:`SMTP` instance has the following methods: ...@@ -171,6 +171,8 @@ An :class:`SMTP` instance has the following methods:
Identify yourself to the SMTP server using ``HELO``. The hostname argument Identify yourself to the SMTP server using ``HELO``. The hostname argument
defaults to the fully qualified domain name of the local host. defaults to the fully qualified domain name of the local host.
The message returned by the server is stored as the :attr:`helo_resp` attribute
of the object.
In normal operation it should not be necessary to call this method explicitly. In normal operation it should not be necessary to call this method explicitly.
It will be implicitly called by the :meth:`sendmail` when necessary. It will be implicitly called by the :meth:`sendmail` when necessary.
...@@ -180,7 +182,13 @@ An :class:`SMTP` instance has the following methods: ...@@ -180,7 +182,13 @@ An :class:`SMTP` instance has the following methods:
Identify yourself to an ESMTP server using ``EHLO``. The hostname argument Identify yourself to an ESMTP server using ``EHLO``. The hostname argument
defaults to the fully qualified domain name of the local host. Examine the defaults to the fully qualified domain name of the local host. Examine the
response for ESMTP option and store them for use by :meth:`has_extn`. response for ESMTP option and store them for use by :meth:`has_extn`.
Also sets several informational attributes: the message returned by
the server is stored as the :attr:`ehlo_resp` attribute, :attr:`does_esmtp`
is set to true or false depending on whether the server supports ESMTP, and
:attr:`esmtp_features` will be a dictionary containing the names of the
SMTP service extensions this server supports, and their
parameters (if any).
Unless you wish to use :meth:`has_extn` before sending mail, it should not be Unless you wish to use :meth:`has_extn` before sending mail, it should not be
necessary to call this method explicitly. It will be implicitly called by necessary to call this method explicitly. It will be implicitly called by
......
...@@ -419,7 +419,7 @@ A :class:`Connection` instance has the following attributes and methods: ...@@ -419,7 +419,7 @@ A :class:`Connection` instance has the following attributes and methods:
import sqlite3, os import sqlite3, os
con = sqlite3.connect('existing_db.db') con = sqlite3.connect('existing_db.db')
full_dump = os.linesep.join([line for line in con.iterdump()]) full_dump = os.linesep.join(con.iterdump())
f = open('dump.sql', 'w') f = open('dump.sql', 'w')
f.writelines(full_dump) f.writelines(full_dump)
f.close() f.close()
......
...@@ -63,7 +63,7 @@ what it can, adding compatibility functions in a ...@@ -63,7 +63,7 @@ what it can, adding compatibility functions in a
usages that will become unsupported in 3.0. usages that will become unsupported in 3.0.
Some significant new packages have been added to the standard library, Some significant new packages have been added to the standard library,
such as the :mod:`multiprocessing` and :mod:`jsonlib` modules, but such as the :mod:`multiprocessing` and :mod:`json` modules, but
there aren't many new features that aren't related to Python 3.0 in there aren't many new features that aren't related to Python 3.0 in
some way. some way.
...@@ -623,7 +623,7 @@ versa.) ...@@ -623,7 +623,7 @@ versa.)
Two other classes, :class:`Pool` and :class:`Manager`, provide Two other classes, :class:`Pool` and :class:`Manager`, provide
higher-level interfaces. :class:`Pool` will create a fixed number of higher-level interfaces. :class:`Pool` will create a fixed number of
worker processes, and requests can then be distributed to the workers worker processes, and requests can then be distributed to the workers
by calling :meth:`apply` or `apply_async` to add a single request, by calling :meth:`apply` or :meth:`apply_async` to add a single request,
and :meth:`map` or :meth:`map_async` to add a number of and :meth:`map` or :meth:`map_async` to add a number of
requests. The following code uses a :class:`Pool` to spread requests requests. The following code uses a :class:`Pool` to spread requests
across 5 worker processes and retrieve a list of results:: across 5 worker processes and retrieve a list of results::
...@@ -977,10 +977,10 @@ sequence of bytes:: ...@@ -977,10 +977,10 @@ sequence of bytes::
bytearray(b'ABC') bytearray(b'ABC')
>>> b = bytearray(u'\u21ef\u3244', 'utf-8') >>> b = bytearray(u'\u21ef\u3244', 'utf-8')
>>> b >>> b
bytearray(b'\xe2\x87\xaf \xe3\x89\x84') bytearray(b'\xe2\x87\xaf\xe3\x89\x84')
>>> b[0] = '\xe3' >>> b[0] = '\xe3'
>>> b >>> b
bytearray(b'\xe3\x87\xaf \xe3\x89\x84') bytearray(b'\xe3\x87\xaf\xe3\x89\x84')
>>> unicode(str(b), 'utf-8') >>> unicode(str(b), 'utf-8')
u'\u31ef \u3244' u'\u31ef \u3244'
...@@ -1975,7 +1975,7 @@ changes, or look through the Subversion logs for all the details. ...@@ -1975,7 +1975,7 @@ changes, or look through the Subversion logs for all the details.
* A new function in the :mod:`heapq` module, ``merge(iter1, iter2, ...)``, * A new function in the :mod:`heapq` module, ``merge(iter1, iter2, ...)``,
takes any number of iterables returning data in sorted takes any number of iterables returning data in sorted
order, and returns a new iterator that returns the contents of all order, and returns a new generator that returns the contents of all
the iterators, also in sorted order. For example:: the iterators, also in sorted order. For example::
heapq.merge([1, 3, 5, 9], [2, 8, 16]) -> heapq.merge([1, 3, 5, 9], [2, 8, 16]) ->
...@@ -2014,56 +2014,56 @@ changes, or look through the Subversion logs for all the details. ...@@ -2014,56 +2014,56 @@ changes, or look through the Subversion logs for all the details.
others, the missing values are set to *fillvalue*. For example:: others, the missing values are set to *fillvalue*. For example::
itertools.izip_longest([1,2,3], [1,2,3,4,5]) -> itertools.izip_longest([1,2,3], [1,2,3,4,5]) ->
[(1, 1), (2, 2), (3, 3), (None, 4), (None, 5)] (1, 1), (2, 2), (3, 3), (None, 4), (None, 5)
``product(iter1, iter2, ..., [repeat=N])`` returns the Cartesian product ``product(iter1, iter2, ..., [repeat=N])`` returns the Cartesian product
of the supplied iterables, a set of tuples containing of the supplied iterables, a set of tuples containing
every possible combination of the elements returned from each iterable. :: every possible combination of the elements returned from each iterable. ::
itertools.product([1,2,3], [4,5,6]) -> itertools.product([1,2,3], [4,5,6]) ->
[(1, 4), (1, 5), (1, 6), (1, 4), (1, 5), (1, 6),
(2, 4), (2, 5), (2, 6), (2, 4), (2, 5), (2, 6),
(3, 4), (3, 5), (3, 6)] (3, 4), (3, 5), (3, 6)
The optional *repeat* keyword argument is used for taking the The optional *repeat* keyword argument is used for taking the
product of an iterable or a set of iterables with themselves, product of an iterable or a set of iterables with themselves,
repeated *N* times. With a single iterable argument, *N*-tuples repeated *N* times. With a single iterable argument, *N*-tuples
are returned:: are returned::
itertools.product([1,2], repeat=3)) -> itertools.product([1,2], repeat=3) ->
[(1, 1, 1), (1, 1, 2), (1, 2, 1), (1, 2, 2), (1, 1, 1), (1, 1, 2), (1, 2, 1), (1, 2, 2),
(2, 1, 1), (2, 1, 2), (2, 2, 1), (2, 2, 2)] (2, 1, 1), (2, 1, 2), (2, 2, 1), (2, 2, 2)
With two iterables, *2N*-tuples are returned. :: With two iterables, *2N*-tuples are returned. ::
itertools(product([1,2], [3,4], repeat=2) -> itertools.product([1,2], [3,4], repeat=2) ->
[(1, 3, 1, 3), (1, 3, 1, 4), (1, 3, 2, 3), (1, 3, 2, 4), (1, 3, 1, 3), (1, 3, 1, 4), (1, 3, 2, 3), (1, 3, 2, 4),
(1, 4, 1, 3), (1, 4, 1, 4), (1, 4, 2, 3), (1, 4, 2, 4), (1, 4, 1, 3), (1, 4, 1, 4), (1, 4, 2, 3), (1, 4, 2, 4),
(2, 3, 1, 3), (2, 3, 1, 4), (2, 3, 2, 3), (2, 3, 2, 4), (2, 3, 1, 3), (2, 3, 1, 4), (2, 3, 2, 3), (2, 3, 2, 4),
(2, 4, 1, 3), (2, 4, 1, 4), (2, 4, 2, 3), (2, 4, 2, 4)] (2, 4, 1, 3), (2, 4, 1, 4), (2, 4, 2, 3), (2, 4, 2, 4)
``combinations(iterable, r)`` returns sub-sequences of length *r* from ``combinations(iterable, r)`` returns sub-sequences of length *r* from
the elements of *iterable*. :: the elements of *iterable*. ::
itertools.combinations('123', 2) -> itertools.combinations('123', 2) ->
[('1', '2'), ('1', '3'), ('2', '3')] ('1', '2'), ('1', '3'), ('2', '3')
itertools.combinations('123', 3) -> itertools.combinations('123', 3) ->
[('1', '2', '3')] ('1', '2', '3')
itertools.combinations('1234', 3) -> itertools.combinations('1234', 3) ->
[('1', '2', '3'), ('1', '2', '4'), ('1', '3', '4'), ('1', '2', '3'), ('1', '2', '4'), ('1', '3', '4'),
('2', '3', '4')] ('2', '3', '4')
``permutations(iter[, r])`` returns all the permutations of length *r* of ``permutations(iter[, r])`` returns all the permutations of length *r* of
the iterable's elements. If *r* is not specified, it will default to the the iterable's elements. If *r* is not specified, it will default to the
number of elements produced by the iterable. :: number of elements produced by the iterable. ::
itertools.permutations([1,2,3,4], 2) -> itertools.permutations([1,2,3,4], 2) ->
[(1, 2), (1, 3), (1, 4), (1, 2), (1, 3), (1, 4),
(2, 1), (2, 3), (2, 4), (2, 1), (2, 3), (2, 4),
(3, 1), (3, 2), (3, 4), (3, 1), (3, 2), (3, 4),
(4, 1), (4, 2), (4, 3)] (4, 1), (4, 2), (4, 3)
``itertools.chain(*iterables)`` is an existing function in ``itertools.chain(*iterables)`` is an existing function in
:mod:`itertools` that gained a new constructor in Python 2.6. :mod:`itertools` that gained a new constructor in Python 2.6.
...@@ -2073,7 +2073,7 @@ changes, or look through the Subversion logs for all the details. ...@@ -2073,7 +2073,7 @@ changes, or look through the Subversion logs for all the details.
all the elements of the second, and so on. :: all the elements of the second, and so on. ::
chain.from_iterable([[1,2,3], [4,5,6]]) -> chain.from_iterable([[1,2,3], [4,5,6]]) ->
[1, 2, 3, 4, 5, 6] 1, 2, 3, 4, 5, 6
(All contributed by Raymond Hettinger.) (All contributed by Raymond Hettinger.)
...@@ -2178,7 +2178,7 @@ changes, or look through the Subversion logs for all the details. ...@@ -2178,7 +2178,7 @@ changes, or look through the Subversion logs for all the details.
:const:`UF_APPEND` to indicate that data can only be appended to the :const:`UF_APPEND` to indicate that data can only be appended to the
file. (Contributed by M. Levinson.) file. (Contributed by M. Levinson.)
``os.closerange(*low*, *high*)`` efficiently closes all file descriptors ``os.closerange(low, high)`` efficiently closes all file descriptors
from *low* to *high*, ignoring any errors and not including *high* itself. from *low* to *high*, ignoring any errors and not including *high* itself.
This function is now used by the :mod:`subprocess` module to make starting This function is now used by the :mod:`subprocess` module to make starting
processes faster. (Contributed by Georg Brandl; :issue:`1663329`.) processes faster. (Contributed by Georg Brandl; :issue:`1663329`.)
...@@ -2311,12 +2311,12 @@ changes, or look through the Subversion logs for all the details. ...@@ -2311,12 +2311,12 @@ changes, or look through the Subversion logs for all the details.
will be ignored, not copied. will be ignored, not copied.
The :mod:`shutil` module also provides an :func:`ignore_patterns` The :mod:`shutil` module also provides an :func:`ignore_patterns`
function for use with this new parameter. function for use with this new parameter. :func:`ignore_patterns`
:func:`ignore_patterns` takes an arbitrary number of glob-style patterns takes an arbitrary number of glob-style patterns and returns a
and will ignore any files and directories that match any of these patterns. callable that will ignore any files and directories that match any
The following example copies a directory tree, but skips both of these patterns. The following example copies a directory tree,
:file:`.svn` directories and Emacs backup but skips both :file:`.svn` directories and Emacs backup files,
files, which have names ending with '~':: which have names ending with '~'::
shutil.copytree('Doc/library', '/tmp/library', shutil.copytree('Doc/library', '/tmp/library',
ignore=shutil.ignore_patterns('*~', '.svn')) ignore=shutil.ignore_patterns('*~', '.svn'))
...@@ -2523,13 +2523,15 @@ changes, or look through the Subversion logs for all the details. ...@@ -2523,13 +2523,15 @@ changes, or look through the Subversion logs for all the details.
(Contributed by Dwayne Bailey; :issue:`1581073`.) (Contributed by Dwayne Bailey; :issue:`1581073`.)
* The :mod:`threading` module API is being changed to use properties such as * The :mod:`threading` module API is being changed to use properties
:attr:`daemon` instead of :meth:`setDaemon` and :meth:`isDaemon` methods, and such as :attr:`daemon` instead of :meth:`setDaemon` and
some methods have been renamed to use underscores instead of camel-case; for :meth:`isDaemon` methods, and some methods have been renamed to use
example, the :meth:`activeCount` method is renamed to :meth:`active_count`. underscores instead of camel-case; for example, the
The 2.6 version of the module supports the same properties and renamed :meth:`activeCount` method is renamed to :meth:`active_count`. Both
methods, but doesn't remove the old methods. 3.0 also fully supports both the 2.6 and 3.0 versions of the module support the same properties
APIs, and a date for the deprecation of the old APIs has not been set yet. and renamed methods, but don't remove the old methods. No date has been set
for the deprecation of the old APIs in Python 3.x; the old APIs won't
be removed in any 2.x version.
(Carried out by several people, most notably Benjamin Peterson.) (Carried out by several people, most notably Benjamin Peterson.)
The :mod:`threading` module's :class:`Thread` objects The :mod:`threading` module's :class:`Thread` objects
...@@ -2735,15 +2737,15 @@ of these built-in functions that can be imported when writing ...@@ -2735,15 +2737,15 @@ of these built-in functions that can be imported when writing
The functions in this module currently include: The functions in this module currently include:
* ``ascii(*obj*)``: equivalent to :func:`repr`. In Python 3.0, * ``ascii(obj)``: equivalent to :func:`repr`. In Python 3.0,
:func:`repr` will return a Unicode string, while :func:`ascii` will :func:`repr` will return a Unicode string, while :func:`ascii` will
return a pure ASCII bytestring. return a pure ASCII bytestring.
* ``filter(*predicate*, *iterable*)``, * ``filter(predicate, iterable)``,
``map(*func*, *iterable1*, ...)``: the 3.0 versions ``map(func, iterable1, ...)``: the 3.0 versions
return iterators, unlike the 2.x built-ins which return lists. return iterators, unlike the 2.x built-ins which return lists.
* ``hex(*value*)``, ``oct(*value*)``: instead of calling the * ``hex(value)``, ``oct(value)``: instead of calling the
:meth:`__hex__` or :meth:`__oct__` methods, these versions will :meth:`__hex__` or :meth:`__oct__` methods, these versions will
call the :meth:`__index__` method and convert the result to hexadecimal call the :meth:`__index__` method and convert the result to hexadecimal
or octal. :func:`oct` will use the new ``0o`` notation for its or octal. :func:`oct` will use the new ``0o`` notation for its
...@@ -3210,7 +3212,8 @@ that may require changes to your code: ...@@ -3210,7 +3212,8 @@ that may require changes to your code:
Acknowledgements Acknowledgements
================ ================
The author would like to thank the following people for offering suggestions, The author would like to thank the following people for offering
corrections and assistance with various drafts of this article: suggestions, corrections and assistance with various drafts of this
Georg Brandl, Steve Brown, Nick Coghlan, Jim Jewett, Antoine Pitrou. article: Georg Brandl, Steve Brown, Nick Coghlan, Jim Jewett, Kent
Johnson, Chris Lambacher, Antoine Pitrou.
...@@ -753,7 +753,7 @@ class StreamHandler(Handler): ...@@ -753,7 +753,7 @@ class StreamHandler(Handler):
self.stream.write(fs % msg) self.stream.write(fs % msg)
else: else:
try: try:
if hasattr(self.stream, 'encoding'): if getattr(self.stream, 'encoding', None) is not None:
self.stream.write(fs % msg.encode(self.stream.encoding)) self.stream.write(fs % msg.encode(self.stream.encoding))
else: else:
self.stream.write(fs % msg) self.stream.write(fs % msg)
......
...@@ -19,7 +19,7 @@ Configuration functions for the logging package for Python. The core package ...@@ -19,7 +19,7 @@ Configuration functions for the logging package for Python. The core package
is based on PEP 282 and comments thereto in comp.lang.python, and influenced is based on PEP 282 and comments thereto in comp.lang.python, and influenced
by Apache's log4j system. by Apache's log4j system.
Copyright (C) 2001-2007 Vinay Sajip. All Rights Reserved. Copyright (C) 2001-2008 Vinay Sajip. All Rights Reserved.
To use, simply 'import logging' and log away! To use, simply 'import logging' and log away!
""" """
...@@ -98,6 +98,8 @@ def _resolve(name): ...@@ -98,6 +98,8 @@ def _resolve(name):
found = getattr(found, n) found = getattr(found, n)
return found return found
def _strip_spaces(alist):
return map(lambda x: x.strip(), alist)
def _create_formatters(cp): def _create_formatters(cp):
"""Create and return formatters""" """Create and return formatters"""
...@@ -105,9 +107,10 @@ def _create_formatters(cp): ...@@ -105,9 +107,10 @@ def _create_formatters(cp):
if not len(flist): if not len(flist):
return {} return {}
flist = flist.split(",") flist = flist.split(",")
flist = _strip_spaces(flist)
formatters = {} formatters = {}
for form in flist: for form in flist:
sectname = "formatter_%s" % form.strip() sectname = "formatter_%s" % form
opts = cp.options(sectname) opts = cp.options(sectname)
if "format" in opts: if "format" in opts:
fs = cp.get(sectname, "format", 1) fs = cp.get(sectname, "format", 1)
...@@ -133,10 +136,11 @@ def _install_handlers(cp, formatters): ...@@ -133,10 +136,11 @@ def _install_handlers(cp, formatters):
if not len(hlist): if not len(hlist):
return {} return {}
hlist = hlist.split(",") hlist = hlist.split(",")
hlist = _strip_spaces(hlist)
handlers = {} handlers = {}
fixups = [] #for inter-handler references fixups = [] #for inter-handler references
for hand in hlist: for hand in hlist:
sectname = "handler_%s" % hand.strip() sectname = "handler_%s" % hand
klass = cp.get(sectname, "class") klass = cp.get(sectname, "class")
opts = cp.options(sectname) opts = cp.options(sectname)
if "formatter" in opts: if "formatter" in opts:
...@@ -189,8 +193,9 @@ def _install_loggers(cp, handlers, disable_existing_loggers): ...@@ -189,8 +193,9 @@ def _install_loggers(cp, handlers, disable_existing_loggers):
hlist = cp.get(sectname, "handlers") hlist = cp.get(sectname, "handlers")
if len(hlist): if len(hlist):
hlist = hlist.split(",") hlist = hlist.split(",")
hlist = _strip_spaces(hlist)
for hand in hlist: for hand in hlist:
log.addHandler(handlers[hand.strip()]) log.addHandler(handlers[hand])
#and now the others... #and now the others...
#we don't want to lose the existing loggers, #we don't want to lose the existing loggers,
...@@ -240,8 +245,9 @@ def _install_loggers(cp, handlers, disable_existing_loggers): ...@@ -240,8 +245,9 @@ def _install_loggers(cp, handlers, disable_existing_loggers):
hlist = cp.get(sectname, "handlers") hlist = cp.get(sectname, "handlers")
if len(hlist): if len(hlist):
hlist = hlist.split(",") hlist = hlist.split(",")
hlist = _strip_spaces(hlist)
for hand in hlist: for hand in hlist:
logger.addHandler(handlers[hand.strip()]) logger.addHandler(handlers[hand])
#Disable any old loggers. There's no point deleting #Disable any old loggers. There's no point deleting
#them as other threads may continue to hold references #them as other threads may continue to hold references
......
...@@ -587,6 +587,48 @@ class ConfigFileTest(BaseTest): ...@@ -587,6 +587,48 @@ class ConfigFileTest(BaseTest):
# config5 specifies a custom handler class to be loaded # config5 specifies a custom handler class to be loaded
config5 = config1.replace('class=StreamHandler', 'class=logging.StreamHandler') config5 = config1.replace('class=StreamHandler', 'class=logging.StreamHandler')
# config6 uses ', ' delimiters in the handlers and formatters sections
config6 = """
[loggers]
keys=root,parser
[handlers]
keys=hand1, hand2
[formatters]
keys=form1, form2
[logger_root]
level=WARNING
handlers=
[logger_parser]
level=DEBUG
handlers=hand1
propagate=1
qualname=compiler.parser
[handler_hand1]
class=StreamHandler
level=NOTSET
formatter=form1
args=(sys.stdout,)
[handler_hand2]
class=FileHandler
level=NOTSET
formatter=form1
args=('test.blah', 'a')
[formatter_form1]
format=%(levelname)s ++ %(message)s
datefmt=
[formatter_form2]
format=%(message)s
datefmt=
"""
def apply_config(self, conf): def apply_config(self, conf):
try: try:
fn = tempfile.mktemp(".ini") fn = tempfile.mktemp(".ini")
...@@ -653,6 +695,9 @@ class ConfigFileTest(BaseTest): ...@@ -653,6 +695,9 @@ class ConfigFileTest(BaseTest):
def test_config5_ok(self): def test_config5_ok(self):
self.test_config1_ok(config=self.config5) self.test_config1_ok(config=self.config5)
def test_config6_ok(self):
self.test_config1_ok(config=self.config6)
class LogRecordStreamHandler(StreamRequestHandler): class LogRecordStreamHandler(StreamRequestHandler):
"""Handler for a streaming logging request. It saves the log message in the """Handler for a streaming logging request. It saves the log message in the
...@@ -814,6 +859,31 @@ class MemoryTest(BaseTest): ...@@ -814,6 +859,31 @@ class MemoryTest(BaseTest):
('foo', 'DEBUG', '3'), ('foo', 'DEBUG', '3'),
]) ])
class EncodingTest(BaseTest):
def test_encoding_plain_file(self):
# In Python 2.x, a plain file object is treated as having no encoding.
log = logging.getLogger("test")
fn = tempfile.mktemp(".log")
# the non-ascii data we write to the log.
data = "foo\x80"
try:
handler = logging.FileHandler(fn, encoding="utf8")
log.addHandler(handler)
try:
# write non-ascii data to the log.
log.warning(data)
finally:
log.removeHandler(handler)
handler.close()
# check we wrote exactly those bytes, ignoring trailing \n etc
f = open(fn, encoding="utf8")
try:
self.failUnlessEqual(f.read().rstrip(), data)
finally:
f.close()
finally:
if os.path.isfile(fn):
os.remove(fn)
# Set the locale to the platform-dependent default. I have no idea # Set the locale to the platform-dependent default. I have no idea
# why the test does this, but in any case we save the current locale # why the test does this, but in any case we save the current locale
...@@ -822,7 +892,8 @@ class MemoryTest(BaseTest): ...@@ -822,7 +892,8 @@ class MemoryTest(BaseTest):
def test_main(): def test_main():
run_unittest(BuiltinLevelsTest, BasicFilterTest, run_unittest(BuiltinLevelsTest, BasicFilterTest,
CustomLevelsAndFiltersTest, MemoryHandlerTest, CustomLevelsAndFiltersTest, MemoryHandlerTest,
ConfigFileTest, SocketHandlerTest, MemoryTest) ConfigFileTest, SocketHandlerTest, MemoryTest,
EncodingTest)
if __name__ == "__main__": if __name__ == "__main__":
test_main() test_main()
...@@ -410,14 +410,14 @@ $(LIBRARY): $(LIBRARY_OBJS) ...@@ -410,14 +410,14 @@ $(LIBRARY): $(LIBRARY_OBJS)
libpython$(VERSION).so: $(LIBRARY_OBJS) libpython$(VERSION).so: $(LIBRARY_OBJS)
if test $(INSTSONAME) != $(LDLIBRARY); then \ if test $(INSTSONAME) != $(LDLIBRARY); then \
$(LDSHARED) -Wl,-h$(INSTSONAME) -o $(INSTSONAME) $(LIBRARY_OBJS) $(SHLIBS) $(LIBC) $(LIBM); \ $(LDSHARED) $(LDFLAGS) -Wl,-h$(INSTSONAME) -o $(INSTSONAME) $(LIBRARY_OBJS) $(SHLIBS) $(LIBC) $(LIBM) $(LDLAST); \
$(LN) -f $(INSTSONAME) $@; \ $(LN) -f $(INSTSONAME) $@; \
else\ else\
$(LDSHARED) -o $@ $(LIBRARY_OBJS) $(SHLIBS) $(LIBC) $(LIBM); \ $(LDSHARED) $(LDFLAGS) -o $@ $(LIBRARY_OBJS) $(SHLIBS) $(LIBC) $(LIBM) $(LDLAST); \
fi fi
libpython$(VERSION).sl: $(LIBRARY_OBJS) libpython$(VERSION).sl: $(LIBRARY_OBJS)
$(LDSHARED) -o $@ $(LIBRARY_OBJS) $(SHLIBS) $(LIBC) $(LIBM) $(LDSHARED) $(LDFLAGS) -o $@ $(LIBRARY_OBJS) $(SHLIBS) $(LIBC) $(LIBM) $(LDLAST)
# This rule is here for OPENSTEP/Rhapsody/MacOSX. It builds a temporary # This rule is here for OPENSTEP/Rhapsody/MacOSX. It builds a temporary
# minimal framework (not including the Lib directory and such) in the current # minimal framework (not including the Lib directory and such) in the current
...@@ -451,8 +451,8 @@ $(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK): \ ...@@ -451,8 +451,8 @@ $(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK): \
# for a shared core library; otherwise, this rule is a noop. # for a shared core library; otherwise, this rule is a noop.
$(DLLLIBRARY) libpython$(VERSION).dll.a: $(LIBRARY_OBJS) $(DLLLIBRARY) libpython$(VERSION).dll.a: $(LIBRARY_OBJS)
if test -n "$(DLLLIBRARY)"; then \ if test -n "$(DLLLIBRARY)"; then \
$(LDSHARED) -Wl,--out-implib=$@ -o $(DLLLIBRARY) $^ \ $(LDSHARED) $(LDFLAGS) -Wl,--out-implib=$@ -o $(DLLLIBRARY) $^ \
$(LIBS) $(MODLIBS) $(SYSLIBS); \ $(LIBS) $(MODLIBS) $(SYSLIBS) $(LDLAST); \
else true; \ else true; \
fi fi
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment