summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/c-api/conversion.rst8
-rw-r--r--Doc/c-api/float.rst7
-rw-r--r--Doc/c-api/sequence.rst4
-rw-r--r--Doc/extending/windows.rst2
-rw-r--r--Doc/library/__future__.rst2
-rw-r--r--Doc/library/ctypes.rst4
-rw-r--r--Doc/library/ftplib.rst2
-rw-r--r--Doc/library/functions.rst1
-rw-r--r--Doc/library/gc.rst5
-rw-r--r--Doc/library/multiprocessing.rst21
-rw-r--r--Doc/library/operator.rst2
-rw-r--r--Doc/library/select.rst4
-rw-r--r--Doc/library/stdtypes.rst2
-rw-r--r--Doc/library/string.rst2
-rw-r--r--Doc/library/sys.rst13
-rw-r--r--Doc/library/tkinter.tix.rst4
-rw-r--r--Doc/library/tkinter.turtle.rst8
-rw-r--r--Doc/library/urllib.request.rst2
-rw-r--r--Doc/library/wsgiref.rst2
-rw-r--r--Doc/library/xmlrpc.client.rst4
-rw-r--r--Doc/tutorial/stdlib2.rst2
-rw-r--r--Doc/using/windows.rst4
-rw-r--r--Doc/whatsnew/2.6.rst200
-rw-r--r--Include/floatobject.h2
-rw-r--r--Include/object.h4
-rw-r--r--Include/traceback.h2
-rw-r--r--Lib/bisect.py8
-rwxr-xr-xLib/fractions.py8
-rw-r--r--Lib/multiprocessing/connection.py4
-rw-r--r--Lib/shutil.py35
-rw-r--r--Lib/test/test_bisect.py8
-rw-r--r--Lib/test/test_float.py18
-rw-r--r--Lib/test/test_fractions.py12
-rw-r--r--Lib/test/test_import.py23
-rw-r--r--Lib/test/test_shutil.py76
-rw-r--r--Lib/zipfile.py82
-rw-r--r--Misc/ACKS1
-rw-r--r--Modules/_bisectmodule.c8
-rw-r--r--Modules/gcmodule.c1
-rw-r--r--Modules/posixmodule.c3
-rw-r--r--Objects/floatobject.c46
-rw-r--r--Python/_warnings.c3
-rw-r--r--Python/import.c25
-rw-r--r--Python/sysmodule.c17
-rw-r--r--Python/traceback.c4
-rwxr-xr-xTools/faqwiz/move-faqwiz.sh12
46 files changed, 498 insertions, 209 deletions
diff --git a/Doc/c-api/conversion.rst b/Doc/c-api/conversion.rst
index f926094..b71283b 100644
--- a/Doc/c-api/conversion.rst
+++ b/Doc/c-api/conversion.rst
@@ -83,11 +83,11 @@ The following functions provide locale-independent string to number conversions.
.. cfunction:: char * PyOS_stricmp(char *s1, char *s2)
- Case insensitive comparison of strings. The functions works almost
- identical to :cfunc:`strcmp` except that it ignores the case.
+ Case insensitive comparison of strings. The function works almost
+ identically to :cfunc:`strcmp` except that it ignores the case.
.. cfunction:: char * PyOS_strnicmp(char *s1, char *s2, Py_ssize_t size)
- Case insensitive comparison of strings. The functions works almost
- identical to :cfunc:`strncmp` except that it ignores the case.
+ Case insensitive comparison of strings. The function works almost
+ identically to :cfunc:`strncmp` except that it ignores the case.
diff --git a/Doc/c-api/float.rst b/Doc/c-api/float.rst
index 8fff0d0..77a8b83 100644
--- a/Doc/c-api/float.rst
+++ b/Doc/c-api/float.rst
@@ -73,8 +73,7 @@ Floating Point Objects
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
- blocks are freed, *bf* is the number of freed blocks and *sum* is the number
- of remaining objects in the blocks.
+ Clear the float free list. Return the number of items that could not
+ be freed.
diff --git a/Doc/c-api/sequence.rst b/Doc/c-api/sequence.rst
index 6d3ef71..0ebc0f3 100644
--- a/Doc/c-api/sequence.rst
+++ b/Doc/c-api/sequence.rst
@@ -143,6 +143,10 @@ Sequence Protocol
Return the underlying array of PyObject pointers. Assumes that *o* was returned
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)
diff --git a/Doc/extending/windows.rst b/Doc/extending/windows.rst
index a0782a7..1811277 100644
--- a/Doc/extending/windows.rst
+++ b/Doc/extending/windows.rst
@@ -23,7 +23,7 @@ C++.
This chapter mentions a number of filenames that include an encoded Python
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
example, if you are using Python 2.2.1, ``XY`` will actually be ``22``.
diff --git a/Doc/library/__future__.rst b/Doc/library/__future__.rst
index e2349cc..d6f82a3 100644
--- a/Doc/library/__future__.rst
+++ b/Doc/library/__future__.rst
@@ -16,7 +16,7 @@
* To document when incompatible changes were introduced, and when they will be
--- 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.
Each statement in :file:`__future__.py` is of the form::
diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst
index 939bf8f..f422bf3 100644
--- a/Doc/library/ctypes.rst
+++ b/Doc/library/ctypes.rst
@@ -1781,8 +1781,8 @@ Utility functions
.. function:: byref(obj[, offset])
Returns a light-weight pointer to ``obj``, which must be an
- instance of a ctypes type. ``offset`` defaults to zero, it must be
- an integer which is added to the internal pointer value.
+ instance of a ctypes type. ``offset`` defaults to zero, and must be
+ an integer that will be added to the internal pointer value.
``byref(obj, offset)`` corresponds to this C code::
diff --git a/Doc/library/ftplib.rst b/Doc/library/ftplib.rst
index f360c60..d4f8888 100644
--- a/Doc/library/ftplib.rst
+++ b/Doc/library/ftplib.rst
@@ -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
"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
subsequent calls (see below).
diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst
index 4b1cbc6..ac40ce7 100644
--- a/Doc/library/functions.rst
+++ b/Doc/library/functions.rst
@@ -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
values are important, use :func:`itertools.zip_longest` instead.
+
.. rubric:: Footnotes
.. [#] Specifying a buffer size currently has no effect on systems that don't have
diff --git a/Doc/library/gc.rst b/Doc/library/gc.rst
index 99504c6..7c425e3 100644
--- a/Doc/library/gc.rst
+++ b/Doc/library/gc.rst
@@ -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
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)
diff --git a/Doc/library/multiprocessing.rst b/Doc/library/multiprocessing.rst
index be87775..10ccb17 100644
--- a/Doc/library/multiprocessing.rst
+++ b/Doc/library/multiprocessing.rst
@@ -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
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.
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**
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.
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
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
- 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
:ref:`multiprocessing-programming`.
@@ -532,7 +532,8 @@ For an example of the usage of queues for interprocess communication see
Equivalent to ``get(False)``.
: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()
@@ -772,7 +773,7 @@ Synchronization primitives
~~~~~~~~~~~~~~~~~~~~~~~~~~
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.
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`.
- (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).
.. class:: Condition([lock])
@@ -891,8 +892,8 @@ processes.
.. note::
- Although it is posible to store a pointer in shared memory remember that this
- will refer to a location in the address space of a specific process.
+ Although it is possible to store a pointer in shared memory remember that
+ 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
process and trying to dereference the pointer from the second process may
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.
- .. method:: server_forever()
+ .. method:: serve_forever()
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
``'[%(levelname)s/%(processName)s] %(message)s'``. (The logger allows use of
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
parent process's logger -- any other customization of the logger will not be
diff --git a/Doc/library/operator.rst b/Doc/library/operator.rst
index 37996e0..a67c6d8 100644
--- a/Doc/library/operator.rst
+++ b/Doc/library/operator.rst
@@ -513,7 +513,7 @@ Python syntax and the functions in the :mod:`operator` module.
+-----------------------+-------------------------+---------------------------------+
| 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)`` |
+-----------------------+-------------------------+---------------------------------+
diff --git a/Doc/library/select.rst b/Doc/library/select.rst
index 102d3ea..f64d6dd 100644
--- a/Doc/library/select.rst
+++ b/Doc/library/select.rst
@@ -330,7 +330,7 @@ http://www.freebsd.org/cgi/man.cgi?query=kqueue&sektion=2
+---------------------------+---------------------------------------------+
| :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 |
+---------------------------+---------------------------------------------+
@@ -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_WRITE` | a write occured |
+ | :const:`KQ_NOTE_WRITE` | a write occurred |
+----------------------------+--------------------------------------------+
| :const:`KQ_NOTE_EXTEND` | the file was extended |
+----------------------------+--------------------------------------------+
diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst
index 586770a..40417d8 100644
--- a/Doc/library/stdtypes.rst
+++ b/Doc/library/stdtypes.rst
@@ -1565,7 +1565,7 @@ The constructors for both classes work the same:
.. method:: isdisjoint(other)
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)
set <= other
diff --git a/Doc/library/string.rst b/Doc/library/string.rst
index 662541e..07a2c4b 100644
--- a/Doc/library/string.rst
+++ b/Doc/library/string.rst
@@ -266,7 +266,7 @@ Then the outer replacement field would be evaluated, producing::
"noses "
-Which is subsitituted into the string, yielding::
+Which is substituted into the string, yielding::
"A man with two noses "
diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst
index f92b1e4..3f73ec2 100644
--- a/Doc/library/sys.rst
+++ b/Doc/library/sys.rst
@@ -54,19 +54,6 @@ always available.
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()
Clear the internal type cache. The type cache is used to speed up attribute
diff --git a/Doc/library/tkinter.tix.rst b/Doc/library/tkinter.tix.rst
index a85aeb1..b555376 100644
--- a/Doc/library/tkinter.tix.rst
+++ b/Doc/library/tkinter.tix.rst
@@ -305,8 +305,8 @@ File Selectors
.. \ulink{FileEntry}{http://tix.sourceforge.net/dist/current/demos/samples/FileEnt.tcl}
-Hierachical ListBox
-^^^^^^^^^^^^^^^^^^^
+Hierarchical ListBox
+^^^^^^^^^^^^^^^^^^^^
.. class:: HList()
diff --git a/Doc/library/tkinter.turtle.rst b/Doc/library/tkinter.turtle.rst
index 575c2fc..6bf9c10 100644
--- a/Doc/library/tkinter.turtle.rst
+++ b/Doc/library/tkinter.turtle.rst
@@ -2,6 +2,10 @@
:mod:`turtle` --- Turtle graphics for Tk
========================================
+.. module:: tkinter.turtle
+ :synopsis: Turtle graphics for Tk
+.. sectionauthor:: Gregor Lingl <gregor.lingl@aon.at>
+
Introduction
============
@@ -1251,7 +1255,7 @@ Window control
... left(10)
...
>>> for _ in range(8):
- ... left(45); fd(2) # a regular octogon
+ ... left(45); fd(2) # a regular octagon
Animation control
@@ -1262,7 +1266,7 @@ Animation control
:param delay: positive integer
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.
Optional argument:
diff --git a/Doc/library/urllib.request.rst b/Doc/library/urllib.request.rst
index c506829..3038588 100644
--- a/Doc/library/urllib.request.rst
+++ b/Doc/library/urllib.request.rst
@@ -1062,7 +1062,7 @@ involved. For example, the :envvar:`http_proxy` environment variable is read to
obtain the HTTP proxy's URL.
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`. ::
proxy_handler = urllib.request.ProxyHandler({'http': 'http://www.example.com:3128/'})
diff --git a/Doc/library/wsgiref.rst b/Doc/library/wsgiref.rst
index 70064fc..fcfe769 100644
--- a/Doc/library/wsgiref.rst
+++ b/Doc/library/wsgiref.rst
@@ -413,7 +413,7 @@ Paste" library.
from wsgiref.validate import validator
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
def simple_app(environ, start_response):
status = '200 OK' # HTTP Status
diff --git a/Doc/library/xmlrpc.client.rst b/Doc/library/xmlrpc.client.rst
index e249b12..1f18810 100644
--- a/Doc/library/xmlrpc.client.rst
+++ b/Doc/library/xmlrpc.client.rst
@@ -344,7 +344,7 @@ The client code for the preceding server::
try:
proxy.add(2, 5)
except xmlrpc.client.Fault, err:
- print("A fault occured")
+ print("A fault occurred")
print("Fault code: %d" % err.faultCode)
print("Fault string: %s" % err.faultString)
@@ -391,7 +391,7 @@ by providing an invalid URI::
try:
proxy.some_method()
except xmlrpc.client.ProtocolError, err:
- print("A protocol error occured")
+ print("A protocol error occurred")
print("URL: %s" % err.url)
print("HTTP/HTTPS headers: %s" % err.headers)
print("Error code: %d" % err.errcode)
diff --git a/Doc/tutorial/stdlib2.rst b/Doc/tutorial/stdlib2.rst
index 7d76363..84dfb61 100644
--- a/Doc/tutorial/stdlib2.rst
+++ b/Doc/tutorial/stdlib2.rst
@@ -286,7 +286,7 @@ sometimes there is a need for alternative implementations with different
performance trade-offs.
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
(typecode ``"H"``) rather than the usual 16 bytes per entry for regular lists of
python int objects::
diff --git a/Doc/using/windows.rst b/Doc/using/windows.rst
index 4064fa1..2dd236f 100644
--- a/Doc/using/windows.rst
+++ b/Doc/using/windows.rst
@@ -186,7 +186,7 @@ of your Python installation directory). This suppresses the terminal window on
startup.
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):
#. Launch a command prompt.
@@ -215,7 +215,7 @@ PyWin32
The `PyWin32 <http://python.net/crew/mhammond/win32/>`_ module by Mark Hammond
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)
* Win32 API calls
diff --git a/Doc/whatsnew/2.6.rst b/Doc/whatsnew/2.6.rst
index 264ec2e..5cf29cb 100644
--- a/Doc/whatsnew/2.6.rst
+++ b/Doc/whatsnew/2.6.rst
@@ -51,7 +51,7 @@
This article explains the new features in Python 2.6. The release
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
the new features, but instead provides a convenient overview. For
@@ -526,28 +526,152 @@ environment variable.
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.
+
+The :mod:`multiprocessing` module started out as an exact emulation of
+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.
+
+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.
+
+::
+
+ import time
+ from multiprocessing import Process, Queue
+
+
+ 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
-:mod:`multiprocessing` makes it easy to distribute work over multiple processes.
-Its API is similiar to that of :mod:`threading`. For example::
+ # Run tasks using the pool
+ for N in range(1, 1000, 10):
+ p.apply_async(factorial, (N, d))
- from multiprocessing import Process
+ # Mark pool as closed -- no more tasks can be added.
+ p.close()
- def long_hard_task(n):
- print n * 43
+ # Wait for tasks to exit
+ p.join()
- for i in range(10):
- Process(target=long_hard_task, args=(i)).start()
+ # Output results
+ for k, v in sorted(d.items()):
+ print k, v
-will multiply the numbers between 0 and 10 times 43 and print out the result
-concurrently.
+This will produce the output::
+
+ 1 1
+ 11 39916800
+ 21 51090942171709440000
+ 31 8222838654177922817725562880000000
+ 41 33452526613163807108170062053440751665152000000000
+ 51 1551118753287382280224243016469303211063259720016986112000000000000
.. seealso::
+ The documentation for the :mod:`multiprocessing` module.
+
:pep:`371` - Addition of the multiprocessing package
PEP written by Jesse Noller and Richard Oudkerk;
implemented by Richard Oudkerk and Jesse Noller.
+
.. ======================================================================
.. _pep-3101:
@@ -1775,21 +1899,6 @@ details.
(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
the display characters for a certain number of characters on a single line.
(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
--------------------------------------------------
diff --git a/Include/floatobject.h b/Include/floatobject.h
index 650d544..364b913 100644
--- a/Include/floatobject.h
+++ b/Include/floatobject.h
@@ -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);
/* 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
(Advanced String Formatting). */
diff --git a/Include/object.h b/Include/object.h
index 7f0e24a..07a4b2c 100644
--- a/Include/object.h
+++ b/Include/object.h
@@ -695,9 +695,9 @@ PyAPI_FUNC(void) _Py_AddToAllObjects(PyObject *, int force);
#define Py_CLEAR(op) \
do { \
if (op) { \
- PyObject *tmp = (PyObject *)(op); \
+ PyObject *_py_tmp = (PyObject *)(op); \
(op) = NULL; \
- Py_DECREF(tmp); \
+ Py_DECREF(_py_tmp); \
} \
} while (0)
diff --git a/Include/traceback.h b/Include/traceback.h
index 0be3ad5..e7943da 100644
--- a/Include/traceback.h
+++ b/Include/traceback.h
@@ -19,7 +19,7 @@ typedef struct _traceback {
PyAPI_FUNC(int) PyTraceBack_Here(struct _frame *);
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 */
PyAPI_DATA(PyTypeObject) PyTraceBack_Type;
diff --git a/Lib/bisect.py b/Lib/bisect.py
index e4a2133..fe84255 100644
--- a/Lib/bisect.py
+++ b/Lib/bisect.py
@@ -9,6 +9,8 @@ def insort_right(a, x, lo=0, hi=None):
slice of a to be searched.
"""
+ if lo < 0:
+ raise ValueError('lo must be non-negative')
if hi is None:
hi = len(a)
while lo < hi:
@@ -30,6 +32,8 @@ def bisect_right(a, x, lo=0, hi=None):
slice of a to be searched.
"""
+ if lo < 0:
+ raise ValueError('lo must be non-negative')
if hi is None:
hi = len(a)
while lo < hi:
@@ -49,6 +53,8 @@ def insort_left(a, x, lo=0, hi=None):
slice of a to be searched.
"""
+ if lo < 0:
+ raise ValueError('lo must be non-negative')
if hi is None:
hi = len(a)
while lo < hi:
@@ -69,6 +75,8 @@ def bisect_left(a, x, lo=0, hi=None):
slice of a to be searched.
"""
+ if lo < 0:
+ raise ValueError('lo must be non-negative')
if hi is None:
hi = len(a)
while lo < hi:
diff --git a/Lib/fractions.py b/Lib/fractions.py
index 3df628a..bc06524 100755
--- a/Lib/fractions.py
+++ b/Lib/fractions.py
@@ -108,7 +108,9 @@ class Fraction(numbers.Rational):
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)" %
(cls.__name__, f, type(f).__name__))
if math.isnan(f) or math.isinf(f):
@@ -119,7 +121,9 @@ class Fraction(numbers.Rational):
def from_decimal(cls, dec):
"""Converts a finite Decimal instance to a rational number, exactly."""
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(
"%s.from_decimal() only takes Decimals, not %r (%s)" %
(cls.__name__, dec, type(dec).__name__))
diff --git a/Lib/multiprocessing/connection.py b/Lib/multiprocessing/connection.py
index 8493ac0..717e14e 100644
--- a/Lib/multiprocessing/connection.py
+++ b/Lib/multiprocessing/connection.py
@@ -222,11 +222,9 @@ class SocketListener(object):
self._family = family
self._last_accepted = None
- sub_debug('listener bound to address %r', self._address)
-
if family == 'AF_UNIX':
self._unlink = Finalize(
- self, os.unlink, args=(self._address,), exitpriority=0
+ self, os.unlink, args=(address,), exitpriority=0
)
else:
self._unlink = None
diff --git a/Lib/shutil.py b/Lib/shutil.py
index e9cebae..56ea7ec 100644
--- a/Lib/shutil.py
+++ b/Lib/shutil.py
@@ -8,6 +8,7 @@ import os
import sys
import stat
from os.path import abspath
+import fnmatch
__all__ = ["copyfileobj","copyfile","copymode","copystat","copy","copy2",
"copytree","move","rmtree","Error"]
@@ -93,8 +94,19 @@ def copy2(src, dst):
copyfile(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().
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
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.
"""
names = os.listdir(src)
+ if ignore is not None:
+ ignored_names = ignore(src, names)
+ else:
+ ignored_names = set()
+
os.makedirs(dst)
errors = []
for name in names:
+ if name in ignored_names:
+ continue
srcname = os.path.join(src, name)
dstname = os.path.join(dst, name)
try:
@@ -119,7 +150,7 @@ def copytree(src, dst, symlinks=False):
linkto = os.readlink(srcname)
os.symlink(linkto, dstname)
elif os.path.isdir(srcname):
- copytree(srcname, dstname, symlinks)
+ copytree(srcname, dstname, symlinks, ignore)
else:
copy2(srcname, dstname)
# XXX What about devices, sockets etc.?
diff --git a/Lib/test/test_bisect.py b/Lib/test/test_bisect.py
index af9f1f7..987f33c 100644
--- a/Lib/test/test_bisect.py
+++ b/Lib/test/test_bisect.py
@@ -114,6 +114,14 @@ class TestBisect(unittest.TestCase):
self.assertEqual(func(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):
from random import randrange
for i in range(n):
diff --git a/Lib/test/test_float.py b/Lib/test/test_float.py
index 7de5320..db91e5e 100644
--- a/Lib/test/test_float.py
+++ b/Lib/test/test_float.py
@@ -284,24 +284,36 @@ class ReprTestCase(unittest.TestCase):
floats_file.close()
# 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):
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("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("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("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("infinity")), "inf")
+ self.assertEqual(str(float("+infinity")), "inf")
+ self.assertEqual(str(float("-infinity")), "-inf")
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, "infinit")
+ self.assertRaises(ValueError, float, "+Infin")
+ self.assertRaises(ValueError, float, "-INFI")
+ self.assertRaises(ValueError, float, "infinitys")
def test_inf_as_str(self):
self.assertEqual(repr(1e300 * 1e300), "inf")
diff --git a/Lib/test/test_fractions.py b/Lib/test/test_fractions.py
index 4f8defb..4fadf6c 100644
--- a/Lib/test/test_fractions.py
+++ b/Lib/test/test_fractions.py
@@ -134,10 +134,8 @@ class FractionTest(unittest.TestCase):
self.assertNotEquals(F(4, 2), r)
def testFromFloat(self):
- self.assertRaisesMessage(
- TypeError, "Fraction.from_float() only takes floats, not 3 (int)",
- F.from_float, 3)
-
+ self.assertRaises(TypeError, F.from_float, 3+4j)
+ self.assertEquals((10, 1), _components(F.from_float(10)))
self.assertEquals((0, 1), _components(F.from_float(-0.0)))
self.assertEquals((10, 1), _components(F.from_float(10.0)))
self.assertEquals((-5, 2), _components(F.from_float(-2.5)))
@@ -161,10 +159,8 @@ class FractionTest(unittest.TestCase):
F.from_float, nan)
def testFromDecimal(self):
- self.assertRaisesMessage(
- TypeError,
- "Fraction.from_decimal() only takes Decimals, not 3 (int)",
- F.from_decimal, 3)
+ self.assertRaises(TypeError, F.from_decimal, 3+4j)
+ self.assertEquals(F(10, 1), F.from_decimal(10))
self.assertEquals(F(0), F.from_decimal(Decimal("-0")))
self.assertEquals(F(5, 10), F.from_decimal(Decimal("0.5")))
self.assertEquals(F(5, 1000), F.from_decimal(Decimal("5e-3")))
diff --git a/Lib/test/test_import.py b/Lib/test/test_import.py
index 81e221d..aa65c7a 100644
--- a/Lib/test/test_import.py
+++ b/Lib/test/test_import.py
@@ -1,5 +1,3 @@
-from test.support import TESTFN, run_unittest, catch_warning
-
import unittest
import os
import random
@@ -8,7 +6,7 @@ import sys
import py_compile
import warnings
import imp
-from test.support import unlink, TESTFN, unload
+from test.support import unlink, TESTFN, unload, run_unittest, catch_warning
def remove_files(name):
@@ -267,6 +265,25 @@ class RelativeImport(unittest.TestCase):
from . import relimport
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):
run_unittest(ImportTest, PathsTests, RelativeImport)
diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py
index 2e680a9..ad60a44 100644
--- a/Lib/test/test_shutil.py
+++ b/Lib/test/test_shutil.py
@@ -108,6 +108,82 @@ class TestShutil(unittest.TestCase):
if os.path.exists(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"):
def test_dont_copy_file_onto_link_to_itself(self):
diff --git a/Lib/zipfile.py b/Lib/zipfile.py
index 59a86e2..fda9903 100644
--- a/Lib/zipfile.py
+++ b/Lib/zipfile.py
@@ -45,9 +45,9 @@ ZIP_DEFLATED = 8
# The "end of central directory" structure, magic number, size, and indices
# (section V.I in the format document)
-structEndCentDir = b"<4s4H2LH"
-magicEndCentDir = b"PK\005\006"
-sizeEndCentDir = struct.calcsize(structEndCentDir)
+structEndArchive = b"<4s4H2LH"
+stringEndArchive = b"PK\005\006"
+sizeEndCentDir = struct.calcsize(structEndArchive)
_ECD_SIGNATURE = 0
_ECD_DISK_NUMBER = 1
@@ -65,37 +65,9 @@ _ECD_LOCATION = 9
# The "central directory" structure, magic number, size, and indices
# of entries in the structure (section V.F in the format document)
structCentralDir = "<4s4B4HL2L5H2L"
-magicCentralDir = b"PK\001\002"
+stringCentralDir = b"PK\001\002"
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
_CD_SIGNATURE = 0
_CD_CREATE_VERSION = 1
@@ -120,7 +92,7 @@ _CD_LOCAL_HEADER_OFFSET = 18
# The "local file header" structure, magic number, size, and indices
# (section V.A in the format document)
structFileHeader = "<4s2B4HL2L2H"
-magicFileHeader = b"PK\003\004"
+stringFileHeader = b"PK\003\004"
sizeFileHeader = struct.calcsize(structFileHeader)
_FH_SIGNATURE = 0
@@ -137,15 +109,15 @@ _FH_FILENAME_LENGTH = 10
_FH_EXTRA_FIELD_LENGTH = 11
# The "Zip64 end of central directory locator" structure, magic number, and size
-structEndCentDir64Locator = "<4sLQL"
-magicEndCentDir64Locator = b"PK\x06\x07"
-sizeEndCentDir64Locator = struct.calcsize(structEndCentDir64Locator)
+structEndArchive64Locator = "<4sLQL"
+stringEndArchive64Locator = b"PK\x06\x07"
+sizeEndCentDir64Locator = struct.calcsize(structEndArchive64Locator)
# 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)
+structEndArchive64 = "<4sQ2H2L4Q"
+stringEndArchive64 = b"PK\x06\x06"
+sizeEndCentDir64 = struct.calcsize(structEndArchive64)
_CD64_SIGNATURE = 0
_CD64_DIRECTORY_RECSIZE = 1
@@ -176,8 +148,8 @@ def _EndRecData64(fpin, offset, endrec):
"""
fpin.seek(offset - sizeEndCentDir64Locator, 2)
data = fpin.read(sizeEndCentDir64Locator)
- sig, diskno, reloff, disks = struct.unpack(structEndCentDir64Locator, data)
- if sig != magicEndCentDir64Locator:
+ sig, diskno, reloff, disks = struct.unpack(structEndArchive64Locator, data)
+ if sig != stringEndArchive64Locator:
return endrec
if diskno != 0 or disks != 1:
@@ -188,8 +160,8 @@ def _EndRecData64(fpin, offset, endrec):
data = fpin.read(sizeEndCentDir64)
sig, sz, create_version, read_version, disk_num, disk_dir, \
dircount, dircount2, dirsize, diroffset = \
- struct.unpack(structEndCentDir64, data)
- if sig != magicEndCentDir64:
+ struct.unpack(structEndArchive64, data)
+ if sig != stringEndArchive64:
return endrec
# Update the original endrec using data from the ZIP64 record
@@ -217,9 +189,9 @@ def _EndRecData(fpin):
# file if this is the case).
fpin.seek(-sizeEndCentDir, 2)
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
- endrec = struct.unpack(structEndCentDir, data)
+ endrec = struct.unpack(structEndArchive, data)
endrec=list(endrec)
# Append a blank comment and record start offset
@@ -241,11 +213,11 @@ def _EndRecData(fpin):
maxCommentStart = max(filesize - (1 << 16) - sizeEndCentDir, 0)
fpin.seek(maxCommentStart, 0)
data = fpin.read()
- start = data.rfind(magicEndCentDir)
+ start = data.rfind(stringEndArchive)
if start >= 0:
# found the magic number; attempt to unpack and interpret
recData = data[start:start+sizeEndCentDir]
- endrec = list(struct.unpack(structEndCentDir, recData))
+ endrec = list(struct.unpack(structEndArchive, recData))
comment = data[start+sizeEndCentDir:]
# check that comment length is correct
if endrec[_ECD_COMMENT_SIZE] == len(comment):
@@ -352,7 +324,7 @@ class ZipInfo (object):
self.create_version = max(45, self.extract_version)
filename, flag_bits = self._encodeFilenameFlags()
- header = struct.pack(structFileHeader, magicFileHeader,
+ header = struct.pack(structFileHeader, stringFileHeader,
self.extract_version, self.reserved, flag_bits,
self.compress_type, dostime, dosdate, CRC,
compress_size, file_size,
@@ -777,7 +749,7 @@ class ZipFile:
total = 0
while total < size_cd:
centdir = fp.read(sizeCentralDir)
- if centdir[0:4] != magicCentralDir:
+ if centdir[0:4] != stringCentralDir:
raise BadZipfile("Bad magic number for central directory")
centdir = struct.unpack(structCentralDir, centdir)
if self.debug > 2:
@@ -892,7 +864,7 @@ class ZipFile:
# Skip the file header:
fheader = zef_file.read(sizeFileHeader)
- if fheader[0:4] != magicFileHeader:
+ if fheader[0:4] != stringFileHeader:
raise BadZipfile("Bad magic number for file header")
fheader = struct.unpack(structFileHeader, fheader)
@@ -1184,7 +1156,7 @@ class ZipFile:
try:
filename, flag_bits = zinfo._encodeFilenameFlags()
centdir = struct.pack(structCentralDir,
- magicCentralDir, create_version,
+ stringCentralDir, create_version,
zinfo.create_system, extract_version, zinfo.reserved,
flag_bits, zinfo.compress_type, dostime, dosdate,
zinfo.CRC, compress_size, file_size,
@@ -1212,13 +1184,13 @@ class ZipFile:
if pos1 > ZIP64_LIMIT:
# Need to write the ZIP64 end-of-archive records
zip64endrec = struct.pack(
- structEndCentDir64, magicEndCentDir64,
+ structEndArchive64, stringEndArchive64,
44, 45, 45, 0, 0, count, count, pos2 - pos1, pos1)
self.fp.write(zip64endrec)
zip64locrec = struct.pack(
- structEndCentDir64Locator,
- magicEndCentDir64Locator, 0, pos2, 1)
+ structEndArchive64Locator,
+ stringEndArchive64Locator, 0, pos2, 1)
self.fp.write(zip64locrec)
centDirOffset = 0xFFFFFFFF
@@ -1229,7 +1201,7 @@ class ZipFile:
% 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,
count % ZIP_FILECOUNT_LIMIT, pos2 - pos1,
centDirOffset, len(self.comment))
diff --git a/Misc/ACKS b/Misc/ACKS
index 7ce335e..0a411e7 100644
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -460,6 +460,7 @@ Luke Mewburn
Mike Meyer
Steven Miale
Trent Mick
+Aristotelis Mikropoulos
Damien Miller
Chad Miller
Jay T. Miller
diff --git a/Modules/_bisectmodule.c b/Modules/_bisectmodule.c
index 1280b04..bf47feb 100644
--- a/Modules/_bisectmodule.c
+++ b/Modules/_bisectmodule.c
@@ -11,6 +11,10 @@ internal_bisect_right(PyObject *list, PyObject *item, Py_ssize_t lo, Py_ssize_t
PyObject *litem;
Py_ssize_t mid, res;
+ if (lo < 0) {
+ PyErr_SetString(PyExc_ValueError, "lo must be non-negative");
+ return -1;
+ }
if (hi == -1) {
hi = PySequence_Size(list);
if (hi < 0)
@@ -108,6 +112,10 @@ internal_bisect_left(PyObject *list, PyObject *item, int lo, int hi)
PyObject *litem;
int mid, res;
+ if (lo < 0) {
+ PyErr_SetString(PyExc_ValueError, "lo must be non-negative");
+ return -1;
+ }
if (hi == -1) {
hi = PySequence_Size(list);
if (hi < 0)
diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c
index 8b505c8..51bcd79f 100644
--- a/Modules/gcmodule.c
+++ b/Modules/gcmodule.c
@@ -706,6 +706,7 @@ clear_freelists(void)
(void)PyCFunction_ClearFreeList();
(void)PyTuple_ClearFreeList();
(void)PyUnicode_ClearFreeList();
+ (void)PyFloat_ClearFreeList();
}
/* This is the main function. Read this to understand how the
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
index 8282134..a6a19c1 100644
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -3638,7 +3638,8 @@ posix_fork1(PyObject *self, PyObject *noargs)
pid_t pid = fork1();
if (pid == -1)
return posix_error();
- PyOS_AfterFork();
+ if (pid == 0)
+ PyOS_AfterFork();
return PyLong_FromLong(pid);
}
#endif
diff --git a/Objects/floatobject.c b/Objects/floatobject.c
index f18e7dd..daf7ee8 100644
--- a/Objects/floatobject.c
+++ b/Objects/floatobject.c
@@ -225,6 +225,9 @@ PyFloat_FromString(PyObject *v)
if (PyOS_strnicmp(p, "inf", 4) == 0) {
Py_RETURN_INF(sign);
}
+ if (PyOS_strnicmp(p, "infinity", 9) == 0) {
+ Py_RETURN_INF(sign);
+ }
#ifdef Py_NAN
if(PyOS_strnicmp(p, "nan", 4) == 0) {
Py_RETURN_NAN;
@@ -1903,30 +1906,28 @@ _PyFloat_Init(void)
PyStructSequence_InitType(&FloatInfoType, &floatinfo_desc);
}
-void
-PyFloat_CompactFreeList(size_t *pbc, size_t *pbf, size_t *bsum)
+int
+PyFloat_ClearFreeList(void)
{
PyFloatObject *p;
PyFloatBlock *list, *next;
- unsigned i;
- size_t bc = 0, bf = 0; /* block count, number of freed blocks */
- size_t fsum = 0; /* total unfreed ints */
- int frem; /* remaining unfreed ints per block */
+ int i;
+ int u; /* remaining unfreed ints per block */
+ int freelist_size = 0;
list = block_list;
block_list = NULL;
free_list = NULL;
while (list != NULL) {
- bc++;
- frem = 0;
+ u = 0;
for (i = 0, p = &list->objects[0];
i < N_FLOATOBJECTS;
i++, p++) {
if (PyFloat_CheckExact(p) && Py_REFCNT(p) != 0)
- frem++;
+ u++;
}
next = list->next;
- if (frem) {
+ if (u) {
list->next = block_list;
block_list = list;
for (i = 0, p = &list->objects[0];
@@ -1941,15 +1942,12 @@ PyFloat_CompactFreeList(size_t *pbc, size_t *pbf, size_t *bsum)
}
}
else {
- PyMem_FREE(list); /* XXX PyObject_FREE ??? */
- bf++;
+ PyMem_FREE(list);
}
- fsum += frem;
+ freelist_size += u;
list = next;
}
- *pbc = bc;
- *pbf = bf;
- *bsum = fsum;
+ return freelist_size;
}
void
@@ -1957,25 +1955,21 @@ PyFloat_Fini(void)
{
PyFloatObject *p;
PyFloatBlock *list;
- unsigned i;
- size_t bc, bf; /* block count, number of freed blocks */
- size_t fsum; /* total unfreed floats per block */
+ int i;
+ int u; /* total unfreed floats per block */
- PyFloat_CompactFreeList(&bc, &bf, &fsum);
+ u = PyFloat_ClearFreeList();
if (!Py_VerboseFlag)
return;
fprintf(stderr, "# cleanup floats");
- if (!fsum) {
+ if (!u) {
fprintf(stderr, "\n");
}
else {
fprintf(stderr,
- ": %" PY_FORMAT_SIZE_T "d unfreed float%s in %"
- PY_FORMAT_SIZE_T "d out of %"
- PY_FORMAT_SIZE_T "d block%s\n",
- fsum, fsum == 1 ? "" : "s",
- bc - bf, bc, bc == 1 ? "" : "s");
+ ": %d unfreed float%s\n",
+ u, u == 1 ? "" : "s");
}
if (Py_VerboseFlag > 1) {
list = block_list;
diff --git a/Python/_warnings.c b/Python/_warnings.c
index e9384ca..cb81b07 100644
--- a/Python/_warnings.c
+++ b/Python/_warnings.c
@@ -266,7 +266,8 @@ show_warning(PyObject *filename, int lineno, PyObject *text, PyObject
PyFile_WriteString("\n", f_stderr);
}
else
- Py_DisplaySourceLine(f_stderr, PyUnicode_AsString(filename), lineno, 2);
+ _Py_DisplaySourceLine(f_stderr, PyUnicode_AsString(filename),
+ lineno, 2);
PyErr_Clear();
}
diff --git a/Python/import.c b/Python/import.c
index 14cda6e..7ad3bf9 100644
--- a/Python/import.c
+++ b/Python/import.c
@@ -2162,6 +2162,7 @@ get_parent(PyObject *globals, char *buf, Py_ssize_t *p_buflen, int level)
static PyObject *pathstr = NULL;
static PyObject *pkgstr = NULL;
PyObject *pkgname, *modname, *modpath, *modules, *parent;
+ int orig_level = level;
if (globals == NULL || !PyDict_Check(globals) || !level)
return Py_None;
@@ -2292,9 +2293,27 @@ get_parent(PyObject *globals, char *buf, Py_ssize_t *p_buflen, int level)
modules = PyImport_GetModuleDict();
parent = PyDict_GetItemString(modules, buf);
- if (parent == NULL)
- PyErr_Format(PyExc_SystemError,
- "Parent module '%.200s' not loaded", buf);
+ if (parent == NULL) {
+ if (orig_level < 1) {
+ 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;
/* We expect, but can't guarantee, if parent != None, that:
- parent.__name__ == buf
diff --git a/Python/sysmodule.c b/Python/sysmodule.c
index 4017ac2..f4118d6 100644
--- a/Python/sysmodule.c
+++ b/Python/sysmodule.c
@@ -824,29 +824,12 @@ PyDoc_STRVAR(sys_clear_type_cache__doc__,
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[] = {
/* Might as well keep this in alphabetic order */
{"callstats", (PyCFunction)PyEval_GetCallStats, METH_NOARGS,
callstats_doc},
{"_clear_type_cache", sys_clear_type_cache, METH_NOARGS,
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_doc},
{"displayhook", sys_displayhook, METH_O, displayhook_doc},
diff --git a/Python/traceback.c b/Python/traceback.c
index 55300fc..d569a18 100644
--- a/Python/traceback.c
+++ b/Python/traceback.c
@@ -129,7 +129,7 @@ PyTraceBack_Here(PyFrameObject *frame)
}
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;
FILE *xfp = NULL;
@@ -241,7 +241,7 @@ tb_displayline(PyObject *f, const char *filename, int lineno, const char *name)
err = PyFile_WriteString(linebuf, f);
if (err != 0)
return err;
- return Py_DisplaySourceLine(f, filename, lineno, 4);
+ return _Py_DisplaySourceLine(f, filename, lineno, 4);
}
static int
diff --git a/Tools/faqwiz/move-faqwiz.sh b/Tools/faqwiz/move-faqwiz.sh
index 6a708aa..b3bcc92 100755
--- a/Tools/faqwiz/move-faqwiz.sh
+++ b/Tools/faqwiz/move-faqwiz.sh
@@ -9,7 +9,7 @@
# blackjesus:~> ./move-faqwiz.sh 2\.1 3\.2
# 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."
exit 2
fi
@@ -19,7 +19,7 @@ if [ ! -d data -o ! -d data/RCS ]; then
exit 2
fi
-function cut_n_pad() {
+cut_n_pad() {
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 }"`
}
@@ -28,7 +28,13 @@ cut_n_pad $1 1 prefix1
cut_n_pad $1 2 suffix1
cut_n_pad $2 1 prefix2
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
file2=faq$prefix2.$suffix2.htp