Merged revisions 64722,64729,64753,64845-64846,64849,64871,64880-64882,64885,64888,64897,64900-64901,64915,64926-64929,64938-64941,64944,64961,64966,64973 via svnmerge from

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

........
  r64722 | georg.brandl | 2008-07-05 12:13:36 +0200 (Sat, 05 Jul 2008) | 4 lines

  #2663: support an *ignore* argument to shutil.copytree(). Patch by Tarek Ziade.

  This is a new feature, but Barry authorized adding it in the beta period.
........
  r64729 | mark.dickinson | 2008-07-05 13:33:52 +0200 (Sat, 05 Jul 2008) | 5 lines

  Issue 3188: accept float('infinity') as well as float('inf').  This
  makes the float constructor behave in the same way as specified
  by various other language standards, including C99, IEEE 754r,
  and the IBM Decimal standard.
........
  r64753 | gregory.p.smith | 2008-07-06 05:35:58 +0200 (Sun, 06 Jul 2008) | 4 lines

  - Issue #2862: Make int and float freelist management consistent with other
    freelists.  Changes their CompactFreeList apis into ClearFreeList apis and
    calls them via gc.collect().
........
  r64845 | raymond.hettinger | 2008-07-10 16:03:19 +0200 (Thu, 10 Jul 2008) | 1 line

  Issue 3301:  Bisect functions behaved badly when lo was negative.
........
  r64846 | raymond.hettinger | 2008-07-10 16:34:57 +0200 (Thu, 10 Jul 2008) | 1 line

  Issue 3285: Fractions from_float() and from_decimal() accept Integral arguments.
........
  r64849 | andrew.kuchling | 2008-07-10 16:43:31 +0200 (Thu, 10 Jul 2008) | 1 line

  Wording changes
........
  r64871 | raymond.hettinger | 2008-07-11 14:00:21 +0200 (Fri, 11 Jul 2008) | 1 line

  Add cautionary note on the use of PySequence_Fast_ITEMS.
........
  r64880 | amaury.forgeotdarc | 2008-07-11 23:28:25 +0200 (Fri, 11 Jul 2008) | 5 lines

  #3317 in zipfile module, restore the previous names of global variables:
  some applications relied on them.

  Also remove duplicated lines.
........
  r64881 | amaury.forgeotdarc | 2008-07-11 23:45:06 +0200 (Fri, 11 Jul 2008) | 3 lines

  #3342: In tracebacks, printed source lines were not indented since r62555.
  #3343: Py_DisplaySourceLine should be a private function. Rename it to _Py_DisplaySourceLine.
........
  r64882 | josiah.carlson | 2008-07-12 00:17:14 +0200 (Sat, 12 Jul 2008) | 2 lines

  Fix for the AttributeError in test_asynchat.
........
  r64885 | josiah.carlson | 2008-07-12 01:26:59 +0200 (Sat, 12 Jul 2008) | 2 lines

  Fixed test for asyncore.
........
  r64888 | matthias.klose | 2008-07-12 09:51:48 +0200 (Sat, 12 Jul 2008) | 2 lines

  - Fix bashisms in Tools/faqwiz/move-faqwiz.sh
........
  r64897 | benjamin.peterson | 2008-07-12 22:16:19 +0200 (Sat, 12 Jul 2008) | 1 line

  fix various doc typos #3320
........
  r64900 | alexandre.vassalotti | 2008-07-13 00:06:53 +0200 (Sun, 13 Jul 2008) | 2 lines

  Fixed typo.
........
  r64901 | benjamin.peterson | 2008-07-13 01:41:19 +0200 (Sun, 13 Jul 2008) | 1 line

  #1778443 robotparser fixes from Aristotelis Mikropoulos
........
  r64915 | nick.coghlan | 2008-07-13 16:52:36 +0200 (Sun, 13 Jul 2008) | 1 line

  Fix issue 3221 by emitting a RuntimeWarning instead of raising SystemError when the parent module can't be found during an absolute import (likely due to non-PEP 361 aware code which sets a module level __package__ attribute)
........
  r64926 | martin.v.loewis | 2008-07-13 22:31:49 +0200 (Sun, 13 Jul 2008) | 2 lines

  Add turtle into the module index.
........
  r64927 | alexandre.vassalotti | 2008-07-13 22:42:44 +0200 (Sun, 13 Jul 2008) | 3 lines

  Issue #3274: Use a less common identifier for the temporary variable
  in Py_CLEAR().
........
  r64928 | andrew.kuchling | 2008-07-13 23:43:25 +0200 (Sun, 13 Jul 2008) | 1 line

  Re-word
........
  r64929 | andrew.kuchling | 2008-07-13 23:43:52 +0200 (Sun, 13 Jul 2008) | 1 line

  Add various items; move ctypes items into a subsection of their own
........
  r64938 | andrew.kuchling | 2008-07-14 02:35:32 +0200 (Mon, 14 Jul 2008) | 1 line

  Typo fixes
........
  r64939 | andrew.kuchling | 2008-07-14 02:40:55 +0200 (Mon, 14 Jul 2008) | 1 line

  Typo fix
........
  r64940 | andrew.kuchling | 2008-07-14 03:18:16 +0200 (Mon, 14 Jul 2008) | 1 line

  Typo fix
........
  r64941 | andrew.kuchling | 2008-07-14 03:18:31 +0200 (Mon, 14 Jul 2008) | 1 line

  Expand the multiprocessing section
........
  r64944 | gregory.p.smith | 2008-07-14 08:06:48 +0200 (Mon, 14 Jul 2008) | 7 lines

  Fix posix.fork1() / os.fork1() to only call PyOS_AfterFork() in the child
  process rather than both parent and child.

  Does anyone actually use fork1()?  It appears to be a Solaris thing
  but if Python is built with pthreads on Solaris, fork1() and fork()
  should be the same.
........
  r64961 | jesse.noller | 2008-07-15 15:47:33 +0200 (Tue, 15 Jul 2008) | 1 line

  multiprocessing/connection.py patch to remove fqdn oddness for issue 3270
........
  r64966 | nick.coghlan | 2008-07-15 17:40:22 +0200 (Tue, 15 Jul 2008) | 1 line

  Add missing NEWS entry for r64962
........
  r64973 | jesse.noller | 2008-07-15 20:29:18 +0200 (Tue, 15 Jul 2008) | 1 line

  Revert 3270 patch: self._address is in pretty widespread use, need to revisit
........
This commit is contained in:
Georg Brandl 2008-07-16 12:55:28 +00:00
parent 38bbc4888a
commit 2ee470f7f9
46 changed files with 498 additions and 209 deletions

View file

@ -83,11 +83,11 @@ The following functions provide locale-independent string to number conversions.
.. cfunction:: char * PyOS_stricmp(char *s1, char *s2) .. cfunction:: char * PyOS_stricmp(char *s1, char *s2)
Case insensitive comparison of strings. The functions works almost Case insensitive comparison of strings. The function works almost
identical to :cfunc:`strcmp` except that it ignores the case. identically to :cfunc:`strcmp` except that it ignores the case.
.. cfunction:: char * PyOS_strnicmp(char *s1, char *s2, Py_ssize_t size) .. cfunction:: char * PyOS_strnicmp(char *s1, char *s2, Py_ssize_t size)
Case insensitive comparison of strings. The functions works almost Case insensitive comparison of strings. The function works almost
identical to :cfunc:`strncmp` except that it ignores the case. identically to :cfunc:`strncmp` except that it ignores the case.

View file

@ -73,8 +73,7 @@ Floating Point Objects
Return the minimum normalized positive float *DBL_MIN* as C :ctype:`double`. Return the minimum normalized positive float *DBL_MIN* as C :ctype:`double`.
.. cfunction:: void PyFloat_CompactFreeList(size_t *bc, size_t *bf, size_t *sum) .. cfunction:: int PyFloat_ClearFreeList(void)
Compact the float free list. *bc* is the number of allocated blocks before Clear the float free list. Return the number of items that could not
blocks are freed, *bf* is the number of freed blocks and *sum* is the number be freed.
of remaining objects in the blocks.

View file

@ -143,6 +143,10 @@ Sequence Protocol
Return the underlying array of PyObject pointers. Assumes that *o* was returned Return the underlying array of PyObject pointers. Assumes that *o* was returned
by :cfunc:`PySequence_Fast` and *o* is not *NULL*. by :cfunc:`PySequence_Fast` and *o* is not *NULL*.
Note, if a list gets resized, the reallocation may relocate the items array.
So, only use the underlying array pointer in contexts where the sequence
cannot change.
.. cfunction:: PyObject* PySequence_ITEM(PyObject *o, Py_ssize_t i) .. cfunction:: PyObject* PySequence_ITEM(PyObject *o, Py_ssize_t i)

View file

@ -23,7 +23,7 @@ C++.
This chapter mentions a number of filenames that include an encoded Python This chapter mentions a number of filenames that include an encoded Python
version number. These filenames are represented with the version number shown version number. These filenames are represented with the version number shown
as ``XY``; in practive, ``'X'`` will be the major version number and ``'Y'`` as ``XY``; in practice, ``'X'`` will be the major version number and ``'Y'``
will be the minor version number of the Python release you're working with. For will be the minor version number of the Python release you're working with. For
example, if you are using Python 2.2.1, ``XY`` will actually be ``22``. example, if you are using Python 2.2.1, ``XY`` will actually be ``22``.

View file

@ -16,7 +16,7 @@
* To document when incompatible changes were introduced, and when they will be * To document when incompatible changes were introduced, and when they will be
--- or were --- made mandatory. This is a form of executable documentation, and --- or were --- made mandatory. This is a form of executable documentation, and
can be inspected programatically via importing :mod:`__future__` and examining can be inspected programmatically via importing :mod:`__future__` and examining
its contents. its contents.
Each statement in :file:`__future__.py` is of the form:: Each statement in :file:`__future__.py` is of the form::

