Merged revisions 62350-62355,62358-62359,62364-62365,62370,62372-62375,62378-62379,62381 via svnmerge from

svn+ssh://pythondev@svn.python.org/python/trunk

........
  r62350 | nick.coghlan | 2008-04-15 12:25:31 +0200 (Tue, 15 Apr 2008) | 1 line

  Issue 2439: add pkgutils.get_data() as a convenience wrapper for the PEP 302 get_data() API (contributed by Paul Moore)
........
  r62351 | nick.coghlan | 2008-04-15 12:28:14 +0200 (Tue, 15 Apr 2008) | 1 line

  Add test file missing from rev 62350
........
  r62352 | benjamin.peterson | 2008-04-15 13:58:46 +0200 (Tue, 15 Apr 2008) | 2 lines

  Add myself to Doc/ACKS.txt
........
  r62353 | andrew.kuchling | 2008-04-15 15:10:07 +0200 (Tue, 15 Apr 2008) | 6 lines

  Add *,**,@ to index, as suggested by
  http://farmdev.com/thoughts/24/what-does-the-def-star-variable-or-def-asterisk-parameter-syntax-do-in-python-/

  The right entry type to use isn't clear; operator seems wrong, because *,**,@
  aren't being used in expressions here.  I put them as 'statement'; 'syntax'
  might be better.
........
  r62354 | andrew.kuchling | 2008-04-15 15:10:41 +0200 (Tue, 15 Apr 2008) | 1 line

  Typo fix
........
  r62355 | mark.dickinson | 2008-04-15 22:51:18 +0200 (Tue, 15 Apr 2008) | 3 lines

  Fix for possible signed overflow:  the behaviour of -LONG_MIN is
  undefined in ANSI C.
........
  r62358 | jeroen.ruigrok | 2008-04-16 14:47:01 +0200 (Wed, 16 Apr 2008) | 2 lines

  Reformat to 80 columns prior to adding documentation.
........
  r62359 | jeroen.ruigrok | 2008-04-16 14:57:43 +0200 (Wed, 16 Apr 2008) | 2 lines

  Add details about the return value for mmap.flush().
........
  r62364 | raymond.hettinger | 2008-04-17 12:48:31 +0200 (Thu, 17 Apr 2008) | 1 line

  Issue 2648: Add leading zero to money format recipe in the docs.
........
  r62365 | jeroen.ruigrok | 2008-04-17 14:39:45 +0200 (Thu, 17 Apr 2008) | 2 lines

  Be consistent in the use of read-only.
........
  r62370 | andrew.kuchling | 2008-04-17 22:44:06 +0200 (Thu, 17 Apr 2008) | 1 line

  Typo fixes
........
  r62372 | andrew.kuchling | 2008-04-18 04:40:47 +0200 (Fri, 18 Apr 2008) | 1 line

  Use correct parameter name
........
  r62373 | andrew.kuchling | 2008-04-18 18:53:09 +0200 (Fri, 18 Apr 2008) | 1 line

  #2654: fix typo
........
  r62374 | andrew.kuchling | 2008-04-18 20:28:23 +0200 (Fri, 18 Apr 2008) | 4 lines

  Remove personal note from Jim Roskind; it no longer applies, and the
  e-mail address is for a previous employer.

  Can we move the big long copyright statement into a sidebar or something?
........
  r62375 | andrew.kuchling | 2008-04-18 20:39:55 +0200 (Fri, 18 Apr 2008) | 1 line

  Rewrite introductory section, and remove old section.  (It was already commented-out, but why keep it?)
........
  r62378 | skip.montanaro | 2008-04-18 22:35:46 +0200 (Fri, 18 Apr 2008) | 1 line

  resolve issue 2014
........
  r62379 | benjamin.peterson | 2008-04-18 22:45:33 +0200 (Fri, 18 Apr 2008) | 2 lines

  Fix indentation in sysmodule.c
........
  r62381 | amaury.forgeotdarc | 2008-04-19 01:31:33 +0200 (Sat, 19 Apr 2008) | 3 lines

  Some tests did not pass on repeated calls (regrtest -R::)
  Perform additional cleanup, mostly deleting from sys.modules, or clearing the warnings registry.
........
This commit is contained in:
Christian Heimes 2008-04-19 00:55:37 +00:00
parent 53876d9cd8
commit dae2a8939d
22 changed files with 412 additions and 189 deletions

View File

@ -145,6 +145,7 @@ docs@python.org), and we'll be glad to correct the problem.
* Harri Pasanen
* Bo Peng
* Tim Peters
* Benjamin Peterson
* Christopher Petrilli
* Justin D. Pettit
* Chris Phoenix

View File

@ -4,7 +4,7 @@
:Author: Moshe Zadka
This document is placed in the public doman.
This document is placed in the public domain.
.. topic:: Abstract

View File

