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 * Harri Pasanen
* Bo Peng * Bo Peng
* Tim Peters * Tim Peters
* Benjamin Peterson
* Christopher Petrilli * Christopher Petrilli
* Justin D. Pettit * Justin D. Pettit
* Chris Phoenix * Chris Phoenix

View file

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

View file

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

View file

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

View file

@ -6,7 +6,7 @@
:synopsis: Utilities to support extension of packages. :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) .. 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 ``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). 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 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. 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: .. _profiler-introduction:
Introduction to the profilers Introduction to the profilers
@ -50,69 +41,38 @@ Introduction to the profilers
single: deterministic profiling single: deterministic profiling
single: profiling, deterministic single: profiling, deterministic
A :dfn:`profiler` is a program that describes the run time performance of a A :dfn:`profiler` is a program that describes the run time performance
program, providing a variety of statistics. This documentation describes the of a program, providing a variety of statistics. This documentation
profiler functionality provided in the modules :mod:`profile` and :mod:`pstats`. describes the profiler functionality provided in the modules
This profiler provides :dfn:`deterministic profiling` of any Python programs. :mod:`cProfile`, :mod:`profile` and :mod:`pstats`. This profiler
It also provides a series of report generation tools to allow users to rapidly 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. examine the results of a profile operation.
The Python standard library provides two different profilers: The Python standard library provides two different profilers:
#. :mod:`profile`, a pure Python module, described in the sequel. Copyright © #. :mod:`cProfile` is recommended for most users; it's a C extension
1994, by InfoSeek Corporation. 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 #. :mod:`profile`, a pure Python module whose interface is imitated by
it suitable for profiling long-running programs. Based on :mod:`lsprof`, :mod:`cProfile`. Adds significant overhead to profiled programs.
contributed by Brett Rosen and Ted Czotter. 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 The :mod:`profile` and :mod:`cProfile` modules export the same interface, so
they are mostly interchangeables; :mod:`cProfile` has a much lower overhead but they are mostly interchangeable; :mod:`cProfile` has a much lower overhead but
is not so far as well-tested and might not be available on all systems. is newer and might not be available on all systems.
:mod:`cProfile` is really a compatibility layer on top of the internal :mod:`cProfile` is really a compatibility layer on top of the internal
<<<<<<< .working
:mod:`_lsprof` module. :mod:`_lsprof` module.
=======
.. \section{How Is This Profiler Different From The Old Profiler?} :mod:`_lsprof` module. The :mod:`hotshot` module is reserved for specialized
\nodename{Profiler Changes} usage.
>>>>>>> .merge-right.r62379
(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}
.. _profile-instant: .. _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, server_side=True,
certfile="mycertfile", certfile="mycertfile",
keyfile="mykeyfile", keyfile="mykeyfile",
ssl_protocol=ssl.PROTOCOL_TLSv1) ssl_version=ssl.PROTOCOL_TLSv1)
deal_with_client(connstream) 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):: 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 The function definition does not execute the function body; this gets executed
only when the function is called. only when the function is called.
.. index::
statement: @
A function definition may be wrapped by one or more :term:`decorator` expressions. 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 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 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") penguin.append("property of the zoo")
return penguin 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 function call always assigns values to all parameters mentioned in the parameter
list, either from position arguments, from keyword arguments, or from default list, either from position arguments, from keyword arguments, or from default
values. If the form "``*identifier``" is present, it is initialized to a tuple 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 Arbitrary Argument Lists
------------------------ ------------------------
.. index::
statement: *
Finally, the least frequently used option is to specify that a function can be 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 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 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 >>> list(range(*args)) # call with arguments unpacked from a list
[3, 4, 5] [3, 4, 5]
.. index::
statement: **
In the same fashion, dictionaries can deliver keyword arguments with the ``**``\ In the same fashion, dictionaries can deliver keyword arguments with the ``**``\
-operator:: -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 Making it easy for others to read your code is always a good idea, and adopting
a nice coding style helps tremendously for that. 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 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 developer should read it at some point; here are the most important points
extracted for you: extracted for you:

View file

