Merged revisions 65910,65977,65980,65984,65986,66000,66011-66012,66014,66017,66020 via svnmerge from

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

........
  r65910 | benjamin.peterson | 2008-08-20 09:07:59 -0500 (Wed, 20 Aug 2008) | 1 line

  fix up the multiprocessing docs a little
........
  r65977 | christian.heimes | 2008-08-22 14:47:25 -0500 (Fri, 22 Aug 2008) | 3 lines

  Silenced compiler warning
  Objects/stringlib/find.h:97: warning: 'stringlib_contains_obj' defined but not used
  Reviewed by Benjamin Peterson
........
  r65980 | christian.heimes | 2008-08-22 15:10:27 -0500 (Fri, 22 Aug 2008) | 3 lines

  Fixed two format strings in the _collections module. For example
  Modules/_collectionsmodule.c:674: warning: format '%i' expects type 'int', but argument 2 has type 'Py_ssize_t'
  Reviewed by Benjamin Peterson
........
  r65984 | christian.heimes | 2008-08-22 16:23:47 -0500 (Fri, 22 Aug 2008) | 1 line

  d is the correct format string
........
  r65986 | mark.hammond | 2008-08-22 19:59:14 -0500 (Fri, 22 Aug 2008) | 2 lines

  Fix bug 3625: test issues on 64bit windows. r=pitrou
........
  r66000 | benjamin.peterson | 2008-08-23 15:27:43 -0500 (Sat, 23 Aug 2008) | 5 lines

  #3643 add a few more checks to _testcapi to prevent segfaults

  Author: Victor Stinner
  Reviewer: Benjamin Peterson
........
  r66011 | neal.norwitz | 2008-08-24 12:27:43 -0500 (Sun, 24 Aug 2008) | 1 line

  Ignore a couple more tests that report leaks inconsistently.
........
  r66012 | neal.norwitz | 2008-08-24 12:29:53 -0500 (Sun, 24 Aug 2008) | 1 line

  Use the actual blacklist of leaky tests
........
  r66014 | georg.brandl | 2008-08-24 13:11:07 -0500 (Sun, 24 Aug 2008) | 2 lines

  #3654: fix duplicate test method name. Review by Benjamin P.
........
  r66017 | benjamin.peterson | 2008-08-24 16:55:03 -0500 (Sun, 24 Aug 2008) | 1 line

  remove note about unimplemented feature
........
  r66020 | brett.cannon | 2008-08-24 18:15:19 -0500 (Sun, 24 Aug 2008) | 1 line

  Clarify that some attributes/methods are listed somewhat separately because they are not part of the threading API.
........
This commit is contained in:
Benjamin Peterson 2008-08-25 21:05:21 +00:00
parent 2532967122
commit a786b026c9
9 changed files with 66 additions and 52 deletions

View File