@ -1374,7 +1374,7 @@ to work with the :class:`Decimal` class::
>>> moneyfmt(Decimal(123456789), sep=' ')
'123 456 789.00'
>>> moneyfmt(Decimal('-0.02'), neg='<', trailneg='>')
'<.02>'
'<0.02>'
"""
q = Decimal(10) ** -places # 2 places --> '0.01'
@ -1387,6 +1387,8 @@ to work with the :class:`Decimal` class::
for i in range(places):
build(next() if digits else '0')
build(dp)
if not digits:
build('0')
i = 0
while digits:
build(next())

View File

@ -96,7 +96,7 @@ loops that truncate the stream.
.. function:: combinations(iterable, r)
Return successive *r* length combinations of elements in the *iterable*.
Return *r* length subsequences of elements from the input *iterable*.
Combinations are emitted in lexicographic sort order. So, if the
input *iterable* is sorted, the combination tuples will be produced
@ -106,9 +106,6 @@ loops that truncate the stream.
value. So if the input elements are unique, there will be no repeat
values in each combination.
Each result tuple is ordered to match the input order. So, every
combination is a subsequence of the input *iterable*.
Equivalent to::
def combinations(iterable, r):
@ -375,11 +372,10 @@ loops that truncate the stream.
Equivalent to nested for-loops in a generator expression. For example,
``product(A, B)`` returns the same as ``((x,y) for x in A for y in B)``.
The leftmost iterators correspond to the outermost for-loop, so the output
tuples cycle like an odometer (with the rightmost element changing on every
iteration). This results in a lexicographic ordering so that if the
inputs iterables are sorted, the product tuples are emitted
in sorted order.
The nested loops cycle like an odometer with the rightmost element advancing
on every iteration. This pattern creates a lexicographic ordering so that if
the input's iterables are sorted, the product tuples are emitted in sorted
order.
To compute the product of an iterable with itself, specify the number of
repetitions with the optional *repeat* keyword argument. For example,

View File

@ -8,54 +8,55 @@
Memory-mapped file objects behave like both strings and like file objects.
Unlike normal string objects, however, these are mutable. You can use mmap
objects in most places where strings are expected; for example, you can use the
:mod:`re` module to search through a memory-mapped file. Since they're mutable,
you can change a single character by doing ``obj[index] = 'a'``, or change a
substring by assigning to a slice: ``obj[i1:i2] = '...'``. You can also read
and write data starting at the current file position, and :meth:`seek` through
the file to different positions.
objects in most places where strings are expected; for example, you can use
the :mod:`re` module to search through a memory-mapped file. Since they're
mutable, you can change a single character by doing ``obj[index] = 'a'``, or
change a substring by assigning to a slice: ``obj[i1:i2] = '...'``. You can
also read and write data starting at the current file position, and
:meth:`seek` through the file to different positions.
A memory-mapped file is created by the :class:`mmap` constructor, which is different
on Unix and on Windows. In either case you must provide a file descriptor for a
file opened for update. If you wish to map an existing Python file object, use
its :meth:`fileno` method to obtain the correct value for the *fileno*
parameter. Otherwise, you can open the file using the :func:`os.open` function,
which returns a file descriptor directly (the file still needs to be closed when
done).
A memory-mapped file is created by the :class:`mmap` constructor, which is
different on Unix and on Windows. In either case you must provide a file
descriptor for a file opened for update. If you wish to map an existing Python
file object, use its :meth:`fileno` method to obtain the correct value for the
*fileno* parameter. Otherwise, you can open the file using the
:func:`os.open` function, which returns a file descriptor directly (the file
still needs to be closed when done).
For both the Unix and Windows versions of the constructor, *access* may be
specified as an optional keyword parameter. *access* accepts one of three
values: :const:`ACCESS_READ`, :const:`ACCESS_WRITE`, or :const:`ACCESS_COPY` to
specify readonly, write-through or copy-on-write memory respectively. *access*
can be used on both Unix and Windows. If *access* is not specified, Windows
mmap returns a write-through mapping. The initial memory values for all three
access types are taken from the specified file. Assignment to an
:const:`ACCESS_READ` memory map raises a :exc:`TypeError` exception. Assignment
to an :const:`ACCESS_WRITE` memory map affects both memory and the underlying
file. Assignment to an :const:`ACCESS_COPY` memory map affects memory but does
not update the underlying file.
values: :const:`ACCESS_READ`, :const:`ACCESS_WRITE`, or :const:`ACCESS_COPY`
to specify read-only, write-through or copy-on-write memory respectively.
*access* can be used on both Unix and Windows. If *access* is not specified,
Windows mmap returns a write-through mapping. The initial memory values for
all three access types are taken from the specified file. Assignment to an
:const:`ACCESS_READ` memory map raises a :exc:`TypeError` exception.
Assignment to an :const:`ACCESS_WRITE` memory map affects both memory and the
underlying file. Assignment to an :const:`ACCESS_COPY` memory map affects
memory but does not update the underlying file.
To map anonymous memory, -1 should be passed as the fileno along with the length.
.. class:: mmap(fileno, length[, tagname[, access[, offset]]])
**(Windows version)** Maps *length* bytes from the file specified by the file
handle *fileno*, and creates a mmap object. If *length* is larger than the
current size of the file, the file is extended to contain *length* bytes. If
*length* is ``0``, the maximum length of the map is the current size of the
file, except that if the file is empty Windows raises an exception (you cannot
create an empty mapping on Windows).
**(Windows version)** Maps *length* bytes from the file specified by the
file handle *fileno*, and creates a mmap object. If *length* is larger
than the current size of the file, the file is extended to contain *length*
bytes. If *length* is ``0``, the maximum length of the map is the current
size of the file, except that if the file is empty Windows raises an
exception (you cannot create an empty mapping on Windows).
*tagname*, if specified and not ``None``, is a string giving a tag name for the
mapping. Windows allows you to have many different mappings against the same
file. If you specify the name of an existing tag, that tag is opened, otherwise
a new tag of this name is created. If this parameter is omitted or ``None``,
the mapping is created without a name. Avoiding the use of the tag parameter
will assist in keeping your code portable between Unix and Windows.
*tagname*, if specified and not ``None``, is a string giving a tag name for
the mapping. Windows allows you to have many different mappings against
the same file. If you specify the name of an existing tag, that tag is
opened, otherwise a new tag of this name is created. If this parameter is
omitted or ``None``, the mapping is created without a name. Avoiding the
use of the tag parameter will assist in keeping your code portable between
Unix and Windows.
*offset* may be specified as a non-negative integer offset. mmap references will
be relative to the offset from the beginning of the file. *offset* defaults to 0.
*offset* must be a multiple of the ALLOCATIONGRANULARITY.
*offset* may be specified as a non-negative integer offset. mmap references
will be relative to the offset from the beginning of the file. *offset*
defaults to 0. *offset* must be a multiple of the ALLOCATIONGRANULARITY.
.. class:: mmap(fileno, length[, flags[, prot[, access[, offset]]]])
@ -63,26 +64,29 @@ To map anonymous memory, -1 should be passed as the fileno along with the length
**(Unix version)** Maps *length* bytes from the file specified by the file
descriptor *fileno*, and returns a mmap object. If *length* is ``0``, the
maximum length of the map will be the current size of the file when :class:`mmap`
is called.
maximum length of the map will be the current size of the file when
:class:`mmap` is called.
*flags* specifies the nature of the mapping. :const:`MAP_PRIVATE` creates a
private copy-on-write mapping, so changes to the contents of the mmap object
will be private to this process, and :const:`MAP_SHARED` creates a mapping
that's shared with all other processes mapping the same areas of the file. The
default value is :const:`MAP_SHARED`.
private copy-on-write mapping, so changes to the contents of the mmap
object will be private to this process, and :const:`MAP_SHARED` creates a
mapping that's shared with all other processes mapping the same areas of
the file. The default value is :const:`MAP_SHARED`.
*prot*, if specified, gives the desired memory protection; the two most useful
values are :const:`PROT_READ` and :const:`PROT_WRITE`, to specify that the pages
may be read or written. *prot* defaults to :const:`PROT_READ \| PROT_WRITE`.
*prot*, if specified, gives the desired memory protection; the two most
useful values are :const:`PROT_READ` and :const:`PROT_WRITE`, to specify
that the pages may be read or written. *prot* defaults to
:const:`PROT_READ \| PROT_WRITE`.
*access* may be specified in lieu of *flags* and *prot* as an optional keyword
parameter. It is an error to specify both *flags*, *prot* and *access*. See
the description of *access* above for information on how to use this parameter.
*access* may be specified in lieu of *flags* and *prot* as an optional
keyword parameter. It is an error to specify both *flags*, *prot* and
*access*. See the description of *access* above for information on how to
use this parameter.
*offset* may be specified as a non-negative integer offset. mmap references will
be relative to the offset from the beginning of the file. *offset* defaults to 0.
*offset* must be a multiple of the PAGESIZE or ALLOCATIONGRANULARITY.
*offset* may be specified as a non-negative integer offset. mmap references
will be relative to the offset from the beginning of the file. *offset*
defaults to 0. *offset* must be a multiple of the PAGESIZE or
ALLOCATIONGRANULARITY.
This example shows a simple way of using :class:`mmap`::
@ -132,32 +136,38 @@ Memory-mapped file objects support the following methods:
.. method:: mmap.close()
Close the file. Subsequent calls to other methods of the object will result in
an exception being raised.
Close the file. Subsequent calls to other methods of the object will
result in an exception being raised.
.. method:: mmap.find(string[, start[, end]])
Returns the lowest index in the object where the substring *string* is found,
such that *string* is contained in the range [*start*, *end*]. Optional
arguments *start* and *end* are interpreted as in slice notation.
Returns the lowest index in the object where the substring *string* is
found, such that *string* is contained in the range [*start*, *end*].
Optional arguments *start* and *end* are interpreted as in slice notation.
Returns ``-1`` on failure.
.. method:: mmap.flush([offset, size])
Flushes changes made to the in-memory copy of a file back to disk. Without use
of this call there is no guarantee that changes are written back before the
object is destroyed. If *offset* and *size* are specified, only changes to the
given range of bytes will be flushed to disk; otherwise, the whole extent of the
mapping is flushed.
Flushes changes made to the in-memory copy of a file back to disk. Without
use of this call there is no guarantee that changes are written back before
the object is destroyed. If *offset* and *size* are specified, only
changes to the given range of bytes will be flushed to disk; otherwise, the
whole extent of the mapping is flushed.
**(Windows version)** A nonzero value returned indicates success; zero
indicates failure.
**(Unix version)** A zero value is returned to indicate success. An
exception is raised when the call failed.
.. method:: mmap.move(dest, src, count)
Copy the *count* bytes starting at offset *src* to the destination index *dest*.
If the mmap was created with :const:`ACCESS_READ`, then calls to move will throw
a :exc:`TypeError` exception.
Copy the *count* bytes starting at offset *src* to the destination index
*dest*. If the mmap was created with :const:`ACCESS_READ`, then calls to
move will throw a :exc:`TypeError` exception.
.. method:: mmap.read(num)
@ -175,31 +185,31 @@ Memory-mapped file objects support the following methods:
.. method:: mmap.readline()
Returns a single line, starting at the current file position and up to the next
newline.
Returns a single line, starting at the current file position and up to the
next newline.
.. method:: mmap.resize(newsize)
Resizes the map and the underlying file, if any. If the mmap was created with
:const:`ACCESS_READ` or :const:`ACCESS_COPY`, resizing the map will throw a
:exc:`TypeError` exception.
Resizes the map and the underlying file, if any. If the mmap was created
with :const:`ACCESS_READ` or :const:`ACCESS_COPY`, resizing the map will
throw a :exc:`TypeError` exception.
.. method:: mmap.rfind(string[, start[, end]])
Returns the highest index in the object where the substring *string* is
found, such that *string* is contained in the range [*start*,
*end*]. Optional arguments *start* and *end* are interpreted as in slice
notation. Returns ``-1`` on failure.
found, such that *string* is contained in the range [*start*, *end*].
Optional arguments *start* and *end* are interpreted as in slice notation.
Returns ``-1`` on failure.
.. method:: mmap.seek(pos[, whence])
Set the file's current position. *whence* argument is optional and defaults to
``os.SEEK_SET`` or ``0`` (absolute file positioning); other values are
``os.SEEK_CUR`` or ``1`` (seek relative to the current position) and
``os.SEEK_END`` or ``2`` (seek relative to the file's end).
Set the file's current position. *whence* argument is optional and
defaults to ``os.SEEK_SET`` or ``0`` (absolute file positioning); other
values are ``os.SEEK_CUR`` or ``1`` (seek relative to the current position)
and ``os.SEEK_END`` or ``2`` (seek relative to the file's end).
.. method:: mmap.size()
@ -217,15 +227,15 @@ Memory-mapped file objects support the following methods:
Write the bytes in *string* into memory at the current position of the file
pointer; the file position is updated to point after the bytes that were
written. If the mmap was created with :const:`ACCESS_READ`, then writing to it
will throw a :exc:`TypeError` exception.
written. If the mmap was created with :const:`ACCESS_READ`, then writing to
it will throw a :exc:`TypeError` exception.
.. method:: mmap.write_byte(byte)
Write the single-character string *byte* into memory at the current position of
the file pointer; the file position is advanced by ``1``. If the mmap was
created with :const:`ACCESS_READ`, then writing to it will throw a
:exc:`TypeError` exception.
Write the single-character string *byte* into memory at the current
position of the file pointer; the file position is advanced by ``1``. If
the mmap was created with :const:`ACCESS_READ`, then writing to it will
throw a :exc:`TypeError` exception.

View File

@ -6,7 +6,7 @@
:synopsis: Utilities to support extension of packages.
This module provides a single function:
This module provides functions to manipulate packages:
.. function:: extend_path(path, name)
@ -38,3 +38,24 @@ This module provides a single function:
``sys.path`` that cause errors when used as filenames may cause this function
to raise an exception (in line with :func:`os.path.isdir` behavior).
.. function:: get_data(package, resource)
Get a resource from a package.
This is a wrapper round the PEP 302 loader :func:`get_data` API. The package
argument should be the name of a package, in standard module format
(foo.bar). The resource argument should be in the form of a relative
filename, using ``/`` as the path separator. The parent directory name
``..`` is not allowed, and nor is a rooted name (starting with a ``/``).
The function returns a binary string, which is the contents of the
specified resource.
For packages located in the filesystem, which have already been imported,
this is the rough equivalent of::
d = os.path.dirname(sys.modules[package].__file__)
data = open(os.path.join(d, resource), 'rb').read()
If the package cannot be located or loaded, or it uses a PEP 302 loader
which does not support :func:`get_data`, then None is returned.

View File

@ -32,15 +32,6 @@ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
The profiler was written after only programming in Python for 3 weeks. As a
result, it is probably clumsy code, but I don't know for sure yet 'cause I'm a
beginner :-). I did work hard to make the code run fast, so that profiling
would be a reasonable thing to do. I tried not to repeat code fragments, but
I'm sure I did some stuff in really awkward ways at times. Please send
suggestions for improvements to: jar@netscape.com. I won't promise *any*
support. ...but I'd appreciate the feedback.
.. _profiler-introduction:
Introduction to the profilers
@ -50,69 +41,38 @@ Introduction to the profilers
single: deterministic profiling
single: profiling, deterministic
A :dfn:`profiler` is a program that describes the run time performance of a
program, providing a variety of statistics. This documentation describes the
profiler functionality provided in the modules :mod:`profile` and :mod:`pstats`.
This profiler provides :dfn:`deterministic profiling` of any Python programs.
It also provides a series of report generation tools to allow users to rapidly
A :dfn:`profiler` is a program that describes the run time performance
of a program, providing a variety of statistics. This documentation
describes the profiler functionality provided in the modules
:mod:`cProfile`, :mod:`profile` and :mod:`pstats`. This profiler
provides :dfn:`deterministic profiling` of Python programs. It also
provides a series of report generation tools to allow users to rapidly
examine the results of a profile operation.
The Python standard library provides two different profilers:
#. :mod:`profile`, a pure Python module, described in the sequel. Copyright ©
1994, by InfoSeek Corporation.
#. :mod:`cProfile` is recommended for most users; it's a C extension
with reasonable overhead
that makes it suitable for profiling long-running programs.
Based on :mod:`lsprof`,
contributed by Brett Rosen and Ted Czotter.
#. :mod:`cProfile`, a module written in C, with a reasonable overhead that makes
it suitable for profiling long-running programs. Based on :mod:`lsprof`,
contributed by Brett Rosen and Ted Czotter.
#. :mod:`profile`, a pure Python module whose interface is imitated by
:mod:`cProfile`. Adds significant overhead to profiled programs.
If you're trying to extend
the profiler in some way, the task might be easier with this module.
Copyright © 1994, by InfoSeek Corporation.
The :mod:`profile` and :mod:`cProfile` modules export the same interface, so
they are mostly interchangeables; :mod:`cProfile` has a much lower overhead but
is not so far as well-tested and might not be available on all systems.
they are mostly interchangeable; :mod:`cProfile` has a much lower overhead but
is newer and might not be available on all systems.
:mod:`cProfile` is really a compatibility layer on top of the internal
<<<<<<< .working
:mod:`_lsprof` module.
.. \section{How Is This Profiler Different From The Old Profiler?}
\nodename{Profiler Changes}
(This section is of historical importance only; the old profiler
discussed here was last seen in Python 1.1.)
The big changes from old profiling module are that you get more
information, and you pay less CPU time. It's not a trade-off, it's a
trade-up.
To be specific:
\begin{description}
\item[Bugs removed:]
Local stack frame is no longer molested, execution time is now charged
to correct functions.
\item[Accuracy increased:]
Profiler execution time is no longer charged to user's code,
calibration for platform is supported, file reads are not done \emph{by}
profiler \emph{during} profiling (and charged to user's code!).
\item[Speed increased:]
Overhead CPU cost was reduced by more than a factor of two (perhaps a
factor of five), lightweight profiler module is all that must be
loaded, and the report generating module (\module{pstats}) is not needed
during profiling.
\item[Recursive functions support:]
Cumulative times in recursive functions are correctly calculated;
recursive entries are counted.
\item[Large growth in report generating UI:]
Distinct profiles runs can be added together forming a comprehensive
report; functions that import statistics take arbitrary lists of
files; sorting criteria is now based on keywords (instead of 4 integer
options); reports shows what functions were profiled as well as what
profile file was referenced; output format has been improved.
\end{description}
=======
:mod:`_lsprof` module. The :mod:`hotshot` module is reserved for specialized
usage.
>>>>>>> .merge-right.r62379
.. _profile-instant:

View File

@ -543,7 +543,7 @@ end, and use :func:`wrap_socket` to create a server-side SSL context for it::
server_side=True,
certfile="mycertfile",
keyfile="mykeyfile",
ssl_protocol=ssl.PROTOCOL_TLSv1)
ssl_version=ssl.PROTOCOL_TLSv1)
deal_with_client(connstream)
Then you'd read data from the ``connstream`` and do something with it till you are finished with the client (or the client is finished with you)::

View File

@ -446,6 +446,9 @@ when the function is called.
The function definition does not execute the function body; this gets executed
only when the function is called.
.. index::
statement: @
A function definition may be wrapped by one or more :term:`decorator` expressions.
Decorator expressions are evaluated when the function is defined, in the scope
that contains the function definition. The result must be a callable, which is
@ -486,7 +489,11 @@ as the default, and explicitly test for it in the body of the function, e.g.::
penguin.append("property of the zoo")
return penguin
Function call semantics are described in more detail in section :ref:`calls`. A
.. index::
statement: *
statement: **
Function call semantics are described in more detail in section :ref:`calls`. A
function call always assigns values to all parameters mentioned in the parameter
list, either from position arguments, from keyword arguments, or from default
values. If the form "``*identifier``" is present, it is initialized to a tuple

View File

@ -467,6 +467,9 @@ if this is not done, the order in which the arguments are printed is undefined.
Arbitrary Argument Lists
------------------------
.. index::
statement: *
Finally, the least frequently used option is to specify that a function can be
called with an arbitrary number of arguments. These arguments will be wrapped
up in a tuple. Before the variable number of arguments, zero or more normal
@ -508,6 +511,9 @@ or tuple::
>>> list(range(*args)) # call with arguments unpacked from a list
[3, 4, 5]
.. index::
statement: **
In the same fashion, dictionaries can deliver keyword arguments with the ``**``\
-operator::
@ -610,7 +616,7 @@ concise, *formatted*) in different styles; some are more readable than others.
Making it easy for others to read your code is always a good idea, and adopting
a nice coding style helps tremendously for that.
For Python, :pep:`8` has emerged as the style guide that most projects adher to;
For Python, :pep:`8` has emerged as the style guide that most projects adhere to;
it promotes a very readable and eye-pleasing coding style. Every Python
developer should read it at some point; here are the most important points
extracted for you:

View File

@ -542,3 +542,40 @@ def extend_path(path, name):
f.close()
return path
def get_data(package, resource):
"""Get a resource from a package.
This is a wrapper round the PEP 302 loader get_data API. The package
argument should be the name of a package, in standard module format
(foo.bar). The resource argument should be in the form of a relative
filename, using '/' as the path separator. The parent directory name '..'
is not allowed, and nor is a rooted name (starting with a '/').
The function returns a binary string, which is the contents of the
specified resource.
For packages located in the filesystem, which have already been imported,
this is the rough equivalent of
d = os.path.dirname(sys.modules[package].__file__)
data = open(os.path.join(d, resource), 'rb').read()
If the package cannot be located or loaded, or it uses a PEP 302 loader
which does not support get_data(), then None is returned.
"""
loader = get_loader(package)
if loader is None or not hasattr(loader, 'get_data'):
return None
mod = sys.modules.get(package) or loader.load_module(package)
if mod is None or not hasattr(mod, '__file__'):
return None
# Modify the resource name to be compatible with the loader.get_data
# signature - an os.path format "filename" starting with the dirname of
# the package's __file__
parts = resource.split('/')
parts.insert(0, os.path.dirname(mod.__file__))
resource_name = os.path.join(*parts)
return loader.get_data(resource_name)

View File

@ -731,6 +731,11 @@ def dash_R_cleanup(fs, ps, pic, abcs):
from distutils.dir_util import _path_created
from weakref import WeakSet
# Clear the warnings registry, so they can be displayed again
for mod in sys.modules.values():
if hasattr(mod, '__warningregistry__'):
del mod.__warningregistry__
# Restore some original values.
warnings.filters[:] = fs
copy_reg.dispatch_table.clear()

View File

@ -39,6 +39,18 @@ class FrozenTests(unittest.TestCase):
else:
self.fail("import __phello__.foo should have failed")
if sys.platform != "mac": # On the Mac this import does succeed.
try:
import __phello__.foo
except ImportError:
pass
else:
self.fail("import __phello__.foo should have failed")
del sys.modules['__hello__']
del sys.modules['__phello__']
del sys.modules['__phello__.spam']
def test_main():
run_unittest(FrozenTests)

View File

@ -46,6 +46,7 @@ class TestPkg(unittest.TestCase):
def setUp(self):
self.root = None
self.pkgname = None
self.syspath = list(sys.path)
self.sysmodules = sys.modules.copy()
@ -56,6 +57,13 @@ class TestPkg(unittest.TestCase):
del self.sysmodules
cleanout(self.root)
# delete all modules concerning the tested hiearchy
if self.pkgname:
modules = [name for name in sys.modules
if self.pkgname in name.split('.')]
for name in modules:
del sys.modules[name]
def run_code(self, code):
exec(textwrap.dedent(code), globals(), {"self": self})
@ -78,6 +86,8 @@ class TestPkg(unittest.TestCase):
f.write('\n')
f.close()
self.root = root
# package name is the name of the first item
self.pkgname = descr[0][0]
def test_1(self):
hier = [("t1", None), ("t1 __init__.py", "")]

127
Lib/test/test_pkgutil.py Normal file
View File

@ -0,0 +1,127 @@
from test.test_support import run_unittest
import unittest
import sys
import imp
import pkgutil
import os
import os.path
import tempfile
import shutil
import zipfile
class PkgutilTests(unittest.TestCase):
def setUp(self):
self.dirname = tempfile.mkdtemp()
sys.path.insert(0, self.dirname)
def tearDown(self):
del sys.path[0]
shutil.rmtree(self.dirname)
def test_getdata_filesys(self):
pkg = 'test_getdata_filesys'
# Include a LF and a CRLF, to test that binary data is read back
RESOURCE_DATA = b'Hello, world!\nSecond line\r\nThird line'
# Make a package with some resources
package_dir = os.path.join(self.dirname, pkg)
os.mkdir(package_dir)
# Empty init.py
f = open(os.path.join(package_dir, '__init__.py'), "wb")
f.close()
# Resource files, res.txt, sub/res.txt
f = open(os.path.join(package_dir, 'res.txt'), "wb")
f.write(RESOURCE_DATA)
f.close()
os.mkdir(os.path.join(package_dir, 'sub'))
f = open(os.path.join(package_dir, 'sub', 'res.txt'), "wb")
f.write(RESOURCE_DATA)
f.close()
# Check we can read the resources
res1 = pkgutil.get_data(pkg, 'res.txt')
self.assertEqual(res1, RESOURCE_DATA)
res2 = pkgutil.get_data(pkg, 'sub/res.txt')
self.assertEqual(res2, RESOURCE_DATA)
del sys.modules[pkg]
def test_getdata_zipfile(self):
zip = 'test_getdata_zipfile.zip'
pkg = 'test_getdata_zipfile'
# Include a LF and a CRLF, to test that binary data is read back
RESOURCE_DATA = b'Hello, world!\nSecond line\r\nThird line'
# Make a package with some resources
zip_file = os.path.join(self.dirname, zip)
z = zipfile.ZipFile(zip_file, 'w')
# Empty init.py
z.writestr(pkg + '/__init__.py', "")
# Resource files, res.txt, sub/res.txt
z.writestr(pkg + '/res.txt', RESOURCE_DATA)
z.writestr(pkg + '/sub/res.txt', RESOURCE_DATA)
z.close()
# Check we can read the resources
sys.path.insert(0, zip_file)
res1 = pkgutil.get_data(pkg, 'res.txt')
self.assertEqual(res1, RESOURCE_DATA)
res2 = pkgutil.get_data(pkg, 'sub/res.txt')
self.assertEqual(res2, RESOURCE_DATA)
del sys.path[0]
del sys.modules[pkg]
class PkgutilPEP302Tests(unittest.TestCase):
class MyTestLoader(object):
def load_module(self, fullname):
# Create an empty module
mod = sys.modules.setdefault(fullname, imp.new_module(fullname))
mod.__file__ = "<%s>" % self.__class__.__name__
mod.__loader__ = self
# Make it a package
mod.__path__ = []
# Count how many times the module is reloaded
mod.__dict__['loads'] = mod.__dict__.get('loads',0) + 1
return mod
def get_data(self, path):
return "Hello, world!"
class MyTestImporter(object):
def find_module(self, fullname, path=None):
return PkgutilPEP302Tests.MyTestLoader()
def setUp(self):
sys.meta_path.insert(0, self.MyTestImporter())
def tearDown(self):
del sys.meta_path[0]
def test_getdata_pep302(self):
# Use a dummy importer/loader
self.assertEqual(pkgutil.get_data('foo', 'dummy'), "Hello, world!")
del sys.modules['foo']
def test_alreadyloaded(self):
# Ensure that get_data works without reloading - the "loads" module
# variable in the example loader should count how many times a reload
# occurs.
import foo
self.assertEqual(foo.loads, 1)
self.assertEqual(pkgutil.get_data('foo', 'dummy'), "Hello, world!")
self.assertEqual(foo.loads, 1)
del sys.modules['foo']
def test_main():
run_unittest(PkgutilTests, PkgutilPEP302Tests)
if __name__ == '__main__':
test_main()

View File

@ -22,8 +22,9 @@ class ProfileTest(unittest.TestCase):
def do_profiling(cls):
results = []
prof = cls.profilerclass(timer, 0.001)
start_timer = timer()
prof.runctx("testfunc()", globals(), locals())
results.append(timer())
results.append(timer() - start_timer)
for methodname in cls.methodnames:
s = StringIO()
stats = pstats.Stats(prof, stream=s)
@ -40,7 +41,7 @@ class ProfileTest(unittest.TestCase):
def test_cprofile(self):
results = self.do_profiling()
self.assertEqual(results[0], 43000)
self.assertEqual(results[0], 1000)
for i, method in enumerate(self.methodnames):
if results[i+1] != self.expected_output[method]:
print("Stats.%s output for %s doesn't fit expectation!" %

View File

@ -101,12 +101,6 @@ class TestWarnings(unittest.TestCase):
def test_main(verbose=None):
# Obscure hack so that this test passes after reloads or repeated calls
# to test_main (regrtest -R).
if '__warningregistry__' in globals():
del globals()['__warningregistry__']
if hasattr(sys, '__warningregistry__'):
del sys.__warningregistry__
test_support.run_unittest(__name__)
if __name__ == "__main__":

View File

@ -391,6 +391,8 @@ class PyWarningsDisplayTests(BaseTest, WarningsDisplayTests):
def test_main():
py_warnings.onceregistry.clear()
c_warnings.onceregistry.clear()
test_support.run_unittest(CFilterTests,
PyFilterTests,
CWarnTests,

View File

@ -49,6 +49,17 @@ class XMLRPCTestCase(unittest.TestCase):
(newdt,), m = xmlrpclib.loads(s, use_datetime=0)
self.assertEquals(newdt, xmlrpclib.DateTime('20050210T11:41:23'))
def test_datetime_before_1900(self):
# same as before but with an date before 1900
dt = datetime.datetime(1, 2, 10, 11, 41, 23)
s = xmlrpclib.dumps((dt,))
(newdt,), m = xmlrpclib.loads(s, use_datetime=1)
self.assertEquals(newdt, dt)
self.assertEquals(m, None)
(newdt,), m = xmlrpclib.loads(s, use_datetime=0)
self.assertEquals(newdt, xmlrpclib.DateTime('00010210T11:41:23'))
def test_cmp_datetime_DateTime(self):
now = datetime.datetime.now()
dt = xmlrpclib.DateTime(now.timetuple())

View File

@ -287,6 +287,20 @@ boolean = Boolean = bool
# @param value The time, given as an ISO 8601 string, a time
# tuple, or a integer time value.
def _strftime(value):
if datetime:
if isinstance(value, datetime.datetime):
return "%04d%02d%02dT%02d:%02d:%02d" % (
value.year, value.month, value.day,
value.hour, value.minute, value.second)
if not isinstance(value, (tuple, time.struct_time)):
if value == 0:
value = time.time()
value = time.localtime(value)
return "%04d%02d%02dT%02d:%02d:%02d" % value[:6]
class DateTime:
"""DateTime wrapper for an ISO 8601 string or time tuple or
localtime integer value to generate 'dateTime.iso8601' XML-RPC
@ -294,16 +308,10 @@ class DateTime:
"""
def __init__(self, value=0):
if not isinstance(value, str):
if datetime and isinstance(value, datetime.datetime):
self.value = value.strftime("%Y%m%dT%H:%M:%S")
return
if not isinstance(value, (tuple, time.struct_time)):
if value == 0:
value = time.time()
value = time.localtime(value)
value = time.strftime("%Y%m%dT%H:%M:%S", value)
self.value = value
if isinstance(value, str):
self.value = value
else:
self.value = _strftime(value)
def make_comparable(self, other):
if isinstance(other, DateTime):
@ -700,7 +708,7 @@ class Marshaller:
if datetime:
def dump_datetime(self, value, write):
write("<value><dateTime.iso8601>")
write(value.strftime("%Y%m%dT%H:%M:%S"))
write(_strftime(value))
write("</dateTime.iso8601></value>\n")
dispatch[datetime.datetime] = dump_datetime

View File

@ -160,6 +160,7 @@ PyObject *
PyLong_FromLong(long ival)
{
PyLongObject *v;
unsigned long abs_ival;
unsigned long t; /* unsigned so >> doesn't propagate sign bit */
int ndigits = 0;
int sign = 1;
@ -167,9 +168,15 @@ PyLong_FromLong(long ival)
CHECK_SMALL_INT(ival);
if (ival < 0) {
ival = -ival;
/* if LONG_MIN == -LONG_MAX-1 (true on most platforms) then
ANSI C says that the result of -ival is undefined when ival
== LONG_MIN. Hence the following workaround. */
abs_ival = (unsigned long)(-1-ival) + 1;
sign = -1;
}
else {
abs_ival = (unsigned long)ival;
}
/* Fast path for single-digits ints */
if (!(ival>>PyLong_SHIFT)) {
@ -193,7 +200,7 @@ PyLong_FromLong(long ival)
}
/* Larger numbers: loop to determine number of digits */
t = (unsigned long)ival;
t = abs_ival;
while (t) {
++ndigits;
t >>= PyLong_SHIFT;
@ -202,7 +209,7 @@ PyLong_FromLong(long ival)
if (v != NULL) {
digit *p = v->ob_digit;
Py_SIZE(v) = ndigits*sign;
t = (unsigned long)ival;
t = abs_ival;
while (t) {
*p++ = (digit)(t & PyLong_MASK);
t >>= PyLong_SHIFT;
@ -1033,21 +1040,27 @@ PyObject *
PyLong_FromLongLong(PY_LONG_LONG ival)
{
PyLongObject *v;
unsigned PY_LONG_LONG abs_ival;
unsigned PY_LONG_LONG t; /* unsigned so >> doesn't propagate sign bit */
int ndigits = 0;
int negative = 0;
CHECK_SMALL_INT(ival);
if (ival < 0) {
ival = -ival;
/* avoid signed overflow on negation; see comments
in PyLong_FromLong above. */
abs_ival = (unsigned PY_LONG_LONG)(-1-ival) + 1;
negative = 1;
}
else {
abs_ival = (unsigned PY_LONG_LONG)ival;
}
/* Count the number of Python digits.
We used to pick 5 ("big enough for anything"), but that's a
waste of time and space given that 5*15 = 75 bits are rarely
needed. */
t = (unsigned PY_LONG_LONG)ival;
t = abs_ival;
while (t) {
++ndigits;
t >>= PyLong_SHIFT;
@ -1056,7 +1069,7 @@ PyLong_FromLongLong(PY_LONG_LONG ival)
if (v != NULL) {
digit *p = v->ob_digit;
Py_SIZE(v) = negative ? -ndigits : ndigits;
t = (unsigned PY_LONG_LONG)ival;
t = abs_ival;
while (t) {
*p++ = (digit)(t & PyLong_MASK);
t >>= PyLong_SHIFT;

View File

@ -1191,9 +1191,9 @@ _PySys_Init(void)
/* stdin/stdout/stderr are now set by pythonrun.c */
PyDict_SetItemString(sysdict, "__displayhook__",
PyDict_GetItemString(sysdict, "displayhook"));
PyDict_GetItemString(sysdict, "displayhook"));
PyDict_SetItemString(sysdict, "__excepthook__",
PyDict_GetItemString(sysdict, "excepthook"));
PyDict_GetItemString(sysdict, "excepthook"));
SET_SYS_FROM_STRING("version",
PyUnicode_FromString(Py_GetVersion()));
SET_SYS_FROM_STRING("hexversion",
@ -1203,7 +1203,7 @@ _PySys_Init(void)
Py_BuildValue("(UUU)", "CPython", branch,
svn_revision));
SET_SYS_FROM_STRING("dont_write_bytecode",
PyBool_FromLong(Py_DontWriteBytecodeFlag));
PyBool_FromLong(Py_DontWriteBytecodeFlag));
/*
* These release level checks are mutually exclusive and cover
* the field, so don't get too fancy with the pre-processor!