@ -542,3 +542,40 @@ def extend_path(path, name):
f.close() f.close()
return path 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 distutils.dir_util import _path_created
from weakref import WeakSet 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. # Restore some original values.
warnings.filters[:] = fs warnings.filters[:] = fs
copy_reg.dispatch_table.clear() copy_reg.dispatch_table.clear()

View file

@ -39,6 +39,18 @@ class FrozenTests(unittest.TestCase):
else: else:
self.fail("import __phello__.foo should have failed") 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(): def test_main():
run_unittest(FrozenTests) run_unittest(FrozenTests)

View file

@ -46,6 +46,7 @@ class TestPkg(unittest.TestCase):
def setUp(self): def setUp(self):
self.root = None self.root = None
self.pkgname = None
self.syspath = list(sys.path) self.syspath = list(sys.path)
self.sysmodules = sys.modules.copy() self.sysmodules = sys.modules.copy()
@ -56,6 +57,13 @@ class TestPkg(unittest.TestCase):
del self.sysmodules del self.sysmodules
cleanout(self.root) 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): def run_code(self, code):
exec(textwrap.dedent(code), globals(), {"self": self}) exec(textwrap.dedent(code), globals(), {"self": self})
@ -78,6 +86,8 @@ class TestPkg(unittest.TestCase):
f.write('\n') f.write('\n')
f.close() f.close()
self.root = root self.root = root
# package name is the name of the first item
self.pkgname = descr[0][0]
def test_1(self): def test_1(self):
hier = [("t1", None), ("t1 __init__.py", "")] 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): def do_profiling(cls):
results = [] results = []
prof = cls.profilerclass(timer, 0.001) prof = cls.profilerclass(timer, 0.001)
start_timer = timer()
prof.runctx("testfunc()", globals(), locals()) prof.runctx("testfunc()", globals(), locals())
results.append(timer()) results.append(timer() - start_timer)
for methodname in cls.methodnames: for methodname in cls.methodnames:
s = StringIO() s = StringIO()
stats = pstats.Stats(prof, stream=s) stats = pstats.Stats(prof, stream=s)
@ -40,7 +41,7 @@ class ProfileTest(unittest.TestCase):
def test_cprofile(self): def test_cprofile(self):
results = self.do_profiling() results = self.do_profiling()
self.assertEqual(results[0], 43000) self.assertEqual(results[0], 1000)
for i, method in enumerate(self.methodnames): for i, method in enumerate(self.methodnames):
if results[i+1] != self.expected_output[method]: if results[i+1] != self.expected_output[method]:
print("Stats.%s output for %s doesn't fit expectation!" % 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): 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__) test_support.run_unittest(__name__)
if __name__ == "__main__": if __name__ == "__main__":

View file

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

View file

@ -49,6 +49,17 @@ class XMLRPCTestCase(unittest.TestCase):
(newdt,), m = xmlrpclib.loads(s, use_datetime=0) (newdt,), m = xmlrpclib.loads(s, use_datetime=0)
self.assertEquals(newdt, xmlrpclib.DateTime('20050210T11:41:23')) 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): def test_cmp_datetime_DateTime(self):
now = datetime.datetime.now() now = datetime.datetime.now()
dt = xmlrpclib.DateTime(now.timetuple()) 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 # @param value The time, given as an ISO 8601 string, a time
# tuple, or a integer time value. # 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: class DateTime:
"""DateTime wrapper for an ISO 8601 string or time tuple or """DateTime wrapper for an ISO 8601 string or time tuple or
localtime integer value to generate 'dateTime.iso8601' XML-RPC localtime integer value to generate 'dateTime.iso8601' XML-RPC
@ -294,16 +308,10 @@ class DateTime:
""" """
def __init__(self, value=0): def __init__(self, value=0):
if not isinstance(value, str): if isinstance(value, str):
if datetime and isinstance(value, datetime.datetime): self.value = value
self.value = value.strftime("%Y%m%dT%H:%M:%S") else:
return self.value = _strftime(value)
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
def make_comparable(self, other): def make_comparable(self, other):
if isinstance(other, DateTime): if isinstance(other, DateTime):
@ -700,7 +708,7 @@ class Marshaller:
if datetime: if datetime:
def dump_datetime(self, value, write): def dump_datetime(self, value, write):
write("<value><dateTime.iso8601>") write("<value><dateTime.iso8601>")
write(value.strftime("%Y%m%dT%H:%M:%S")) write(_strftime(value))
write("</dateTime.iso8601></value>\n") write("</dateTime.iso8601></value>\n")
dispatch[datetime.datetime] = dump_datetime dispatch[datetime.datetime] = dump_datetime