@ -8,11 +8,7 @@ Python is a mature programming language which has established a reputation for
stability. In order to maintain this reputation, the developers would like to stability. In order to maintain this reputation, the developers would like to
know of any deficiencies you find in Python. know of any deficiencies you find in Python.
If you find errors in the documentation, please use either the "Add a comment" Bug reports should be submitted via the Python Bug Tracker
or the "Suggest a change" features of the relevant page in the most recent
online documentation at http://docs.python.org/.
All other bug reports should be submitted via the Python Bug Tracker
(http://bugs.python.org/). The bug tracker offers a Web form which allows (http://bugs.python.org/). The bug tracker offers a Web form which allows
pertinent information to be entered and submitted to the developers. pertinent information to be entered and submitted to the developers.

View File

@ -248,7 +248,7 @@ The :mod:`multiprocessing` package mostly replicates the API of the
The constructor should always be called with keyword arguments. *group* The constructor should always be called with keyword arguments. *group*
should always be ``None``; it exists solely for compatibility with should always be ``None``; it exists solely for compatibility with
:class:`~threading.Thread`. *target* is the callable object to be invoked by :class:`threading.Thread`. *target* is the callable object to be invoked by
the :meth:`run()` method. It defaults to ``None``, meaning nothing is the :meth:`run()` method. It defaults to ``None``, meaning nothing is
called. *name* is the process name. By default, a unique name is constructed called. *name* is the process name. By default, a unique name is constructed
of the form 'Process-N\ :sub:`1`:N\ :sub:`2`:...:N\ :sub:`k`' where N\ of the form 'Process-N\ :sub:`1`:N\ :sub:`2`:...:N\ :sub:`k`' where N\
@ -290,13 +290,9 @@ The :mod:`multiprocessing` package mostly replicates the API of the
A process cannot join itself because this would cause a deadlock. It is A process cannot join itself because this would cause a deadlock. It is
an error to attempt to join a process before it has been started. an error to attempt to join a process before it has been started.
.. attribute:: Process.name .. attribute:: name
Return the process's name. The process's name.
.. attribute:: Process.name = name
Set the process's name.
The name is a string used for identification purposes only. It has no The name is a string used for identification purposes only. It has no
semantics. Multiple processes may be given the same name. The initial semantics. Multiple processes may be given the same name. The initial
@ -309,14 +305,10 @@ The :mod:`multiprocessing` package mostly replicates the API of the
Roughly, a process object is alive from the moment the :meth:`start` Roughly, a process object is alive from the moment the :meth:`start`
method returns until the child process terminates. method returns until the child process terminates.
.. attribute:: Process.daemon .. attribute:: daemon
Return the process's daemon flag., this is a boolean. The process's daemon flag, a Boolean value. This must be called before
:meth:`start` is called.
.. attribute:: Process.daemon = daemonic
Set the process's daemon flag to the Boolean value *daemonic*. This must
be called before :meth:`start` is called.
The initial value is inherited from the creating process. The initial value is inherited from the creating process.
@ -327,36 +319,33 @@ The :mod:`multiprocessing` package mostly replicates the API of the
Otherwise a daemonic process would leave its children orphaned if it gets Otherwise a daemonic process would leave its children orphaned if it gets
terminated when its parent process exits. terminated when its parent process exits.
In addition process objects also support the following methods: In addition to the :class:`Threading.Thread` API, :class:`Process` objects
also support the following attributes and methods:
.. attribute:: Process.pid .. attribute:: pid
Return the process ID. Before the process is spawned, this will be Return the process ID. Before the process is spawned, this will be
``None``. ``None``.
.. attribute:: Process.exitcode .. attribute:: exitcode
Return the child's exit code. This will be ``None`` if the process has The child's exit code. This will be ``None`` if the process has not yet
not yet terminated. A negative value *-N* indicates that the child was terminated. A negative value *-N* indicates that the child was terminated
terminated by signal *N*. by signal *N*.
.. attribute:: Process.authkey .. attribute:: authkey
Return the process's authentication key (a byte string). The process's authentication key (a byte string).
When :mod:`multiprocessing` is initialized the main process is assigned a When :mod:`multiprocessing` is initialized the main process is assigned a
random string using :func:`os.random`. random string using :func:`os.random`.
When a :class:`Process` object is created, it will inherit the When a :class:`Process` object is created, it will inherit the
authentication key of its parent process, although this may be changed authentication key of its parent process, although this may be changed by
using :attr:`Process.authkey` below. setting :attr:`authkey` to another byte string.
See :ref:`multiprocessing-auth-keys`. See :ref:`multiprocessing-auth-keys`.
.. attribute:: Process.authkey = authkey
Set the process's authentication key which must be a byte string.
.. method:: terminate() .. method:: terminate()
Terminate the process. On Unix this is done using the ``SIGTERM`` signal; Terminate the process. On Unix this is done using the ``SIGTERM`` signal;
@ -375,8 +364,8 @@ The :mod:`multiprocessing` package mostly replicates the API of the
cause other processes to deadlock. cause other processes to deadlock.
Note that the :meth:`start`, :meth:`join`, :meth:`is_alive` and Note that the :meth:`start`, :meth:`join`, :meth:`is_alive` and
:meth:`get_exit_code` methods should only be called by the process that :attr:`exit_code` methods should only be called by the process that created
created the process object. the process object.
Example usage of some of the methods of :class:`Process`:: Example usage of some of the methods of :class:`Process`::
@ -390,7 +379,7 @@ The :mod:`multiprocessing` package mostly replicates the API of the
>>> p.terminate() >>> p.terminate()
>>> print p, p.is_alive() >>> print p, p.is_alive()
<Process(Process-1, stopped[SIGTERM])> False <Process(Process-1, stopped[SIGTERM])> False
>>> p.get_exit_code() == -signal.SIGTERM >>> p.exitcode == -signal.SIGTERM
True True
@ -1075,7 +1064,7 @@ their parent process exits. The manager classes are defined in the
*authkey* is the authentication key which will be used to check the validity *authkey* is the authentication key which will be used to check the validity
of incoming connections to the server process. If *authkey* is ``None`` then of incoming connections to the server process. If *authkey* is ``None`` then
``current_process().get_auth_key()``. Otherwise *authkey* is used and it ``current_process().authkey``. Otherwise *authkey* is used and it
must be a string. must be a string.
.. method:: start() .. method:: start()
@ -1599,7 +1588,7 @@ authentication* using the :mod:`hmac` module.
If *authentication* is ``True`` or *authkey* is a string then digest If *authentication* is ``True`` or *authkey* is a string then digest
authentication is used. The key used for authentication will be either authentication is used. The key used for authentication will be either
*authkey* or ``current_process().get_auth_key()`` if *authkey* is ``None``. *authkey* or ``current_process().authkey)`` if *authkey* is ``None``.
If authentication fails then :exc:`AuthenticationError` is raised. See If authentication fails then :exc:`AuthenticationError` is raised. See
:ref:`multiprocessing-auth-keys`. :ref:`multiprocessing-auth-keys`.
@ -1632,7 +1621,7 @@ authentication* using the :mod:`hmac` module.
otherwise it must be *None*. otherwise it must be *None*.
If *authkey* is ``None`` and *authenticate* is ``True`` then If *authkey* is ``None`` and *authenticate* is ``True`` then
``current_process().get_auth_key()`` is used as the authentication key. If ``current_process().authkey`` is used as the authentication key. If
*authkey* is ``None`` and *authentication* is ``False`` then no *authkey* is ``None`` and *authentication* is ``False`` then no
authentication is done. If authentication fails then authentication is done. If authentication fails then
:exc:`AuthenticationError` is raised. See :ref:`multiprocessing-auth-keys`. :exc:`AuthenticationError` is raised. See :ref:`multiprocessing-auth-keys`.
@ -1748,7 +1737,7 @@ authentication key. (Demonstrating that both ends are using the same key does
**not** involve sending the key over the connection.) **not** involve sending the key over the connection.)
If authentication is requested but do authentication key is specified then the If authentication is requested but do authentication key is specified then the
return value of ``current_process().get_auth_key`` is used (see return value of ``current_process().authkey`` is used (see
:class:`~multiprocessing.Process`). This value will automatically inherited by :class:`~multiprocessing.Process`). This value will automatically inherited by
any :class:`~multiprocessing.Process` object that the current process creates. any :class:`~multiprocessing.Process` object that the current process creates.
This means that (by default) all processes of a multi-process program will share This means that (by default) all processes of a multi-process program will share