View file

@ -1781,8 +1781,8 @@ Utility functions
.. function:: byref(obj[, offset]) .. function:: byref(obj[, offset])
Returns a light-weight pointer to ``obj``, which must be an Returns a light-weight pointer to ``obj``, which must be an
instance of a ctypes type. ``offset`` defaults to zero, it must be instance of a ctypes type. ``offset`` defaults to zero, and must be
an integer which is added to the internal pointer value. an integer that will be added to the internal pointer value.
``byref(obj, offset)`` corresponds to this C code:: ``byref(obj, offset)`` corresponds to this C code::

View file

@ -300,7 +300,7 @@ followed by ``lines`` for the text version or ``binary`` for the binary version.
Send a ``QUIT`` command to the server and close the connection. This is the Send a ``QUIT`` command to the server and close the connection. This is the
"polite" way to close a connection, but it may raise an exception of the server "polite" way to close a connection, but it may raise an exception of the server
reponds with an error to the ``QUIT`` command. This implies a call to the responds with an error to the ``QUIT`` command. This implies a call to the
:meth:`close` method which renders the :class:`FTP` instance useless for :meth:`close` method which renders the :class:`FTP` instance useless for
subsequent calls (see below). subsequent calls (see below).

View file

@ -1186,6 +1186,7 @@ are always available. They are listed here in alphabetical order.
care about trailing, unmatched values from the longer iterables. If those care about trailing, unmatched values from the longer iterables. If those
values are important, use :func:`itertools.zip_longest` instead. values are important, use :func:`itertools.zip_longest` instead.
.. rubric:: Footnotes .. rubric:: Footnotes
.. [#] Specifying a buffer size currently has no effect on systems that don't have .. [#] Specifying a buffer size currently has no effect on systems that don't have

View file

@ -44,6 +44,11 @@ The :mod:`gc` module provides the following functions:
:exc:`ValueError` is raised if the generation number is invalid. The number of :exc:`ValueError` is raised if the generation number is invalid. The number of
unreachable objects found is returned. unreachable objects found is returned.
The free lists maintained for a number of builtin types are cleared
whenever a full collection or collection of the highest generation (2)
is run. Not all items in some free lists may be freed due to the
particular implementation, in particular :class:`float`.
.. function:: set_debug(flags) .. function:: set_debug(flags)

View file

@ -158,7 +158,7 @@ However, if you really do need to use some shared data then
The ``'d'`` and ``'i'`` arguments used when creating ``num`` and ``arr`` are The ``'d'`` and ``'i'`` arguments used when creating ``num`` and ``arr`` are
typecodes of the kind used by the :mod:`array` module: ``'d'`` indicates a typecodes of the kind used by the :mod:`array` module: ``'d'`` indicates a
double precision float and ``'i'`` inidicates a signed integer. These shared double precision float and ``'i'`` indicates a signed integer. These shared
objects will be process and thread safe. objects will be process and thread safe.
For more flexibility in using shared memory one can use the For more flexibility in using shared memory one can use the
@ -168,7 +168,7 @@ However, if you really do need to use some shared data then
**Server process** **Server process**
A manager object returned by :func:`Manager` controls a server process which A manager object returned by :func:`Manager` controls a server process which
holds python objects and allows other processes to manipulate them using holds Python objects and allows other processes to manipulate them using
proxies. proxies.
A manager returned by :func:`Manager` will support types :class:`list`, A manager returned by :func:`Manager` will support types :class:`list`,
@ -451,7 +451,7 @@ Note that one can also create a shared queue by using a manager object -- see
This means that if you try joining that process you may get a deadlock unless This means that if you try joining that process you may get a deadlock unless
you are sure that all items which have been put on the queue have been you are sure that all items which have been put on the queue have been
consumed. Similarly, if the child process is non-daemonic then the parent consumed. Similarly, if the child process is non-daemonic then the parent
process may hang on exit when it tries to join all it non-daemonic children. process may hang on exit when it tries to join all its non-daemonic children.
Note that a queue created using a manager does not have this issue. See Note that a queue created using a manager does not have this issue. See
:ref:`multiprocessing-programming`. :ref:`multiprocessing-programming`.
@ -532,7 +532,8 @@ For an example of the usage of queues for interprocess communication see
Equivalent to ``get(False)``. Equivalent to ``get(False)``.
:class:`multiprocessing.Queue` has a few additional methods not found in :class:`multiprocessing.Queue` has a few additional methods not found in
:class:`queue.Queue` which are usually unnecessary: :class:`queue.Queue`. These methods are usually unnecessary for most
code:
.. method:: close() .. method:: close()
@ -772,7 +773,7 @@ Synchronization primitives
~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~
Generally synchronization primitives are not as necessary in a multiprocess Generally synchronization primitives are not as necessary in a multiprocess
program as they are in a mulithreaded program. See the documentation for program as they are in a multithreaded program. See the documentation for
:mod:`threading` module. :mod:`threading` module.
Note that one can also create synchronization primitives by using a manager Note that one can also create synchronization primitives by using a manager
@ -782,7 +783,7 @@ object -- see :ref:`multiprocessing-managers`.
A bounded semaphore object: a clone of :class:`threading.BoundedSemaphore`. A bounded semaphore object: a clone of :class:`threading.BoundedSemaphore`.
(On Mac OSX this is indistiguishable from :class:`Semaphore` because (On Mac OSX this is indistinguishable from :class:`Semaphore` because
``sem_getvalue()`` is not implemented on that platform). ``sem_getvalue()`` is not implemented on that platform).
.. class:: Condition([lock]) .. class:: Condition([lock])
@ -891,8 +892,8 @@ processes.
.. note:: .. note::
Although it is posible to store a pointer in shared memory remember that this Although it is possible to store a pointer in shared memory remember that
will refer to a location in the address space of a specific process. this will refer to a location in the address space of a specific process.
However, the pointer is quite likely to be invalid in the context of a second However, the pointer is quite likely to be invalid in the context of a second
process and trying to dereference the pointer from the second process may process and trying to dereference the pointer from the second process may
cause a crash. cause a crash.
@ -1081,7 +1082,7 @@ their parent process exits. The manager classes are defined in the
Start a subprocess to start the manager. Start a subprocess to start the manager.
.. method:: server_forever() .. method:: serve_forever()
Run the server in the current process. Run the server in the current process.
@ -1774,7 +1775,7 @@ handler type) for messages from different processes to get mixed up.
handler which sends output to :data:`sys.stderr` using format handler which sends output to :data:`sys.stderr` using format
``'[%(levelname)s/%(processName)s] %(message)s'``. (The logger allows use of ``'[%(levelname)s/%(processName)s] %(message)s'``. (The logger allows use of
the non-standard ``'%(processName)s'`` format.) Message sent to this logger the non-standard ``'%(processName)s'`` format.) Message sent to this logger
will not by default propogate to the root logger. will not by default propagate to the root logger.
Note that on Windows child processes will only inherit the level of the Note that on Windows child processes will only inherit the level of the
parent process's logger -- any other customization of the logger will not be parent process's logger -- any other customization of the logger will not be

View file

@ -513,7 +513,7 @@ Python syntax and the functions in the :mod:`operator` module.
+-----------------------+-------------------------+---------------------------------+ +-----------------------+-------------------------+---------------------------------+
| Right Shift | ``a >> b`` | ``rshift(a, b)`` | | Right Shift | ``a >> b`` | ``rshift(a, b)`` |
+-----------------------+-------------------------+---------------------------------+ +-----------------------+-------------------------+---------------------------------+
| Sequence Repitition | ``seq * i`` | ``repeat(seq, i)`` | | Sequence Repetition | ``seq * i`` | ``repeat(seq, i)`` |
+-----------------------+-------------------------+---------------------------------+ +-----------------------+-------------------------+---------------------------------+
| String Formatting | ``s % obj`` | ``mod(s, obj)`` | | String Formatting | ``s % obj`` | ``mod(s, obj)`` |
+-----------------------+-------------------------+---------------------------------+ +-----------------------+-------------------------+---------------------------------+

View file

@ -330,7 +330,7 @@ http://www.freebsd.org/cgi/man.cgi?query=kqueue&sektion=2
+---------------------------+---------------------------------------------+ +---------------------------+---------------------------------------------+
| :const:`KQ_EV_DISABLE` | Disablesevent | | :const:`KQ_EV_DISABLE` | Disablesevent |
+---------------------------+---------------------------------------------+ +---------------------------+---------------------------------------------+
| :const:`KQ_EV_ONESHOT` | Removes event after first occurence | | :const:`KQ_EV_ONESHOT` | Removes event after first occurrence |
+---------------------------+---------------------------------------------+ +---------------------------+---------------------------------------------+
| :const:`KQ_EV_CLEAR` | Reset the state after an event is retrieved | | :const:`KQ_EV_CLEAR` | Reset the state after an event is retrieved |
+---------------------------+---------------------------------------------+ +---------------------------+---------------------------------------------+
@ -365,7 +365,7 @@ http://www.freebsd.org/cgi/man.cgi?query=kqueue&sektion=2
+============================+============================================+ +============================+============================================+
| :const:`KQ_NOTE_DELETE` | *unlink()* was called | | :const:`KQ_NOTE_DELETE` | *unlink()* was called |
+----------------------------+--------------------------------------------+ +----------------------------+--------------------------------------------+
| :const:`KQ_NOTE_WRITE` | a write occured | | :const:`KQ_NOTE_WRITE` | a write occurred |
+----------------------------+--------------------------------------------+ +----------------------------+--------------------------------------------+
| :const:`KQ_NOTE_EXTEND` | the file was extended | | :const:`KQ_NOTE_EXTEND` | the file was extended |
+----------------------------+--------------------------------------------+ +----------------------------+--------------------------------------------+