View file

@ -160,6 +160,7 @@ PyObject *
PyLong_FromLong(long ival) PyLong_FromLong(long ival)
{ {
PyLongObject *v; PyLongObject *v;
unsigned long abs_ival;
unsigned long t; /* unsigned so >> doesn't propagate sign bit */ unsigned long t; /* unsigned so >> doesn't propagate sign bit */
int ndigits = 0; int ndigits = 0;
int sign = 1; int sign = 1;
@ -167,9 +168,15 @@ PyLong_FromLong(long ival)
CHECK_SMALL_INT(ival); CHECK_SMALL_INT(ival);
if (ival < 0) { 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; sign = -1;
} }
else {
abs_ival = (unsigned long)ival;
}
/* Fast path for single-digits ints */ /* Fast path for single-digits ints */
if (!(ival>>PyLong_SHIFT)) { if (!(ival>>PyLong_SHIFT)) {
@ -193,7 +200,7 @@ PyLong_FromLong(long ival)
} }
/* Larger numbers: loop to determine number of digits */ /* Larger numbers: loop to determine number of digits */
t = (unsigned long)ival; t = abs_ival;
while (t) { while (t) {
++ndigits; ++ndigits;
t >>= PyLong_SHIFT; t >>= PyLong_SHIFT;
@ -202,7 +209,7 @@ PyLong_FromLong(long ival)
if (v != NULL) { if (v != NULL) {
digit *p = v->ob_digit; digit *p = v->ob_digit;
Py_SIZE(v) = ndigits*sign; Py_SIZE(v) = ndigits*sign;
t = (unsigned long)ival; t = abs_ival;
while (t) { while (t) {
*p++ = (digit)(t & PyLong_MASK); *p++ = (digit)(t & PyLong_MASK);
t >>= PyLong_SHIFT; t >>= PyLong_SHIFT;
@ -1033,21 +1040,27 @@ PyObject *
PyLong_FromLongLong(PY_LONG_LONG ival) PyLong_FromLongLong(PY_LONG_LONG ival)
{ {
PyLongObject *v; PyLongObject *v;
unsigned PY_LONG_LONG abs_ival;
unsigned PY_LONG_LONG t; /* unsigned so >> doesn't propagate sign bit */ unsigned PY_LONG_LONG t; /* unsigned so >> doesn't propagate sign bit */
int ndigits = 0; int ndigits = 0;
int negative = 0; int negative = 0;
CHECK_SMALL_INT(ival); CHECK_SMALL_INT(ival);
if (ival < 0) { 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; negative = 1;
} }
else {
abs_ival = (unsigned PY_LONG_LONG)ival;
}
/* Count the number of Python digits. /* Count the number of Python digits.
We used to pick 5 ("big enough for anything"), but that's a 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 waste of time and space given that 5*15 = 75 bits are rarely
needed. */ needed. */
t = (unsigned PY_LONG_LONG)ival; t = abs_ival;
while (t) { while (t) {
++ndigits; ++ndigits;
t >>= PyLong_SHIFT; t >>= PyLong_SHIFT;
@ -1056,7 +1069,7 @@ PyLong_FromLongLong(PY_LONG_LONG ival)
if (v != NULL) { if (v != NULL) {
digit *p = v->ob_digit; digit *p = v->ob_digit;
Py_SIZE(v) = negative ? -ndigits : ndigits; Py_SIZE(v) = negative ? -ndigits : ndigits;
t = (unsigned PY_LONG_LONG)ival; t = abs_ival;
while (t) { while (t) {
*p++ = (digit)(t & PyLong_MASK); *p++ = (digit)(t & PyLong_MASK);
t >>= PyLong_SHIFT; t >>= PyLong_SHIFT;

View file

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