View File

@ -15,6 +15,23 @@ class ListTest(list_tests.CommonTest):
self.assertEqual(list(''), []) self.assertEqual(list(''), [])
self.assertEqual(list('spam'), ['s', 'p', 'a', 'm']) self.assertEqual(list('spam'), ['s', 'p', 'a', 'm'])
if sys.maxsize == 0x7fffffff:
# This test can currently only work on 32-bit machines.
# XXX If/when PySequence_Length() returns a ssize_t, it should be
# XXX re-enabled.
# Verify clearing of bug #556025.
# This assumes that the max data size (sys.maxint) == max
# address size this also assumes that the address size is at
# least 4 bytes with 8 byte addresses, the bug is not well
# tested
#
# Note: This test is expected to SEGV under Cygwin 1.3.12 or
# earlier due to a newlib bug. See the following mailing list
# thread for the details:
# http://sources.redhat.com/ml/newlib/2002/msg00369.html
self.assertRaises(MemoryError, list, range(sys.maxsize // 2))
# This code used to segfault in Py2.4a3 # This code used to segfault in Py2.4a3
x = [] x = []
x.extend(-y for y in x) x.extend(-y for y in x)

View File

@ -352,10 +352,6 @@ class ReTests(unittest.TestCase):
self.assertEqual(re.search(r"\d\D\w\W\s\S", self.assertEqual(re.search(r"\d\D\w\W\s\S",
"1aa! a", re.UNICODE).group(0), "1aa! a") "1aa! a", re.UNICODE).group(0), "1aa! a")
def test_ignore_case(self):
self.assertEqual(re.match("abc", "ABC", re.I).group(0), "ABC")
self.assertEqual(re.match("abc", "ABC", re.I).group(0), "ABC")
def test_bigcharset(self): def test_bigcharset(self):
self.assertEqual(re.match("([\u2222\u2223])", self.assertEqual(re.match("([\u2222\u2223])",
"\u2222").group(1), "\u2222") "\u2222").group(1), "\u2222")
@ -383,6 +379,8 @@ class ReTests(unittest.TestCase):
self.assertEqual(re.match(r"(a)(?!\s(abc|a))", "a b").group(1), "a") self.assertEqual(re.match(r"(a)(?!\s(abc|a))", "a b").group(1), "a")
def test_ignore_case(self): def test_ignore_case(self):
self.assertEqual(re.match("abc", "ABC", re.I).group(0), "ABC")
self.assertEqual(re.match("abc", "ABC", re.I).group(0), "ABC")
self.assertEqual(re.match(r"(a\s[^a])", "a b", re.I).group(1), "a b") self.assertEqual(re.match(r"(a\s[^a])", "a b", re.I).group(1), "a b")
self.assertEqual(re.match(r"(a\s[^a]*)", "a bb", re.I).group(1), "a bb") self.assertEqual(re.match(r"(a\s[^a]*)", "a bb", re.I).group(1), "a bb")
self.assertEqual(re.match(r"(a\s[abc])", "a b", re.I).group(1), "a b") self.assertEqual(re.match(r"(a\s[abc])", "a b", re.I).group(1), "a b")

View File

@ -67,7 +67,7 @@ REFLOG="build/reflog.txt.out"
# Note: test_XXX (none currently) really leak, but are disabled # Note: test_XXX (none currently) really leak, but are disabled
# so we don't send spam. Any test which really leaks should only # so we don't send spam. Any test which really leaks should only
# be listed here if there are also test cases under Lib/test/leakers. # be listed here if there are also test cases under Lib/test/leakers.
LEAKY_TESTS="test_(asynchat|cmd_line|popen2|socket|smtplib|sys|threadsignals|urllib2_localnet|httpservers)" LEAKY_TESTS="test_(asynchat|cmd_line|docxmlrpc|dumbdbm|file|ftplib|httpservers|imaplib|popen2|socket|smtplib|sys|telnetlib|threadedtempfile|threading|threadsignals|urllib2_localnet|xmlrpc)"
# These tests always fail, so skip them so we don't get false positives. # These tests always fail, so skip them so we don't get false positives.
_ALWAYS_SKIP="" _ALWAYS_SKIP=""

View File

@ -670,8 +670,9 @@ deque_repr(PyObject *deque)
return NULL; return NULL;
} }
if (((dequeobject *)deque)->maxlen != -1) if (((dequeobject *)deque)->maxlen != -1)
result = PyUnicode_FromFormat("deque(%R, maxlen=%i)", aslist,
((dequeobject *)deque)->maxlen); result = PyUnicode_FromFormat("deque(%R, maxlen=%" PY_FORMAT_SIZE_T "d)",
aslist, ((dequeobject *)deque)->maxlen);
else else
result = PyUnicode_FromFormat("deque(%R)", aslist); result = PyUnicode_FromFormat("deque(%R)", aslist);
Py_DECREF(aslist); Py_DECREF(aslist);