View file

@ -1565,7 +1565,7 @@ The constructors for both classes work the same:
.. method:: isdisjoint(other) .. method:: isdisjoint(other)
Return True if the set has no elements in common with *other*. Sets are Return True if the set has no elements in common with *other*. Sets are
disjoint if and only if their interesection is the empty set. disjoint if and only if their intersection is the empty set.
.. method:: issubset(other) .. method:: issubset(other)
set <= other set <= other

View file

@ -266,7 +266,7 @@ Then the outer replacement field would be evaluated, producing::
"noses " "noses "
Which is subsitituted into the string, yielding:: Which is substituted into the string, yielding::
"A man with two noses " "A man with two noses "

View file

@ -54,19 +54,6 @@ always available.
A string containing the copyright pertaining to the Python interpreter. A string containing the copyright pertaining to the Python interpreter.
.. function:: _compact_freelists()
Compact the free list of floats by deallocating unused blocks.
It can reduce the memory usage of the Python process several tenth of
thousands of integers or floats have been allocated at once.
The return value is a tuple of tuples each containing three elements,
amount of used objects, total block count before the blocks are deallocated
and amount of freed blocks.
This function should be used for specialized purposes only.
.. function:: _clear_type_cache() .. function:: _clear_type_cache()
Clear the internal type cache. The type cache is used to speed up attribute Clear the internal type cache. The type cache is used to speed up attribute

View file

@ -305,8 +305,8 @@ File Selectors
.. \ulink{FileEntry}{http://tix.sourceforge.net/dist/current/demos/samples/FileEnt.tcl} .. \ulink{FileEntry}{http://tix.sourceforge.net/dist/current/demos/samples/FileEnt.tcl}
Hierachical ListBox Hierarchical ListBox
^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^
.. class:: HList() .. class:: HList()

View file

@ -2,6 +2,10 @@
:mod:`turtle` --- Turtle graphics for Tk :mod:`turtle` --- Turtle graphics for Tk
======================================== ========================================
.. module:: tkinter.turtle
:synopsis: Turtle graphics for Tk
.. sectionauthor:: Gregor Lingl <gregor.lingl@aon.at>
Introduction Introduction
============ ============
@ -1251,7 +1255,7 @@ Window control
... left(10) ... left(10)
... ...
>>> for _ in range(8): >>> for _ in range(8):
... left(45); fd(2) # a regular octogon ... left(45); fd(2) # a regular octagon
Animation control Animation control
@ -1262,7 +1266,7 @@ Animation control
:param delay: positive integer :param delay: positive integer
Set or return the drawing *delay* in milliseconds. (This is approximately Set or return the drawing *delay* in milliseconds. (This is approximately
the time interval between two consecutived canvas updates.) The longer the the time interval between two consecutive canvas updates.) The longer the
drawing delay, the slower the animation. drawing delay, the slower the animation.
Optional argument: Optional argument:

View file

@ -1062,7 +1062,7 @@ involved. For example, the :envvar:`http_proxy` environment variable is read to
obtain the HTTP proxy's URL. obtain the HTTP proxy's URL.
This example replaces the default :class:`ProxyHandler` with one that uses This example replaces the default :class:`ProxyHandler` with one that uses
programatically-supplied proxy URLs, and adds proxy authorization support with programmatically-supplied proxy URLs, and adds proxy authorization support with
:class:`ProxyBasicAuthHandler`. :: :class:`ProxyBasicAuthHandler`. ::
proxy_handler = urllib.request.ProxyHandler({'http': 'http://www.example.com:3128/'}) proxy_handler = urllib.request.ProxyHandler({'http': 'http://www.example.com:3128/'})

View file

@ -413,7 +413,7 @@ Paste" library.
from wsgiref.validate import validator from wsgiref.validate import validator
from wsgiref.simple_server import make_server from wsgiref.simple_server import make_server
# Our callable object which is intentionally not compilant to the # Our callable object which is intentionally not compliant to the
# standard, so the validator is going to break # standard, so the validator is going to break
def simple_app(environ, start_response): def simple_app(environ, start_response):
status = '200 OK' # HTTP Status status = '200 OK' # HTTP Status

View file

@ -344,7 +344,7 @@ The client code for the preceding server::
try: try:
proxy.add(2, 5) proxy.add(2, 5)
except xmlrpc.client.Fault, err: except xmlrpc.client.Fault, err:
print("A fault occured") print("A fault occurred")
print("Fault code: %d" % err.faultCode) print("Fault code: %d" % err.faultCode)
print("Fault string: %s" % err.faultString) print("Fault string: %s" % err.faultString)
@ -391,7 +391,7 @@ by providing an invalid URI::
try: try:
proxy.some_method() proxy.some_method()
except xmlrpc.client.ProtocolError, err: except xmlrpc.client.ProtocolError, err:
print("A protocol error occured") print("A protocol error occurred")
print("URL: %s" % err.url) print("URL: %s" % err.url)
print("HTTP/HTTPS headers: %s" % err.headers) print("HTTP/HTTPS headers: %s" % err.headers)
print("Error code: %d" % err.errcode) print("Error code: %d" % err.errcode)

View file

@ -286,7 +286,7 @@ sometimes there is a need for alternative implementations with different
performance trade-offs. performance trade-offs.
The :mod:`array` module provides an :class:`array()` object that is like a list The :mod:`array` module provides an :class:`array()` object that is like a list
that stores only homogenous data and stores it more compactly. The following that stores only homogeneous data and stores it more compactly. The following
example shows an array of numbers stored as two byte unsigned binary numbers example shows an array of numbers stored as two byte unsigned binary numbers
(typecode ``"H"``) rather than the usual 16 bytes per entry for regular lists of (typecode ``"H"``) rather than the usual 16 bytes per entry for regular lists of
python int objects:: python int objects::

View file

@ -186,7 +186,7 @@ of your Python installation directory). This suppresses the terminal window on
startup. startup.
You can also make all ``.py`` scripts execute with :program:`pythonw.exe`, You can also make all ``.py`` scripts execute with :program:`pythonw.exe`,
setting this through the usual facilites, for example (might require setting this through the usual facilities, for example (might require
administrative rights): administrative rights):
#. Launch a command prompt. #. Launch a command prompt.
@ -215,7 +215,7 @@ PyWin32
The `PyWin32 <http://python.net/crew/mhammond/win32/>`_ module by Mark Hammond The `PyWin32 <http://python.net/crew/mhammond/win32/>`_ module by Mark Hammond
is a collection of modules for advanced Windows-specific support. This includes is a collection of modules for advanced Windows-specific support. This includes
utilites for: utilities for:
* `Component Object Model <http://www.microsoft.com/com/>`_ (COM) * `Component Object Model <http://www.microsoft.com/com/>`_ (COM)
* Win32 API calls * Win32 API calls

View file