View File

@ -714,14 +714,17 @@ raise_exception(PyObject *self, PyObject *args)
*/ */
static PyThread_type_lock thread_done = NULL; static PyThread_type_lock thread_done = NULL;
static void static int
_make_call(void *callable) _make_call(void *callable)
{ {
PyObject *rc; PyObject *rc;
int success;
PyGILState_STATE s = PyGILState_Ensure(); PyGILState_STATE s = PyGILState_Ensure();
rc = PyObject_CallFunction((PyObject *)callable, ""); rc = PyObject_CallFunction((PyObject *)callable, "");
success = (rc != NULL);
Py_XDECREF(rc); Py_XDECREF(rc);
PyGILState_Release(s); PyGILState_Release(s);
return success;
} }
/* Same thing, but releases `thread_done` when it returns. This variant /* Same thing, but releases `thread_done` when it returns. This variant
@ -738,10 +741,17 @@ static PyObject *
test_thread_state(PyObject *self, PyObject *args) test_thread_state(PyObject *self, PyObject *args)
{ {
PyObject *fn; PyObject *fn;
int success = 1;
if (!PyArg_ParseTuple(args, "O:test_thread_state", &fn)) if (!PyArg_ParseTuple(args, "O:test_thread_state", &fn))
return NULL; return NULL;
if (!PyCallable_Check(fn)) {
PyErr_Format(PyExc_TypeError, "'%s' object is not callable",
fn->ob_type->tp_name);
return NULL;
}
/* Ensure Python is set up for threading */ /* Ensure Python is set up for threading */
PyEval_InitThreads(); PyEval_InitThreads();
thread_done = PyThread_allocate_lock(); thread_done = PyThread_allocate_lock();
@ -752,10 +762,10 @@ test_thread_state(PyObject *self, PyObject *args)
/* Start a new thread with our callback. */ /* Start a new thread with our callback. */
PyThread_start_new_thread(_make_call_from_thread, fn); PyThread_start_new_thread(_make_call_from_thread, fn);
/* Make the callback with the thread lock held by this thread */ /* Make the callback with the thread lock held by this thread */
_make_call(fn); success &= _make_call(fn);
/* Do it all again, but this time with the thread-lock released */ /* Do it all again, but this time with the thread-lock released */
Py_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS
_make_call(fn); success &= _make_call(fn);
PyThread_acquire_lock(thread_done, 1); /* wait for thread to finish */ PyThread_acquire_lock(thread_done, 1); /* wait for thread to finish */
Py_END_ALLOW_THREADS Py_END_ALLOW_THREADS
@ -765,7 +775,7 @@ test_thread_state(PyObject *self, PyObject *args)
*/ */
Py_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS
PyThread_start_new_thread(_make_call_from_thread, fn); PyThread_start_new_thread(_make_call_from_thread, fn);
_make_call(fn); success &= _make_call(fn);
PyThread_acquire_lock(thread_done, 1); /* wait for thread to finish */ PyThread_acquire_lock(thread_done, 1); /* wait for thread to finish */
Py_END_ALLOW_THREADS Py_END_ALLOW_THREADS
@ -773,6 +783,8 @@ test_thread_state(PyObject *self, PyObject *args)
PyThread_release_lock(thread_done); PyThread_release_lock(thread_done);
PyThread_free_lock(thread_done); PyThread_free_lock(thread_done);
if (!success)
return NULL;
Py_RETURN_NONE; Py_RETURN_NONE;
} }
#endif #endif

View File

@ -1026,6 +1026,7 @@ bytes_dealloc(PyByteArrayObject *self)
#define STRINGLIB_EMPTY nullbytes #define STRINGLIB_EMPTY nullbytes
#define STRINGLIB_CHECK_EXACT PyByteArray_CheckExact #define STRINGLIB_CHECK_EXACT PyByteArray_CheckExact
#define STRINGLIB_MUTABLE 1 #define STRINGLIB_MUTABLE 1
#define FROM_BYTEARRAY 1
#include "stringlib/fastsearch.h" #include "stringlib/fastsearch.h"
#include "stringlib/count.h" #include "stringlib/count.h"

View File

@ -90,7 +90,7 @@ stringlib_rfind_slice(const STRINGLIB_CHAR* str, Py_ssize_t str_len,
return stringlib_rfind(str + start, end - start, sub, sub_len, start); return stringlib_rfind(str + start, end - start, sub, sub_len, start);
} }
#ifdef STRINGLIB_WANT_CONTAINS_OBJ #ifdef STRINGLIB_WANT_CONTAINS_OBJ && !defined(FROM_BYTEARRAY)
Py_LOCAL_INLINE(int) Py_LOCAL_INLINE(int)
stringlib_contains_obj(PyObject* str, PyObject* sub) stringlib_contains_obj(PyObject* str, PyObject* sub)