@ -51,7 +51,7 @@
This article explains the new features in Python 2.6. The release This article explains the new features in Python 2.6. The release
schedule is described in :pep:`361`; currently the final release is schedule is described in :pep:`361`; currently the final release is
scheduled for September 3 2008. scheduled for October 1 2008.
This article doesn't attempt to provide a complete specification of This article doesn't attempt to provide a complete specification of
the new features, but instead provides a convenient overview. For the new features, but instead provides a convenient overview. For
@ -526,28 +526,152 @@ environment variable.
PEP 371: The ``multiprocessing`` Package PEP 371: The ``multiprocessing`` Package
===================================================== =====================================================
.. XXX I think this still needs help The new :mod:`multiprocessing` package lets Python programs create new
processes that will perform a computation and return a result to the
parent. The parent and child processes can communicate using queues
and pipes, synchronize their operations using locks and semaphores,
and can share simple arrays of data.
:mod:`multiprocessing` makes it easy to distribute work over multiple processes. The :mod:`multiprocessing` module started out as an exact emulation of
Its API is similiar to that of :mod:`threading`. For example:: the :mod:`threading` module using processes instead of threads. That
goal was discarded along the path to Python 2.6, but the general
approach of the module is still similar. The fundamental class
is the :class:`Process`, which is passed a callable object and
a collection of arguments. The :meth:`start` method
sets the callable running in a subprocess, after which you can call
the :meth:`is_alive` method to check whether the subprocess is still running
and the :meth:`join` method to wait for the process to exit.
from multiprocessing import Process Here's a simple example where the subprocess will calculate a
factorial. The function doing the calculation is a bit strange; it's
written to take significantly longer when the input argument is a
multiple of 4.
def long_hard_task(n): ::
print n * 43
for i in range(10): import time
Process(target=long_hard_task, args=(i)).start() from multiprocessing import Process, Queue
will multiply the numbers between 0 and 10 times 43 and print out the result
concurrently. def factorial(queue, N):
"Compute a factorial."
# If N is a multiple of 4, this function will take much longer.
if (N % 4) == 0:
time.sleep(.05 * N/4)
# Calculate the result
fact = 1L
for i in range(1, N+1):
fact = fact * i
# Put the result on the queue
queue.put(fact)
if __name__ == '__main__':
queue = Queue()
N = 5
p = Process(target=factorial, args=(queue, N))
p.start()
p.join()
result = queue.get()
print 'Factorial', N, '=', result
A :class:`Queue` object is created and stored as a global. The child
process will use the value of the variable when the child was created;
because it's a :class:`Queue`, parent and child can use the object to
communicate. (If the parent were to change the value of the global
variable, the child's value would be unaffected, and vice versa.)
Two other classes, :class:`Pool` and :class:`Manager`, provide
higher-level interfaces. :class:`Pool` will create a fixed number of
worker processes, and requests can then be distributed to the workers
by calling :meth:`apply` or `apply_async`, adding a single request,
and :meth:`map` or :meth:`map_async` to distribute a number of
requests. The following code uses a :class:`Pool` to spread requests
across 5 worker processes, receiving a list of results back.
::
from multiprocessing import Pool
p = Pool(5)
result = p.map(factorial, range(1, 1000, 10))
for v in result:
print v
This produces the following output::
1
39916800
51090942171709440000
8222838654177922817725562880000000
33452526613163807108170062053440751665152000000000
...
The :class:`Manager` class creates a separate server process that can
hold master copies of Python data structures. Other processes can
then access and modify these data structures by using proxy objects.
The following example creates a shared dictionary by calling the
:meth:`dict` method; the worker processes then insert values into the
dictionary. (No locking is done automatically, which doesn't matter
in this example. :class:`Manager`'s methods also include
:meth:`Lock`, :meth:`RLock`, and :meth:`Semaphore` to create shared locks.
::
import time
from multiprocessing import Pool, Manager
def factorial(N, dictionary):
"Compute a factorial."
# Calculate the result
fact = 1L
for i in range(1, N+1):
fact = fact * i
# Store result in dictionary
dictionary[N] = fact
if __name__ == '__main__':
p = Pool(5)
mgr = Manager()
d = mgr.dict() # Create shared dictionary
# Run tasks using the pool
for N in range(1, 1000, 10):
p.apply_async(factorial, (N, d))
# Mark pool as closed -- no more tasks can be added.
p.close()
# Wait for tasks to exit
p.join()
# Output results
for k, v in sorted(d.items()):
print k, v
This will produce the output::
1 1
11 39916800
21 51090942171709440000
31 8222838654177922817725562880000000
41 33452526613163807108170062053440751665152000000000
51 1551118753287382280224243016469303211063259720016986112000000000000
.. seealso:: .. seealso::
The documentation for the :mod:`multiprocessing` module.
:pep:`371` - Addition of the multiprocessing package :pep:`371` - Addition of the multiprocessing package
PEP written by Jesse Noller and Richard Oudkerk; PEP written by Jesse Noller and Richard Oudkerk;
implemented by Richard Oudkerk and Jesse Noller. implemented by Richard Oudkerk and Jesse Noller.
.. ====================================================================== .. ======================================================================
.. _pep-3101: .. _pep-3101:
@ -1775,21 +1899,6 @@ details.
(Contributed by Raymond Hettinger.) (Contributed by Raymond Hettinger.)
* XXX Describe the new ctypes calling convention that allows safe
access to errno.
(Implemented by Thomas Heller; :issue:`1798`.)
* The :mod:`ctypes` module now supports a :class:`c_bool` datatype
that represents the C99 ``bool`` type. (Contributed by David Remahl;
:issue:`1649190`.)
The :mod:`ctypes` string, buffer and array types also have improved
support for extended slicing syntax,
where various combinations of ``(start, stop, step)`` are supplied.
(Implemented by Thomas Wouters.)
.. Revision 57769
* A new method in the :mod:`curses` module: for a window, :meth:`chgat` changes * A new method in the :mod:`curses` module: for a window, :meth:`chgat` changes
the display characters for a certain number of characters on a single line. the display characters for a certain number of characters on a single line.
(Contributed by Fabian Kreutz.) (Contributed by Fabian Kreutz.)
@ -2628,6 +2737,45 @@ Using the module is simple::
.. ====================================================================== .. ======================================================================
ctypes Enhancements
--------------------------------------------------
Thomas Heller continued to maintain and enhance the
:mod:`ctypes` module.
:mod:`ctypes` now supports a :class:`c_bool` datatype
that represents the C99 ``bool`` type. (Contributed by David Remahl;
:issue:`1649190`.)
The :mod:`ctypes` string, buffer and array types have improved
support for extended slicing syntax,
where various combinations of ``(start, stop, step)`` are supplied.
(Implemented by Thomas Wouters.)
.. Revision 57769
A new calling convention tells :mod:`ctypes` to clear the ``errno`` or
Win32 LastError variables at the outset of each wrapped call.
(Implemented by Thomas Heller; :issue:`1798`.)
For the Unix ``errno`` variable: when creating a wrapped function,
you can supply ``use_errno=True`` as a keyword parameter
to the :func:`DLL` function
and then call the module-level methods :meth:`set_errno`
and :meth:`get_errno` to set and retrieve the error value.
The Win32 LastError variable is supported similarly by
the :func:`DLL`, :func:`OleDLL`, and :func:`WinDLL` functions.
You supply ``use_last_error=True`` as a keyword parameter
and then call the module-level methods :meth:`set_last_error`
and :meth:`get_last_error`.
The :func:`byref` function, used to retrieve a pointer to a ctypes
instance, now has an optional **offset** parameter that is a byte
count that will be added to the returned pointer.
.. ======================================================================
Improved SSL Support Improved SSL Support
-------------------------------------------------- --------------------------------------------------

View file

@ -103,7 +103,7 @@ PyAPI_FUNC(double) _PyFloat_Unpack4(const unsigned char *p, int le);
PyAPI_FUNC(double) _PyFloat_Unpack8(const unsigned char *p, int le); PyAPI_FUNC(double) _PyFloat_Unpack8(const unsigned char *p, int le);
/* free list api */ /* free list api */
PyAPI_FUNC(void) PyFloat_CompactFreeList(size_t *, size_t *, size_t *); PyAPI_FUNC(int) PyFloat_ClearFreeList(void);
/* Format the object based on the format_spec, as defined in PEP 3101 /* Format the object based on the format_spec, as defined in PEP 3101
(Advanced String Formatting). */ (Advanced String Formatting). */

View file

@ -695,9 +695,9 @@ PyAPI_FUNC(void) _Py_AddToAllObjects(PyObject *, int force);
#define Py_CLEAR(op) \ #define Py_CLEAR(op) \
do { \ do { \
if (op) { \ if (op) { \
PyObject *tmp = (PyObject *)(op); \ PyObject *_py_tmp = (PyObject *)(op); \
(op) = NULL; \ (op) = NULL; \
Py_DECREF(tmp); \ Py_DECREF(_py_tmp); \
} \ } \
} while (0) } while (0)

View file

@ -19,7 +19,7 @@ typedef struct _traceback {
PyAPI_FUNC(int) PyTraceBack_Here(struct _frame *); PyAPI_FUNC(int) PyTraceBack_Here(struct _frame *);
PyAPI_FUNC(int) PyTraceBack_Print(PyObject *, PyObject *); PyAPI_FUNC(int) PyTraceBack_Print(PyObject *, PyObject *);
PyAPI_FUNC(int) Py_DisplaySourceLine(PyObject *, const char *, int, int); PyAPI_FUNC(int) _Py_DisplaySourceLine(PyObject *, const char *, int, int);
/* Reveal traceback type so we can typecheck traceback objects */ /* Reveal traceback type so we can typecheck traceback objects */
PyAPI_DATA(PyTypeObject) PyTraceBack_Type; PyAPI_DATA(PyTypeObject) PyTraceBack_Type;

View file

@ -9,6 +9,8 @@ def insort_right(a, x, lo=0, hi=None):
slice of a to be searched. slice of a to be searched.
""" """
if lo < 0:
raise ValueError('lo must be non-negative')
if hi is None: if hi is None:
hi = len(a) hi = len(a)
while lo < hi: while lo < hi:
@ -30,6 +32,8 @@ def bisect_right(a, x, lo=0, hi=None):
slice of a to be searched. slice of a to be searched.
""" """
if lo < 0:
raise ValueError('lo must be non-negative')
if hi is None: if hi is None:
hi = len(a) hi = len(a)
while lo < hi: while lo < hi:
@ -49,6 +53,8 @@ def insort_left(a, x, lo=0, hi=None):
slice of a to be searched. slice of a to be searched.
""" """
if lo < 0:
raise ValueError('lo must be non-negative')
if hi is None: if hi is None:
hi = len(a) hi = len(a)
while lo < hi: while lo < hi:
@ -69,6 +75,8 @@ def bisect_left(a, x, lo=0, hi=None):
slice of a to be searched. slice of a to be searched.
""" """
if lo < 0:
raise ValueError('lo must be non-negative')
if hi is None: if hi is None:
hi = len(a) hi = len(a)
while lo < hi: while lo < hi:

View file

@ -108,7 +108,9 @@ class Fraction(numbers.Rational):
Beware that Fraction.from_float(0.3) != Fraction(3, 10). Beware that Fraction.from_float(0.3) != Fraction(3, 10).
""" """
if not isinstance(f, float): if isinstance(f, numbers.Integral):
f = float(f)
elif not isinstance(f, float):
raise TypeError("%s.from_float() only takes floats, not %r (%s)" % raise TypeError("%s.from_float() only takes floats, not %r (%s)" %
(cls.__name__, f, type(f).__name__)) (cls.__name__, f, type(f).__name__))
if math.isnan(f) or math.isinf(f): if math.isnan(f) or math.isinf(f):
@ -119,7 +121,9 @@ class Fraction(numbers.Rational):
def from_decimal(cls, dec): def from_decimal(cls, dec):
"""Converts a finite Decimal instance to a rational number, exactly.""" """Converts a finite Decimal instance to a rational number, exactly."""
from decimal import Decimal from decimal import Decimal
if not isinstance(dec, Decimal): if isinstance(dec, numbers.Integral):
dec = Decimal(int(dec))
elif not isinstance(dec, Decimal):
raise TypeError( raise TypeError(
"%s.from_decimal() only takes Decimals, not %r (%s)" % "%s.from_decimal() only takes Decimals, not %r (%s)" %
(cls.__name__, dec, type(dec).__name__)) (cls.__name__, dec, type(dec).__name__))

View file

@ -222,11 +222,9 @@ class SocketListener(object):
self._family = family self._family = family
self._last_accepted = None self._last_accepted = None
sub_debug('listener bound to address %r', self._address)
if family == 'AF_UNIX': if family == 'AF_UNIX':
self._unlink = Finalize( self._unlink = Finalize(
self, os.unlink, args=(self._address,), exitpriority=0 self, os.unlink, args=(address,), exitpriority=0
) )
else: else:
self._unlink = None self._unlink = None

View file

@ -8,6 +8,7 @@ import os
import sys import sys
import stat import stat
from os.path import abspath from os.path import abspath
import fnmatch
__all__ = ["copyfileobj","copyfile","copymode","copystat","copy","copy2", __all__ = ["copyfileobj","copyfile","copymode","copystat","copy","copy2",
"copytree","move","rmtree","Error"] "copytree","move","rmtree","Error"]
@ -93,8 +94,19 @@ def copy2(src, dst):
copyfile(src, dst) copyfile(src, dst)
copystat(src, dst) copystat(src, dst)
def ignore_patterns(*patterns):
"""Function that can be used as copytree() ignore parameter.
def copytree(src, dst, symlinks=False): Patterns is a sequence of glob-style patterns
that are used to exclude files"""
def _ignore_patterns(path, names):
ignored_names = []
for pattern in patterns:
ignored_names.extend(fnmatch.filter(names, pattern))
return set(ignored_names)
return _ignore_patterns
def copytree(src, dst, symlinks=False, ignore=None):
"""Recursively copy a directory tree using copy2(). """Recursively copy a directory tree using copy2().
The destination directory must not already exist. The destination directory must not already exist.
@ -105,13 +117,32 @@ def copytree(src, dst, symlinks=False):
it is false, the contents of the files pointed to by symbolic it is false, the contents of the files pointed to by symbolic
links are copied. links are copied.
The optional ignore argument is a callable. If given, it
is called with the `src` parameter, which is the directory
being visited by copytree(), and `names` which is the list of
`src` contents, as returned by os.listdir():
callable(src, names) -> ignored_names
Since copytree() is called recursively, the callable will be
called once for each directory that is copied. It returns a
list of names relative to the `src` directory that should
not be copied.
XXX Consider this example code rather than the ultimate tool. XXX Consider this example code rather than the ultimate tool.
""" """
names = os.listdir(src) names = os.listdir(src)
if ignore is not None:
ignored_names = ignore(src, names)
else:
ignored_names = set()
os.makedirs(dst) os.makedirs(dst)
errors = [] errors = []
for name in names: for name in names:
if name in ignored_names:
continue
srcname = os.path.join(src, name) srcname = os.path.join(src, name)
dstname = os.path.join(dst, name) dstname = os.path.join(dst, name)
try: try:
@ -119,7 +150,7 @@ def copytree(src, dst, symlinks=False):
linkto = os.readlink(srcname) linkto = os.readlink(srcname)
os.symlink(linkto, dstname) os.symlink(linkto, dstname)
elif os.path.isdir(srcname): elif os.path.isdir(srcname):
copytree(srcname, dstname, symlinks) copytree(srcname, dstname, symlinks, ignore)
else: else:
copy2(srcname, dstname) copy2(srcname, dstname)
# XXX What about devices, sockets etc.? # XXX What about devices, sockets etc.?

View file

@ -114,6 +114,14 @@ class TestBisect(unittest.TestCase):
self.assertEqual(func(data, elem), expected) self.assertEqual(func(data, elem), expected)
self.assertEqual(func(UserList(data), elem), expected) self.assertEqual(func(UserList(data), elem), expected)
def test_negative_lo(self):
# Issue 3301
mod = self.module
self.assertRaises(ValueError, mod.bisect_left, [1, 2, 3], 5, -1, 3),
self.assertRaises(ValueError, mod.bisect_right, [1, 2, 3], 5, -1, 3),
self.assertRaises(ValueError, mod.insort_left, [1, 2, 3], 5, -1, 3),
self.assertRaises(ValueError, mod.insort_right, [1, 2, 3], 5, -1, 3),
def test_random(self, n=25): def test_random(self, n=25):
from random import randrange from random import randrange
for i in range(n): for i in range(n):

View file

@ -284,24 +284,36 @@ class ReprTestCase(unittest.TestCase):
floats_file.close() floats_file.close()
# Beginning with Python 2.6 float has cross platform compatible # Beginning with Python 2.6 float has cross platform compatible
# ways to create and representate inf and nan # ways to create and represent inf and nan
class InfNanTest(unittest.TestCase): class InfNanTest(unittest.TestCase):
def test_inf_from_str(self): def test_inf_from_str(self):
self.assert_(isinf(float("inf"))) self.assert_(isinf(float("inf")))
self.assert_(isinf(float("+inf"))) self.assert_(isinf(float("+inf")))
self.assert_(isinf(float("-inf"))) self.assert_(isinf(float("-inf")))
self.assert_(isinf(float("infinity")))
self.assert_(isinf(float("+infinity")))
self.assert_(isinf(float("-infinity")))
self.assertEqual(repr(float("inf")), "inf") self.assertEqual(repr(float("inf")), "inf")
self.assertEqual(repr(float("+inf")), "inf") self.assertEqual(repr(float("+inf")), "inf")
self.assertEqual(repr(float("-inf")), "-inf") self.assertEqual(repr(float("-inf")), "-inf")
self.assertEqual(repr(float("infinity")), "inf")
self.assertEqual(repr(float("+infinity")), "inf")
self.assertEqual(repr(float("-infinity")), "-inf")
self.assertEqual(repr(float("INF")), "inf") self.assertEqual(repr(float("INF")), "inf")
self.assertEqual(repr(float("+Inf")), "inf") self.assertEqual(repr(float("+Inf")), "inf")
self.assertEqual(repr(float("-iNF")), "-inf") self.assertEqual(repr(float("-iNF")), "-inf")
self.assertEqual(repr(float("Infinity")), "inf")
self.assertEqual(repr(float("+iNfInItY")), "inf")
self.assertEqual(repr(float("-INFINITY")), "-inf")
self.assertEqual(str(float("inf")), "inf") self.assertEqual(str(float("inf")), "inf")
self.assertEqual(str(float("+inf")), "inf") self.assertEqual(str(float("+inf")), "inf")
self.assertEqual(str(float("-inf")), "-inf") self.assertEqual(str(float("-inf")), "-inf")
self.assertEqual(str(float("infinity")), "inf")
self.assertEqual(str(float("+infinity")), "inf")
self.assertEqual(str(float("-infinity")), "-inf")
self.assertRaises(ValueError, float, "info") self.assertRaises(ValueError, float, "info")
self.assertRaises(ValueError, float, "+info") self.assertRaises(ValueError, float, "+info")
@ -309,6 +321,10 @@ class InfNanTest(unittest.TestCase):
self.assertRaises(ValueError, float, "in") self.assertRaises(ValueError, float, "in")
self.assertRaises(ValueError, float, "+in") self.assertRaises(ValueError, float, "+in")
self.assertRaises(ValueError, float, "-in") self.assertRaises(ValueError, float, "-in")
self.assertRaises(ValueError, float, "infinit")
self.assertRaises(ValueError, float, "+Infin")
self.assertRaises(ValueError, float, "-INFI")
self.assertRaises(ValueError, float, "infinitys")
def test_inf_as_str(self): def test_inf_as_str(self):
self.assertEqual(repr(1e300 * 1e300), "inf") self.assertEqual(repr(1e300 * 1e300), "inf")

View file

@ -134,10 +134,8 @@ class FractionTest(unittest.TestCase):
self.assertNotEquals(F(4, 2), r) self.assertNotEquals(F(4, 2), r)
def testFromFloat(self): def testFromFloat(self):
self.assertRaisesMessage( self.assertRaises(TypeError, F.from_float, 3+4j)
TypeError, "Fraction.from_float() only takes floats, not 3 (int)", self.assertEquals((10, 1), _components(F.from_float(10)))
F.from_float, 3)
self.assertEquals((0, 1), _components(F.from_float(-0.0))) self.assertEquals((0, 1), _components(F.from_float(-0.0)))
self.assertEquals((10, 1), _components(F.from_float(10.0))) self.assertEquals((10, 1), _components(F.from_float(10.0)))
self.assertEquals((-5, 2), _components(F.from_float(-2.5))) self.assertEquals((-5, 2), _components(F.from_float(-2.5)))
@ -161,10 +159,8 @@ class FractionTest(unittest.TestCase):
F.from_float, nan) F.from_float, nan)
def testFromDecimal(self): def testFromDecimal(self):
self.assertRaisesMessage( self.assertRaises(TypeError, F.from_decimal, 3+4j)
TypeError, self.assertEquals(F(10, 1), F.from_decimal(10))
"Fraction.from_decimal() only takes Decimals, not 3 (int)",
F.from_decimal, 3)
self.assertEquals(F(0), F.from_decimal(Decimal("-0"))) self.assertEquals(F(0), F.from_decimal(Decimal("-0")))
self.assertEquals(F(5, 10), F.from_decimal(Decimal("0.5"))) self.assertEquals(F(5, 10), F.from_decimal(Decimal("0.5")))
self.assertEquals(F(5, 1000), F.from_decimal(Decimal("5e-3"))) self.assertEquals(F(5, 1000), F.from_decimal(Decimal("5e-3")))

View file

@ -1,5 +1,3 @@
from test.support import TESTFN, run_unittest, catch_warning
import unittest import unittest
import os import os
import random import random
@ -8,7 +6,7 @@ import sys
import py_compile import py_compile
import warnings import warnings
import imp import imp
from test.support import unlink, TESTFN, unload from test.support import unlink, TESTFN, unload, run_unittest, catch_warning
def remove_files(name): def remove_files(name):
@ -267,6 +265,25 @@ class RelativeImport(unittest.TestCase):
from . import relimport from . import relimport
self.assertTrue(hasattr(relimport, "RelativeImport")) self.assertTrue(hasattr(relimport, "RelativeImport"))
def test_issue3221(self):
def check_relative():
exec("from . import relimport", ns)
# Check both OK with __package__ and __name__ correct
ns = dict(__package__='test', __name__='test.notarealmodule')
check_relative()
# Check both OK with only __name__ wrong
ns = dict(__package__='test', __name__='notarealpkg.notarealmodule')
check_relative()
# Check relative fails with only __package__ wrong
ns = dict(__package__='foo', __name__='test.notarealmodule')
self.assertRaises(SystemError, check_relative)
# Check relative fails with __package__ and __name__ wrong
ns = dict(__package__='foo', __name__='notarealpkg.notarealmodule')
self.assertRaises(SystemError, check_relative)
# Check both fail with package set to a non-string
ns = dict(__package__=object())
self.assertRaises(ValueError, check_relative)
def test_main(verbose=None): def test_main(verbose=None):
run_unittest(ImportTest, PathsTests, RelativeImport) run_unittest(ImportTest, PathsTests, RelativeImport)

View file

@ -108,6 +108,82 @@ class TestShutil(unittest.TestCase):
if os.path.exists(path): if os.path.exists(path):
shutil.rmtree(path) shutil.rmtree(path)
def test_copytree_with_exclude(self):
def write_data(path, data):
f = open(path, "w")
f.write(data)
f.close()
def read_data(path):
f = open(path)
data = f.read()
f.close()
return data
# creating data
join = os.path.join
exists = os.path.exists
src_dir = tempfile.mkdtemp()
dst_dir = join(tempfile.mkdtemp(), 'destination')
write_data(join(src_dir, 'test.txt'), '123')
write_data(join(src_dir, 'test.tmp'), '123')
os.mkdir(join(src_dir, 'test_dir'))
write_data(join(src_dir, 'test_dir', 'test.txt'), '456')
os.mkdir(join(src_dir, 'test_dir2'))
write_data(join(src_dir, 'test_dir2', 'test.txt'), '456')
os.mkdir(join(src_dir, 'test_dir2', 'subdir'))
os.mkdir(join(src_dir, 'test_dir2', 'subdir2'))
write_data(join(src_dir, 'test_dir2', 'subdir', 'test.txt'), '456')
write_data(join(src_dir, 'test_dir2', 'subdir2', 'test.py'), '456')
# testing glob-like patterns
try:
patterns = shutil.ignore_patterns('*.tmp', 'test_dir2')
shutil.copytree(src_dir, dst_dir, ignore=patterns)
# checking the result: some elements should not be copied
self.assert_(exists(join(dst_dir, 'test.txt')))
self.assert_(not exists(join(dst_dir, 'test.tmp')))
self.assert_(not exists(join(dst_dir, 'test_dir2')))
finally:
if os.path.exists(dst_dir):
shutil.rmtree(dst_dir)
try:
patterns = shutil.ignore_patterns('*.tmp', 'subdir*')
shutil.copytree(src_dir, dst_dir, ignore=patterns)
# checking the result: some elements should not be copied
self.assert_(not exists(join(dst_dir, 'test.tmp')))
self.assert_(not exists(join(dst_dir, 'test_dir2', 'subdir2')))
self.assert_(not exists(join(dst_dir, 'test_dir2', 'subdir')))
finally:
if os.path.exists(dst_dir):
shutil.rmtree(dst_dir)
# testing callable-style
try:
def _filter(src, names):
res = []
for name in names:
path = os.path.join(src, name)
if (os.path.isdir(path) and
path.split()[-1] == 'subdir'):
res.append(name)
elif os.path.splitext(path)[-1] in ('.py'):
res.append(name)
return res
shutil.copytree(src_dir, dst_dir, ignore=_filter)
# checking the result: some elements should not be copied
self.assert_(not exists(join(dst_dir, 'test_dir2', 'subdir2',
'test.py')))
self.assert_(not exists(join(dst_dir, 'test_dir2', 'subdir')))
finally:
if os.path.exists(dst_dir):
shutil.rmtree(dst_dir)
if hasattr(os, "symlink"): if hasattr(os, "symlink"):
def test_dont_copy_file_onto_link_to_itself(self): def test_dont_copy_file_onto_link_to_itself(self):

View file

@ -45,9 +45,9 @@ ZIP_DEFLATED = 8
# The "end of central directory" structure, magic number, size, and indices # The "end of central directory" structure, magic number, size, and indices
# (section V.I in the format document) # (section V.I in the format document)
structEndCentDir = b"<4s4H2LH" structEndArchive = b"<4s4H2LH"
magicEndCentDir = b"PK\005\006" stringEndArchive = b"PK\005\006"
sizeEndCentDir = struct.calcsize(structEndCentDir) sizeEndCentDir = struct.calcsize(structEndArchive)
_ECD_SIGNATURE = 0 _ECD_SIGNATURE = 0
_ECD_DISK_NUMBER = 1 _ECD_DISK_NUMBER = 1
@ -65,37 +65,9 @@ _ECD_LOCATION = 9
# The "central directory" structure, magic number, size, and indices # The "central directory" structure, magic number, size, and indices
# of entries in the structure (section V.F in the format document) # of entries in the structure (section V.F in the format document)
structCentralDir = "<4s4B4HL2L5H2L" structCentralDir = "<4s4B4HL2L5H2L"
magicCentralDir = b"PK\001\002" stringCentralDir = b"PK\001\002"
sizeCentralDir = struct.calcsize(structCentralDir) sizeCentralDir = struct.calcsize(structCentralDir)
# The "local file header" structure, magic number, size, and indices
# (section V.A in the format document)
structFileHeader = "<4s2B4HL2L2H"
magicFileHeader = b"PK\003\004"
sizeFileHeader = struct.calcsize(structFileHeader)
# The "Zip64 end of central directory locator" structure, magic number, and size
structEndCentDir64Locator = "<4sLQL"
magicEndCentDir64Locator = b"PK\x06\x07"
sizeEndCentDir64Locator = struct.calcsize(structEndCentDir64Locator)
# The "Zip64 end of central directory" record, magic number, size, and indices
# (section V.G in the format document)
structEndCentDir64 = "<4sQ2H2L4Q"
magicEndCentDir64 = b"PK\x06\x06"
sizeEndCentDir64 = struct.calcsize(structEndCentDir64)
_CD64_SIGNATURE = 0
_CD64_DIRECTORY_RECSIZE = 1
_CD64_CREATE_VERSION = 2
_CD64_EXTRACT_VERSION = 3
_CD64_DISK_NUMBER = 4
_CD64_DISK_NUMBER_START = 5
_CD64_NUMBER_ENTRIES_THIS_DISK = 6
_CD64_NUMBER_ENTRIES_TOTAL = 7
_CD64_DIRECTORY_SIZE = 8
_CD64_OFFSET_START_CENTDIR = 9
# indexes of entries in the central directory structure # indexes of entries in the central directory structure
_CD_SIGNATURE = 0 _CD_SIGNATURE = 0
_CD_CREATE_VERSION = 1 _CD_CREATE_VERSION = 1
@ -120,7 +92,7 @@ _CD_LOCAL_HEADER_OFFSET = 18
# The "local file header" structure, magic number, size, and indices # The "local file header" structure, magic number, size, and indices
# (section V.A in the format document) # (section V.A in the format document)
structFileHeader = "<4s2B4HL2L2H" structFileHeader = "<4s2B4HL2L2H"
magicFileHeader = b"PK\003\004" stringFileHeader = b"PK\003\004"
sizeFileHeader = struct.calcsize(structFileHeader) sizeFileHeader = struct.calcsize(structFileHeader)
_FH_SIGNATURE = 0 _FH_SIGNATURE = 0
@ -137,15 +109,15 @@ _FH_FILENAME_LENGTH = 10
_FH_EXTRA_FIELD_LENGTH = 11 _FH_EXTRA_FIELD_LENGTH = 11
# The "Zip64 end of central directory locator" structure, magic number, and size # The "Zip64 end of central directory locator" structure, magic number, and size
structEndCentDir64Locator = "<4sLQL" structEndArchive64Locator = "<4sLQL"
magicEndCentDir64Locator = b"PK\x06\x07" stringEndArchive64Locator = b"PK\x06\x07"
sizeEndCentDir64Locator = struct.calcsize(structEndCentDir64Locator) sizeEndCentDir64Locator = struct.calcsize(structEndArchive64Locator)
# The "Zip64 end of central directory" record, magic number, size, and indices # The "Zip64 end of central directory" record, magic number, size, and indices
# (section V.G in the format document) # (section V.G in the format document)
structEndCentDir64 = "<4sQ2H2L4Q" structEndArchive64 = "<4sQ2H2L4Q"
magicEndCentDir64 = b"PK\x06\x06" stringEndArchive64 = b"PK\x06\x06"
sizeEndCentDir64 = struct.calcsize(structEndCentDir64) sizeEndCentDir64 = struct.calcsize(structEndArchive64)
_CD64_SIGNATURE = 0 _CD64_SIGNATURE = 0
_CD64_DIRECTORY_RECSIZE = 1 _CD64_DIRECTORY_RECSIZE = 1
@ -176,8 +148,8 @@ def _EndRecData64(fpin, offset, endrec):
""" """
fpin.seek(offset - sizeEndCentDir64Locator, 2) fpin.seek(offset - sizeEndCentDir64Locator, 2)
data = fpin.read(sizeEndCentDir64Locator) data = fpin.read(sizeEndCentDir64Locator)
sig, diskno, reloff, disks = struct.unpack(structEndCentDir64Locator, data) sig, diskno, reloff, disks = struct.unpack(structEndArchive64Locator, data)
if sig != magicEndCentDir64Locator: if sig != stringEndArchive64Locator:
return endrec return endrec
if diskno != 0 or disks != 1: if diskno != 0 or disks != 1:
@ -188,8 +160,8 @@ def _EndRecData64(fpin, offset, endrec):
data = fpin.read(sizeEndCentDir64) data = fpin.read(sizeEndCentDir64)
sig, sz, create_version, read_version, disk_num, disk_dir, \ sig, sz, create_version, read_version, disk_num, disk_dir, \
dircount, dircount2, dirsize, diroffset = \ dircount, dircount2, dirsize, diroffset = \
struct.unpack(structEndCentDir64, data) struct.unpack(structEndArchive64, data)
if sig != magicEndCentDir64: if sig != stringEndArchive64:
return endrec return endrec
# Update the original endrec using data from the ZIP64 record # Update the original endrec using data from the ZIP64 record
@ -217,9 +189,9 @@ def _EndRecData(fpin):
# file if this is the case). # file if this is the case).
fpin.seek(-sizeEndCentDir, 2) fpin.seek(-sizeEndCentDir, 2)
data = fpin.read() data = fpin.read()
if data[0:4] == magicEndCentDir and data[-2:] == b"\000\000": if data[0:4] == stringEndArchive and data[-2:] == b"\000\000":
# the signature is correct and there's no comment, unpack structure # the signature is correct and there's no comment, unpack structure
endrec = struct.unpack(structEndCentDir, data) endrec = struct.unpack(structEndArchive, data)
endrec=list(endrec) endrec=list(endrec)
# Append a blank comment and record start offset # Append a blank comment and record start offset
@ -241,11 +213,11 @@ def _EndRecData(fpin):
maxCommentStart = max(filesize - (1 << 16) - sizeEndCentDir, 0) maxCommentStart = max(filesize - (1 << 16) - sizeEndCentDir, 0)
fpin.seek(maxCommentStart, 0) fpin.seek(maxCommentStart, 0)
data = fpin.read() data = fpin.read()
start = data.rfind(magicEndCentDir) start = data.rfind(stringEndArchive)
if start >= 0: if start >= 0:
# found the magic number; attempt to unpack and interpret # found the magic number; attempt to unpack and interpret
recData = data[start:start+sizeEndCentDir] recData = data[start:start+sizeEndCentDir]
endrec = list(struct.unpack(structEndCentDir, recData)) endrec = list(struct.unpack(structEndArchive, recData))
comment = data[start+sizeEndCentDir:] comment = data[start+sizeEndCentDir:]
# check that comment length is correct # check that comment length is correct
if endrec[_ECD_COMMENT_SIZE] == len(comment): if endrec[_ECD_COMMENT_SIZE] == len(comment):
@ -352,7 +324,7 @@ class ZipInfo (object):
self.create_version = max(45, self.extract_version) self.create_version = max(45, self.extract_version)
filename, flag_bits = self._encodeFilenameFlags() filename, flag_bits = self._encodeFilenameFlags()
header = struct.pack(structFileHeader, magicFileHeader, header = struct.pack(structFileHeader, stringFileHeader,
self.extract_version, self.reserved, flag_bits, self.extract_version, self.reserved, flag_bits,
self.compress_type, dostime, dosdate, CRC, self.compress_type, dostime, dosdate, CRC,
compress_size, file_size, compress_size, file_size,
@ -777,7 +749,7 @@ class ZipFile:
total = 0 total = 0
while total < size_cd: while total < size_cd:
centdir = fp.read(sizeCentralDir) centdir = fp.read(sizeCentralDir)
if centdir[0:4] != magicCentralDir: if centdir[0:4] != stringCentralDir:
raise BadZipfile("Bad magic number for central directory") raise BadZipfile("Bad magic number for central directory")
centdir = struct.unpack(structCentralDir, centdir) centdir = struct.unpack(structCentralDir, centdir)
if self.debug > 2: if self.debug > 2:
@ -892,7 +864,7 @@ class ZipFile:
# Skip the file header: # Skip the file header:
fheader = zef_file.read(sizeFileHeader) fheader = zef_file.read(sizeFileHeader)
if fheader[0:4] != magicFileHeader: if fheader[0:4] != stringFileHeader:
raise BadZipfile("Bad magic number for file header") raise BadZipfile("Bad magic number for file header")
fheader = struct.unpack(structFileHeader, fheader) fheader = struct.unpack(structFileHeader, fheader)
@ -1184,7 +1156,7 @@ class ZipFile:
try: try:
filename, flag_bits = zinfo._encodeFilenameFlags() filename, flag_bits = zinfo._encodeFilenameFlags()
centdir = struct.pack(structCentralDir, centdir = struct.pack(structCentralDir,
magicCentralDir, create_version, stringCentralDir, create_version,
zinfo.create_system, extract_version, zinfo.reserved, zinfo.create_system, extract_version, zinfo.reserved,
flag_bits, zinfo.compress_type, dostime, dosdate, flag_bits, zinfo.compress_type, dostime, dosdate,
zinfo.CRC, compress_size, file_size, zinfo.CRC, compress_size, file_size,
@ -1212,13 +1184,13 @@ class ZipFile:
if pos1 > ZIP64_LIMIT: if pos1 > ZIP64_LIMIT:
# Need to write the ZIP64 end-of-archive records # Need to write the ZIP64 end-of-archive records
zip64endrec = struct.pack( zip64endrec = struct.pack(
structEndCentDir64, magicEndCentDir64, structEndArchive64, stringEndArchive64,
44, 45, 45, 0, 0, count, count, pos2 - pos1, pos1) 44, 45, 45, 0, 0, count, count, pos2 - pos1, pos1)
self.fp.write(zip64endrec) self.fp.write(zip64endrec)
zip64locrec = struct.pack( zip64locrec = struct.pack(
structEndCentDir64Locator, structEndArchive64Locator,
magicEndCentDir64Locator, 0, pos2, 1) stringEndArchive64Locator, 0, pos2, 1)
self.fp.write(zip64locrec) self.fp.write(zip64locrec)
centDirOffset = 0xFFFFFFFF centDirOffset = 0xFFFFFFFF
@ -1229,7 +1201,7 @@ class ZipFile:
% ZIP_MAX_COMMENT % ZIP_MAX_COMMENT
self.comment = self.comment[:ZIP_MAX_COMMENT] self.comment = self.comment[:ZIP_MAX_COMMENT]
endrec = struct.pack(structEndCentDir, magicEndCentDir, endrec = struct.pack(structEndArchive, stringEndArchive,
0, 0, count % ZIP_FILECOUNT_LIMIT, 0, 0, count % ZIP_FILECOUNT_LIMIT,
count % ZIP_FILECOUNT_LIMIT, pos2 - pos1, count % ZIP_FILECOUNT_LIMIT, pos2 - pos1,
centDirOffset, len(self.comment)) centDirOffset, len(self.comment))

View file

@ -460,6 +460,7 @@ Luke Mewburn
Mike Meyer Mike Meyer
Steven Miale Steven Miale
Trent Mick Trent Mick
Aristotelis Mikropoulos
Damien Miller Damien Miller
Chad Miller Chad Miller
Jay T. Miller Jay T. Miller

View file

@ -11,6 +11,10 @@ internal_bisect_right(PyObject *list, PyObject *item, Py_ssize_t lo, Py_ssize_t
PyObject *litem; PyObject *litem;
Py_ssize_t mid, res; Py_ssize_t mid, res;
if (lo < 0) {
PyErr_SetString(PyExc_ValueError, "lo must be non-negative");
return -1;
}
if (hi == -1) { if (hi == -1) {
hi = PySequence_Size(list); hi = PySequence_Size(list);
if (hi < 0) if (hi < 0)
@ -108,6 +112,10 @@ internal_bisect_left(PyObject *list, PyObject *item, int lo, int hi)
PyObject *litem; PyObject *litem;
int mid, res; int mid, res;
if (lo < 0) {
PyErr_SetString(PyExc_ValueError, "lo must be non-negative");
return -1;
}
if (hi == -1) { if (hi == -1) {
hi = PySequence_Size(list); hi = PySequence_Size(list);
if (hi < 0) if (hi < 0)

View file

@ -706,6 +706,7 @@ clear_freelists(void)
(void)PyCFunction_ClearFreeList(); (void)PyCFunction_ClearFreeList();
(void)PyTuple_ClearFreeList(); (void)PyTuple_ClearFreeList();
(void)PyUnicode_ClearFreeList(); (void)PyUnicode_ClearFreeList();
(void)PyFloat_ClearFreeList();
} }
/* This is the main function. Read this to understand how the /* This is the main function. Read this to understand how the

View file

@ -3638,7 +3638,8 @@ posix_fork1(PyObject *self, PyObject *noargs)
pid_t pid = fork1(); pid_t pid = fork1();
if (pid == -1) if (pid == -1)
return posix_error(); return posix_error();
PyOS_AfterFork(); if (pid == 0)
PyOS_AfterFork();
return PyLong_FromLong(pid); return PyLong_FromLong(pid);
} }
#endif #endif

View file

@ -225,6 +225,9 @@ PyFloat_FromString(PyObject *v)
if (PyOS_strnicmp(p, "inf", 4) == 0) { if (PyOS_strnicmp(p, "inf", 4) == 0) {
Py_RETURN_INF(sign); Py_RETURN_INF(sign);
} }
if (PyOS_strnicmp(p, "infinity", 9) == 0) {
Py_RETURN_INF(sign);
}
#ifdef Py_NAN #ifdef Py_NAN
if(PyOS_strnicmp(p, "nan", 4) == 0) { if(PyOS_strnicmp(p, "nan", 4) == 0) {
Py_RETURN_NAN; Py_RETURN_NAN;
@ -1903,30 +1906,28 @@ _PyFloat_Init(void)
PyStructSequence_InitType(&FloatInfoType, &floatinfo_desc); PyStructSequence_InitType(&FloatInfoType, &floatinfo_desc);
} }
void int
PyFloat_CompactFreeList(size_t *pbc, size_t *pbf, size_t *bsum) PyFloat_ClearFreeList(void)
{ {
PyFloatObject *p; PyFloatObject *p;
PyFloatBlock *list, *next; PyFloatBlock *list, *next;
unsigned i; int i;
size_t bc = 0, bf = 0; /* block count, number of freed blocks */ int u; /* remaining unfreed ints per block */
size_t fsum = 0; /* total unfreed ints */ int freelist_size = 0;
int frem; /* remaining unfreed ints per block */
list = block_list; list = block_list;
block_list = NULL; block_list = NULL;
free_list = NULL; free_list = NULL;
while (list != NULL) { while (list != NULL) {
bc++; u = 0;
frem = 0;
for (i = 0, p = &list->objects[0]; for (i = 0, p = &list->objects[0];
i < N_FLOATOBJECTS; i < N_FLOATOBJECTS;
i++, p++) { i++, p++) {
if (PyFloat_CheckExact(p) && Py_REFCNT(p) != 0) if (PyFloat_CheckExact(p) && Py_REFCNT(p) != 0)
frem++; u++;
} }
next = list->next; next = list->next;
if (frem) { if (u) {
list->next = block_list; list->next = block_list;
block_list = list; block_list = list;
for (i = 0, p = &list->objects[0]; for (i = 0, p = &list->objects[0];
@ -1941,15 +1942,12 @@ PyFloat_CompactFreeList(size_t *pbc, size_t *pbf, size_t *bsum)
} }
} }
else { else {
PyMem_FREE(list); /* XXX PyObject_FREE ??? */ PyMem_FREE(list);
bf++;
} }
fsum += frem; freelist_size += u;
list = next; list = next;
} }
*pbc = bc; return freelist_size;
*pbf = bf;
*bsum = fsum;
} }
void void
@ -1957,25 +1955,21 @@ PyFloat_Fini(void)
{ {
PyFloatObject *p; PyFloatObject *p;
PyFloatBlock *list; PyFloatBlock *list;
unsigned i; int i;
size_t bc, bf; /* block count, number of freed blocks */ int u; /* total unfreed floats per block */
size_t fsum; /* total unfreed floats per block */
PyFloat_CompactFreeList(&bc, &bf, &fsum); u = PyFloat_ClearFreeList();
if (!Py_VerboseFlag) if (!Py_VerboseFlag)
return; return;
fprintf(stderr, "# cleanup floats"); fprintf(stderr, "# cleanup floats");
if (!fsum) { if (!u) {
fprintf(stderr, "\n"); fprintf(stderr, "\n");
} }
else { else {
fprintf(stderr, fprintf(stderr,
": %" PY_FORMAT_SIZE_T "d unfreed float%s in %" ": %d unfreed float%s\n",
PY_FORMAT_SIZE_T "d out of %" u, u == 1 ? "" : "s");
PY_FORMAT_SIZE_T "d block%s\n",
fsum, fsum == 1 ? "" : "s",
bc - bf, bc, bc == 1 ? "" : "s");
} }
if (Py_VerboseFlag > 1) { if (Py_VerboseFlag > 1) {
list = block_list; list = block_list;

View file

@ -266,7 +266,8 @@ show_warning(PyObject *filename, int lineno, PyObject *text, PyObject
PyFile_WriteString("\n", f_stderr); PyFile_WriteString("\n", f_stderr);
} }
else else
Py_DisplaySourceLine(f_stderr, PyUnicode_AsString(filename), lineno, 2); _Py_DisplaySourceLine(f_stderr, PyUnicode_AsString(filename),
lineno, 2);
PyErr_Clear(); PyErr_Clear();
} }

View file

@ -2162,6 +2162,7 @@ get_parent(PyObject *globals, char *buf, Py_ssize_t *p_buflen, int level)
static PyObject *pathstr = NULL; static PyObject *pathstr = NULL;
static PyObject *pkgstr = NULL; static PyObject *pkgstr = NULL;
PyObject *pkgname, *modname, *modpath, *modules, *parent; PyObject *pkgname, *modname, *modpath, *modules, *parent;
int orig_level = level;
if (globals == NULL || !PyDict_Check(globals) || !level) if (globals == NULL || !PyDict_Check(globals) || !level)
return Py_None; return Py_None;
@ -2292,9 +2293,27 @@ get_parent(PyObject *globals, char *buf, Py_ssize_t *p_buflen, int level)
modules = PyImport_GetModuleDict(); modules = PyImport_GetModuleDict();
parent = PyDict_GetItemString(modules, buf); parent = PyDict_GetItemString(modules, buf);
if (parent == NULL) if (parent == NULL) {
PyErr_Format(PyExc_SystemError, if (orig_level < 1) {
"Parent module '%.200s' not loaded", buf); PyObject *err_msg = PyBytes_FromFormat(
"Parent module '%.200s' not found "
"while handling absolute import", buf);
if (err_msg == NULL) {
return NULL;
}
if (!PyErr_WarnEx(PyExc_RuntimeWarning,
PyBytes_AsString(err_msg), 1)) {
*buf = '\0';
*p_buflen = 0;
parent = Py_None;
}
Py_DECREF(err_msg);
} else {
PyErr_Format(PyExc_SystemError,
"Parent module '%.200s' not loaded, "
"cannot perform relative import", buf);
}
}
return parent; return parent;
/* We expect, but can't guarantee, if parent != None, that: /* We expect, but can't guarantee, if parent != None, that:
- parent.__name__ == buf - parent.__name__ == buf

View file

@ -824,29 +824,12 @@ PyDoc_STRVAR(sys_clear_type_cache__doc__,
Clear the internal type lookup cache."); Clear the internal type lookup cache.");
static PyObject *
sys_compact_freelists(PyObject* self, PyObject* args)
{
size_t fsum, fbc, fbf;
PyFloat_CompactFreeList(&fbc, &fbf, &fsum);
return Py_BuildValue("((kkk))", fsum, fbc, fbf);
}
PyDoc_STRVAR(sys_compact_freelists__doc__,
"_compact_freelists() -> ((remaing_objects, total_blocks, freed_blocks),)\n\
Compact the free lists of floats.");
static PyMethodDef sys_methods[] = { static PyMethodDef sys_methods[] = {
/* Might as well keep this in alphabetic order */ /* Might as well keep this in alphabetic order */
{"callstats", (PyCFunction)PyEval_GetCallStats, METH_NOARGS, {"callstats", (PyCFunction)PyEval_GetCallStats, METH_NOARGS,
callstats_doc}, callstats_doc},
{"_clear_type_cache", sys_clear_type_cache, METH_NOARGS, {"_clear_type_cache", sys_clear_type_cache, METH_NOARGS,
sys_clear_type_cache__doc__}, sys_clear_type_cache__doc__},
{"_compact_freelists", sys_compact_freelists, METH_NOARGS,
sys_compact_freelists__doc__},
{"_current_frames", sys_current_frames, METH_NOARGS, {"_current_frames", sys_current_frames, METH_NOARGS,
current_frames_doc}, current_frames_doc},
{"displayhook", sys_displayhook, METH_O, displayhook_doc}, {"displayhook", sys_displayhook, METH_O, displayhook_doc},

View file

@ -129,7 +129,7 @@ PyTraceBack_Here(PyFrameObject *frame)
} }
int int
Py_DisplaySourceLine(PyObject *f, const char *filename, int lineno, int indent) _Py_DisplaySourceLine(PyObject *f, const char *filename, int lineno, int indent)
{ {
int err = 0; int err = 0;
FILE *xfp = NULL; FILE *xfp = NULL;
@ -241,7 +241,7 @@ tb_displayline(PyObject *f, const char *filename, int lineno, const char *name)
err = PyFile_WriteString(linebuf, f); err = PyFile_WriteString(linebuf, f);
if (err != 0) if (err != 0)
return err; return err;
return Py_DisplaySourceLine(f, filename, lineno, 4); return _Py_DisplaySourceLine(f, filename, lineno, 4);
} }
static int static int

View file

@ -9,7 +9,7 @@
# blackjesus:~> ./move-faqwiz.sh 2\.1 3\.2 # blackjesus:~> ./move-faqwiz.sh 2\.1 3\.2
# Moving FAQ question 02.001 to 03.002 # Moving FAQ question 02.001 to 03.002
if [ x$2 == x ]; then if [ x$2 = x ]; then
echo "Need 2 args: original_version final_version." echo "Need 2 args: original_version final_version."
exit 2 exit 2
fi fi
@ -19,7 +19,7 @@ if [ ! -d data -o ! -d data/RCS ]; then
exit 2 exit 2
fi fi
function cut_n_pad() { cut_n_pad() {
t=`echo $1 | cut -d. -f $2` t=`echo $1 | cut -d. -f $2`
export $3=`echo $t | awk "{ tmp = \\$0; l = length(tmp); for (i = 0; i < $2-l+1; i++) { tmp = "0".tmp } print tmp }"` export $3=`echo $t | awk "{ tmp = \\$0; l = length(tmp); for (i = 0; i < $2-l+1; i++) { tmp = "0".tmp } print tmp }"`
} }
@ -28,7 +28,13 @@ cut_n_pad $1 1 prefix1
cut_n_pad $1 2 suffix1 cut_n_pad $1 2 suffix1
cut_n_pad $2 1 prefix2 cut_n_pad $2 1 prefix2
cut_n_pad $2 2 suffix2 cut_n_pad $2 2 suffix2
tmpfile=tmp$RANDOM.tmp if which tempfile >/dev/null; then
tmpfile=$(tempfile -d .)
elif [ -n "$RANDOM" ]; then
tmpfile=tmp$RANDOM.tmp
else
tmpfile=tmp$$.tmp
fi
file1=faq$prefix1.$suffix1.htp file1=faq$prefix1.$suffix1.htp
file2=faq$prefix2.$suffix2.htp file2=faq$prefix2.$suffix2.htp