diff -r e34b09c69dd3 -r f1bd5468dae6 .hgignore --- a/.hgignore Sat Mar 12 22:31:06 2011 -0500 +++ b/.hgignore Wed Mar 16 19:19:36 2011 -0400 @@ -50,6 +50,7 @@ *~ Lib/lib2to3/*.pickle Lib/test/data/* +Misc/*.wpu PC/python_nt*.h PC/pythonnt_rc*.h PC/*.obj diff -r e34b09c69dd3 -r f1bd5468dae6 Doc/ACKS.txt --- a/Doc/ACKS.txt Sat Mar 12 22:31:06 2011 -0500 +++ b/Doc/ACKS.txt Wed Mar 16 19:19:36 2011 -0400 @@ -120,6 +120,7 @@ * Robert Lehmann * Marc-André Lemburg * Ross Light + * Gediminas Liktaras * Ulf A. Lindgren * Everett Lipman * Mirko Liss diff -r e34b09c69dd3 -r f1bd5468dae6 Doc/c-api/buffer.rst --- a/Doc/c-api/buffer.rst Sat Mar 12 22:31:06 2011 -0500 +++ b/Doc/c-api/buffer.rst Wed Mar 16 19:19:36 2011 -0400 @@ -304,20 +304,6 @@ :c:data:`~Py_buffer.format`. -.. c:function:: int PyObject_CopyToObject(PyObject *obj, void *buf, Py_ssize_t len, char fortran) - - Copy *len* bytes of data pointed to by the contiguous chunk of memory - pointed to by *buf* into the buffer exported by obj. The buffer must of - course be writable. Return 0 on success and return -1 and raise an error - on failure. If the object does not have a writable buffer, then an error - is raised. If *fortran* is ``'F'``, then if the object is - multi-dimensional, then the data will be copied into the array in - Fortran-style (first dimension varies the fastest). If *fortran* is - ``'C'``, then the data will be copied into the array in C-style (last - dimension varies the fastest). If *fortran* is ``'A'``, then it does not - matter and the copy will be made in whatever way is more efficient. - - .. c:function:: int PyBuffer_IsContiguous(Py_buffer *view, char fortran) Return 1 if the memory defined by the *view* is C-style (*fortran* is diff -r e34b09c69dd3 -r f1bd5468dae6 Doc/c-api/init.rst --- a/Doc/c-api/init.rst Sat Mar 12 22:31:06 2011 -0500 +++ b/Doc/c-api/init.rst Wed Mar 16 19:19:36 2011 -0400 @@ -29,8 +29,7 @@ Initialize the Python interpreter. In an application embedding Python, this should be called before using any other Python/C API functions; with the - exception of :c:func:`Py_SetProgramName`, :c:func:`Py_SetPath`, - and :c:func:`PyEval_InitThreads`. This initializes + exception of :c:func:`Py_SetProgramName` and :c:func:`Py_SetPath`. This initializes the table of loaded modules (``sys.modules``), and creates the fundamental modules :mod:`builtins`, :mod:`__main__` and :mod:`sys`. It also initializes the module search path (``sys.path``). It does not set ``sys.argv``; use @@ -538,10 +537,10 @@ operations such as ``PyEval_ReleaseThread(tstate)``. It is not needed before calling :c:func:`PyEval_SaveThread` or :c:func:`PyEval_RestoreThread`. - .. index:: single: Py_Initialize() + This is a no-op when called for a second time. - This is a no-op when called for a second time. It is safe to call this function - before calling :c:func:`Py_Initialize`. + .. versionchanged:: 3.2 + This function cannot be called before :c:func:`Py_Initialize()` anymore. .. index:: module: _thread diff -r e34b09c69dd3 -r f1bd5468dae6 Doc/includes/sqlite3/shared_cache.py --- a/Doc/includes/sqlite3/shared_cache.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Doc/includes/sqlite3/shared_cache.py Wed Mar 16 19:19:36 2011 -0400 @@ -1,6 +1,6 @@ import sqlite3 # The shared cache is only available in SQLite versions 3.3.3 or later -# See the SQLite documentaton for details. +# See the SQLite documentation for details. sqlite3.enable_shared_cache(True) diff -r e34b09c69dd3 -r f1bd5468dae6 Doc/library/collections.rst --- a/Doc/library/collections.rst Sat Mar 12 22:31:06 2011 -0500 +++ b/Doc/library/collections.rst Wed Mar 16 19:19:36 2011 -0400 @@ -706,7 +706,7 @@ :options: +NORMALIZE_WHITESPACE >>> # Basic example - >>> Point = namedtuple('Point', 'x y') + >>> Point = namedtuple('Point', ['x', 'y']) >>> p = Point(x=10, y=11) >>> # Example using the verbose option to print the class definition @@ -851,15 +851,15 @@ a fixed-width print format: >>> class Point(namedtuple('Point', 'x y')): - ... __slots__ = () - ... @property - ... def hypot(self): - ... return (self.x ** 2 + self.y ** 2) ** 0.5 - ... def __str__(self): - ... return 'Point: x=%6.3f y=%6.3f hypot=%6.3f' % (self.x, self.y, self.hypot) + __slots__ = () + @property + def hypot(self): + return (self.x ** 2 + self.y ** 2) ** 0.5 + def __str__(self): + return 'Point: x=%6.3f y=%6.3f hypot=%6.3f' % (self.x, self.y, self.hypot) >>> for p in Point(3, 4), Point(14, 5/7): - ... print(p) + print(p) Point: x= 3.000 y= 4.000 hypot= 5.000 Point: x=14.000 y= 0.714 hypot=14.018 @@ -886,7 +886,7 @@ >>> Status.open, Status.pending, Status.closed (0, 1, 2) >>> class Status: - ... open, pending, closed = range(3) + open, pending, closed = range(3) .. seealso:: diff -r e34b09c69dd3 -r f1bd5468dae6 Doc/library/email.message.rst --- a/Doc/library/email.message.rst Sat Mar 12 22:31:06 2011 -0500 +++ b/Doc/library/email.message.rst Wed Mar 16 19:19:36 2011 -0400 @@ -46,15 +46,16 @@ be generated or modified). Note that this method is provided as a convenience and may not always - format the message the way you want. For example, by default it mangles - lines that begin with ``From``. For more flexibility, instantiate a + format the message the way you want. For example, by default it does + not do the mangling of lines that begin with ``From`` that is + required by the unix mbox format. For more flexibility, instantiate a :class:`~email.generator.Generator` instance and use its :meth:`flatten` method directly. For example:: from io import StringIO from email.generator import Generator fp = StringIO() - g = Generator(fp, mangle_from_=False, maxheaderlen=60) + g = Generator(fp, mangle_from_=True, maxheaderlen=60) g.flatten(msg) text = fp.getvalue() @@ -138,15 +139,22 @@ string naming a character set, or ``None``. If it is a string, it will be converted to a :class:`~email.charset.Charset` instance. If *charset* is ``None``, the ``charset`` parameter will be removed from the - :mailheader:`Content-Type` header. Anything else will generate a - :exc:`TypeError`. + :mailheader:`Content-Type` header (the message will not be otherwise + modified). Anything else will generate a :exc:`TypeError`. - The message will be assumed to be of type :mimetype:`text/\*` encoded with - *charset.input_charset*. It will be converted to *charset.output_charset* - and encoded properly, if needed, when generating the plain text - representation of the message. MIME headers (:mailheader:`MIME-Version`, - :mailheader:`Content-Type`, :mailheader:`Content-Transfer-Encoding`) will - be added as needed. + If there is no existing :mailheader:`MIME-Version` header one will be + added. If there is no existing :mailheader:`Content-Type` header, one + will be added with a value of :mimetype:`text/plain`. Whether the + :mailheader:`Content-Type` header already exists or not, its ``charset`` + parameter will be set to *charset.output_charset*. If + *charset.input_charset* and *charset.output_charset* differ, the payload + will be re-encoded to the *output_charset*. If there is no existing + :mailheader:`Content-Transfer-Encoding` header, then the payload will be + transfer-encoded, if needed, using the specified + :class:`~email.charset.Charset`, and a header with the appropriate value + will be added. If a :mailheader:`Content-Transfer-Encoding` header + already exists, the payload is assumed to already be correctly encoded + using that :mailheader:`Content-Transfer-Encoding` and is not modified. .. method:: get_charset() @@ -222,12 +230,6 @@ headers. - .. method:: Message.__contains__(name) - - Return true if the message contains a header field named *name*, otherwise - return false. - - .. method:: keys() Return a list of all the message's header field names. diff -r e34b09c69dd3 -r f1bd5468dae6 Doc/library/inspect.rst --- a/Doc/library/inspect.rst Sat Mar 12 22:31:06 2011 -0500 +++ b/Doc/library/inspect.rst Wed Mar 16 19:19:36 2011 -0400 @@ -589,14 +589,11 @@ that raise AttributeError). It can also return descriptors objects instead of instance members. + If the instance `__dict__` is shadowed by another member (for example a + property) then this function will be unable to find instance members. + .. versionadded:: 3.2 -The only known case that can cause `getattr_static` to trigger code execution, -and cause it to return incorrect results (or even break), is where a class uses -:data:`~object.__slots__` and provides a `__dict__` member using a property or -descriptor. If you find other cases please report them so they can be fixed -or documented. - `getattr_static` does not resolve descriptors, for example slot descriptors or getset descriptors on objects implemented in C. The descriptor object is returned instead of the underlying attribute. diff -r e34b09c69dd3 -r f1bd5468dae6 Doc/library/multiprocessing.rst --- a/Doc/library/multiprocessing.rst Sat Mar 12 22:31:06 2011 -0500 +++ b/Doc/library/multiprocessing.rst Wed Mar 16 19:19:36 2011 -0400 @@ -875,7 +875,7 @@ .. class:: Semaphore([value]) - A bounded semaphore object: a clone of :class:`threading.Semaphore`. + A semaphore object: a clone of :class:`threading.Semaphore`. .. note:: diff -r e34b09c69dd3 -r f1bd5468dae6 Doc/library/smtplib.rst --- a/Doc/library/smtplib.rst Sat Mar 12 22:31:06 2011 -0500 +++ b/Doc/library/smtplib.rst Wed Mar 16 19:19:36 2011 -0400 @@ -34,6 +34,20 @@ For normal use, you should only require the initialization/connect, :meth:`sendmail`, and :meth:`quit` methods. An example is included below. + The :class:`SMTP` class supports the :keyword:`with` statement. When used + like this, the SMTP ``QUIT`` command is issued automatically when the + :keyword:`with` statement exits. E.g.:: + + >>> from smtplib import SMTP + >>> with SMTP("domain.org") as smtp: + ... smtp.noop() + ... + (250, b'Ok') + >>> + + .. versionadded:: 3.3 + Support for the :keyword:`with` statement was added. + .. class:: SMTP_SSL(host='', port=0, local_hostname=None, keyfile=None, certfile=None[, timeout]) diff -r e34b09c69dd3 -r f1bd5468dae6 Doc/library/subprocess.rst --- a/Doc/library/subprocess.rst Sat Mar 12 22:31:06 2011 -0500 +++ b/Doc/library/subprocess.rst Wed Mar 16 19:19:36 2011 -0400 @@ -125,12 +125,14 @@ *stdin*, *stdout* and *stderr* specify the executed programs' standard input, standard output and standard error file handles, respectively. Valid values - are :data:`PIPE`, an existing file descriptor (a positive integer), an - existing :term:`file object`, and ``None``. :data:`PIPE` indicates that a - new pipe to the child should be created. With ``None``, no redirection will - occur; the child's file handles will be inherited from the parent. Additionally, - *stderr* can be :data:`STDOUT`, which indicates that the stderr data from the - applications should be captured into the same file handle as for stdout. + are :data:`PIPE`, :data:`DEVNULL`, an existing file descriptor (a positive + integer), an existing :term:`file object`, and ``None``. :data:`PIPE` + indicates that a new pipe to the child should be created. :data:`DEVNULL` + indicates that the special file :data:`os.devnull` will be used. With ``None``, + no redirection will occur; the child's file handles will be inherited from + the parent. Additionally, *stderr* can be :data:`STDOUT`, which indicates + that the stderr data from the applications should be captured into the same + file handle as for stdout. If *preexec_fn* is set to a callable object, this object will be called in the child process just before the child is executed. @@ -229,6 +231,15 @@ Added context manager support. +.. data:: DEVNULL + + Special value that can be used as the *stdin*, *stdout* or *stderr* argument + to :class:`Popen` and indicates that the special file :data:`os.devnull` + will be used. + + .. versionadded:: 3.3 + + .. data:: PIPE Special value that can be used as the *stdin*, *stdout* or *stderr* argument @@ -249,15 +260,21 @@ This module also defines four shortcut functions: -.. function:: call(*popenargs, **kwargs) +.. function:: call(*popenargs, timeout=None, **kwargs) Run command with arguments. Wait for command to complete, then return the :attr:`returncode` attribute. - The arguments are the same as for the :class:`Popen` constructor. Example:: + The arguments are the same as for the :class:`Popen` constructor, with the + exception of the *timeout* argument, which is given to :meth:`Popen.wait`. + Example:: >>> retcode = subprocess.call(["ls", "-l"]) + If the timeout expires, the child process will be killed and then waited for + again. The :exc:`TimeoutExpired` exception will be re-raised after the child + process has terminated. + .. warning:: Like :meth:`Popen.wait`, this will deadlock when using @@ -265,34 +282,43 @@ generates enough output to a pipe such that it blocks waiting for the OS pipe buffer to accept more data. + .. versionchanged:: 3.3 + *timeout* was added. -.. function:: check_call(*popenargs, **kwargs) + +.. function:: check_call(*popenargs, timeout=None, **kwargs) Run command with arguments. Wait for command to complete. If the exit code was zero then return, otherwise raise :exc:`CalledProcessError`. The :exc:`CalledProcessError` object will have the return code in the :attr:`returncode` attribute. - The arguments are the same as for the :class:`Popen` constructor. Example:: + The arguments are the same as for the :func:`call` function. Example:: >>> subprocess.check_call(["ls", "-l"]) 0 + As in the :func:`call` function, if the timeout expires, the child process + will be killed and the wait retried. The :exc:`TimeoutExpired` exception + will be re-raised after the child process has terminated. + .. warning:: See the warning for :func:`call`. + .. versionchanged:: 3.3 + *timeout* was added. -.. function:: check_output(*popenargs, **kwargs) + +.. function:: check_output(*popenargs, timeout=None, **kwargs) Run command with arguments and return its output as a byte string. If the exit code was non-zero it raises a :exc:`CalledProcessError`. The :exc:`CalledProcessError` object will have the return code in the - :attr:`returncode` - attribute and output in the :attr:`output` attribute. + :attr:`returncode` attribute and output in the :attr:`output` attribute. - The arguments are the same as for the :class:`Popen` constructor. Example:: + The arguments are the same as for the :func:`call` function. Example:: >>> subprocess.check_output(["ls", "-l", "/dev/null"]) b'crw-rw-rw- 1 root root 1, 3 Oct 18 2007 /dev/null\n' @@ -305,8 +331,17 @@ ... stderr=subprocess.STDOUT) b'ls: non_existent_file: No such file or directory\n' + As in the :func:`call` function, if the timeout expires, the child process + will be killed and the wait retried. The :exc:`TimeoutExpired` exception + will be re-raised after the child process has terminated. The output from + the child process so far will be in the :attr:`output` attribute of the + exception. + .. versionadded:: 3.1 + .. versionchanged:: 3.3 + *timeout* was added. + .. function:: getstatusoutput(cmd) @@ -359,6 +394,15 @@ check_call() will raise :exc:`CalledProcessError`, if the called process returns a non-zero return code. +All of the functions and methods that accept a *timeout* parameter, such as +:func:`call` and :meth:`Popen.communicate` will raise :exc:`TimeoutExpired` if +the timeout expires before the process exits. + +Exceptions defined in this module all inherit from :exc:`SubprocessError`. + + .. versionadded:: 3.3 + The :exc:`SubprocessError` base class was added. + Security ^^^^^^^^ @@ -380,11 +424,15 @@ attribute. -.. method:: Popen.wait() +.. method:: Popen.wait(timeout=None) Wait for child process to terminate. Set and return :attr:`returncode` attribute. + If the process does not terminate after *timeout* seconds, raise a + :exc:`TimeoutExpired` exception. It is safe to catch this exception and + retry the wait. + .. warning:: This will deadlock when using ``stdout=PIPE`` and/or @@ -392,11 +440,14 @@ a pipe such that it blocks waiting for the OS pipe buffer to accept more data. Use :meth:`communicate` to avoid that. + .. versionchanged:: 3.3 + *timeout* was added. -.. method:: Popen.communicate(input=None) + +.. method:: Popen.communicate(input=None, timeout=None) Interact with process: Send data to stdin. Read data from stdout and stderr, - until end-of-file is reached. Wait for process to terminate. The optional + until end-of-file is reached. Wait for process to terminate. The optional *input* argument should be a byte string to be sent to the child process, or ``None``, if no data should be sent to the child. @@ -407,11 +458,29 @@ ``None`` in the result tuple, you need to give ``stdout=PIPE`` and/or ``stderr=PIPE`` too. + If the process does not terminate after *timeout* seconds, a + :exc:`TimeoutExpired` exception will be raised. Catching this exception and + retrying communication will not lose any output. + + The child process is not killed if the timeout expires, so in order to + cleanup properly a well-behaved application should kill the child process and + finish communication:: + + proc = subprocess.Popen(...) + try: + outs, errs = proc.communicate(timeout=15) + except TimeoutExpired: + proc.kill() + outs, errs = proc.communicate() + .. note:: The data read is buffered in memory, so do not use this method if the data size is large or unlimited. + .. versionchanged:: 3.3 + *timeout* was added. + .. method:: Popen.send_signal(signal) diff -r e34b09c69dd3 -r f1bd5468dae6 Doc/library/unittest.rst --- a/Doc/library/unittest.rst Sat Mar 12 22:31:06 2011 -0500 +++ b/Doc/library/unittest.rst Wed Mar 16 19:19:36 2011 -0400 @@ -723,7 +723,7 @@ Here, we create two instances of :class:`WidgetTestCase`, each of which runs a single test. - .. versionchanged:: + .. versionchanged:: 3.2 `TestCase` can be instantiated successfully without providing a method name. This makes it easier to experiment with `TestCase` from the interactive interpreter. @@ -792,11 +792,14 @@ Run the test, collecting the result into the test result object passed as *result*. If *result* is omitted or ``None``, a temporary result object is created (by calling the :meth:`defaultTestResult` method) and - used. The result object is not returned to :meth:`run`'s caller. + used. The result object is returned to :meth:`run`'s caller. The same effect may be had by simply calling the :class:`TestCase` instance. + .. versionchanged:: 3.3 + Previous versions of ``run`` did not return the result. Neither did + calling an instance. .. method:: skipTest(reason) diff -r e34b09c69dd3 -r f1bd5468dae6 Doc/whatsnew/3.2.rst --- a/Doc/whatsnew/3.2.rst Sat Mar 12 22:31:06 2011 -0500 +++ b/Doc/whatsnew/3.2.rst Wed Mar 16 19:19:36 2011 -0400 @@ -2698,3 +2698,7 @@ a new function, :func:`asyncore.handle_accepted`, was added to replace it. (Contributed by Giampaolo Rodola in :issue:`6706`.) + +* Due to the new :term:`GIL` implementation, :c:func:`PyEval_InitThreads()` + cannot be called before :c:func:`Py_Initialize()` anymore. + diff -r e34b09c69dd3 -r f1bd5468dae6 Include/abstract.h --- a/Include/abstract.h Sat Mar 12 22:31:06 2011 -0500 +++ b/Include/abstract.h Wed Mar 16 19:19:36 2011 -0400 @@ -468,7 +468,7 @@ arbitrary data. 0 is returned on success. buffer and buffer_len are only - set in case no error occurrs. Otherwise, -1 is returned and + set in case no error occurs. Otherwise, -1 is returned and an exception set. */ @@ -482,7 +482,7 @@ writable memory location in buffer of size buffer_len. 0 is returned on success. buffer and buffer_len are only - set in case no error occurrs. Otherwise, -1 is returned and + set in case no error occurs. Otherwise, -1 is returned and an exception set. */ diff -r e34b09c69dd3 -r f1bd5468dae6 Include/patchlevel.h --- a/Include/patchlevel.h Sat Mar 12 22:31:06 2011 -0500 +++ b/Include/patchlevel.h Wed Mar 16 19:19:36 2011 -0400 @@ -26,9 +26,6 @@ #define PY_VERSION "3.3a0" /*--end constants--*/ -/* Subversion Revision number of this file (not of the repository) */ -#define PY_PATCHLEVEL_REVISION "$Revision$" - /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. Use this for numeric comparisons, e.g. #if PY_VERSION_HEX >= ... */ #define PY_VERSION_HEX ((PY_MAJOR_VERSION << 24) | \ diff -r e34b09c69dd3 -r f1bd5468dae6 Include/pymacconfig.h --- a/Include/pymacconfig.h Sat Mar 12 22:31:06 2011 -0500 +++ b/Include/pymacconfig.h Wed Mar 16 19:19:36 2011 -0400 @@ -61,7 +61,7 @@ # endif # if defined(__LP64__) - /* MacOSX 10.4 (the first release to suppport 64-bit code + /* MacOSX 10.4 (the first release to support 64-bit code * at all) only supports 64-bit in the UNIX layer. * Therefore surpress the toolbox-glue in 64-bit mode. */ diff -r e34b09c69dd3 -r f1bd5468dae6 Include/pymath.h --- a/Include/pymath.h Sat Mar 12 22:31:06 2011 -0500 +++ b/Include/pymath.h Wed Mar 16 19:19:36 2011 -0400 @@ -37,12 +37,6 @@ #endif /* __STDC__ */ #endif /* _MSC_VER */ -#ifdef _OSF_SOURCE -/* OSF1 5.1 doesn't make these available with XOPEN_SOURCE_EXTENDED defined */ -extern int finite(double); -extern double copysign(double, double); -#endif - /* High precision defintion of pi and e (Euler) * The values are taken from libc6's math.h. */ diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/collections/__init__.py --- a/Lib/collections/__init__.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/collections/__init__.py Wed Mar 16 19:19:36 2011 -0400 @@ -1,7 +1,7 @@ __all__ = ['deque', 'defaultdict', 'namedtuple', 'UserDict', 'UserList', 'UserString', 'Counter', 'OrderedDict'] -# For backwards compatability, continue to make the collections ABCs +# For backwards compatibility, continue to make the collections ABCs # available through the collections module. from collections.abc import * import collections.abc diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/csv.py --- a/Lib/csv.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/csv.py Wed Mar 16 19:19:36 2011 -0400 @@ -284,7 +284,7 @@ an all or nothing approach, so we allow for small variations in this number. 1) build a table of the frequency of each character on every line. - 2) build a table of freqencies of this frequency (meta-frequency?), + 2) build a table of frequencies of this frequency (meta-frequency?), e.g. 'x occurred 5 times in 10 rows, 6 times in 1000 rows, 7 times in 2 rows' 3) use the mode of the meta-frequency to determine the /expected/ diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/ctypes/test/test_arrays.py --- a/Lib/ctypes/test/test_arrays.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/ctypes/test/test_arrays.py Wed Mar 16 19:19:36 2011 -0400 @@ -37,7 +37,7 @@ values = [ia[i] for i in range(len(init))] self.assertEqual(values, [0] * len(init)) - # Too many in itializers should be caught + # Too many initializers should be caught self.assertRaises(IndexError, int_array, *range(alen*2)) CharArray = ARRAY(c_char, 3) diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/ctypes/test/test_functions.py --- a/Lib/ctypes/test/test_functions.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/ctypes/test/test_functions.py Wed Mar 16 19:19:36 2011 -0400 @@ -116,7 +116,7 @@ self.assertEqual(result, 21) self.assertEqual(type(result), int) - # You cannot assing character format codes as restype any longer + # You cannot assign character format codes as restype any longer self.assertRaises(TypeError, setattr, f, "restype", "i") def test_floatresult(self): diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/ctypes/test/test_init.py --- a/Lib/ctypes/test/test_init.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/ctypes/test/test_init.py Wed Mar 16 19:19:36 2011 -0400 @@ -27,7 +27,7 @@ self.assertEqual((y.x.a, y.x.b), (0, 0)) self.assertEqual(y.x.new_was_called, False) - # But explicitely creating an X structure calls __new__ and __init__, of course. + # But explicitly creating an X structure calls __new__ and __init__, of course. x = X() self.assertEqual((x.a, x.b), (9, 12)) self.assertEqual(x.new_was_called, True) diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/ctypes/test/test_numbers.py --- a/Lib/ctypes/test/test_numbers.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/ctypes/test/test_numbers.py Wed Mar 16 19:19:36 2011 -0400 @@ -157,7 +157,7 @@ def test_int_from_address(self): from array import array for t in signed_types + unsigned_types: - # the array module doesn't suppport all format codes + # the array module doesn't support all format codes # (no 'q' or 'Q') try: array(t._type_) diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/ctypes/test/test_win32.py --- a/Lib/ctypes/test/test_win32.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/ctypes/test/test_win32.py Wed Mar 16 19:19:36 2011 -0400 @@ -17,7 +17,7 @@ # ValueError: Procedure probably called with not enough arguments (4 bytes missing) self.assertRaises(ValueError, IsWindow) - # This one should succeeed... + # This one should succeed... self.assertEqual(0, IsWindow(0)) # ValueError: Procedure probably called with too many arguments (8 bytes in excess) diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/dbm/__init__.py --- a/Lib/dbm/__init__.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/dbm/__init__.py Wed Mar 16 19:19:36 2011 -0400 @@ -67,10 +67,10 @@ if not _defaultmod: raise ImportError("no dbm clone found; tried %s" % _names) - # guess the type of an existing database - result = whichdb(file) + # guess the type of an existing database, if not creating a new one + result = whichdb(file) if 'n' not in flag else None if result is None: - # db doesn't exist + # db doesn't exist or 'n' flag was specified to create a new db if 'c' in flag or 'n' in flag: # file doesn't exist and the new flag was used so use default type mod = _defaultmod diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/decimal.py --- a/Lib/decimal.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/decimal.py Wed Mar 16 19:19:36 2011 -0400 @@ -6088,7 +6088,7 @@ def _format_align(sign, body, spec): """Given an unpadded, non-aligned numeric string 'body' and sign - string 'sign', add padding and aligment conforming to the given + string 'sign', add padding and alignment conforming to the given format specifier dictionary 'spec' (as produced by parse_format_specifier). diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/difflib.py --- a/Lib/difflib.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/difflib.py Wed Mar 16 19:19:36 2011 -0400 @@ -1719,7 +1719,7 @@ line = line.replace(' ','\0') # expand tabs into spaces line = line.expandtabs(self._tabsize) - # relace spaces from expanded tabs back into tab characters + # replace spaces from expanded tabs back into tab characters # (we'll replace them with markup after we do differencing) line = line.replace(' ','\t') return line.replace('\0',' ').rstrip('\n') diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/distutils/archive_util.py --- a/Lib/distutils/archive_util.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/distutils/archive_util.py Wed Mar 16 19:19:36 2011 -0400 @@ -9,6 +9,12 @@ from warnings import warn import sys +try: + import zipfile +except ImportError: + zipfile = None + + from distutils.errors import DistutilsExecError from distutils.spawn import spawn from distutils.dir_util import mkpath @@ -74,11 +80,6 @@ available, raises DistutilsExecError. Returns the name of the output zip file. """ - try: - import zipfile - except ImportError: - zipfile = None - zip_filename = base_name + ".zip" mkpath(os.path.dirname(zip_filename), dry_run=dry_run) @@ -105,8 +106,12 @@ zip_filename, base_dir) if not dry_run: - zip = zipfile.ZipFile(zip_filename, "w", - compression=zipfile.ZIP_DEFLATED) + try: + zip = zipfile.ZipFile(zip_filename, "w", + compression=zipfile.ZIP_DEFLATED) + except RuntimeError: + zip = zipfile.ZipFile(zip_filename, "w", + compression=zipfile.ZIP_STORED) for dirpath, dirnames, filenames in os.walk(base_dir): for name in filenames: diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/distutils/cmd.py --- a/Lib/distutils/cmd.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/distutils/cmd.py Wed Mar 16 19:19:36 2011 -0400 @@ -359,7 +359,7 @@ not self.force, dry_run=self.dry_run) def move_file (self, src, dst, level=1): - """Move a file respectin dry-run flag.""" + """Move a file respecting dry-run flag.""" return file_util.move_file(src, dst, dry_run=self.dry_run) def spawn(self, cmd, search_path=1, level=1): diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/distutils/cygwinccompiler.py --- a/Lib/distutils/cygwinccompiler.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/distutils/cygwinccompiler.py Wed Mar 16 19:19:36 2011 -0400 @@ -155,7 +155,7 @@ self.dll_libraries = get_msvcr() def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts): - """Compiles the source by spawing GCC and windres if needed.""" + """Compiles the source by spawning GCC and windres if needed.""" if ext == '.rc' or ext == '.res': # gcc needs '.res' and '.rc' compiled to object files !!! try: diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/distutils/tests/test_archive_util.py --- a/Lib/distutils/tests/test_archive_util.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/distutils/tests/test_archive_util.py Wed Mar 16 19:19:36 2011 -0400 @@ -7,12 +7,13 @@ from os.path import splitdrive import warnings +from distutils import archive_util from distutils.archive_util import (check_archive_formats, make_tarball, make_zipfile, make_archive, ARCHIVE_FORMATS) from distutils.spawn import find_executable, spawn from distutils.tests import support -from test.support import check_warnings, run_unittest +from test.support import check_warnings, run_unittest, patch try: import zipfile @@ -20,10 +21,18 @@ except ImportError: ZIP_SUPPORT = find_executable('zip') +try: + import zlib + ZLIB_SUPPORT = True +except ImportError: + ZLIB_SUPPORT = False + + class ArchiveUtilTestCase(support.TempdirManager, support.LoggingSilencer, unittest.TestCase): + @unittest.skipUnless(ZLIB_SUPPORT, 'Need zlib support to run') def test_make_tarball(self): # creating something to tar tmpdir = self.mkdtemp() @@ -84,8 +93,9 @@ base_name = os.path.join(tmpdir2, 'archive') return tmpdir, tmpdir2, base_name - @unittest.skipUnless(find_executable('tar') and find_executable('gzip'), - 'Need the tar command to run') + @unittest.skipUnless(find_executable('tar') and find_executable('gzip') + and ZLIB_SUPPORT, + 'Need the tar, gzip and zlib command to run') def test_tarfile_vs_tar(self): tmpdir, tmpdir2, base_name = self._create_files() old_dir = os.getcwd() @@ -169,7 +179,8 @@ self.assertTrue(not os.path.exists(tarball)) self.assertEqual(len(w.warnings), 1) - @unittest.skipUnless(ZIP_SUPPORT, 'Need zip support to run') + @unittest.skipUnless(ZIP_SUPPORT and ZLIB_SUPPORT, + 'Need zip and zlib support to run') def test_make_zipfile(self): # creating something to tar tmpdir = self.mkdtemp() @@ -182,6 +193,29 @@ # check if the compressed tarball was created tarball = base_name + '.zip' + self.assertTrue(os.path.exists(tarball)) + + @unittest.skipUnless(ZIP_SUPPORT, 'Need zip support to run') + def test_make_zipfile_no_zlib(self): + patch(self, archive_util.zipfile, 'zlib', None) # force zlib ImportError + + called = [] + zipfile_class = zipfile.ZipFile + def fake_zipfile(*a, **kw): + if kw.get('compression', None) == zipfile.ZIP_STORED: + called.append((a, kw)) + return zipfile_class(*a, **kw) + + patch(self, archive_util.zipfile, 'ZipFile', fake_zipfile) + + # create something to tar and compress + tmpdir, tmpdir2, base_name = self._create_files() + make_zipfile(base_name, tmpdir) + + tarball = base_name + '.zip' + self.assertEqual(called, + [((tarball, "w"), {'compression': zipfile.ZIP_STORED})]) + self.assertTrue(os.path.exists(tarball)) def test_check_archive_formats(self): self.assertEqual(check_archive_formats(['gztar', 'xxx', 'zip']), diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/distutils/tests/test_bdist_dumb.py --- a/Lib/distutils/tests/test_bdist_dumb.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/distutils/tests/test_bdist_dumb.py Wed Mar 16 19:19:36 2011 -0400 @@ -18,6 +18,13 @@ """ +try: + import zlib + ZLIB_SUPPORT = True +except ImportError: + ZLIB_SUPPORT = False + + class BuildDumbTestCase(support.TempdirManager, support.LoggingSilencer, support.EnvironGuard, @@ -34,6 +41,7 @@ sys.argv[:] = self.old_sys_argv[1] super(BuildDumbTestCase, self).tearDown() + @unittest.skipUnless(ZLIB_SUPPORT, 'Need zlib support to run') def test_simple_built(self): # let's create a simple package diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/distutils/tests/test_clean.py --- a/Lib/distutils/tests/test_clean.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/distutils/tests/test_clean.py Wed Mar 16 19:19:36 2011 -0400 @@ -39,7 +39,7 @@ self.assertTrue(not os.path.exists(path), '%s was not removed' % path) - # let's run the command again (should spit warnings but suceed) + # let's run the command again (should spit warnings but succeed) cmd.all = 1 cmd.ensure_finalized() cmd.run() diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/distutils/tests/test_install.py --- a/Lib/distutils/tests/test_install.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/distutils/tests/test_install.py Wed Mar 16 19:19:36 2011 -0400 @@ -62,7 +62,7 @@ if sys.version < '2.6': return - # preparing the environement for the test + # preparing the environment for the test self.old_user_base = site.USER_BASE self.old_user_site = site.USER_SITE self.tmpdir = self.mkdtemp() diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/distutils/tests/test_sdist.py --- a/Lib/distutils/tests/test_sdist.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/distutils/tests/test_sdist.py Wed Mar 16 19:19:36 2011 -0400 @@ -40,6 +40,13 @@ somecode%(sep)sdoc.txt """ +try: + import zlib + ZLIB_SUPPORT = True +except ImportError: + ZLIB_SUPPORT = False + + class SDistTestCase(PyPIRCCommandTestCase): def setUp(self): @@ -78,6 +85,7 @@ cmd.warn = _warn return dist, cmd + @unittest.skipUnless(ZLIB_SUPPORT, 'Need zlib support to run') def test_prune_file_list(self): # this test creates a package with some vcs dirs in it # and launch sdist to make sure they get pruned @@ -119,6 +127,7 @@ # making sure everything has been pruned correctly self.assertEqual(len(content), 4) + @unittest.skipUnless(ZLIB_SUPPORT, 'Need zlib support to run') def test_make_distribution(self): # check if tar and gzip are installed @@ -153,6 +162,7 @@ result.sort() self.assertEqual(result, ['fake-1.0.tar', 'fake-1.0.tar.gz']) + @unittest.skipUnless(ZLIB_SUPPORT, 'Need zlib support to run') def test_add_defaults(self): # http://bugs.python.org/issue2279 @@ -218,6 +228,7 @@ finally: f.close() + @unittest.skipUnless(ZLIB_SUPPORT, 'Need zlib support to run') def test_metadata_check_option(self): # testing the `medata-check` option dist, cmd = self.get_cmd(metadata={}) @@ -277,7 +288,7 @@ cmd.formats = 'supazipa' self.assertRaises(DistutilsOptionError, cmd.finalize_options) - + @unittest.skipUnless(ZLIB_SUPPORT, 'Need zlib support to run') def test_get_file_list(self): # make sure MANIFEST is recalculated dist, cmd = self.get_cmd() @@ -300,7 +311,7 @@ # adding a file self.write_file((self.tmp_dir, 'somecode', 'doc2.txt'), '#') - # make sure build_py is reinitinialized, like a fresh run + # make sure build_py is reinitialized, like a fresh run build_py = dist.get_command_obj('build_py') build_py.finalized = False build_py.ensure_finalized() @@ -318,6 +329,7 @@ self.assertEqual(len(manifest2), 6) self.assertIn('doc2.txt', manifest2[-1]) + @unittest.skipUnless(ZLIB_SUPPORT, 'Need zlib support to run') def test_manifest_marker(self): # check that autogenerated MANIFESTs have a marker dist, cmd = self.get_cmd() @@ -334,6 +346,7 @@ self.assertEqual(manifest[0], '# file GENERATED by distutils, do NOT edit') + @unittest.skipUnless(ZLIB_SUPPORT, 'Need zlib support to run') def test_manual_manifest(self): # check that a MANIFEST without a marker is left alone dist, cmd = self.get_cmd() diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/doctest.py --- a/Lib/doctest.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/doctest.py Wed Mar 16 19:19:36 2011 -0400 @@ -1211,7 +1211,7 @@ # Process each example. for examplenum, example in enumerate(test.examples): - # If REPORT_ONLY_FIRST_FAILURE is set, then supress + # If REPORT_ONLY_FIRST_FAILURE is set, then suppress # reporting after the first failure. quiet = (self.optionflags & REPORT_ONLY_FIRST_FAILURE and failures > 0) @@ -2135,7 +2135,7 @@ caller can catch the errors and initiate post-mortem debugging. The DocTestCase provides a debug method that raises - UnexpectedException errors if there is an unexepcted + UnexpectedException errors if there is an unexpected exception: >>> test = DocTestParser().get_doctest('>>> raise KeyError\n42', diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/email/_parseaddr.py --- a/Lib/email/_parseaddr.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/email/_parseaddr.py Wed Mar 16 19:19:36 2011 -0400 @@ -99,6 +99,14 @@ tss = '0' elif len(tm) == 3: [thh, tmm, tss] = tm + elif len(tm) == 1 and '.' in tm[0]: + # Some non-compliant MUAs use '.' to separate time elements. + tm = tm[0].split('.') + if len(tm) == 2: + [thh, tmm] = tm + tss = 0 + elif len(tm) == 3: + [thh, tmm, tss] = tm else: return None try: diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/email/charset.py --- a/Lib/email/charset.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/email/charset.py Wed Mar 16 19:19:36 2011 -0400 @@ -263,7 +263,7 @@ Returns "quoted-printable" if self.body_encoding is QP. Returns "base64" if self.body_encoding is BASE64. - Returns "7bit" otherwise. + Returns conversion function otherwise. """ assert self.body_encoding != SHORTEST if self.body_encoding == QP: @@ -321,7 +321,7 @@ codec = self.output_codec or 'us-ascii' header_bytes = _encode(string, codec) encoder_module = self._get_encoder(header_bytes) - encoder = partial(encoder_module.header_encode, charset=str(self)) + encoder = partial(encoder_module.header_encode, charset=codec) # Calculate the number of characters that the RFC 2047 chrome will # contribute to each line. charset = self.get_output_charset() @@ -381,7 +381,10 @@ """Body-encode a string by converting it first to bytes. The type of encoding (base64 or quoted-printable) will be based on - self.body_encoding. + self.body_encoding. If body_encoding is None, we assume the + output charset is a 7bit encoding, so re-encoding the decoded + string using the ascii codec produces the correct string version + of the content. """ # 7bit/8bit encodings return the string unchanged (module conversions) if self.body_encoding is BASE64: @@ -391,4 +394,6 @@ elif self.body_encoding is QP: return email.quoprimime.body_encode(string) else: + if isinstance(string, str): + string = string.encode(self.output_charset).decode('ascii') return string diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/email/encoders.py --- a/Lib/email/encoders.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/email/encoders.py Wed Mar 16 19:19:36 2011 -0400 @@ -12,7 +12,7 @@ ] -from base64 import b64encode as _bencode +from base64 import encodebytes as _bencode from quopri import encodestring as _encodestring @@ -54,10 +54,13 @@ # There's no payload. For backwards compatibility we use 7bit msg['Content-Transfer-Encoding'] = '7bit' return - # We play a trick to make this go fast. If encoding to ASCII succeeds, we - # know the data must be 7bit, otherwise treat it as 8bit. + # We play a trick to make this go fast. If encoding/decode to ASCII + # succeeds, we know the data must be 7bit, otherwise treat it as 8bit. try: - orig.encode('ascii') + if isinstance(orig, str): + orig.encode('ascii') + else: + orig.decode('ascii') except UnicodeError: # iso-2022-* is non-ASCII but still 7-bit charset = msg.get_charset() diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/email/generator.py --- a/Lib/email/generator.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/email/generator.py Wed Mar 16 19:19:36 2011 -0400 @@ -59,7 +59,7 @@ self._fp.write(s) def flatten(self, msg, unixfrom=False, linesep='\n'): - """Print the message object tree rooted at msg to the output file + r"""Print the message object tree rooted at msg to the output file specified when the Generator instance was created. unixfrom is a flag that forces the printing of a Unix From_ delimiter @@ -70,7 +70,10 @@ Note that for subobjects, no From_ line is printed. linesep specifies the characters used to indicate a new line in - the output. + the output. The default value is the most useful for typical + Python applications, but it can be set to \r\n to produce RFC-compliant + line separators when needed. + """ # We use the _XXX constants for operating on data that comes directly # from the msg, and _encoded_XXX constants for operating on data that diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/email/header.py --- a/Lib/email/header.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/email/header.py Wed Mar 16 19:19:36 2011 -0400 @@ -47,7 +47,7 @@ # For use with .match() fcre = re.compile(r'[\041-\176]+:$') -# Find a header embeded in a putative header value. Used to check for +# Find a header embedded in a putative header value. Used to check for # header injection attack. _embeded_header = re.compile(r'\n[^ \t]+:') @@ -276,7 +276,7 @@ self._chunks.append((s, charset)) def encode(self, splitchars=';, \t', maxlinelen=None, linesep='\n'): - """Encode a message header into an RFC-compliant format. + r"""Encode a message header into an RFC-compliant format. There are many issues involved in converting a given string for use in an email header. Only certain character sets are readable in most @@ -314,7 +314,7 @@ self._continuation_ws, splitchars) for string, charset in self._chunks: lines = string.splitlines() - formatter.feed(lines[0], charset) + formatter.feed(lines[0] if lines else '', charset) for line in lines[1:]: formatter.newline() if charset.header_encoding is not None: diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/email/message.py --- a/Lib/email/message.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/email/message.py Wed Mar 16 19:19:36 2011 -0400 @@ -157,8 +157,7 @@ header. This is a convenience method and may not generate the message exactly - as you intend because by default it mangles lines that begin with - "From ". For more flexibility, use the flatten() method of a + as you intend. For more flexibility, use the flatten() method of a Generator instance. """ from email.generator import Generator @@ -242,7 +241,7 @@ raise TypeError('Expected list, got %s' % type(self._payload)) payload = self._payload cte = self.get('content-transfer-encoding', '').lower() - # payload can be bytes here, (I wonder if that is actually a bug?) + # payload may be bytes here. if isinstance(payload, str): if _has_surrogates(payload): bpayload = payload.encode('ascii', 'surrogateescape') diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/email/mime/application.py --- a/Lib/email/mime/application.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/email/mime/application.py Wed Mar 16 19:19:36 2011 -0400 @@ -17,7 +17,7 @@ _encoder=encoders.encode_base64, **_params): """Create an application/* type MIME document. - _data is a string containing the raw applicatoin data. + _data is a string containing the raw application data. _subtype is the MIME content type subtype, defaulting to 'octet-stream'. diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/email/test/test_email.py --- a/Lib/email/test/test_email.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/email/test/test_email.py Wed Mar 16 19:19:36 2011 -0400 @@ -573,9 +573,18 @@ msg['Dummy'] = 'dummy\nX-Injected-Header: test' self.assertRaises(errors.HeaderParseError, msg.as_string) - # Test the email.encoders module class TestEncoders(unittest.TestCase): + + def test_EncodersEncode_base64(self): + with openfile('PyBanner048.gif', 'rb') as fp: + bindata = fp.read() + mimed = email.mime.image.MIMEImage(bindata) + base64ed = mimed.get_payload() + # the transfer-encoded body lines should all be <=76 characters + lines = base64ed.split('\n') + self.assertLessEqual(max([ len(x) for x in lines ]), 76) + def test_encode_empty_payload(self): eq = self.assertEqual msg = Message() @@ -725,6 +734,20 @@ wasnipoop; giraffes="very-long-necked-animals"; \tspooge="yummy"; hippos="gargantuan"; marshmallows="gooey"''') + def test_header_encode_with_different_output_charset(self): + h = Header('文', 'euc-jp') + self.assertEqual(h.encode(), "=?iso-2022-jp?b?GyRCSjgbKEI=?=") + + def test_long_header_encode_with_different_output_charset(self): + h = Header(b'test-ja \xa4\xd8\xc5\xea\xb9\xc6\xa4\xb5\xa4\xec\xa4' + b'\xbf\xa5\xe1\xa1\xbc\xa5\xeb\xa4\xcf\xbb\xca\xb2\xf1\xbc\xd4' + b'\xa4\xce\xbe\xb5\xc7\xa7\xa4\xf2\xc2\xd4\xa4\xc3\xa4\xc6\xa4' + b'\xa4\xa4\xde\xa4\xb9'.decode('euc-jp'), 'euc-jp') + res = """\ +=?iso-2022-jp?b?dGVzdC1qYSAbJEIkWEVqOUYkNSRsJD8lYSE8JWskTztKMnE8VCROPjUbKEI=?= + =?iso-2022-jp?b?GyRCRyckckJUJEMkRiQkJF4kORsoQg==?=""" + self.assertEqual(h.encode(), res) + def test_header_splitter(self): eq = self.ndiffAssertEqual msg = MIMEText('') @@ -1127,10 +1150,11 @@ def test_body(self): eq = self.assertEqual - bytes = b'\xfa\xfb\xfc\xfd\xfe\xff' - msg = MIMEApplication(bytes) - eq(msg.get_payload(), '+vv8/f7/') - eq(msg.get_payload(decode=True), bytes) + bytesdata = b'\xfa\xfb\xfc\xfd\xfe\xff' + msg = MIMEApplication(bytesdata) + # whitespace in the cte encoded block is RFC-irrelevant. + eq(msg.get_payload().strip(), '+vv8/f7/') + eq(msg.get_payload(decode=True), bytesdata) @@ -2328,6 +2352,13 @@ (2002, 4, 3, 14, 58, 26, 0, 1, -1, -28800)) + def test_parsedate_accepts_time_with_dots(self): + eq = self.assertEqual + eq(utils.parsedate_tz('5 Feb 2003 13.47.26 -0800'), + (2003, 2, 5, 13, 47, 26, 0, 1, -1, -28800)) + eq(utils.parsedate_tz('5 Feb 2003 13.47 -0800'), + (2003, 2, 5, 13, 47, 0, 0, 1, -1, -28800)) + def test_parsedate_acceptable_to_time_functions(self): eq = self.assertEqual timetup = utils.parsedate('5 Feb 2003 13:47:26 -0800') @@ -3351,9 +3382,9 @@ # built-in encodings where the header encoding is QP but the body # encoding is not. from email import charset as CharsetModule - CharsetModule.add_charset('fake', CharsetModule.QP, None) + CharsetModule.add_charset('fake', CharsetModule.QP, None, 'utf-8') c = Charset('fake') - eq('hello w\xf6rld', c.body_encode('hello w\xf6rld')) + eq('hello world', c.body_encode('hello world')) def test_unicode_charset_name(self): charset = Charset('us-ascii') @@ -3674,6 +3705,13 @@ h = Header('文', charset='shift_jis') self.assertEqual(h.encode(), '=?iso-2022-jp?b?GyRCSjgbKEI=?=') + def test_flatten_header_with_no_value(self): + # Issue 11401 (regression from email 4.x) Note that the space after + # the header doesn't reflect the input, but this is also the way + # email 4.x behaved. At some point it would be nice to fix that. + msg = email.message_from_string("EmptyHeader:") + self.assertEqual(str(msg), "EmptyHeader: \n\n") + # Test RFC 2231 header parameters (en/de)coding diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/email/test/test_email_codecs.py --- a/Lib/email/test/test_email_codecs.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/email/test/test_email_codecs.py Wed Mar 16 19:19:36 2011 -0400 @@ -13,7 +13,7 @@ # We're compatible with Python 2.3, but it doesn't have the built-in Asian # codecs, so we have to skip all these tests. try: - str('foo', 'euc-jp') + str(b'foo', 'euc-jp') except LookupError: raise unittest.SkipTest @@ -22,11 +22,14 @@ class TestEmailAsianCodecs(TestEmailBase): def test_japanese_codecs(self): eq = self.ndiffAssertEqual - j = Charset("euc-jp") - g = Charset("iso-8859-1") + jcode = "euc-jp" + gcode = "iso-8859-1" + j = Charset(jcode) + g = Charset(gcode) h = Header("Hello World!") - jhello = '\xa5\xcf\xa5\xed\xa1\xbc\xa5\xef\xa1\xbc\xa5\xeb\xa5\xc9\xa1\xaa' - ghello = 'Gr\xfc\xdf Gott!' + jhello = str(b'\xa5\xcf\xa5\xed\xa1\xbc\xa5\xef\xa1\xbc' + b'\xa5\xeb\xa5\xc9\xa1\xaa', jcode) + ghello = str(b'Gr\xfc\xdf Gott!', gcode) h.append(jhello, j) h.append(ghello, g) # BAW: This used to -- and maybe should -- fold the two iso-8859-1 @@ -36,13 +39,17 @@ # encoded word. eq(h.encode(), """\ Hello World! =?iso-2022-jp?b?GyRCJU8lbSE8JW8hPCVrJUkhKhsoQg==?= - =?iso-8859-1?q?Gr=FC=DF?= =?iso-8859-1?q?_Gott!?=""") + =?iso-8859-1?q?Gr=FC=DF_Gott!?=""") eq(decode_header(h.encode()), - [('Hello World!', None), - ('\x1b$B%O%m!<%o!<%k%I!*\x1b(B', 'iso-2022-jp'), - ('Gr\xfc\xdf Gott!', 'iso-8859-1')]) - int = 'test-ja \xa4\xd8\xc5\xea\xb9\xc6\xa4\xb5\xa4\xec\xa4\xbf\xa5\xe1\xa1\xbc\xa5\xeb\xa4\xcf\xbb\xca\xb2\xf1\xbc\xd4\xa4\xce\xbe\xb5\xc7\xa7\xa4\xf2\xc2\xd4\xa4\xc3\xa4\xc6\xa4\xa4\xa4\xde\xa4\xb9' - h = Header(int, j, header_name="Subject") + [(b'Hello World!', None), + (b'\x1b$B%O%m!<%o!<%k%I!*\x1b(B', 'iso-2022-jp'), + (b'Gr\xfc\xdf Gott!', gcode)]) + subject_bytes = (b'test-ja \xa4\xd8\xc5\xea\xb9\xc6\xa4\xb5' + b'\xa4\xec\xa4\xbf\xa5\xe1\xa1\xbc\xa5\xeb\xa4\xcf\xbb\xca\xb2' + b'\xf1\xbc\xd4\xa4\xce\xbe\xb5\xc7\xa7\xa4\xf2\xc2\xd4\xa4\xc3' + b'\xa4\xc6\xa4\xa4\xa4\xde\xa4\xb9') + subject = str(subject_bytes, jcode) + h = Header(subject, j, header_name="Subject") # test a very long header enc = h.encode() # TK: splitting point may differ by codec design and/or Header encoding @@ -50,15 +57,24 @@ =?iso-2022-jp?b?dGVzdC1qYSAbJEIkWEVqOUYkNSRsJD8lYSE8JWskTztKGyhC?= =?iso-2022-jp?b?GyRCMnE8VCROPjVHJyRyQlQkQyRGJCQkXiQ5GyhC?=""") # TK: full decode comparison - eq(h.__unicode__().encode('euc-jp'), int) + eq(str(h).encode(jcode), subject_bytes) + + def test_payload_encoding_utf8(self): + jhello = str(b'\xa5\xcf\xa5\xed\xa1\xbc\xa5\xef\xa1\xbc' + b'\xa5\xeb\xa5\xc9\xa1\xaa', 'euc-jp') + msg = Message() + msg.set_payload(jhello, 'utf-8') + ustr = msg.get_payload(decode=True).decode(msg.get_content_charset()) + self.assertEqual(jhello, ustr) def test_payload_encoding(self): - jhello = '\xa5\xcf\xa5\xed\xa1\xbc\xa5\xef\xa1\xbc\xa5\xeb\xa5\xc9\xa1\xaa' jcode = 'euc-jp' + jhello = str(b'\xa5\xcf\xa5\xed\xa1\xbc\xa5\xef\xa1\xbc' + b'\xa5\xeb\xa5\xc9\xa1\xaa', jcode) msg = Message() msg.set_payload(jhello, jcode) - ustr = str(msg.get_payload(), msg.get_content_charset()) - self.assertEqual(jhello, ustr.encode(jcode)) + ustr = msg.get_payload(decode=True).decode(msg.get_content_charset()) + self.assertEqual(jhello, ustr) diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/ftplib.py --- a/Lib/ftplib.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/ftplib.py Wed Mar 16 19:19:36 2011 -0400 @@ -620,7 +620,7 @@ Usage example: >>> from ftplib import FTP_TLS >>> ftps = FTP_TLS('ftp.python.org') - >>> ftps.login() # login anonimously previously securing control channel + >>> ftps.login() # login anonymously previously securing control channel '230 Guest login ok, access restrictions apply.' >>> ftps.prot_p() # switch to secure data connection '200 Protection level set to P' diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/gettext.py --- a/Lib/gettext.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/gettext.py Wed Mar 16 19:19:36 2011 -0400 @@ -282,7 +282,7 @@ # Note: we unconditionally convert both msgids and msgstrs to # Unicode using the character encoding specified in the charset # parameter of the Content-Type header. The gettext documentation - # strongly encourages msgids to be us-ascii, but some appliations + # strongly encourages msgids to be us-ascii, but some applications # require alternative encodings (e.g. Zope's ZCML and ZPT). For # traditional gettext applications, the msgid conversion will # cause no problems since us-ascii should always be a subset of diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/http/client.py --- a/Lib/http/client.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/http/client.py Wed Mar 16 19:19:36 2011 -0400 @@ -798,7 +798,7 @@ del self._buffer[:] # If msg and message_body are sent in a single send() call, # it will avoid performance problems caused by the interaction - # between delayed ack and the Nagle algorithim. + # between delayed ack and the Nagle algorithm. if isinstance(message_body, bytes): msg += message_body message_body = None diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/idlelib/EditorWindow.py --- a/Lib/idlelib/EditorWindow.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/idlelib/EditorWindow.py Wed Mar 16 19:19:36 2011 -0400 @@ -104,8 +104,8 @@ self.top = top = WindowList.ListedToplevel(root, menu=self.menubar) if flist: self.tkinter_vars = flist.vars - #self.top.instance_dict makes flist.inversedict avalable to - #configDialog.py so it can access all EditorWindow instaces + #self.top.instance_dict makes flist.inversedict available to + #configDialog.py so it can access all EditorWindow instances self.top.instance_dict = flist.inversedict else: self.tkinter_vars = {} # keys: Tkinter event names diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/idlelib/FormatParagraph.py --- a/Lib/idlelib/FormatParagraph.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/idlelib/FormatParagraph.py Wed Mar 16 19:19:36 2011 -0400 @@ -54,7 +54,7 @@ # If the block ends in a \n, we dont want the comment # prefix inserted after it. (Im not sure it makes sense to # reformat a comment block that isnt made of complete - # lines, but whatever!) Can't think of a clean soltution, + # lines, but whatever!) Can't think of a clean solution, # so we hack away block_suffix = "" if not newdata[-1]: diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/idlelib/HISTORY.txt --- a/Lib/idlelib/HISTORY.txt Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/idlelib/HISTORY.txt Wed Mar 16 19:19:36 2011 -0400 @@ -13,7 +13,7 @@ - New tarball released as a result of the 'revitalisation' of the IDLEfork project. -- This release requires python 2.1 or better. Compatability with earlier +- This release requires python 2.1 or better. Compatibility with earlier versions of python (especially ancient ones like 1.5x) is no longer a priority in IDLEfork development. diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/idlelib/extend.txt --- a/Lib/idlelib/extend.txt Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/idlelib/extend.txt Wed Mar 16 19:19:36 2011 -0400 @@ -18,7 +18,7 @@ An IDLE extension class is instantiated with a single argument, `editwin', an EditorWindow instance. The extension cannot assume much -about this argument, but it is guarateed to have the following instance +about this argument, but it is guaranteed to have the following instance variables: text a Text instance (a widget) diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/idlelib/macosxSupport.py --- a/Lib/idlelib/macosxSupport.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/idlelib/macosxSupport.py Wed Mar 16 19:19:36 2011 -0400 @@ -53,8 +53,8 @@ def addOpenEventSupport(root, flist): """ - This ensures that the application will respont to open AppleEvents, which - makes is feaseable to use IDLE as the default application for python files. + This ensures that the application will respond to open AppleEvents, which + makes is feasible to use IDLE as the default application for python files. """ def doOpenFile(*args): for fn in args: diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/importlib/_bootstrap.py --- a/Lib/importlib/_bootstrap.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/importlib/_bootstrap.py Wed Mar 16 19:19:36 2011 -0400 @@ -152,7 +152,7 @@ loader can handle. The first argument (self) must define _name which the second argument is - comapred against. If the comparison fails then ImportError is raised. + compared against. If the comparison fails then ImportError is raised. """ def inner(self, name, *args, **kwargs): @@ -240,7 +240,7 @@ @classmethod @_requires_builtin def is_package(cls, fullname): - """Return None as built-in module are never packages.""" + """Return None as built-in modules are never packages.""" return False @@ -304,7 +304,7 @@ def _bytes_from_bytecode(self, fullname, data, source_mtime): """Return the marshalled bytes from bytecode, verifying the magic - number and timestamp alon the way. + number and timestamp along the way. If source_mtime is None then skip the timestamp check. @@ -765,7 +765,7 @@ being made from, and the level adjustment. This function represents the greatest common denominator of functionality - between import_module and __import__. This includes settting __package__ if + between import_module and __import__. This includes setting __package__ if the loader did not. """ @@ -855,7 +855,7 @@ module = _gcd_import(name) else: # __package__ is not guaranteed to be defined or could be set to None - # to represent that it's proper value is unknown + # to represent that its proper value is unknown package = globals.get('__package__') if package is None: package = globals['__name__'] diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/inspect.py --- a/Lib/inspect.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/inspect.py Wed Mar 16 19:19:36 2011 -0400 @@ -1069,15 +1069,16 @@ instance_dict = object.__getattribute__(obj, "__dict__") except AttributeError: pass - return instance_dict.get(attr, _sentinel) + return dict.get(instance_dict, attr, _sentinel) def _check_class(klass, attr): for entry in _static_getmro(klass): - try: - return entry.__dict__[attr] - except KeyError: - pass + if not _shadowed_dict(type(entry)): + try: + return entry.__dict__[attr] + except KeyError: + pass return _sentinel def _is_type(obj): @@ -1087,6 +1088,19 @@ return False return True +def _shadowed_dict(klass): + dict_attr = type.__dict__["__dict__"] + for entry in _static_getmro(klass): + try: + class_dict = dict_attr.__get__(entry)["__dict__"] + except KeyError: + pass + else: + if not (type(class_dict) is types.GetSetDescriptorType and + class_dict.__name__ == "__dict__" and + class_dict.__objclass__ is entry): + return True + return False def getattr_static(obj, attr, default=_sentinel): """Retrieve attributes without triggering dynamic lookup via the @@ -1101,8 +1115,9 @@ """ instance_result = _sentinel if not _is_type(obj): - instance_result = _check_instance(obj, attr) klass = type(obj) + if not _shadowed_dict(klass): + instance_result = _check_instance(obj, attr) else: klass = obj diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/lib2to3/fixes/fix_metaclass.py --- a/Lib/lib2to3/fixes/fix_metaclass.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/lib2to3/fixes/fix_metaclass.py Wed Mar 16 19:19:36 2011 -0400 @@ -48,7 +48,7 @@ """ for node in cls_node.children: if node.type == syms.suite: - # already in the prefered format, do nothing + # already in the preferred format, do nothing return # !%@#! oneliners have no suite node, we have to fake one up diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/lib2to3/pgen2/conv.py --- a/Lib/lib2to3/pgen2/conv.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/lib2to3/pgen2/conv.py Wed Mar 16 19:19:36 2011 -0400 @@ -51,7 +51,7 @@ self.finish_off() def parse_graminit_h(self, filename): - """Parse the .h file writen by pgen. (Internal) + """Parse the .h file written by pgen. (Internal) This file is a sequence of #define statements defining the nonterminals of the grammar as numbers. We build two tables @@ -82,7 +82,7 @@ return True def parse_graminit_c(self, filename): - """Parse the .c file writen by pgen. (Internal) + """Parse the .c file written by pgen. (Internal) The file looks as follows. The first two lines are always this: diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/lib2to3/pytree.py --- a/Lib/lib2to3/pytree.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/lib2to3/pytree.py Wed Mar 16 19:19:36 2011 -0400 @@ -658,8 +658,8 @@ content: optional sequence of subsequences of patterns; if absent, matches one node; if present, each subsequence is an alternative [*] - min: optinal minumum number of times to match, default 0 - max: optional maximum number of times tro match, default HUGE + min: optional minimum number of times to match, default 0 + max: optional maximum number of times to match, default HUGE name: optional name assigned to this match [*] Thus, if content is [[a, b, c], [d, e], [f, g, h]] this is diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/lib2to3/tests/data/py2_test_grammar.py --- a/Lib/lib2to3/tests/data/py2_test_grammar.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/lib2to3/tests/data/py2_test_grammar.py Wed Mar 16 19:19:36 2011 -0400 @@ -316,7 +316,7 @@ ### simple_stmt: small_stmt (';' small_stmt)* [';'] x = 1; pass; del x def foo(): - # verify statments that end with semi-colons + # verify statements that end with semi-colons x = 1; pass; del x; foo() diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/lib2to3/tests/data/py3_test_grammar.py --- a/Lib/lib2to3/tests/data/py3_test_grammar.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/lib2to3/tests/data/py3_test_grammar.py Wed Mar 16 19:19:36 2011 -0400 @@ -356,7 +356,7 @@ ### simple_stmt: small_stmt (';' small_stmt)* [';'] x = 1; pass; del x def foo(): - # verify statments that end with semi-colons + # verify statements that end with semi-colons x = 1; pass; del x; foo() diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/multiprocessing/__init__.py --- a/Lib/multiprocessing/__init__.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/multiprocessing/__init__.py Wed Mar 16 19:19:36 2011 -0400 @@ -115,8 +115,11 @@ except (ValueError, KeyError): num = 0 elif 'bsd' in sys.platform or sys.platform == 'darwin': + comm = '/sbin/sysctl -n hw.ncpu' + if sys.platform == 'darwin': + comm = '/usr' + comm try: - with os.popen('sysctl -n hw.ncpu') as p: + with os.popen(comm) as p: num = int(p.read()) except ValueError: num = 0 diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/nntplib.py --- a/Lib/nntplib.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/nntplib.py Wed Mar 16 19:19:36 2011 -0400 @@ -315,7 +315,7 @@ readermode is sometimes necessary if you are connecting to an NNTP server on the local machine and intend to call - reader-specific comamnds, such as `group'. If you get + reader-specific commands, such as `group'. If you get unexpected NNTPPermanentErrors, you might need to set readermode. """ @@ -1015,7 +1015,7 @@ readermode is sometimes necessary if you are connecting to an NNTP server on the local machine and intend to call - reader-specific comamnds, such as `group'. If you get + reader-specific commands, such as `group'. If you get unexpected NNTPPermanentErrors, you might need to set readermode. """ diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/ntpath.py --- a/Lib/ntpath.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/ntpath.py Wed Mar 16 19:19:36 2011 -0400 @@ -405,7 +405,7 @@ # - $varname is accepted. # - %varname% is accepted. # - varnames can be made out of letters, digits and the characters '_-' -# (though is not verifed in the ${varname} and %varname% cases) +# (though is not verified in the ${varname} and %varname% cases) # XXX With COMMAND.COM you can use any characters in a variable name, # XXX except '^|<>='. diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/pickletools.py --- a/Lib/pickletools.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/pickletools.py Wed Mar 16 19:19:36 2011 -0400 @@ -1406,7 +1406,7 @@ proto=0, doc="""Read an object from the memo and push it on the stack. - The index of the memo object to push is given by the newline-teriminated + The index of the memo object to push is given by the newline-terminated decimal string following. BINGET and LONG_BINGET are space-optimized versions. """), diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/platform.py --- a/Lib/platform.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/platform.py Wed Mar 16 19:19:36 2011 -0400 @@ -417,7 +417,7 @@ info = pipe.read() if pipe.close(): raise os.error('command failed') - # XXX How can I supress shell errors from being written + # XXX How can I suppress shell errors from being written # to stderr ? except os.error as why: #print 'Command %s failed: %s' % (cmd,why) diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/shutil.py --- a/Lib/shutil.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/shutil.py Wed Mar 16 19:19:36 2011 -0400 @@ -737,8 +737,8 @@ except KeyError: raise ValueError("Unknown unpack format '{0}'".format(format)) - func = format_info[0] - func(filename, extract_dir, **dict(format_info[1])) + func = format_info[1] + func(filename, extract_dir, **dict(format_info[2])) else: # we need to look at the registered unpackers supported extensions format = _find_unpack_format(filename) diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/smtplib.py --- a/Lib/smtplib.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/smtplib.py Wed Mar 16 19:19:36 2011 -0400 @@ -269,6 +269,19 @@ pass self.local_hostname = '[%s]' % addr + def __enter__(self): + return self + + def __exit__(self, *args): + try: + code, message = self.docmd("QUIT") + if code != 221: + raise SMTPResponseException(code, message) + except SMTPServerDisconnected: + pass + finally: + self.close() + def set_debuglevel(self, debuglevel): """Set the debug output level. diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/socketserver.py --- a/Lib/socketserver.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/socketserver.py Wed Mar 16 19:19:36 2011 -0400 @@ -675,7 +675,7 @@ # A timeout to apply to the request socket, if not None. timeout = None - # Disable nagle algoritm for this socket, if True. + # Disable nagle algorithm for this socket, if True. # Use only when wbufsize != 0, to avoid small packets. disable_nagle_algorithm = False diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/subprocess.py --- a/Lib/subprocess.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/subprocess.py Wed Mar 16 19:19:36 2011 -0400 @@ -191,8 +191,10 @@ A ValueError will be raised if Popen is called with invalid arguments. -check_call() and check_output() will raise CalledProcessError, if the -called process returns a non-zero return code. +Exceptions defined within this module inherit from SubprocessError. +check_call() and check_output() will raise CalledProcessError if the +called process returns a non-zero return code. TimeoutExpired +be raised if a timeout was specified and expired. Security @@ -340,6 +342,7 @@ import io import os +import time import traceback import gc import signal @@ -347,7 +350,10 @@ import warnings # Exception classes used by this module. -class CalledProcessError(Exception): +class SubprocessError(Exception): pass + + +class CalledProcessError(SubprocessError): """This exception is raised when a process run by check_call() or check_output() returns a non-zero exit status. The exit status will be stored in the returncode attribute; @@ -361,6 +367,20 @@ return "Command '%s' returned non-zero exit status %d" % (self.cmd, self.returncode) +class TimeoutExpired(SubprocessError): + """This exception is raised when the timeout expires while waiting for a + child process. + """ + def __init__(self, cmd, timeout, output=None): + self.cmd = cmd + self.timeout = timeout + self.output = output + + def __str__(self): + return ("Command '%s' timed out after %s seconds" % + (self.cmd, self.timeout)) + + if mswindows: import threading import msvcrt @@ -412,7 +432,7 @@ return fds __all__ = ["Popen", "PIPE", "STDOUT", "call", "check_call", "getstatusoutput", - "getoutput", "check_output", "CalledProcessError"] + "getoutput", "check_output", "CalledProcessError", "DEVNULL"] if mswindows: from _subprocess import CREATE_NEW_CONSOLE, CREATE_NEW_PROCESS_GROUP @@ -437,6 +457,7 @@ PIPE = -1 STDOUT = -2 +DEVNULL = -3 def _eintr_retry_call(func, *args): @@ -449,15 +470,21 @@ raise -def call(*popenargs, **kwargs): - """Run command with arguments. Wait for command to complete, then - return the returncode attribute. +def call(*popenargs, timeout=None, **kwargs): + """Run command with arguments. Wait for command to complete or + timeout, then return the returncode attribute. The arguments are the same as for the Popen constructor. Example: retcode = call(["ls", "-l"]) """ - return Popen(*popenargs, **kwargs).wait() + p = Popen(*popenargs, **kwargs) + try: + return p.wait(timeout=timeout) + except TimeoutExpired: + p.kill() + p.wait() + raise def check_call(*popenargs, **kwargs): @@ -466,7 +493,7 @@ CalledProcessError. The CalledProcessError object will have the return code in the returncode attribute. - The arguments are the same as for the Popen constructor. Example: + The arguments are the same as for the call function. Example: check_call(["ls", "-l"]) """ @@ -479,7 +506,7 @@ return 0 -def check_output(*popenargs, **kwargs): +def check_output(*popenargs, timeout=None, **kwargs): r"""Run command with arguments and return its output as a byte string. If the exit code was non-zero it raises a CalledProcessError. The @@ -502,13 +529,15 @@ if 'stdout' in kwargs: raise ValueError('stdout argument not allowed, it will be overridden.') process = Popen(*popenargs, stdout=PIPE, **kwargs) - output, unused_err = process.communicate() + try: + output, unused_err = process.communicate(timeout=timeout) + except TimeoutExpired: + process.kill() + output, unused_err = process.communicate() + raise TimeoutExpired(process.args, timeout, output=output) retcode = process.poll() if retcode: - cmd = kwargs.get("args") - if cmd is None: - cmd = popenargs[0] - raise CalledProcessError(retcode, cmd, output=output) + raise CalledProcessError(retcode, process.args, output=output) return output @@ -639,6 +668,8 @@ _cleanup() self._child_created = False + self._input = None + self._communication_started = False if bufsize is None: bufsize = 0 # Restore default if not isinstance(bufsize, int): @@ -673,6 +704,7 @@ raise ValueError("creationflags is only supported on Windows " "platforms") + self.args = args self.stdin = None self.stdout = None self.stderr = None @@ -770,8 +802,12 @@ # Child is still running, keep us alive until we can wait on it. _active.append(self) + def _get_devnull(self): + if not hasattr(self, '_devnull'): + self._devnull = os.open(os.devnull, os.O_RDWR) + return self._devnull - def communicate(self, input=None): + def communicate(self, input=None, timeout=None): """Interact with process: Send data to stdin. Read data from stdout and stderr, until end-of-file is reached. Wait for process to terminate. The optional input argument should be a @@ -780,9 +816,19 @@ communicate() returns a tuple (stdout, stderr).""" - # Optimization: If we are only using one pipe, or no pipe at - # all, using select() or threads is unnecessary. - if [self.stdin, self.stdout, self.stderr].count(None) >= 2: + if self._communication_started and input: + raise ValueError("Cannot send input after starting communication") + + if timeout is not None: + endtime = time.time() + timeout + else: + endtime = None + + # Optimization: If we are not worried about timeouts, we haven't + # started communicating, and we have one or zero pipes, using select() + # or threads is unnecessary. + if (endtime is None and not self._communication_started and + [self.stdin, self.stdout, self.stderr].count(None) >= 2): stdout = None stderr = None if self.stdin: @@ -798,13 +844,36 @@ self.wait() return (stdout, stderr) - return self._communicate(input) + try: + stdout, stderr = self._communicate(input, endtime, timeout) + finally: + self._communication_started = True + + sts = self.wait(timeout=self._remaining_time(endtime)) + + return (stdout, stderr) def poll(self): return self._internal_poll() + def _remaining_time(self, endtime): + """Convenience for _communicate when computing timeouts.""" + if endtime is None: + return None + else: + return endtime - time.time() + + + def _check_timeout(self, endtime, orig_timeout): + """Convenience for checking if a timeout has expired.""" + if endtime is None: + return + if time.time() > endtime: + raise TimeoutExpired(self.args, orig_timeout) + + if mswindows: # # Windows methods @@ -826,6 +895,8 @@ p2cread, _ = _subprocess.CreatePipe(None, 0) elif stdin == PIPE: p2cread, p2cwrite = _subprocess.CreatePipe(None, 0) + elif stdin == DEVNULL: + p2cread = msvcrt.get_osfhandle(self._get_devnull()) elif isinstance(stdin, int): p2cread = msvcrt.get_osfhandle(stdin) else: @@ -839,6 +910,8 @@ _, c2pwrite = _subprocess.CreatePipe(None, 0) elif stdout == PIPE: c2pread, c2pwrite = _subprocess.CreatePipe(None, 0) + elif stdout == DEVNULL: + c2pwrite = msvcrt.get_osfhandle(self._get_devnull()) elif isinstance(stdout, int): c2pwrite = msvcrt.get_osfhandle(stdout) else: @@ -854,6 +927,8 @@ errread, errwrite = _subprocess.CreatePipe(None, 0) elif stderr == STDOUT: errwrite = c2pwrite + elif stderr == DEVNULL: + errwrite = msvcrt.get_osfhandle(self._get_devnull()) elif isinstance(stderr, int): errwrite = msvcrt.get_osfhandle(stderr) else: @@ -947,7 +1022,7 @@ except pywintypes.error as e: # Translate pywintypes.error to WindowsError, which is # a subclass of OSError. FIXME: We should really - # translate errno using _sys_errlist (or simliar), but + # translate errno using _sys_errlist (or similar), but # how can this be done from Python? raise WindowsError(*e.args) finally: @@ -963,6 +1038,8 @@ c2pwrite.Close() if errwrite != -1: errwrite.Close() + if hasattr(self, '_devnull'): + os.close(self._devnull) # Retain the process handle, but close the thread handle self._child_created = True @@ -987,12 +1064,19 @@ return self.returncode - def wait(self): + def wait(self, timeout=None, endtime=None): """Wait for child process to terminate. Returns returncode attribute.""" + if endtime is not None: + timeout = self._remaining_time(endtime) + if timeout is None: + timeout = _subprocess.INFINITE + else: + timeout = int(timeout * 1000) if self.returncode is None: - _subprocess.WaitForSingleObject(self._handle, - _subprocess.INFINITE) + result = _subprocess.WaitForSingleObject(self._handle, timeout) + if result == _subprocess.WAIT_TIMEOUT: + raise TimeoutExpired(self.args, timeout) self.returncode = _subprocess.GetExitCodeProcess(self._handle) return self.returncode @@ -1002,32 +1086,51 @@ fh.close() - def _communicate(self, input): - stdout = None # Return - stderr = None # Return - - if self.stdout: - stdout = [] - stdout_thread = threading.Thread(target=self._readerthread, - args=(self.stdout, stdout)) - stdout_thread.daemon = True - stdout_thread.start() - if self.stderr: - stderr = [] - stderr_thread = threading.Thread(target=self._readerthread, - args=(self.stderr, stderr)) - stderr_thread.daemon = True - stderr_thread.start() + def _communicate(self, input, endtime, orig_timeout): + # Start reader threads feeding into a list hanging off of this + # object, unless they've already been started. + if self.stdout and not hasattr(self, "_stdout_buff"): + self._stdout_buff = [] + self.stdout_thread = \ + threading.Thread(target=self._readerthread, + args=(self.stdout, self._stdout_buff)) + self.stdout_thread.daemon = True + self.stdout_thread.start() + if self.stderr and not hasattr(self, "_stderr_buff"): + self._stderr_buff = [] + self.stderr_thread = \ + threading.Thread(target=self._readerthread, + args=(self.stderr, self._stderr_buff)) + self.stderr_thread.daemon = True + self.stderr_thread.start() if self.stdin: if input is not None: self.stdin.write(input) self.stdin.close() + # Wait for the reader threads, or time out. If we time out, the + # threads remain reading and the fds left open in case the user + # calls communicate again. + if self.stdout is not None: + self.stdout_thread.join(self._remaining_time(endtime)) + if self.stdout_thread.isAlive(): + raise TimeoutExpired(self.args) + if self.stderr is not None: + self.stderr_thread.join(self._remaining_time(endtime)) + if self.stderr_thread.isAlive(): + raise TimeoutExpired(self.args) + + # Collect the output from and close both pipes, now that we know + # both have been read successfully. + stdout = None + stderr = None if self.stdout: - stdout_thread.join() + stdout = self._stdout_buff + self.stdout.close() if self.stderr: - stderr_thread.join() + stderr = self._stderr_buff + self.stderr.close() # All data exchanged. Translate lists into strings. if stdout is not None: @@ -1035,7 +1138,6 @@ if stderr is not None: stderr = stderr[0] - self.wait() return (stdout, stderr) def send_signal(self, sig): @@ -1073,6 +1175,8 @@ pass elif stdin == PIPE: p2cread, p2cwrite = _create_pipe() + elif stdin == DEVNULL: + p2cread = self._get_devnull() elif isinstance(stdin, int): p2cread = stdin else: @@ -1083,6 +1187,8 @@ pass elif stdout == PIPE: c2pread, c2pwrite = _create_pipe() + elif stdout == DEVNULL: + c2pwrite = self._get_devnull() elif isinstance(stdout, int): c2pwrite = stdout else: @@ -1095,6 +1201,8 @@ errread, errwrite = _create_pipe() elif stderr == STDOUT: errwrite = c2pwrite + elif stderr == DEVNULL: + errwrite = self._get_devnull() elif isinstance(stderr, int): errwrite = stderr else: @@ -1288,6 +1396,8 @@ os.close(c2pwrite) if errwrite != -1 and errread != -1: os.close(errwrite) + if hasattr(self, '_devnull'): + os.close(self._devnull) # Wait for exec to fail or succeed; possibly raising an # exception (limited in size) @@ -1365,25 +1475,57 @@ return self.returncode - def wait(self): + def _try_wait(self, wait_flags): + try: + (pid, sts) = _eintr_retry_call(os.waitpid, self.pid, wait_flags) + except OSError as e: + if e.errno != errno.ECHILD: + raise + # This happens if SIGCLD is set to be ignored or waiting + # for child processes has otherwise been disabled for our + # process. This child is dead, we can't get the status. + pid = self.pid + sts = 0 + return (pid, sts) + + + def wait(self, timeout=None, endtime=None): """Wait for child process to terminate. Returns returncode attribute.""" - if self.returncode is None: - try: - pid, sts = _eintr_retry_call(os.waitpid, self.pid, 0) - except OSError as e: - if e.errno != errno.ECHILD: - raise - # This happens if SIGCLD is set to be ignored or waiting - # for child processes has otherwise been disabled for our - # process. This child is dead, we can't get the status. - sts = 0 + if self.returncode is not None: + return self.returncode + + # endtime is preferred to timeout. timeout is only used for + # printing. + if endtime is not None or timeout is not None: + if endtime is None: + endtime = time.time() + timeout + elif timeout is None: + timeout = self._remaining_time(endtime) + + if endtime is not None: + # Enter a busy loop if we have a timeout. This busy loop was + # cribbed from Lib/threading.py in Thread.wait() at r71065. + delay = 0.0005 # 500 us -> initial delay of 1 ms + while True: + (pid, sts) = self._try_wait(os.WNOHANG) + assert pid == self.pid or pid == 0 + if pid == self.pid: + self._handle_exitstatus(sts) + break + remaining = self._remaining_time(endtime) + if remaining <= 0: + raise TimeoutExpired(self.args, timeout) + delay = min(delay * 2, remaining, .05) + time.sleep(delay) + elif self.returncode is None: + (pid, sts) = self._try_wait(0) self._handle_exitstatus(sts) return self.returncode - def _communicate(self, input): - if self.stdin: + def _communicate(self, input, endtime, orig_timeout): + if self.stdin and not self._communication_started: # Flush stdio buffer. This might block, if the user has # been writing to .stdin in an uncontrolled fashion. self.stdin.flush() @@ -1391,9 +1533,13 @@ self.stdin.close() if _has_poll: - stdout, stderr = self._communicate_with_poll(input) + stdout, stderr = self._communicate_with_poll(input, endtime, + orig_timeout) else: - stdout, stderr = self._communicate_with_select(input) + stdout, stderr = self._communicate_with_select(input, endtime, + orig_timeout) + + self.wait(timeout=self._remaining_time(endtime)) # All data exchanged. Translate lists into strings. if stdout is not None: @@ -1411,60 +1557,77 @@ stderr = self._translate_newlines(stderr, self.stderr.encoding) - self.wait() return (stdout, stderr) - def _communicate_with_poll(self, input): + def _communicate_with_poll(self, input, endtime, orig_timeout): stdout = None # Return stderr = None # Return - fd2file = {} - fd2output = {} + + if not self._communication_started: + self._fd2file = {} poller = select.poll() def register_and_append(file_obj, eventmask): poller.register(file_obj.fileno(), eventmask) - fd2file[file_obj.fileno()] = file_obj + self._fd2file[file_obj.fileno()] = file_obj def close_unregister_and_remove(fd): poller.unregister(fd) - fd2file[fd].close() - fd2file.pop(fd) + self._fd2file[fd].close() + self._fd2file.pop(fd) if self.stdin and input: register_and_append(self.stdin, select.POLLOUT) + # Only create this mapping if we haven't already. + if not self._communication_started: + self._fd2output = {} + if self.stdout: + self._fd2output[self.stdout.fileno()] = [] + if self.stderr: + self._fd2output[self.stderr.fileno()] = [] + select_POLLIN_POLLPRI = select.POLLIN | select.POLLPRI if self.stdout: register_and_append(self.stdout, select_POLLIN_POLLPRI) - fd2output[self.stdout.fileno()] = stdout = [] + stdout = self._fd2output[self.stdout.fileno()] if self.stderr: register_and_append(self.stderr, select_POLLIN_POLLPRI) - fd2output[self.stderr.fileno()] = stderr = [] + stderr = self._fd2output[self.stderr.fileno()] - input_offset = 0 - while fd2file: + # Save the input here so that if we time out while communicating, + # we can continue sending input if we retry. + if self.stdin and self._input is None: + self._input_offset = 0 + self._input = input + if self.universal_newlines: + self._input = self._input.encode(self.stdin.encoding) + + while self._fd2file: try: - ready = poller.poll() + ready = poller.poll(self._remaining_time(endtime)) except select.error as e: if e.args[0] == errno.EINTR: continue raise + self._check_timeout(endtime, orig_timeout) # XXX Rewrite these to use non-blocking I/O on the # file objects; they are no longer using C stdio! for fd, mode in ready: if mode & select.POLLOUT: - chunk = input[input_offset : input_offset + _PIPE_BUF] - input_offset += os.write(fd, chunk) - if input_offset >= len(input): + chunk = self._input[self._input_offset : + self._input_offset + _PIPE_BUF] + self._input_offset += os.write(fd, chunk) + if self._input_offset >= len(self._input): close_unregister_and_remove(fd) elif mode & select_POLLIN_POLLPRI: data = os.read(fd, 4096) if not data: close_unregister_and_remove(fd) - fd2output[fd].append(data) + self._fd2output[fd].append(data) else: # Ignore hang up or errors. close_unregister_and_remove(fd) @@ -1472,53 +1635,76 @@ return (stdout, stderr) - def _communicate_with_select(self, input): - read_set = [] - write_set = [] + def _communicate_with_select(self, input, endtime, orig_timeout): + if not self._communication_started: + self._read_set = [] + self._write_set = [] + if self.stdin and input: + self._write_set.append(self.stdin) + if self.stdout: + self._read_set.append(self.stdout) + if self.stderr: + self._read_set.append(self.stderr) + + if self.stdin and self._input is None: + self._input_offset = 0 + self._input = input + if self.universal_newlines: + self._input = self._input.encode(self.stdin.encoding) + stdout = None # Return stderr = None # Return - if self.stdin and input: - write_set.append(self.stdin) if self.stdout: - read_set.append(self.stdout) - stdout = [] + if not self._communication_started: + self._stdout_buff = [] + stdout = self._stdout_buff if self.stderr: - read_set.append(self.stderr) - stderr = [] + if not self._communication_started: + self._stderr_buff = [] + stderr = self._stderr_buff - input_offset = 0 - while read_set or write_set: + while self._read_set or self._write_set: try: - rlist, wlist, xlist = select.select(read_set, write_set, []) + (rlist, wlist, xlist) = \ + select.select(self._read_set, self._write_set, [], + self._remaining_time(endtime)) except select.error as e: if e.args[0] == errno.EINTR: continue raise + # According to the docs, returning three empty lists indicates + # that the timeout expired. + if not (rlist or wlist or xlist): + raise TimeoutExpired(self.args, orig_timeout) + # We also check what time it is ourselves for good measure. + self._check_timeout(endtime, orig_timeout) + # XXX Rewrite these to use non-blocking I/O on the # file objects; they are no longer using C stdio! if self.stdin in wlist: - chunk = input[input_offset : input_offset + _PIPE_BUF] + chunk = self._input[self._input_offset : + self._input_offset + _PIPE_BUF] bytes_written = os.write(self.stdin.fileno(), chunk) - input_offset += bytes_written - if input_offset >= len(input): + self._input_offset += bytes_written + if self._input_offset >= len(self._input): self.stdin.close() - write_set.remove(self.stdin) + self._write_set.remove(self.stdin) if self.stdout in rlist: data = os.read(self.stdout.fileno(), 1024) if not data: self.stdout.close() - read_set.remove(self.stdout) + self._read_set.remove(self.stdout) stdout.append(data) if self.stderr in rlist: data = os.read(self.stderr.fileno(), 1024) if not data: self.stderr.close() - read_set.remove(self.stderr) + self._read_set.remove(self.stderr) stderr.append(data) return (stdout, stderr) diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/test/crashers/recursion_limit_too_high.py --- a/Lib/test/crashers/recursion_limit_too_high.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/test/crashers/recursion_limit_too_high.py Wed Mar 16 19:19:36 2011 -0400 @@ -5,7 +5,7 @@ # file handles. # The point of this example is to show that sys.setrecursionlimit() is a -# hack, and not a robust solution. This example simply exercices a path +# hack, and not a robust solution. This example simply exercises a path # where it takes many C-level recursions, consuming a lot of stack # space, for each Python-level recursion. So 1000 times this amount of # stack space may be too much for standard platforms already. diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/test/datetimetester.py --- a/Lib/test/datetimetester.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/test/datetimetester.py Wed Mar 16 19:19:36 2011 -0400 @@ -3414,7 +3414,7 @@ self.assertEqual(dt, there_and_back) # Because we have a redundant spelling when DST begins, there is - # (unforunately) an hour when DST ends that can't be spelled at all in + # (unfortunately) an hour when DST ends that can't be spelled at all in # local time. When DST ends, the clock jumps from 1:59 back to 1:00 # again. The hour 1:MM DST has no spelling then: 1:MM is taken to be # standard time. 1:MM DST == 0:MM EST, but 0:MM is taken to be diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/test/pyclbr_input.py --- a/Lib/test/pyclbr_input.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/test/pyclbr_input.py Wed Mar 16 19:19:36 2011 -0400 @@ -19,7 +19,7 @@ # XXX: This causes test_pyclbr.py to fail, but only because the # introspection-based is_method() code in the test can't - # distinguish between this and a geniune method function like m(). + # distinguish between this and a genuine method function like m(). # The pyclbr.py module gets this right as it parses the text. # #f = f diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/test/support.py --- a/Lib/test/support.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/test/support.py Wed Mar 16 19:19:36 2011 -0400 @@ -1374,7 +1374,7 @@ def args_from_interpreter_flags(): """Return a list of command-line arguments reproducing the current - settings in sys.flags.""" + settings in sys.flags and sys.warnoptions.""" flag_opt_map = { 'bytes_warning': 'b', 'dont_write_bytecode': 'B', @@ -1389,6 +1389,9 @@ v = getattr(sys.flags, flag) if v > 0: args.append('-' + opt * v) + if sys.warnoptions: + args.append('-W') + args.extend(sys.warnoptions) return args #============================================================ @@ -1462,9 +1465,11 @@ global _can_symlink if _can_symlink is not None: return _can_symlink + symlink_path = TESTFN + "can_symlink" try: - os.symlink(TESTFN, TESTFN + "can_symlink") + os.symlink(TESTFN, symlink_path) can = True + os.remove(symlink_path) except (OSError, NotImplementedError): can = False _can_symlink = can @@ -1475,3 +1480,36 @@ ok = can_symlink() msg = "Requires functional symlink implementation" return test if ok else unittest.skip(msg)(test) + +def patch(test_instance, object_to_patch, attr_name, new_value): + """Override 'object_to_patch'.'attr_name' with 'new_value'. + + Also, add a cleanup procedure to 'test_instance' to restore + 'object_to_patch' value for 'attr_name'. + The 'attr_name' should be a valid attribute for 'object_to_patch'. + + """ + # check that 'attr_name' is a real attribute for 'object_to_patch' + # will raise AttributeError if it does not exist + getattr(object_to_patch, attr_name) + + # keep a copy of the old value + attr_is_local = False + try: + old_value = object_to_patch.__dict__[attr_name] + except (AttributeError, KeyError): + old_value = getattr(object_to_patch, attr_name, None) + else: + attr_is_local = True + + # restore the value when the test is done + def cleanup(): + if attr_is_local: + setattr(object_to_patch, attr_name, old_value) + else: + delattr(object_to_patch, attr_name) + + test_instance.addCleanup(cleanup) + + # actually override the attribute + setattr(object_to_patch, attr_name, new_value) diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/test/test_capi.py --- a/Lib/test/test_capi.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/test/test_capi.py Wed Mar 16 19:19:36 2011 -0400 @@ -127,7 +127,7 @@ context.event.set() def test_pendingcalls_non_threaded(self): - #again, just using the main thread, likely they will all be dispathced at + #again, just using the main thread, likely they will all be dispatched at #once. It is ok to ask for too many, because we loop until we find a slot. #the loop can be interrupted to dispatch. #there are only 32 dispatch slots, so we go for twice that! diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/test/test_compile.py --- a/Lib/test/test_compile.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/test/test_compile.py Wed Mar 16 19:19:36 2011 -0400 @@ -190,7 +190,7 @@ self.assertEqual(eval("-" + all_one_bits), -18446744073709551615) else: self.fail("How many bits *does* this machine have???") - # Verify treatment of contant folding on -(sys.maxsize+1) + # Verify treatment of constant folding on -(sys.maxsize+1) # i.e. -2147483648 on 32 bit platforms. Should return int, not long. self.assertIsInstance(eval("%s" % (-sys.maxsize - 1)), int) self.assertIsInstance(eval("%s" % (-sys.maxsize - 2)), int) diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/test/test_dbm.py --- a/Lib/test/test_dbm.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/test/test_dbm.py Wed Mar 16 19:19:36 2011 -0400 @@ -70,6 +70,14 @@ self.read_helper(f) f.close() + def test_anydbm_creation_n_file_exists_with_invalid_contents(self): + with open(_fname, "w") as w: + pass # create an empty file + + f = dbm.open(_fname, 'n') + self.addCleanup(f.close) + self.assertEqual(len(f), 0) + def test_anydbm_modification(self): self.init_db() f = dbm.open(_fname, 'c') diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/test/test_decimal.py --- a/Lib/test/test_decimal.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/test/test_decimal.py Wed Mar 16 19:19:36 2011 -0400 @@ -228,7 +228,7 @@ try: t = self.eval_line(line) except DecimalException as exception: - #Exception raised where there shoudn't have been one. + #Exception raised where there shouldn't have been one. self.fail('Exception "'+exception.__class__.__name__ + '" raised on line '+line) return diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/test/test_descr.py --- a/Lib/test/test_descr.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/test/test_descr.py Wed Mar 16 19:19:36 2011 -0400 @@ -772,7 +772,7 @@ # see "A Monotonic Superclass Linearization for Dylan", # by Kim Barrett et al. (OOPSLA 1996) def test_consistency_with_epg(self): - # Testing consistentcy with EPG... + # Testing consistency with EPG... class Pane(object): pass class ScrollingMixin(object): pass class EditingMixin(object): pass @@ -3967,7 +3967,7 @@ except TypeError: pass else: - self.fail("Carlo Verre __setattr__ suceeded!") + self.fail("Carlo Verre __setattr__ succeeded!") try: object.__delattr__(str, "lower") except TypeError: diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/test/test_dis.py --- a/Lib/test/test_dis.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/test/test_dis.py Wed Mar 16 19:19:36 2011 -0400 @@ -1,11 +1,35 @@ # Minimal tests for dis module from test.support import run_unittest, captured_stdout +import difflib import unittest import sys import dis import io +class _C: + def __init__(self, x): + self.x = x == 1 + +dis_c_instance_method = """\ + %-4d 0 LOAD_FAST 1 (x) + 3 LOAD_CONST 1 (1) + 6 COMPARE_OP 2 (==) + 9 LOAD_FAST 0 (self) + 12 STORE_ATTR 0 (x) + 15 LOAD_CONST 0 (None) + 18 RETURN_VALUE +""" % (_C.__init__.__code__.co_firstlineno + 1,) + +dis_c_instance_method_bytes = """\ + 0 LOAD_FAST 1 (1) + 3 LOAD_CONST 1 (1) + 6 COMPARE_OP 2 (==) + 9 LOAD_FAST 0 (0) + 12 STORE_ATTR 0 (0) + 15 LOAD_CONST 0 (0) + 18 RETURN_VALUE +""" def _f(a): print(a) @@ -23,6 +47,16 @@ _f.__code__.co_firstlineno + 2) +dis_f_co_code = """\ + 0 LOAD_GLOBAL 0 (0) + 3 LOAD_FAST 0 (0) + 6 CALL_FUNCTION 1 + 9 POP_TOP + 10 LOAD_CONST 1 (1) + 13 RETURN_VALUE +""" + + def bug708901(): for res in range(1, 10): @@ -138,18 +172,27 @@ """ class DisTests(unittest.TestCase): - def do_disassembly_test(self, func, expected): + + def get_disassembly(self, func, lasti=-1, wrapper=True): s = io.StringIO() save_stdout = sys.stdout sys.stdout = s - dis.dis(func) - sys.stdout = save_stdout - got = s.getvalue() + try: + if wrapper: + dis.dis(func) + else: + dis.disassemble(func, lasti) + finally: + sys.stdout = save_stdout # Trim trailing blanks (if any). - lines = got.split('\n') - lines = [line.rstrip() for line in lines] - expected = expected.split("\n") - import difflib + return [line.rstrip() for line in s.getvalue().splitlines()] + + def get_disassemble_as_string(self, func, lasti=-1): + return '\n'.join(self.get_disassembly(func, lasti, False)) + + def do_disassembly_test(self, func, expected): + lines = self.get_disassembly(func) + expected = expected.splitlines() if expected != lines: self.fail( "events did not match expectation:\n" + @@ -211,6 +254,44 @@ self.do_disassembly_test(simple_stmt_str, dis_simple_stmt_str) self.do_disassembly_test(compound_stmt_str, dis_compound_stmt_str) + def test_disassemble_bytes(self): + self.do_disassembly_test(_f.__code__.co_code, dis_f_co_code) + + def test_disassemble_method(self): + self.do_disassembly_test(_C(1).__init__, dis_c_instance_method) + + def test_disassemble_method_bytes(self): + method_bytecode = _C(1).__init__.__code__.co_code + self.do_disassembly_test(method_bytecode, dis_c_instance_method_bytes) + + def test_dis_none(self): + try: + del sys.last_traceback + except AttributeError: + pass + self.assertRaises(RuntimeError, dis.dis, None) + + def test_dis_object(self): + self.assertRaises(TypeError, dis.dis, object()) + + def test_dis_traceback(self): + try: + del sys.last_traceback + except AttributeError: + pass + + try: + 1/0 + except Exception as e: + tb = e.__traceback__ + sys.last_traceback = tb + + tb_dis = self.get_disassemble_as_string(tb.tb_frame.f_code, tb.tb_lasti) + self.do_disassembly_test(None, tb_dis) + + def test_dis_object(self): + self.assertRaises(TypeError, dis.dis, object()) + code_info_code_info = """\ Name: code_info Filename: (.*) @@ -363,6 +444,13 @@ dis.show_code(x) self.assertRegex(output.getvalue(), expected+"\n") + def test_code_info_object(self): + self.assertRaises(TypeError, dis.code_info, object()) + + def test_pretty_flags_no_flags(self): + self.assertEqual(dis.pretty_flags(0), '0x0') + + def test_main(): run_unittest(DisTests, CodeInfoTests) diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/test/test_doctest.py --- a/Lib/test/test_doctest.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/test/test_doctest.py Wed Mar 16 19:19:36 2011 -0400 @@ -1297,7 +1297,7 @@ ? + ++ ^ TestResults(failed=1, attempted=1) -The REPORT_ONLY_FIRST_FAILURE supresses result output after the first +The REPORT_ONLY_FIRST_FAILURE suppresses result output after the first failing example: >>> def f(x): @@ -1327,7 +1327,7 @@ 2 TestResults(failed=3, attempted=5) -However, output from `report_start` is not supressed: +However, output from `report_start` is not suppressed: >>> doctest.DocTestRunner(verbose=True, optionflags=flags).run(test) ... # doctest: +ELLIPSIS @@ -2278,7 +2278,7 @@ >>> doctest.master = None # Reset master. (Note: we'll be clearing doctest.master after each call to -`doctest.testfile`, to supress warnings about multiple tests with the +`doctest.testfile`, to suppress warnings about multiple tests with the same name.) Globals may be specified with the `globs` and `extraglobs` parameters: @@ -2314,7 +2314,7 @@ TestResults(failed=0, attempted=2) >>> doctest.master = None # Reset master. -Verbosity can be increased with the optional `verbose` paremter: +Verbosity can be increased with the optional `verbose` parameter: >>> doctest.testfile('test_doctest.txt', globs=globs, verbose=True) Trying: @@ -2351,7 +2351,7 @@ TestResults(failed=1, attempted=2) >>> doctest.master = None # Reset master. -The summary report may be supressed with the optional `report` +The summary report may be suppressed with the optional `report` parameter: >>> doctest.testfile('test_doctest.txt', report=False) diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/test/test_email.py --- a/Lib/test/test_email.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/test/test_email.py Wed Mar 16 19:19:36 2011 -0400 @@ -3,10 +3,12 @@ # The specific tests now live in Lib/email/test from email.test.test_email import suite +from email.test.test_email_codecs import suite as codecs_suite from test import support def test_main(): support.run_unittest(suite()) + support.run_unittest(codecs_suite()) if __name__ == '__main__': test_main() diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/test/test_extcall.py --- a/Lib/test/test_extcall.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/test/test_extcall.py Wed Mar 16 19:19:36 2011 -0400 @@ -228,7 +228,7 @@ >>> Foo.method(1, *[2, 3]) 5 -A PyCFunction that takes only positional parameters shoud allow an +A PyCFunction that takes only positional parameters should allow an empty keyword dictionary to pass without a complaint, but raise a TypeError if te dictionary is not empty diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/test/test_fileinput.py --- a/Lib/test/test_fileinput.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/test/test_fileinput.py Wed Mar 16 19:19:36 2011 -0400 @@ -2,18 +2,27 @@ Tests for fileinput module. Nick Mathewson ''' +import os +import sys +import re +import fileinput +import collections +import gzip +import bz2 +import types +import codecs +import unittest -import unittest -from test.support import verbose, TESTFN, run_unittest -from test.support import unlink as safe_unlink -import sys, re from io import StringIO from fileinput import FileInput, hook_encoded +from test.support import verbose, TESTFN, run_unittest +from test.support import unlink as safe_unlink + + # The fileinput module has 2 interfaces: the FileInput class which does # all the work, and a few functions (input, etc.) that use a global _state -# variable. We only test the FileInput class, since the other functions -# only provide a thin facade over FileInput. +# variable. # Write lines (a list of lines) to temp file number i, and return the # temp file's name. @@ -121,7 +130,16 @@ self.assertEqual(int(m.group(1)), fi.filelineno()) fi.close() +class UnconditionallyRaise: + def __init__(self, exception_type): + self.exception_type = exception_type + self.invoked = False + def __call__(self, *args, **kwargs): + self.invoked = True + raise self.exception_type() + class FileInputTests(unittest.TestCase): + def test_zero_byte_files(self): t1 = t2 = t3 = t4 = None try: @@ -219,17 +237,20 @@ self.fail("FileInput should check openhook for being callable") except ValueError: pass - # XXX The rot13 codec was removed. - # So this test needs to be changed to use something else. - # (Or perhaps the API needs to change so we can just pass - # an encoding rather than using a hook?) -## try: -## t1 = writeTmp(1, ["A\nB"], mode="wb") -## fi = FileInput(files=t1, openhook=hook_encoded("rot13")) -## lines = list(fi) -## self.assertEqual(lines, ["N\n", "O"]) -## finally: -## remove_tempfiles(t1) + + class CustomOpenHook: + def __init__(self): + self.invoked = False + def __call__(self, *args): + self.invoked = True + return open(*args) + + t = writeTmp(1, ["\n"]) + self.addCleanup(remove_tempfiles, t) + custom_open_hook = CustomOpenHook() + with FileInput([t], openhook=custom_open_hook) as fi: + fi.readline() + self.assertTrue(custom_open_hook.invoked, "openhook not invoked") def test_context_manager(self): try: @@ -254,9 +275,583 @@ finally: remove_tempfiles(t1) + def test_empty_files_list_specified_to_constructor(self): + with FileInput(files=[]) as fi: + self.assertEqual(fi._files, ('-',)) + + def test__getitem__(self): + """Tests invoking FileInput.__getitem__() with the current + line number""" + t = writeTmp(1, ["line1\n", "line2\n"]) + self.addCleanup(remove_tempfiles, t) + with FileInput(files=[t]) as fi: + retval1 = fi[0] + self.assertEqual(retval1, "line1\n") + retval2 = fi[1] + self.assertEqual(retval2, "line2\n") + + def test__getitem__invalid_key(self): + """Tests invoking FileInput.__getitem__() with an index unequal to + the line number""" + t = writeTmp(1, ["line1\n", "line2\n"]) + self.addCleanup(remove_tempfiles, t) + with FileInput(files=[t]) as fi: + with self.assertRaises(RuntimeError) as cm: + fi[1] + self.assertEqual(cm.exception.args, ("accessing lines out of order",)) + + def test__getitem__eof(self): + """Tests invoking FileInput.__getitem__() with the line number but at + end-of-input""" + t = writeTmp(1, []) + self.addCleanup(remove_tempfiles, t) + with FileInput(files=[t]) as fi: + with self.assertRaises(IndexError) as cm: + fi[0] + self.assertEqual(cm.exception.args, ("end of input reached",)) + + def test_nextfile_oserror_deleting_backup(self): + """Tests invoking FileInput.nextfile() when the attempt to delete + the backup file would raise OSError. This error is expected to be + silently ignored""" + + os_unlink_orig = os.unlink + os_unlink_replacement = UnconditionallyRaise(OSError) + try: + t = writeTmp(1, ["\n"]) + self.addCleanup(remove_tempfiles, t) + with FileInput(files=[t], inplace=True) as fi: + next(fi) # make sure the file is opened + os.unlink = os_unlink_replacement + fi.nextfile() + finally: + os.unlink = os_unlink_orig + + # sanity check to make sure that our test scenario was actually hit + self.assertTrue(os_unlink_replacement.invoked, + "os.unlink() was not invoked") + + def test_readline_os_fstat_raises_OSError(self): + """Tests invoking FileInput.readline() when os.fstat() raises OSError. + This exception should be silently discarded.""" + + os_fstat_orig = os.fstat + os_fstat_replacement = UnconditionallyRaise(OSError) + try: + t = writeTmp(1, ["\n"]) + self.addCleanup(remove_tempfiles, t) + with FileInput(files=[t], inplace=True) as fi: + os.fstat = os_fstat_replacement + fi.readline() + finally: + os.fstat = os_fstat_orig + + # sanity check to make sure that our test scenario was actually hit + self.assertTrue(os_fstat_replacement.invoked, + "os.fstat() was not invoked") + + @unittest.skipIf(not hasattr(os, "chmod"), "os.chmod does not exist") + def test_readline_os_chmod_raises_OSError(self): + """Tests invoking FileInput.readline() when os.chmod() raises OSError. + This exception should be silently discarded.""" + + os_chmod_orig = os.chmod + os_chmod_replacement = UnconditionallyRaise(OSError) + try: + t = writeTmp(1, ["\n"]) + self.addCleanup(remove_tempfiles, t) + with FileInput(files=[t], inplace=True) as fi: + os.chmod = os_chmod_replacement + fi.readline() + finally: + os.chmod = os_chmod_orig + + # sanity check to make sure that our test scenario was actually hit + self.assertTrue(os_chmod_replacement.invoked, + "os.fstat() was not invoked") + + def test_fileno_when_ValueError_raised(self): + class FilenoRaisesValueError(UnconditionallyRaise): + def __init__(self): + UnconditionallyRaise.__init__(self, ValueError) + def fileno(self): + self.__call__() + + unconditionally_raise_ValueError = FilenoRaisesValueError() + t = writeTmp(1, ["\n"]) + self.addCleanup(remove_tempfiles, t) + with FileInput(files=[t]) as fi: + file_backup = fi._file + try: + fi._file = unconditionally_raise_ValueError + result = fi.fileno() + finally: + fi._file = file_backup # make sure the file gets cleaned up + + # sanity check to make sure that our test scenario was actually hit + self.assertTrue(unconditionally_raise_ValueError.invoked, + "_file.fileno() was not invoked") + + self.assertEqual(result, -1, "fileno() should return -1") + +class MockFileInput: + """A class that mocks out fileinput.FileInput for use during unit tests""" + + def __init__(self, files=None, inplace=False, backup="", bufsize=0, + mode="r", openhook=None): + self.files = files + self.inplace = inplace + self.backup = backup + self.bufsize = bufsize + self.mode = mode + self.openhook = openhook + self._file = None + self.invocation_counts = collections.defaultdict(lambda: 0) + self.return_values = {} + + def close(self): + self.invocation_counts["close"] += 1 + + def nextfile(self): + self.invocation_counts["nextfile"] += 1 + return self.return_values["nextfile"] + + def filename(self): + self.invocation_counts["filename"] += 1 + return self.return_values["filename"] + + def lineno(self): + self.invocation_counts["lineno"] += 1 + return self.return_values["lineno"] + + def filelineno(self): + self.invocation_counts["filelineno"] += 1 + return self.return_values["filelineno"] + + def fileno(self): + self.invocation_counts["fileno"] += 1 + return self.return_values["fileno"] + + def isfirstline(self): + self.invocation_counts["isfirstline"] += 1 + return self.return_values["isfirstline"] + + def isstdin(self): + self.invocation_counts["isstdin"] += 1 + return self.return_values["isstdin"] + +class BaseFileInputGlobalMethodsTest(unittest.TestCase): + """Base class for unit tests for the global function of + the fileinput module.""" + + def setUp(self): + self._orig_state = fileinput._state + self._orig_FileInput = fileinput.FileInput + fileinput.FileInput = MockFileInput + + def tearDown(self): + fileinput.FileInput = self._orig_FileInput + fileinput._state = self._orig_state + + def assertExactlyOneInvocation(self, mock_file_input, method_name): + # assert that the method with the given name was invoked once + actual_count = mock_file_input.invocation_counts[method_name] + self.assertEqual(actual_count, 1, method_name) + # assert that no other unexpected methods were invoked + actual_total_count = len(mock_file_input.invocation_counts) + self.assertEqual(actual_total_count, 1) + +class Test_fileinput_input(BaseFileInputGlobalMethodsTest): + """Unit tests for fileinput.input()""" + + def test_state_is_not_None_and_state_file_is_not_None(self): + """Tests invoking fileinput.input() when fileinput._state is not None + and its _file attribute is also not None. Expect RuntimeError to + be raised with a meaningful error message and for fileinput._state + to *not* be modified.""" + instance = MockFileInput() + instance._file = object() + fileinput._state = instance + with self.assertRaises(RuntimeError) as cm: + fileinput.input() + self.assertEqual(("input() already active",), cm.exception.args) + self.assertIs(instance, fileinput._state, "fileinput._state") + + def test_state_is_not_None_and_state_file_is_None(self): + """Tests invoking fileinput.input() when fileinput._state is not None + but its _file attribute *is* None. Expect it to create and return + a new fileinput.FileInput object with all method parameters passed + explicitly to the __init__() method; also ensure that + fileinput._state is set to the returned instance.""" + instance = MockFileInput() + instance._file = None + fileinput._state = instance + self.do_test_call_input() + + def test_state_is_None(self): + """Tests invoking fileinput.input() when fileinput._state is None + Expect it to create and return a new fileinput.FileInput object + with all method parameters passed explicitly to the __init__() + method; also ensure that fileinput._state is set to the returned + instance.""" + fileinput._state = None + self.do_test_call_input() + + def do_test_call_input(self): + """Tests that fileinput.input() creates a new fileinput.FileInput + object, passing the given parameters unmodified to + fileinput.FileInput.__init__(). Note that this test depends on the + monkey patching of fileinput.FileInput done by setUp().""" + files = object() + inplace = object() + backup = object() + bufsize = object() + mode = object() + openhook = object() + + # call fileinput.input() with different values for each argument + result = fileinput.input(files=files, inplace=inplace, backup=backup, + bufsize=bufsize, + mode=mode, openhook=openhook) + + # ensure fileinput._state was set to the returned object + self.assertIs(result, fileinput._state, "fileinput._state") + + # ensure the parameters to fileinput.input() were passed directly + # to FileInput.__init__() + self.assertIs(files, result.files, "files") + self.assertIs(inplace, result.inplace, "inplace") + self.assertIs(backup, result.backup, "backup") + self.assertIs(bufsize, result.bufsize, "bufsize") + self.assertIs(mode, result.mode, "mode") + self.assertIs(openhook, result.openhook, "openhook") + +class Test_fileinput_close(BaseFileInputGlobalMethodsTest): + """Unit tests for fileinput.close()""" + + def test_state_is_None(self): + """Tests that fileinput.close() does nothing if fileinput._state + is None""" + fileinput._state = None + fileinput.close() + self.assertIsNone(fileinput._state) + + def test_state_is_not_None(self): + """Tests that fileinput.close() invokes close() on fileinput._state + and sets _state=None""" + instance = MockFileInput() + fileinput._state = instance + fileinput.close() + self.assertExactlyOneInvocation(instance, "close") + self.assertIsNone(fileinput._state) + +class Test_fileinput_nextfile(BaseFileInputGlobalMethodsTest): + """Unit tests for fileinput.nextfile()""" + + def test_state_is_None(self): + """Tests fileinput.nextfile() when fileinput._state is None. + Ensure that it raises RuntimeError with a meaningful error message + and does not modify fileinput._state""" + fileinput._state = None + with self.assertRaises(RuntimeError) as cm: + fileinput.nextfile() + self.assertEqual(("no active input()",), cm.exception.args) + self.assertIsNone(fileinput._state) + + def test_state_is_not_None(self): + """Tests fileinput.nextfile() when fileinput._state is not None. + Ensure that it invokes fileinput._state.nextfile() exactly once, + returns whatever it returns, and does not modify fileinput._state + to point to a different object.""" + nextfile_retval = object() + instance = MockFileInput() + instance.return_values["nextfile"] = nextfile_retval + fileinput._state = instance + retval = fileinput.nextfile() + self.assertExactlyOneInvocation(instance, "nextfile") + self.assertIs(retval, nextfile_retval) + self.assertIs(fileinput._state, instance) + +class Test_fileinput_filename(BaseFileInputGlobalMethodsTest): + """Unit tests for fileinput.filename()""" + + def test_state_is_None(self): + """Tests fileinput.filename() when fileinput._state is None. + Ensure that it raises RuntimeError with a meaningful error message + and does not modify fileinput._state""" + fileinput._state = None + with self.assertRaises(RuntimeError) as cm: + fileinput.filename() + self.assertEqual(("no active input()",), cm.exception.args) + self.assertIsNone(fileinput._state) + + def test_state_is_not_None(self): + """Tests fileinput.filename() when fileinput._state is not None. + Ensure that it invokes fileinput._state.filename() exactly once, + returns whatever it returns, and does not modify fileinput._state + to point to a different object.""" + filename_retval = object() + instance = MockFileInput() + instance.return_values["filename"] = filename_retval + fileinput._state = instance + retval = fileinput.filename() + self.assertExactlyOneInvocation(instance, "filename") + self.assertIs(retval, filename_retval) + self.assertIs(fileinput._state, instance) + +class Test_fileinput_lineno(BaseFileInputGlobalMethodsTest): + """Unit tests for fileinput.lineno()""" + + def test_state_is_None(self): + """Tests fileinput.lineno() when fileinput._state is None. + Ensure that it raises RuntimeError with a meaningful error message + and does not modify fileinput._state""" + fileinput._state = None + with self.assertRaises(RuntimeError) as cm: + fileinput.lineno() + self.assertEqual(("no active input()",), cm.exception.args) + self.assertIsNone(fileinput._state) + + def test_state_is_not_None(self): + """Tests fileinput.lineno() when fileinput._state is not None. + Ensure that it invokes fileinput._state.lineno() exactly once, + returns whatever it returns, and does not modify fileinput._state + to point to a different object.""" + lineno_retval = object() + instance = MockFileInput() + instance.return_values["lineno"] = lineno_retval + fileinput._state = instance + retval = fileinput.lineno() + self.assertExactlyOneInvocation(instance, "lineno") + self.assertIs(retval, lineno_retval) + self.assertIs(fileinput._state, instance) + +class Test_fileinput_filelineno(BaseFileInputGlobalMethodsTest): + """Unit tests for fileinput.filelineno()""" + + def test_state_is_None(self): + """Tests fileinput.filelineno() when fileinput._state is None. + Ensure that it raises RuntimeError with a meaningful error message + and does not modify fileinput._state""" + fileinput._state = None + with self.assertRaises(RuntimeError) as cm: + fileinput.filelineno() + self.assertEqual(("no active input()",), cm.exception.args) + self.assertIsNone(fileinput._state) + + def test_state_is_not_None(self): + """Tests fileinput.filelineno() when fileinput._state is not None. + Ensure that it invokes fileinput._state.filelineno() exactly once, + returns whatever it returns, and does not modify fileinput._state + to point to a different object.""" + filelineno_retval = object() + instance = MockFileInput() + instance.return_values["filelineno"] = filelineno_retval + fileinput._state = instance + retval = fileinput.filelineno() + self.assertExactlyOneInvocation(instance, "filelineno") + self.assertIs(retval, filelineno_retval) + self.assertIs(fileinput._state, instance) + +class Test_fileinput_fileno(BaseFileInputGlobalMethodsTest): + """Unit tests for fileinput.fileno()""" + + def test_state_is_None(self): + """Tests fileinput.fileno() when fileinput._state is None. + Ensure that it raises RuntimeError with a meaningful error message + and does not modify fileinput._state""" + fileinput._state = None + with self.assertRaises(RuntimeError) as cm: + fileinput.fileno() + self.assertEqual(("no active input()",), cm.exception.args) + self.assertIsNone(fileinput._state) + + def test_state_is_not_None(self): + """Tests fileinput.fileno() when fileinput._state is not None. + Ensure that it invokes fileinput._state.fileno() exactly once, + returns whatever it returns, and does not modify fileinput._state + to point to a different object.""" + fileno_retval = object() + instance = MockFileInput() + instance.return_values["fileno"] = fileno_retval + instance.fileno_retval = fileno_retval + fileinput._state = instance + retval = fileinput.fileno() + self.assertExactlyOneInvocation(instance, "fileno") + self.assertIs(retval, fileno_retval) + self.assertIs(fileinput._state, instance) + +class Test_fileinput_isfirstline(BaseFileInputGlobalMethodsTest): + """Unit tests for fileinput.isfirstline()""" + + def test_state_is_None(self): + """Tests fileinput.isfirstline() when fileinput._state is None. + Ensure that it raises RuntimeError with a meaningful error message + and does not modify fileinput._state""" + fileinput._state = None + with self.assertRaises(RuntimeError) as cm: + fileinput.isfirstline() + self.assertEqual(("no active input()",), cm.exception.args) + self.assertIsNone(fileinput._state) + + def test_state_is_not_None(self): + """Tests fileinput.isfirstline() when fileinput._state is not None. + Ensure that it invokes fileinput._state.isfirstline() exactly once, + returns whatever it returns, and does not modify fileinput._state + to point to a different object.""" + isfirstline_retval = object() + instance = MockFileInput() + instance.return_values["isfirstline"] = isfirstline_retval + fileinput._state = instance + retval = fileinput.isfirstline() + self.assertExactlyOneInvocation(instance, "isfirstline") + self.assertIs(retval, isfirstline_retval) + self.assertIs(fileinput._state, instance) + +class Test_fileinput_isstdin(BaseFileInputGlobalMethodsTest): + """Unit tests for fileinput.isstdin()""" + + def test_state_is_None(self): + """Tests fileinput.isstdin() when fileinput._state is None. + Ensure that it raises RuntimeError with a meaningful error message + and does not modify fileinput._state""" + fileinput._state = None + with self.assertRaises(RuntimeError) as cm: + fileinput.isstdin() + self.assertEqual(("no active input()",), cm.exception.args) + self.assertIsNone(fileinput._state) + + def test_state_is_not_None(self): + """Tests fileinput.isstdin() when fileinput._state is not None. + Ensure that it invokes fileinput._state.isstdin() exactly once, + returns whatever it returns, and does not modify fileinput._state + to point to a different object.""" + isstdin_retval = object() + instance = MockFileInput() + instance.return_values["isstdin"] = isstdin_retval + fileinput._state = instance + retval = fileinput.isstdin() + self.assertExactlyOneInvocation(instance, "isstdin") + self.assertIs(retval, isstdin_retval) + self.assertIs(fileinput._state, instance) + +class InvocationRecorder: + def __init__(self): + self.invocation_count = 0 + def __call__(self, *args, **kwargs): + self.invocation_count += 1 + self.last_invocation = (args, kwargs) + +class Test_hook_compressed(unittest.TestCase): + """Unit tests for fileinput.hook_compressed()""" + + def setUp(self): + self.fake_open = InvocationRecorder() + + def test_empty_string(self): + self.do_test_use_builtin_open("", 1) + + def test_no_ext(self): + self.do_test_use_builtin_open("abcd", 2) + + def test_gz_ext_fake(self): + original_open = gzip.open + gzip.open = self.fake_open + try: + result = fileinput.hook_compressed("test.gz", 3) + finally: + gzip.open = original_open + + self.assertEqual(self.fake_open.invocation_count, 1) + self.assertEqual(self.fake_open.last_invocation, (("test.gz", 3), {})) + + def test_bz2_ext_fake(self): + original_open = bz2.BZ2File + bz2.BZ2File = self.fake_open + try: + result = fileinput.hook_compressed("test.bz2", 4) + finally: + bz2.BZ2File = original_open + + self.assertEqual(self.fake_open.invocation_count, 1) + self.assertEqual(self.fake_open.last_invocation, (("test.bz2", 4), {})) + + def test_blah_ext(self): + self.do_test_use_builtin_open("abcd.blah", 5) + + def test_gz_ext_builtin(self): + self.do_test_use_builtin_open("abcd.Gz", 6) + + def test_bz2_ext_builtin(self): + self.do_test_use_builtin_open("abcd.Bz2", 7) + + def do_test_use_builtin_open(self, filename, mode): + original_open = self.replace_builtin_open(self.fake_open) + try: + result = fileinput.hook_compressed(filename, mode) + finally: + self.replace_builtin_open(original_open) + + self.assertEqual(self.fake_open.invocation_count, 1) + self.assertEqual(self.fake_open.last_invocation, + ((filename, mode), {})) + + @staticmethod + def replace_builtin_open(new_open_func): + builtins_type = type(__builtins__) + if builtins_type is dict: + original_open = __builtins__["open"] + __builtins__["open"] = new_open_func + elif builtins_type is types.ModuleType: + original_open = __builtins__.open + __builtins__.open = new_open_func + else: + raise RuntimeError( + "unknown __builtins__ type: %r (unable to replace open)" % + builtins_type) + + return original_open + +class Test_hook_encoded(unittest.TestCase): + """Unit tests for fileinput.hook_encoded()""" + + def test(self): + encoding = object() + result = fileinput.hook_encoded(encoding) + + fake_open = InvocationRecorder() + original_open = codecs.open + codecs.open = fake_open + try: + filename = object() + mode = object() + open_result = result(filename, mode) + finally: + codecs.open = original_open + + self.assertEqual(fake_open.invocation_count, 1) + + args = fake_open.last_invocation[0] + self.assertIs(args[0], filename) + self.assertIs(args[1], mode) + self.assertIs(args[2], encoding) def test_main(): - run_unittest(BufferSizesTests, FileInputTests) + run_unittest( + BufferSizesTests, + FileInputTests, + Test_fileinput_input, + Test_fileinput_close, + Test_fileinput_nextfile, + Test_fileinput_filename, + Test_fileinput_lineno, + Test_fileinput_filelineno, + Test_fileinput_fileno, + Test_fileinput_isfirstline, + Test_fileinput_isstdin, + Test_hook_compressed, + Test_hook_encoded, + ) if __name__ == "__main__": test_main() diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/test/test_float.py --- a/Lib/test/test_float.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/test/test_float.py Wed Mar 16 19:19:36 2011 -0400 @@ -67,7 +67,7 @@ def test_float_with_comma(self): # set locale to something that doesn't use '.' for the decimal point # float must not accept the locale specific decimal point but - # it still has to accept the normal python syntac + # it still has to accept the normal python syntax import locale if not locale.localeconv()['decimal_point'] == ',': return @@ -189,7 +189,7 @@ def assertEqualAndEqualSign(self, a, b): # fail unless a == b and a and b have the same sign bit; # the only difference from assertEqual is that this test - # distingishes -0.0 and 0.0. + # distinguishes -0.0 and 0.0. self.assertEqual((a, copysign(1.0, a)), (b, copysign(1.0, b))) @support.requires_IEEE_754 diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/test/test_gdb.py --- a/Lib/test/test_gdb.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/test/test_gdb.py Wed Mar 16 19:19:36 2011 -0400 @@ -127,6 +127,9 @@ " inferior's thread library, thread debugging will" " not be available.\n", '') + err = err.replace("warning: Cannot initialize thread debugging" + " library: Debugger service failed\n", + '') # Ensure no unexpected error messages: self.assertEqual(err, '') diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/test/test_grammar.py --- a/Lib/test/test_grammar.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/test/test_grammar.py Wed Mar 16 19:19:36 2011 -0400 @@ -350,7 +350,7 @@ ### simple_stmt: small_stmt (';' small_stmt)* [';'] x = 1; pass; del x def foo(): - # verify statments that end with semi-colons + # verify statements that end with semi-colons x = 1; pass; del x; foo() diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/test/test_httpservers.py --- a/Lib/test/test_httpservers.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/test/test_httpservers.py Wed Mar 16 19:19:36 2011 -0400 @@ -462,7 +462,7 @@ return False class BaseHTTPRequestHandlerTestCase(unittest.TestCase): - """Test the functionaility of the BaseHTTPServer. + """Test the functionality of the BaseHTTPServer. Test the support for the Expect 100-continue header. """ diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/test/test_importhooks.py --- a/Lib/test/test_importhooks.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/test/test_importhooks.py Wed Mar 16 19:19:36 2011 -0400 @@ -51,7 +51,7 @@ def __init__(self, path=test_path): if path != test_path: - # if out class is on sys.path_hooks, we must raise + # if our class is on sys.path_hooks, we must raise # ImportError for any path item that we can't handle. raise ImportError self.path = path diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/test/test_inspect.py --- a/Lib/test/test_inspect.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/test/test_inspect.py Wed Mar 16 19:19:36 2011 -0400 @@ -906,6 +906,53 @@ self.assertEqual(inspect.getattr_static(Something(), 'foo'), 3) self.assertEqual(inspect.getattr_static(Something, 'foo'), 3) + def test_dict_as_property(self): + test = self + test.called = False + + class Foo(dict): + a = 3 + @property + def __dict__(self): + test.called = True + return {} + + foo = Foo() + foo.a = 4 + self.assertEqual(inspect.getattr_static(foo, 'a'), 3) + self.assertFalse(test.called) + + def test_custom_object_dict(self): + test = self + test.called = False + + class Custom(dict): + def get(self, key, default=None): + test.called = True + super().get(key, default) + + class Foo(object): + a = 3 + foo = Foo() + foo.__dict__ = Custom() + self.assertEqual(inspect.getattr_static(foo, 'a'), 3) + self.assertFalse(test.called) + + def test_metaclass_dict_as_property(self): + class Meta(type): + @property + def __dict__(self): + self.executed = True + + class Thing(metaclass=Meta): + executed = False + + def __init__(self): + self.spam = 42 + + instance = Thing() + self.assertEqual(inspect.getattr_static(instance, "spam"), 42) + self.assertFalse(Thing.executed) class TestGetGeneratorState(unittest.TestCase): diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/test/test_iterlen.py --- a/Lib/test/test_iterlen.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/test/test_iterlen.py Wed Mar 16 19:19:36 2011 -0400 @@ -20,11 +20,11 @@ Some containers become temporarily immutable during iteration. This includes dicts, sets, and collections.deque. Their implementation is equally simple -though they need to permantently set their length to zero whenever there is +though they need to permanently set their length to zero whenever there is an attempt to iterate after a length mutation. The situation slightly more involved whenever an object allows length mutation -during iteration. Lists and sequence iterators are dynanamically updatable. +during iteration. Lists and sequence iterators are dynamically updatable. So, if a list is extended during iteration, the iterator will continue through the new items. If it shrinks to a point before the most recent iteration, then no further items are available and the length is reported at zero. diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/test/test_itertools.py --- a/Lib/test/test_itertools.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/test/test_itertools.py Wed Mar 16 19:19:36 2011 -0400 @@ -1526,7 +1526,7 @@ ... return chain(iterable, repeat(None)) >>> def ncycles(iterable, n): -... "Returns the seqeuence elements n times" +... "Returns the sequence elements n times" ... return chain(*repeat(iterable, n)) >>> def dotproduct(vec1, vec2): diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/test/test_marshal.py --- a/Lib/test/test_marshal.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/test/test_marshal.py Wed Mar 16 19:19:36 2011 -0400 @@ -194,7 +194,7 @@ # >>> type(loads(dumps(Int()))) # for typ in (int, float, complex, tuple, list, dict, set, frozenset): - # Note: str sublclasses are not tested because they get handled + # Note: str subclasses are not tested because they get handled # by marshal's routines for objects supporting the buffer API. subtyp = type('subtyp', (typ,), {}) self.assertRaises(ValueError, marshal.dumps, subtyp()) diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/test/test_math.py --- a/Lib/test/test_math.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/test/test_math.py Wed Mar 16 19:19:36 2011 -0400 @@ -820,7 +820,7 @@ # the following tests have been commented out since they don't # really belong here: the implementation of ** for floats is - # independent of the implemention of math.pow + # independent of the implementation of math.pow #self.assertEqual(1**NAN, 1) #self.assertEqual(1**INF, 1) #self.assertEqual(1**NINF, 1) diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/test/test_mmap.py --- a/Lib/test/test_mmap.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/test/test_mmap.py Wed Mar 16 19:19:36 2011 -0400 @@ -594,7 +594,7 @@ m2.close() m1.close() - # Test differnt tag + # Test different tag m1 = mmap.mmap(-1, len(data1), tagname="foo") m1[:] = data1 m2 = mmap.mmap(-1, len(data2), tagname="boo") diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/test/test_multiprocessing.py --- a/Lib/test/test_multiprocessing.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/test/test_multiprocessing.py Wed Mar 16 19:19:36 2011 -0400 @@ -795,7 +795,7 @@ event = self.Event() wait = TimingWrapper(event.wait) - # Removed temporaily, due to API shear, this does not + # Removed temporarily, due to API shear, this does not # work with threading._Event objects. is_set == isSet self.assertEqual(event.is_set(), False) @@ -1765,7 +1765,7 @@ util.Finalize(None, conn.send, args=('STOP',), exitpriority=-100) - # call mutliprocessing's cleanup function then exit process without + # call multiprocessing's cleanup function then exit process without # garbage collecting locals util._exit_function() conn.close() diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/test/test_numeric_tower.py --- a/Lib/test/test_numeric_tower.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/test/test_numeric_tower.py Wed Mar 16 19:19:36 2011 -0400 @@ -1,4 +1,4 @@ -# test interactions betwen int, float, Decimal and Fraction +# test interactions between int, float, Decimal and Fraction import unittest import random diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/test/test_os.py --- a/Lib/test/test_os.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/test/test_os.py Wed Mar 16 19:19:36 2011 -0400 @@ -284,7 +284,7 @@ except TypeError: pass - # Use the constructr with a too-long tuple. + # Use the constructor with a too-long tuple. try: result2 = os.stat_result((0,1,2,3,4,5,6,7,8,9,10,11,12,13,14)) except TypeError: @@ -340,7 +340,7 @@ except TypeError: pass - # Use the constructr with a too-long tuple. + # Use the constructor with a too-long tuple. try: result2 = os.statvfs_result((0,1,2,3,4,5,6,7,8,9,10,11,12,13,14)) except TypeError: @@ -1528,18 +1528,16 @@ def test_trailers(self): TESTFN2 = support.TESTFN + "2" - f = open(TESTFN2, 'wb') - f.write(b"abcde") - f.close() - f = open(TESTFN2, 'rb') - try: - os.sendfile(self.sockno, f.fileno(), 0, 4096, trailers=[b"12345"]) + with open(TESTFN2, 'wb') as f: + f.write(b"abcde") + with open(TESTFN2, 'rb')as f: + self.addCleanup(os.remove, TESTFN2) + os.sendfile(self.sockno, f.fileno(), 0, 4096, + trailers=[b"12345"]) self.client.close() self.server.wait() data = self.server.handler_instance.get_data() self.assertEqual(data, b"abcde12345") - finally: - os.remove(TESTFN2) if hasattr(os, "SF_NODISKIO"): def test_flags(self): diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/test/test_peepholer.py --- a/Lib/test/test_peepholer.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/test/test_peepholer.py Wed Mar 16 19:19:36 2011 -0400 @@ -19,6 +19,7 @@ def dis_single(line): return disassemble(compile(line, '', 'single')) + class TestTranforms(unittest.TestCase): def test_unot(self): @@ -294,11 +295,23 @@ self.assertNotIn('BINARY_', asm, e) self.assertNotIn('BUILD_', asm, e) +class TestBuglets(unittest.TestCase): + + def test_bug_11510(self): + # folded constant set optimization was commingled with the tuple + # unpacking optimization which would fail if the set had duplicate + # elements so that the set length was unexpected + def f(): + x, y = {1, 1} + return x, y + with self.assertRaises(ValueError): + f() + def test_main(verbose=None): import sys from test import support - test_classes = (TestTranforms,) + test_classes = (TestTranforms, TestBuglets) support.run_unittest(*test_classes) # verify reference counting diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/test/test_pep292.py --- a/Lib/test/test_pep292.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/test/test_pep292.py Wed Mar 16 19:19:36 2011 -0400 @@ -42,6 +42,19 @@ s = Template('$who likes $$') eq(s.substitute(dict(who='tim', what='ham')), 'tim likes $') + def test_invalid(self): + class MyPattern(Template): + pattern = r""" + (?: + (?P) | + (?P%(delim)s) | + @(?P%(id)s) | + @{(?P%(id)s)} + ) + """ + s = MyPattern('$') + self.assertRaises(ValueError, s.substitute, dict()) + def test_percents(self): eq = self.assertEqual s = Template('%(foo)s $foo ${foo}') diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/test/test_pkg.py --- a/Lib/test/test_pkg.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/test/test_pkg.py Wed Mar 16 19:19:36 2011 -0400 @@ -56,7 +56,7 @@ if self.root: # Only clean if the test was actually run cleanout(self.root) - # delete all modules concerning the tested hiearchy + # delete all modules concerning the tested hierarchy if self.pkgname: modules = [name for name in sys.modules if self.pkgname in name.split('.')] diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/test/test_posixpath.py --- a/Lib/test/test_posixpath.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/test/test_posixpath.py Wed Mar 16 19:19:36 2011 -0400 @@ -6,6 +6,11 @@ import sys from posixpath import realpath, abspath, dirname, basename +try: + import posix +except ImportError: + posix = None + # An absolute path to a temporary filename for testing. We can't rely on TESTFN # being an absolute path, so we need this. @@ -150,6 +155,7 @@ def test_islink(self): self.assertIs(posixpath.islink(support.TESTFN + "1"), False) + self.assertIs(posixpath.lexists(support.TESTFN + "2"), False) f = open(support.TESTFN + "1", "wb") try: f.write(b"foo") @@ -225,6 +231,44 @@ def test_ismount(self): self.assertIs(posixpath.ismount("/"), True) + self.assertIs(posixpath.ismount(b"/"), True) + + def test_ismount_non_existent(self): + # Non-existent mountpoint. + self.assertIs(posixpath.ismount(ABSTFN), False) + try: + os.mkdir(ABSTFN) + self.assertIs(posixpath.ismount(ABSTFN), False) + finally: + safe_rmdir(ABSTFN) + + @unittest.skipUnless(support.can_symlink(), + "Test requires symlink support") + def test_ismount_symlinks(self): + # Symlinks are never mountpoints. + try: + os.symlink("/", ABSTFN) + self.assertIs(posixpath.ismount(ABSTFN), False) + finally: + os.unlink(ABSTFN) + + @unittest.skipIf(posix is None, "Test requires posix module") + def test_ismount_different_device(self): + # Simulate the path being on a different device from its parent by + # mocking out st_dev. + save_lstat = os.lstat + def fake_lstat(path): + st_ino = 0 + st_dev = 0 + if path == ABSTFN: + st_dev = 1 + st_ino = 1 + return posix.stat_result((0, st_ino, st_dev, 0, 0, 0, 0, 0, 0, 0)) + try: + os.lstat = fake_lstat + self.assertIs(posixpath.ismount(ABSTFN), True) + finally: + os.lstat = save_lstat def test_expanduser(self): self.assertEqual(posixpath.expanduser("foo"), "foo") @@ -254,6 +298,10 @@ with support.EnvironmentVarGuard() as env: env['HOME'] = '/' self.assertEqual(posixpath.expanduser("~"), "/") + # expanduser should fall back to using the password database + del env['HOME'] + home = pwd.getpwuid(os.getuid()).pw_dir + self.assertEqual(posixpath.expanduser("~"), home) def test_normpath(self): self.assertEqual(posixpath.normpath(""), ".") @@ -289,6 +337,16 @@ @unittest.skipUnless(hasattr(os, "symlink"), "Missing symlink implementation") @skip_if_ABSTFN_contains_backslash + def test_realpath_relative(self): + try: + os.symlink(posixpath.relpath(ABSTFN+"1"), ABSTFN) + self.assertEqual(realpath(ABSTFN), ABSTFN+"1") + finally: + support.unlink(ABSTFN) + + @unittest.skipUnless(hasattr(os, "symlink"), + "Missing symlink implementation") + @skip_if_ABSTFN_contains_backslash def test_realpath_symlink_loops(self): # Bug #930024, return the path unchanged if we get into an infinite # symlink loop. @@ -443,6 +501,11 @@ finally: os.getcwdb = real_getcwdb + def test_sameopenfile(self): + fname = support.TESTFN + "1" + with open(fname, "wb") as a, open(fname, "wb") as b: + self.assertTrue(posixpath.sameopenfile(a.fileno(), b.fileno())) + class PosixCommonTest(test_genericpath.CommonTest): pathmodule = posixpath diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/test/test_print.py --- a/Lib/test/test_print.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/test/test_print.py Wed Mar 16 19:19:36 2011 -0400 @@ -20,7 +20,7 @@ # A dispatch table all 8 combinations of providing # sep, end, and file # I use this machinery so that I'm not just passing default -# values to print, I'm eiher passing or not passing in the +# values to print, I'm either passing or not passing in the # arguments dispatch = { (False, False, False): diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/test/test_pulldom.py --- a/Lib/test/test_pulldom.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/test/test_pulldom.py Wed Mar 16 19:19:36 2011 -0400 @@ -32,7 +32,9 @@ # fragment. # Test with a filename: - list(pulldom.parse(tstfile)) + handler = pulldom.parse(tstfile) + self.addCleanup(handler.stream.close) + list(handler) # Test with a file object: with open(tstfile, "rb") as fin: diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/test/test_re.py --- a/Lib/test/test_re.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/test/test_re.py Wed Mar 16 19:19:36 2011 -0400 @@ -7,7 +7,7 @@ # Misc tests from Tim Peters' re.doc # WARNING: Don't change details in these tests if you don't know -# what you're doing. Some of these tests were carefuly modeled to +# what you're doing. Some of these tests were carefully modeled to # cover most of the code. import unittest diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/test/test_readline.py --- a/Lib/test/test_readline.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/test/test_readline.py Wed Mar 16 19:19:36 2011 -0400 @@ -12,6 +12,10 @@ readline = import_module('readline') class TestHistoryManipulation (unittest.TestCase): + + @unittest.skipIf(not hasattr(readline, 'clear_history'), + "The history update test cannot be run because the " + "clear_history method is not available.") def testHistoryUpdates(self): readline.clear_history() diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/test/test_set.py --- a/Lib/test/test_set.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/test/test_set.py Wed Mar 16 19:19:36 2011 -0400 @@ -583,7 +583,7 @@ self.le_called = True return False - # This first tries the bulitin rich set comparison, which doesn't know + # This first tries the builtin rich set comparison, which doesn't know # how to handle the custom object. Upon returning NotImplemented, the # corresponding comparison on the right object is invoked. myset = {1, 2, 3} diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/test/test_shutil.py --- a/Lib/test/test_shutil.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/test/test_shutil.py Wed Mar 16 19:19:36 2011 -0400 @@ -7,6 +7,7 @@ import stat import os import os.path +import functools from test import support from test.support import TESTFN from os.path import splitdrive @@ -48,6 +49,21 @@ except ImportError: ZIP_SUPPORT = find_executable('zip') +def _fake_rename(*args, **kwargs): + # Pretend the destination path is on a different filesystem. + raise OSError() + +def mock_rename(func): + @functools.wraps(func) + def wrap(*args, **kwargs): + try: + builtin_rename = os.rename + os.rename = _fake_rename + return func(*args, **kwargs) + finally: + os.rename = builtin_rename + return wrap + class TestShutil(unittest.TestCase): def setUp(self): @@ -393,6 +409,41 @@ shutil.copytree(src_dir, dst_dir, symlinks=True) self.assertIn('test.txt', os.listdir(dst_dir)) + def _copy_file(self, method): + fname = 'test.txt' + tmpdir = self.mkdtemp() + self.write_file([tmpdir, fname]) + file1 = os.path.join(tmpdir, fname) + tmpdir2 = self.mkdtemp() + method(file1, tmpdir2) + file2 = os.path.join(tmpdir2, fname) + return (file1, file2) + + @unittest.skipUnless(hasattr(os, 'chmod'), 'requires os.chmod') + def test_copy(self): + # Ensure that the copied file exists and has the same mode bits. + file1, file2 = self._copy_file(shutil.copy) + self.assertTrue(os.path.exists(file2)) + self.assertEqual(os.stat(file1).st_mode, os.stat(file2).st_mode) + + @unittest.skipUnless(hasattr(os, 'chmod'), 'requires os.chmod') + @unittest.skipUnless(hasattr(os, 'chmod'), 'requires os.utime') + def test_copy2(self): + # Ensure that the copied file exists and has the same mode and + # modification time bits. + file1, file2 = self._copy_file(shutil.copy2) + self.assertTrue(os.path.exists(file2)) + file1_stat = os.stat(file1) + file2_stat = os.stat(file2) + self.assertEqual(file1_stat.st_mode, file2_stat.st_mode) + for attr in 'st_atime', 'st_mtime': + # The modification times may be truncated in the new file. + self.assertLessEqual(getattr(file1_stat, attr), + getattr(file2_stat, attr) + 1) + if hasattr(os, 'chflags') and hasattr(file1_stat, 'st_flags'): + self.assertEqual(getattr(file1_stat, 'st_flags'), + getattr(file2_stat, 'st_flags')) + @unittest.skipUnless(zlib, "requires zlib") def test_make_tarball(self): # creating something to tar @@ -403,6 +454,8 @@ self.write_file([tmpdir, 'sub', 'file3'], 'xxx') tmpdir2 = self.mkdtemp() + # force shutil to create the directory + os.rmdir(tmpdir2) unittest.skipUnless(splitdrive(tmpdir)[0] == splitdrive(tmpdir2)[0], "source and target should be on same drive") @@ -518,6 +571,8 @@ self.write_file([tmpdir, 'file2'], 'xxx') tmpdir2 = self.mkdtemp() + # force shutil to create the directory + os.rmdir(tmpdir2) base_name = os.path.join(tmpdir2, 'archive') _make_zipfile(base_name, tmpdir) @@ -645,6 +700,14 @@ diff = self._compare_dirs(tmpdir, tmpdir2) self.assertEqual(diff, []) + # and again, this time with the format specified + tmpdir3 = self.mkdtemp() + unpack_archive(filename, tmpdir3, format=format) + diff = self._compare_dirs(tmpdir, tmpdir3) + self.assertEqual(diff, []) + self.assertRaises(shutil.ReadError, unpack_archive, TESTFN) + self.assertRaises(ValueError, unpack_archive, TESTFN, format='xxx') + def test_unpack_registery(self): formats = get_unpack_formats() @@ -680,20 +743,11 @@ self.dst_dir = tempfile.mkdtemp() self.src_file = os.path.join(self.src_dir, filename) self.dst_file = os.path.join(self.dst_dir, filename) - # Try to create a dir in the current directory, hoping that it is - # not located on the same filesystem as the system tmp dir. - try: - self.dir_other_fs = tempfile.mkdtemp( - dir=os.path.dirname(__file__)) - self.file_other_fs = os.path.join(self.dir_other_fs, - filename) - except OSError: - self.dir_other_fs = None with open(self.src_file, "wb") as f: f.write(b"spam") def tearDown(self): - for d in (self.src_dir, self.dst_dir, self.dir_other_fs): + for d in (self.src_dir, self.dst_dir): try: if d: shutil.rmtree(d) @@ -722,21 +776,15 @@ # Move a file inside an existing dir on the same filesystem. self._check_move_file(self.src_file, self.dst_dir, self.dst_file) + @mock_rename def test_move_file_other_fs(self): # Move a file to an existing dir on another filesystem. - if not self.dir_other_fs: - # skip - return - self._check_move_file(self.src_file, self.file_other_fs, - self.file_other_fs) + self.test_move_file() + @mock_rename def test_move_file_to_dir_other_fs(self): # Move a file to another location on another filesystem. - if not self.dir_other_fs: - # skip - return - self._check_move_file(self.src_file, self.dir_other_fs, - self.file_other_fs) + self.test_move_file_to_dir() def test_move_dir(self): # Move a dir to another location on the same filesystem. @@ -749,32 +797,20 @@ except: pass + @mock_rename def test_move_dir_other_fs(self): # Move a dir to another location on another filesystem. - if not self.dir_other_fs: - # skip - return - dst_dir = tempfile.mktemp(dir=self.dir_other_fs) - try: - self._check_move_dir(self.src_dir, dst_dir, dst_dir) - finally: - try: - shutil.rmtree(dst_dir) - except: - pass + self.test_move_dir() def test_move_dir_to_dir(self): # Move a dir inside an existing dir on the same filesystem. self._check_move_dir(self.src_dir, self.dst_dir, os.path.join(self.dst_dir, os.path.basename(self.src_dir))) + @mock_rename def test_move_dir_to_dir_other_fs(self): # Move a dir inside an existing dir on another filesystem. - if not self.dir_other_fs: - # skip - return - self._check_move_dir(self.src_dir, self.dir_other_fs, - os.path.join(self.dir_other_fs, os.path.basename(self.src_dir))) + self.test_move_dir_to_dir() def test_existing_file_inside_dest_dir(self): # A file with the same name inside the destination dir already exists. diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/test/test_smtplib.py --- a/Lib/test/test_smtplib.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/test/test_smtplib.py Wed Mar 16 19:19:36 2011 -0400 @@ -424,6 +424,9 @@ # Simulated SMTP channel & server class SimSMTPChannel(smtpd.SMTPChannel): + # For testing failures in QUIT when using the context manager API. + quit_response = None + def __init__(self, extra_features, *args, **kw): self._extrafeatures = ''.join( [ "250-{0}\r\n".format(x) for x in extra_features ]) @@ -475,19 +478,31 @@ else: self.push('550 No access for you!') + def smtp_QUIT(self, arg): + # args is ignored + if self.quit_response is None: + super(SimSMTPChannel, self).smtp_QUIT(arg) + else: + self.push(self.quit_response) + self.close_when_done() + def handle_error(self): raise class SimSMTPServer(smtpd.SMTPServer): + # For testing failures in QUIT when using the context manager API. + quit_response = None + def __init__(self, *args, **kw): self._extra_features = [] smtpd.SMTPServer.__init__(self, *args, **kw) def handle_accepted(self, conn, addr): - self._SMTPchannel = SimSMTPChannel(self._extra_features, - self, conn, addr) + self._SMTPchannel = SimSMTPChannel( + self._extra_features, self, conn, addr) + self._SMTPchannel.quit_response = self.quit_response def process_message(self, peer, mailfrom, rcpttos, data): pass @@ -620,6 +635,25 @@ self.assertIn(sim_auth_credentials['cram-md5'], str(err)) smtp.close() + def test_with_statement(self): + with smtplib.SMTP(HOST, self.port) as smtp: + code, message = smtp.noop() + self.assertEqual(code, 250) + self.assertRaises(smtplib.SMTPServerDisconnected, smtp.send, b'foo') + with smtplib.SMTP(HOST, self.port) as smtp: + smtp.close() + self.assertRaises(smtplib.SMTPServerDisconnected, smtp.send, b'foo') + + def test_with_statement_QUIT_failure(self): + self.serv.quit_response = '421 QUIT FAILED' + with self.assertRaises(smtplib.SMTPResponseException) as error: + with smtplib.SMTP(HOST, self.port) as smtp: + smtp.noop() + self.assertEqual(error.exception.smtp_code, 421) + self.assertEqual(error.exception.smtp_error, b'QUIT FAILED') + # We don't need to clean up self.serv.quit_response because a new + # server is always instantiated in the setUp(). + #TODO: add tests for correct AUTH method fallback now that the #test infrastructure can support it. diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/test/test_string.py --- a/Lib/test/test_string.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/test/test_string.py Wed Mar 16 19:19:36 2011 -0400 @@ -93,7 +93,7 @@ # test all parameters used class CheckAllUsedFormatter(string.Formatter): def check_unused_args(self, used_args, args, kwargs): - # Track which arguments actuallly got used + # Track which arguments actually got used unused_args = set(kwargs.keys()) unused_args.update(range(0, len(args))) @@ -112,6 +112,30 @@ self.assertRaises(ValueError, fmt.format, "{0}", 10, 20, i=100) self.assertRaises(ValueError, fmt.format, "{i}", 10, 20, i=100) + def test_vformat_assert(self): + cls = string.Formatter() + kwargs = { + "i": 100 + } + self.assertRaises(ValueError, cls._vformat, + cls.format, "{0}", kwargs, set(), -2) + + def test_convert_field(self): + cls = string.Formatter() + self.assertEqual(cls.format("{0!s}", 'foo'), 'foo') + self.assertRaises(ValueError, cls.format, "{0!h}", 'foo') + + def test_get_field(self): + cls = string.Formatter() + class MyClass: + name = 'lumberjack' + x = MyClass() + self.assertEqual(cls.format("{0.name}", x), 'lumberjack') + + lookup = ["eggs", "and", "spam"] + self.assertEqual(cls.format("{0[2]}", lookup), 'spam') + + def test_main(): support.run_unittest(ModuleTest) diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/test/test_strlit.py --- a/Lib/test/test_strlit.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/test/test_strlit.py Wed Mar 16 19:19:36 2011 -0400 @@ -22,7 +22,7 @@ exec()/eval(), which uses a different code path. This file is really about correct treatment of encodings and -backslashes. It doens't concern itself with issues like single +backslashes. It doesn't concern itself with issues like single vs. double quotes or singly- vs. triply-quoted strings: that's dealt with elsewhere (I assume). """ diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/test/test_strptime.py --- a/Lib/test/test_strptime.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/test/test_strptime.py Wed Mar 16 19:19:36 2011 -0400 @@ -536,7 +536,7 @@ self.assertIsNot(first_time_re, second_time_re) # Possible test locale is not supported while initial locale is. # If this is the case just suppress the exception and fall-through - # to the reseting to the original locale. + # to the resetting to the original locale. except locale.Error: pass # Make sure we don't trample on the locale setting once we leave the diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/test/test_struct.py --- a/Lib/test/test_struct.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/test/test_struct.py Wed Mar 16 19:19:36 2011 -0400 @@ -463,7 +463,7 @@ test_string) def test_unpack_with_buffer(self): - # SF bug 1563759: struct.unpack doens't support buffer protocol objects + # SF bug 1563759: struct.unpack doesn't support buffer protocol objects data1 = array.array('B', b'\x12\x34\x56\x78') data2 = memoryview(b'\x12\x34\x56\x78') # XXX b'......XXXX......', 6, 4 for data in [data1, data2]: diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/test/test_subprocess.py --- a/Lib/test/test_subprocess.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/test/test_subprocess.py Wed Mar 16 19:19:36 2011 -0400 @@ -3,6 +3,7 @@ import subprocess import sys import signal +import io import os import errno import tempfile @@ -11,6 +12,7 @@ import sysconfig import warnings import select +import shutil try: import gc except ImportError: @@ -56,6 +58,8 @@ # shutdown time. That frustrates tests trying to check stderr produced # from a spawned Python process. actual = support.strip_python_stderr(stderr) + # strip_python_stderr also strips whitespace, so we do too. + expected = expected.strip() self.assertEqual(actual, expected, msg) @@ -67,6 +71,15 @@ "import sys; sys.exit(47)"]) self.assertEqual(rc, 47) + def test_call_timeout(self): + # call() function with timeout argument; we want to test that the child + # process gets killed when the timeout expires. If the child isn't + # killed, this call will deadlock since subprocess.call waits for the + # child. + self.assertRaises(subprocess.TimeoutExpired, subprocess.call, + [sys.executable, "-c", "while True: pass"], + timeout=0.1) + def test_check_call_zero(self): # check_call() function with zero return code rc = subprocess.check_call([sys.executable, "-c", @@ -109,6 +122,20 @@ self.fail("Expected ValueError when stdout arg supplied.") self.assertIn('stdout', c.exception.args[0]) + def test_check_output_timeout(self): + # check_output() function with timeout arg + with self.assertRaises(subprocess.TimeoutExpired) as c: + output = subprocess.check_output( + [sys.executable, "-c", + "import sys; sys.stdout.write('BDFL')\n" + "sys.stdout.flush()\n" + "while True: pass"], + # Some heavily loaded buildbots (sparc Debian 3.x) require + # this much time to start and print. + timeout=3) + self.fail("Expected TimeoutExpired.") + self.assertEqual(c.exception.output, b'BDFL') + def test_call_kwargs(self): # call() function with keyword args newenv = os.environ.copy() @@ -298,6 +325,31 @@ rc = subprocess.call([sys.executable, "-c", cmd], stdout=1) self.assertEqual(rc, 2) + def test_stdout_devnull(self): + p = subprocess.Popen([sys.executable, "-c", + 'for i in range(10240):' + 'print("x" * 1024)'], + stdout=subprocess.DEVNULL) + p.wait() + self.assertEqual(p.stdout, None) + + def test_stderr_devnull(self): + p = subprocess.Popen([sys.executable, "-c", + 'import sys\n' + 'for i in range(10240):' + 'sys.stderr.write("x" * 1024)'], + stderr=subprocess.DEVNULL) + p.wait() + self.assertEqual(p.stderr, None) + + def test_stdin_devnull(self): + p = subprocess.Popen([sys.executable, "-c", + 'import sys;' + 'sys.stdin.read(1)'], + stdin=subprocess.DEVNULL) + p.wait() + self.assertEqual(p.stdin, None) + def test_cwd(self): tmpdir = tempfile.gettempdir() # We cannot use os.path.realpath to canonicalize the path, @@ -366,6 +418,41 @@ self.assertEqual(stdout, b"banana") self.assertStderrEqual(stderr, b"pineapple") + def test_communicate_timeout(self): + p = subprocess.Popen([sys.executable, "-c", + 'import sys,os,time;' + 'sys.stderr.write("pineapple\\n");' + 'time.sleep(1);' + 'sys.stderr.write("pear\\n");' + 'sys.stdout.write(sys.stdin.read())'], + universal_newlines=True, + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + self.assertRaises(subprocess.TimeoutExpired, p.communicate, "banana", + timeout=0.3) + # Make sure we can keep waiting for it, and that we get the whole output + # after it completes. + (stdout, stderr) = p.communicate() + self.assertEqual(stdout, "banana") + self.assertStderrEqual(stderr.encode(), b"pineapple\npear\n") + + def test_communicate_timeout_large_ouput(self): + # Test a expring timeout while the child is outputting lots of data. + p = subprocess.Popen([sys.executable, "-c", + 'import sys,os,time;' + 'sys.stdout.write("a" * (64 * 1024));' + 'time.sleep(0.2);' + 'sys.stdout.write("a" * (64 * 1024));' + 'time.sleep(0.2);' + 'sys.stdout.write("a" * (64 * 1024));' + 'time.sleep(0.2);' + 'sys.stdout.write("a" * (64 * 1024));'], + stdout=subprocess.PIPE) + self.assertRaises(subprocess.TimeoutExpired, p.communicate, timeout=0.4) + (stdout, _) = p.communicate() + self.assertEqual(len(stdout), 4 * 64 * 1024) + # Test for the fd leak reported in http://bugs.python.org/issue2791. def test_communicate_pipe_fd_leak(self): for stdin_pipe in (False, True): @@ -488,11 +575,12 @@ else: max_handles = 2050 # too much for (at least some) Windows setups handles = [] + tmpdir = tempfile.mkdtemp() try: for i in range(max_handles): try: - handles.append(os.open(support.TESTFN, - os.O_WRONLY | os.O_CREAT)) + tmpfile = os.path.join(tmpdir, support.TESTFN) + handles.append(os.open(tmpfile, os.O_WRONLY|os.O_CREAT)) except OSError as e: if e.errno != errno.EMFILE: raise @@ -517,6 +605,7 @@ finally: for h in handles: os.close(h) + shutil.rmtree(tmpdir) def test_list2cmdline(self): self.assertEqual(subprocess.list2cmdline(['a b c', 'd', 'e']), @@ -560,6 +649,15 @@ # Subsequent invocations should just return the returncode self.assertEqual(p.wait(), 0) + def test_wait_timeout(self): + p = subprocess.Popen([sys.executable, + "-c", "import time; time.sleep(0.1)"]) + with self.assertRaises(subprocess.TimeoutExpired) as c: + p.wait(timeout=0.01) + self.assertIn("0.01", str(c.exception)) # For coverage of __str__. + # Some heavily loaded buildbots (sparc Debian 3.x) require this much + # time to start. + self.assertEqual(p.wait(timeout=3), 0) def test_invalid_bufsize(self): # an invalid type of the bufsize argument should raise @@ -587,7 +685,8 @@ subprocess.Popen(['nonexisting_i_hope'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) - if c.exception.errno != errno.ENOENT: # ignore "no such file" + # ignore errors that indicate the command was not found + if c.exception.errno not in (errno.ENOENT, errno.EACCES): raise c.exception def test_issue8780(self): @@ -1187,6 +1286,24 @@ close_fds=False, pass_fds=(fd, ))) self.assertIn('overriding close_fds', str(context.warning)) + def test_stdout_stdin_are_single_inout_fd(self): + with io.open(os.devnull, "r+") as inout: + p = subprocess.Popen([sys.executable, "-c", "import sys; sys.exit(0)"], + stdout=inout, stdin=inout) + p.wait() + + def test_stdout_stderr_are_single_inout_fd(self): + with io.open(os.devnull, "r+") as inout: + p = subprocess.Popen([sys.executable, "-c", "import sys; sys.exit(0)"], + stdout=inout, stderr=inout) + p.wait() + + def test_stderr_stdin_are_single_inout_fd(self): + with io.open(os.devnull, "r+") as inout: + p = subprocess.Popen([sys.executable, "-c", "import sys; sys.exit(0)"], + stderr=inout, stdin=inout) + p.wait() + def test_wait_when_sigchild_ignored(self): # NOTE: sigchild_ignore.py may not be an effective test on all OSes. sigchild_ignore = support.findfile("sigchild_ignore.py", @@ -1474,4 +1591,4 @@ support.reap_children() if __name__ == "__main__": - test_main() + unittest.main() diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/test/test_sundry.py --- a/Lib/test/test_sundry.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/test/test_sundry.py Wed Mar 16 19:19:36 2011 -0400 @@ -54,7 +54,6 @@ import py_compile import sndhdr import tabnanny - import timeit try: import tty # not available on Windows except ImportError: diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/test/test_syntax.py --- a/Lib/test/test_syntax.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/test/test_syntax.py Wed Mar 16 19:19:36 2011 -0400 @@ -237,7 +237,7 @@ Test continue in finally in weird combinations. -continue in for loop under finally shouuld be ok. +continue in for loop under finally should be ok. >>> def test(): ... try: diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/test/test_sys.py --- a/Lib/test/test_sys.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/test/test_sys.py Wed Mar 16 19:19:36 2011 -0400 @@ -492,7 +492,7 @@ # provide too much opportunity for insane things to happen. # We don't want them in the interned dict and if they aren't # actually interned, we don't want to create the appearance - # that they are by allowing intern() to succeeed. + # that they are by allowing intern() to succeed. class S(str): def __hash__(self): return 123 diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/test/test_tempfile.py --- a/Lib/test/test_tempfile.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/test/test_tempfile.py Wed Mar 16 19:19:36 2011 -0400 @@ -704,6 +704,23 @@ f.write(b'x') self.assertTrue(f._rolled) + def test_writelines(self): + # Verify writelines with a SpooledTemporaryFile + f = self.do_create() + f.writelines((b'x', b'y', b'z')) + f.seek(0) + buf = f.read() + self.assertEqual(buf, b'xyz') + + def test_writelines_sequential(self): + # A SpooledTemporaryFile should hold exactly max_size bytes, and roll + # over afterward + f = self.do_create(max_size=35) + f.writelines((b'x' * 20, b'x' * 10, b'x' * 5)) + self.assertFalse(f._rolled) + f.write(b'x') + self.assertTrue(f._rolled) + def test_sparse(self): # A SpooledTemporaryFile that is written late in the file will extend # when that occurs diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/test/test_threading.py --- a/Lib/test/test_threading.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/test/test_threading.py Wed Mar 16 19:19:36 2011 -0400 @@ -578,7 +578,7 @@ # This acquires the lock and then waits until the child has forked # before returning, which will release the lock soon after. If # someone else tries to fix this test case by acquiring this lock - # before forking instead of reseting it, the test case will + # before forking instead of resetting it, the test case will # deadlock when it shouldn't. condition = w._block orig_acquire = condition.acquire diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/test/test_threadsignals.py --- a/Lib/test/test_threadsignals.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/test/test_threadsignals.py Wed Mar 16 19:19:36 2011 -0400 @@ -73,18 +73,29 @@ def test_lock_acquire_interruption(self): # Mimic receiving a SIGINT (KeyboardInterrupt) with SIGALRM while stuck # in a deadlock. + # XXX this test can fail when the legacy (non-semaphore) implementation + # of locks is used in thread_pthread.h, see issue #11223. oldalrm = signal.signal(signal.SIGALRM, self.alarm_interrupt) try: lock = thread.allocate_lock() lock.acquire() signal.alarm(1) - self.assertRaises(KeyboardInterrupt, lock.acquire) + t1 = time.time() + self.assertRaises(KeyboardInterrupt, lock.acquire, timeout=5) + dt = time.time() - t1 + # Checking that KeyboardInterrupt was raised is not sufficient. + # We want to assert that lock.acquire() was interrupted because + # of the signal, not that the signal handler was called immediately + # after timeout return of lock.acquire() (which can fool assertRaises). + self.assertLess(dt, 3.0) finally: signal.signal(signal.SIGALRM, oldalrm) def test_rlock_acquire_interruption(self): # Mimic receiving a SIGINT (KeyboardInterrupt) with SIGALRM while stuck # in a deadlock. + # XXX this test can fail when the legacy (non-semaphore) implementation + # of locks is used in thread_pthread.h, see issue #11223. oldalrm = signal.signal(signal.SIGALRM, self.alarm_interrupt) try: rlock = thread.RLock() @@ -98,7 +109,11 @@ rlock.release() time.sleep(0.01) signal.alarm(1) - self.assertRaises(KeyboardInterrupt, rlock.acquire) + t1 = time.time() + self.assertRaises(KeyboardInterrupt, rlock.acquire, timeout=5) + dt = time.time() - t1 + # See rationale above in test_lock_acquire_interruption + self.assertLess(dt, 3.0) finally: signal.signal(signal.SIGALRM, oldalrm) diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/test/test_timeit.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Lib/test/test_timeit.py Wed Mar 16 19:19:36 2011 -0400 @@ -0,0 +1,305 @@ +import timeit +import unittest +import sys +import io +import time +from textwrap import dedent + +from test.support import run_unittest +from test.support import captured_stdout +from test.support import captured_stderr + +# timeit's default number of iterations. +DEFAULT_NUMBER = 1000000 + +# timeit's default number of repetitions. +DEFAULT_REPEAT = 3 + +# XXX: some tests are commented out that would improve the coverage but take a +# long time to run because they test the default number of loops, which is +# large. The tests could be enabled if there was a way to override the default +# number of loops during testing, but this would require changing the signature +# of some functions that use the default as a default argument. + +class FakeTimer: + BASE_TIME = 42.0 + def __init__(self, seconds_per_increment=1.0): + self.count = 0 + self.setup_calls = 0 + self.seconds_per_increment=seconds_per_increment + timeit._fake_timer = self + + def __call__(self): + return self.BASE_TIME + self.count * self.seconds_per_increment + + def inc(self): + self.count += 1 + + def setup(self): + self.setup_calls += 1 + + def wrap_timer(self, timer): + """Records 'timer' and returns self as callable timer.""" + self.saved_timer = timer + return self + +class TestTimeit(unittest.TestCase): + + def tearDown(self): + try: + del timeit._fake_timer + except AttributeError: + pass + + def test_reindent_empty(self): + self.assertEqual(timeit.reindent("", 0), "") + self.assertEqual(timeit.reindent("", 4), "") + + def test_reindent_single(self): + self.assertEqual(timeit.reindent("pass", 0), "pass") + self.assertEqual(timeit.reindent("pass", 4), "pass") + + def test_reindent_multi_empty(self): + self.assertEqual(timeit.reindent("\n\n", 0), "\n\n") + self.assertEqual(timeit.reindent("\n\n", 4), "\n \n ") + + def test_reindent_multi(self): + self.assertEqual(timeit.reindent( + "print()\npass\nbreak", 0), + "print()\npass\nbreak") + self.assertEqual(timeit.reindent( + "print()\npass\nbreak", 4), + "print()\n pass\n break") + + def test_timer_invalid_stmt(self): + self.assertRaises(ValueError, timeit.Timer, stmt=None) + + def test_timer_invalid_setup(self): + self.assertRaises(ValueError, timeit.Timer, setup=None) + + fake_setup = "import timeit; timeit._fake_timer.setup()" + fake_stmt = "import timeit; timeit._fake_timer.inc()" + + def fake_callable_setup(self): + self.fake_timer.setup() + + def fake_callable_stmt(self): + self.fake_timer.inc() + + def timeit(self, stmt, setup, number=None): + self.fake_timer = FakeTimer() + t = timeit.Timer(stmt=stmt, setup=setup, timer=self.fake_timer) + kwargs = {} + if number is None: + number = DEFAULT_NUMBER + else: + kwargs['number'] = number + delta_time = t.timeit(**kwargs) + self.assertEqual(self.fake_timer.setup_calls, 1) + self.assertEqual(self.fake_timer.count, number) + self.assertEqual(delta_time, number) + + # Takes too long to run in debug build. + #def test_timeit_default_iters(self): + # self.timeit(self.fake_stmt, self.fake_setup) + + def test_timeit_zero_iters(self): + self.timeit(self.fake_stmt, self.fake_setup, number=0) + + def test_timeit_few_iters(self): + self.timeit(self.fake_stmt, self.fake_setup, number=3) + + def test_timeit_callable_stmt(self): + self.timeit(self.fake_callable_stmt, self.fake_setup, number=3) + + def test_timeit_callable_stmt_and_setup(self): + self.timeit(self.fake_callable_stmt, + self.fake_callable_setup, number=3) + + # Takes too long to run in debug build. + #def test_timeit_function(self): + # delta_time = timeit.timeit(self.fake_stmt, self.fake_setup, + # timer=FakeTimer()) + # self.assertEqual(delta_time, DEFAULT_NUMBER) + + def test_timeit_function_zero_iters(self): + delta_time = timeit.timeit(self.fake_stmt, self.fake_setup, number=0, + timer=FakeTimer()) + self.assertEqual(delta_time, 0) + + def repeat(self, stmt, setup, repeat=None, number=None): + self.fake_timer = FakeTimer() + t = timeit.Timer(stmt=stmt, setup=setup, timer=self.fake_timer) + kwargs = {} + if repeat is None: + repeat = DEFAULT_REPEAT + else: + kwargs['repeat'] = repeat + if number is None: + number = DEFAULT_NUMBER + else: + kwargs['number'] = number + delta_times = t.repeat(**kwargs) + self.assertEqual(self.fake_timer.setup_calls, repeat) + self.assertEqual(self.fake_timer.count, repeat * number) + self.assertEqual(delta_times, repeat * [float(number)]) + + # Takes too long to run in debug build. + #def test_repeat_default(self): + # self.repeat(self.fake_stmt, self.fake_setup) + + def test_repeat_zero_reps(self): + self.repeat(self.fake_stmt, self.fake_setup, repeat=0) + + def test_repeat_zero_iters(self): + self.repeat(self.fake_stmt, self.fake_setup, number=0) + + def test_repeat_few_reps_and_iters(self): + self.repeat(self.fake_stmt, self.fake_setup, repeat=3, number=5) + + def test_repeat_callable_stmt(self): + self.repeat(self.fake_callable_stmt, self.fake_setup, + repeat=3, number=5) + + def test_repeat_callable_stmt_and_setup(self): + self.repeat(self.fake_callable_stmt, self.fake_callable_setup, + repeat=3, number=5) + + # Takes too long to run in debug build. + #def test_repeat_function(self): + # delta_times = timeit.repeat(self.fake_stmt, self.fake_setup, + # timer=FakeTimer()) + # self.assertEqual(delta_times, DEFAULT_REPEAT * [float(DEFAULT_NUMBER)]) + + def test_repeat_function_zero_reps(self): + delta_times = timeit.repeat(self.fake_stmt, self.fake_setup, repeat=0, + timer=FakeTimer()) + self.assertEqual(delta_times, []) + + def test_repeat_function_zero_iters(self): + delta_times = timeit.repeat(self.fake_stmt, self.fake_setup, number=0, + timer=FakeTimer()) + self.assertEqual(delta_times, DEFAULT_REPEAT * [0.0]) + + def assert_exc_string(self, exc_string, expected_exc_name): + exc_lines = exc_string.splitlines() + self.assertGreater(len(exc_lines), 2) + self.assertTrue(exc_lines[0].startswith('Traceback')) + self.assertTrue(exc_lines[-1].startswith(expected_exc_name)) + + def test_print_exc(self): + s = io.StringIO() + t = timeit.Timer("1/0") + try: + t.timeit() + except: + t.print_exc(s) + self.assert_exc_string(s.getvalue(), 'ZeroDivisionError') + + MAIN_DEFAULT_OUTPUT = "10 loops, best of 3: 1 sec per loop\n" + + def run_main(self, seconds_per_increment=1.0, switches=None, timer=None): + if timer is None: + timer = FakeTimer(seconds_per_increment=seconds_per_increment) + if switches is None: + args = [] + else: + args = switches[:] + args.append(self.fake_stmt) + # timeit.main() modifies sys.path, so save and restore it. + orig_sys_path = sys.path[:] + with captured_stdout() as s: + timeit.main(args=args, _wrap_timer=timer.wrap_timer) + sys.path[:] = orig_sys_path[:] + return s.getvalue() + + def test_main_bad_switch(self): + s = self.run_main(switches=['--bad-switch']) + self.assertEqual(s, dedent("""\ + option --bad-switch not recognized + use -h/--help for command line help + """)) + + def test_main_seconds(self): + s = self.run_main(seconds_per_increment=5.5) + self.assertEqual(s, "10 loops, best of 3: 5.5 sec per loop\n") + + def test_main_milliseconds(self): + s = self.run_main(seconds_per_increment=0.0055) + self.assertEqual(s, "100 loops, best of 3: 5.5 msec per loop\n") + + def test_main_microseconds(self): + s = self.run_main(seconds_per_increment=0.0000025, switches=['-n100']) + self.assertEqual(s, "100 loops, best of 3: 2.5 usec per loop\n") + + def test_main_fixed_iters(self): + s = self.run_main(seconds_per_increment=2.0, switches=['-n35']) + self.assertEqual(s, "35 loops, best of 3: 2 sec per loop\n") + + def test_main_setup(self): + s = self.run_main(seconds_per_increment=2.0, + switches=['-n35', '-s', 'print("CustomSetup")']) + self.assertEqual(s, "CustomSetup\n" * 3 + + "35 loops, best of 3: 2 sec per loop\n") + + def test_main_fixed_reps(self): + s = self.run_main(seconds_per_increment=60.0, switches=['-r9']) + self.assertEqual(s, "10 loops, best of 9: 60 sec per loop\n") + + def test_main_negative_reps(self): + s = self.run_main(seconds_per_increment=60.0, switches=['-r-5']) + self.assertEqual(s, "10 loops, best of 1: 60 sec per loop\n") + + def test_main_help(self): + s = self.run_main(switches=['-h']) + # Note: It's not clear that the trailing space was intended as part of + # the help text, but since it's there, check for it. + self.assertEqual(s, timeit.__doc__ + ' ') + + def test_main_using_time(self): + fake_timer = FakeTimer() + s = self.run_main(switches=['-t'], timer=fake_timer) + self.assertEqual(s, self.MAIN_DEFAULT_OUTPUT) + self.assertIs(fake_timer.saved_timer, time.time) + + def test_main_using_clock(self): + fake_timer = FakeTimer() + s = self.run_main(switches=['-c'], timer=fake_timer) + self.assertEqual(s, self.MAIN_DEFAULT_OUTPUT) + self.assertIs(fake_timer.saved_timer, time.clock) + + def test_main_verbose(self): + s = self.run_main(switches=['-v']) + self.assertEqual(s, dedent("""\ + 10 loops -> 10 secs + raw times: 10 10 10 + 10 loops, best of 3: 1 sec per loop + """)) + + def test_main_very_verbose(self): + s = self.run_main(seconds_per_increment=0.000050, switches=['-vv']) + self.assertEqual(s, dedent("""\ + 10 loops -> 0.0005 secs + 100 loops -> 0.005 secs + 1000 loops -> 0.05 secs + 10000 loops -> 0.5 secs + raw times: 0.5 0.5 0.5 + 10000 loops, best of 3: 50 usec per loop + """)) + + def test_main_exception(self): + with captured_stderr() as error_stringio: + s = self.run_main(switches=['1/0']) + self.assert_exc_string(error_stringio.getvalue(), 'ZeroDivisionError') + + def test_main_exception_fixed_reps(self): + with captured_stderr() as error_stringio: + s = self.run_main(switches=['-n1', '1/0']) + self.assert_exc_string(error_stringio.getvalue(), 'ZeroDivisionError') + + +def test_main(): + run_unittest(TestTimeit) + +if __name__ == '__main__': + test_main() diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/test/test_trace.py --- a/Lib/test/test_trace.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/test/test_trace.py Wed Mar 16 19:19:36 2011 -0400 @@ -209,7 +209,7 @@ (self.my_py_filename, firstlineno + 4): 1, } - # When used through 'run', some other spurios counts are produced, like + # When used through 'run', some other spurious counts are produced, like # the settrace of threading, which we ignore, just making sure that the # counts fo traced_func_loop were right. # diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/test/test_urllib.py --- a/Lib/test/test_urllib.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/test/test_urllib.py Wed Mar 16 19:19:36 2011 -0400 @@ -1021,7 +1021,7 @@ # Just commented them out. # Can't really tell why keep failing in windows and sparc. -# Everywhere else they work ok, but on those machines, someteimes +# Everywhere else they work ok, but on those machines, sometimes # fail in one of the tests, sometimes in other. I have a linux, and # the tests go ok. # If anybody has one of the problematic enviroments, please help! diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/test/test_urllib2.py --- a/Lib/test/test_urllib2.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/test/test_urllib2.py Wed Mar 16 19:19:36 2011 -0400 @@ -7,7 +7,9 @@ import array import urllib.request -from urllib.request import Request, OpenerDirector +# The proxy bypass method imported below has logic specific to the OSX +# proxy config data structure but is testable on all platforms. +from urllib.request import Request, OpenerDirector, _proxy_bypass_macosx_sysconf # XXX # Request @@ -1076,6 +1078,17 @@ self.assertEqual(req.get_host(), "www.python.org") del os.environ['no_proxy'] + def test_proxy_no_proxy_all(self): + os.environ['no_proxy'] = '*' + o = OpenerDirector() + ph = urllib.request.ProxyHandler(dict(http="proxy.example.com")) + o.add_handler(ph) + req = Request("http://www.python.org") + self.assertEqual(req.get_host(), "www.python.org") + r = o.open(req) + self.assertEqual(req.get_host(), "www.python.org") + del os.environ['no_proxy'] + def test_proxy_https(self): o = OpenerDirector() @@ -1116,6 +1129,26 @@ self.assertEqual(req.get_host(), "proxy.example.com:3128") self.assertEqual(req.get_header("Proxy-authorization"),"FooBar") + def test_osx_proxy_bypass(self): + bypass = { + 'exclude_simple': False, + 'exceptions': ['foo.bar', '*.bar.com', '127.0.0.1', '10.10', + '10.0/16'] + } + # Check hosts that should trigger the proxy bypass + for host in ('foo.bar', 'www.bar.com', '127.0.0.1', '10.10.0.1', + '10.0.0.1'): + self.assertTrue(_proxy_bypass_macosx_sysconf(host, bypass), + 'expected bypass of %s to be True' % host) + # Check hosts that should not trigger the proxy bypass + for host in ('abc.foo.bar', 'bar.com', '127.0.0.2', '10.11.0.1', 'test'): + self.assertFalse(_proxy_bypass_macosx_sysconf(host, bypass), + 'expected bypass of %s to be False' % host) + + # Check the exclude_simple flag + bypass = {'exclude_simple': True, 'exceptions': []} + self.assertTrue(_proxy_bypass_macosx_sysconf('test', bypass)) + def test_basic_auth(self, quote_char='"'): opener = OpenerDirector() password_manager = MockPasswordManager() diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/test/test_warnings.py --- a/Lib/test/test_warnings.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/test/test_warnings.py Wed Mar 16 19:19:36 2011 -0400 @@ -332,7 +332,7 @@ sys.argv = argv def test_warn_explicit_type_errors(self): - # warn_explicit() shoud error out gracefully if it is given objects + # warn_explicit() should error out gracefully if it is given objects # of the wrong types. # lineno is expected to be an integer. self.assertRaises(TypeError, self.module.warn_explicit, @@ -758,7 +758,7 @@ class BootstrapTest(unittest.TestCase): def test_issue_8766(self): # "import encodings" emits a warning whereas the warnings is not loaded - # or not completly loaded (warnings imports indirectly encodings by + # or not completely loaded (warnings imports indirectly encodings by # importing linecache) yet with support.temp_cwd() as cwd, support.temp_cwd('encodings'): env = os.environ.copy() diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/test/test_zipfile.py --- a/Lib/test/test_zipfile.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/test/test_zipfile.py Wed Mar 16 19:19:36 2011 -0400 @@ -489,6 +489,7 @@ except zipfile.BadZipFile: self.assertTrue(zipfp2.fp is None, 'zipfp is not closed') + @skipUnless(zlib, "requires zlib") def test_unicode_filenames(self): # bug #10801 fname = findfile('zip_cp437_header.zip') diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/timeit.py --- a/Lib/timeit.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/timeit.py Wed Mar 16 19:19:36 2011 -0400 @@ -232,10 +232,10 @@ """Convenience function to create Timer object and call repeat method.""" return Timer(stmt, setup, timer).repeat(repeat, number) -def main(args=None): +def main(args=None, *, _wrap_timer=None): """Main program, used when run as a script. - The optional argument specifies the command line to be parsed, + The optional 'args' argument specifies the command line to be parsed, defaulting to sys.argv[1:]. The return value is an exit code to be passed to sys.exit(); it @@ -244,6 +244,10 @@ When an exception happens during timing, a traceback is printed to stderr and the return value is 1. Exceptions at other times (including the template compilation) are not caught. + + '_wrap_timer' is an internal interface used for unit testing. If it + is not None, it must be a callable that accepts a timer function + and returns another timer function (used for unit testing). """ if args is None: args = sys.argv[1:] @@ -289,6 +293,8 @@ # directory) import os sys.path.insert(0, os.curdir) + if _wrap_timer is not None: + timer = _wrap_timer(timer) t = Timer(stmt, setup, timer) if number == 0: # determine number so that 0.2 <= total time < 2.0 diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/tkinter/__init__.py --- a/Lib/tkinter/__init__.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/tkinter/__init__.py Wed Mar 16 19:19:36 2011 -0400 @@ -1649,7 +1649,7 @@ class Tk(Misc, Wm): """Toplevel widget of Tk which represents mostly the main window - of an appliation. It has an associated Tcl interpreter.""" + of an application. It has an associated Tcl interpreter.""" _w = '.' def __init__(self, screenName=None, baseName=None, className='Tk', useTk=1, sync=0, use=None): diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/tkinter/test/test_ttk/test_functions.py --- a/Lib/tkinter/test/test_ttk/test_functions.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/tkinter/test/test_ttk/test_functions.py Wed Mar 16 19:19:36 2011 -0400 @@ -135,7 +135,7 @@ # minimum acceptable for image type self.assertEqual(ttk._format_elemcreate('image', False, 'test'), ("test ", ())) - # specifiyng a state spec + # specifying a state spec self.assertEqual(ttk._format_elemcreate('image', False, 'test', ('', 'a')), ("test {} a", ())) # state spec with multiple states diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/tkinter/tix.py --- a/Lib/tkinter/tix.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/tkinter/tix.py Wed Mar 16 19:19:36 2011 -0400 @@ -163,7 +163,7 @@ extensions) exist, then the image type is chosen according to the depth of the X display: xbm images are chosen on monochrome displays and color images are chosen on color displays. By using - tix_ getimage, you can advoid hard coding the pathnames of the + tix_ getimage, you can avoid hard coding the pathnames of the image files in your application. When successful, this command returns the name of the newly created image, which can be used to configure the -image option of the Tk and Tix widgets. @@ -171,7 +171,7 @@ return self.tk.call('tix', 'getimage', name) def tix_option_get(self, name): - """Gets the options manitained by the Tix + """Gets the options maintained by the Tix scheme mechanism. Available options include: active_bg active_fg bg @@ -576,7 +576,7 @@ class ComboBox(TixWidget): """ComboBox - an Entry field with a dropdown menu. The user can select a - choice by either typing in the entry subwdget or selecting from the + choice by either typing in the entry subwidget or selecting from the listbox subwidget. Subwidget Class @@ -869,7 +869,7 @@ """HList - Hierarchy display widget can be used to display any data that have a hierarchical structure, for example, file system directory trees. The list entries are indented and connected by branch lines - according to their places in the hierachy. + according to their places in the hierarchy. Subwidgets - None""" @@ -1519,7 +1519,7 @@ self.tk.call(self._w, 'selection', 'set', first, last) class Tree(TixWidget): - """Tree - The tixTree widget can be used to display hierachical + """Tree - The tixTree widget can be used to display hierarchical data in a tree form. The user can adjust the view of the tree by opening or closing parts of the tree.""" diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/tkinter/ttk.py --- a/Lib/tkinter/ttk.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/tkinter/ttk.py Wed Mar 16 19:19:36 2011 -0400 @@ -707,7 +707,7 @@ textvariable, values, width """ # The "values" option may need special formatting, so leave to - # _format_optdict the responsability to format it + # _format_optdict the responsibility to format it if "values" in kw: kw["values"] = _format_optdict({'v': kw["values"]})[1] @@ -993,7 +993,7 @@ pane is either an integer index or the name of a managed subwindow. If kw is not given, returns a dict of the pane option values. If option is specified then the value for that option is returned. - Otherwise, sets the options to the correspoding values.""" + Otherwise, sets the options to the corresponding values.""" if option is not None: kw[option] = None return _val_or_dict(kw, self.tk.call, self._w, "pane", pane) diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/turtle.py --- a/Lib/turtle.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/turtle.py Wed Mar 16 19:19:36 2011 -0400 @@ -1464,7 +1464,7 @@ Optional argument: picname -- a string, name of a gif-file or "nopic". - If picname is a filename, set the corresponing image as background. + If picname is a filename, set the corresponding image as background. If picname is "nopic", delete backgroundimage, if present. If picname is None, return the filename of the current backgroundimage. @@ -1488,7 +1488,7 @@ Optional arguments: canvwidth -- positive integer, new width of canvas in pixels canvheight -- positive integer, new height of canvas in pixels - bg -- colorstring or color-tupel, new backgroundcolor + bg -- colorstring or color-tuple, new backgroundcolor If no arguments are given, return current (canvaswidth, canvasheight) Do not alter the drawing window. To observe hidden parts of @@ -3242,9 +3242,9 @@ fill="", width=ps) # Turtle now at position old, self._position = old - ## if undo is done during crating a polygon, the last vertex - ## will be deleted. if the polygon is entirel deleted, - ## creatigPoly will be set to False. + ## if undo is done during creating a polygon, the last vertex + ## will be deleted. if the polygon is entirely deleted, + ## creatingPoly will be set to False. ## Polygons created before the last one will not be affected by undo() if self._creatingPoly: if len(self._poly) > 0: @@ -3352,7 +3352,7 @@ def dot(self, size=None, *color): """Draw a dot with diameter size, using color. - Optional argumentS: + Optional arguments: size -- an integer >= 1 (if given) color -- a colorstring or a numeric color tuple @@ -3796,7 +3796,7 @@ class Turtle(RawTurtle): - """RawTurtle auto-crating (scrolled) canvas. + """RawTurtle auto-creating (scrolled) canvas. When a Turtle object is created or a function derived from some Turtle method is called a TurtleScreen object is automatically created. @@ -3836,7 +3836,7 @@ filename -- a string, used as filename default value is turtle_docstringdict - Has to be called explicitely, (not used by the turtle-graphics classes) + Has to be called explicitly, (not used by the turtle-graphics classes) The docstring dictionary will be written to the Python script .py It is intended to serve as a template for translation of the docstrings into different languages. diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/turtledemo/bytedesign.py --- a/Lib/turtledemo/bytedesign.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/turtledemo/bytedesign.py Wed Mar 16 19:19:36 2011 -0400 @@ -4,7 +4,7 @@ tdemo_bytedesign.py An example adapted from the example-suite -of PythonCard's turtle graphcis. +of PythonCard's turtle graphics. It's based on an article in BYTE magazine Problem Solving with Logo: Using Turtle diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/unittest/case.py --- a/Lib/unittest/case.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/unittest/case.py Wed Mar 16 19:19:36 2011 -0400 @@ -469,7 +469,7 @@ warnings.warn("TestResult has no addExpectedFailure method, reporting as passes", RuntimeWarning) result.addSuccess(self) - + return result finally: result.stopTest(self) if orig_result is None: diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/unittest/test/test_case.py --- a/Lib/unittest/test/test_case.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/unittest/test/test_case.py Wed Mar 16 19:19:36 2011 -0400 @@ -386,27 +386,62 @@ self.assertIsInstance(Foo().id(), str) - # "If result is omitted or None, a temporary result object is created - # and used, but is not made available to the caller. As TestCase owns the + # "If result is omitted or None, a temporary result object is created, + # used, and is made available to the caller. As TestCase owns the # temporary result startTestRun and stopTestRun are called. def test_run__uses_defaultTestResult(self): events = [] + defaultResult = LoggingResult(events) class Foo(unittest.TestCase): def test(self): events.append('test') def defaultTestResult(self): - return LoggingResult(events) + return defaultResult # Make run() find a result object on its own - Foo('test').run() + result = Foo('test').run() + self.assertIs(result, defaultResult) expected = ['startTestRun', 'startTest', 'test', 'addSuccess', 'stopTest', 'stopTestRun'] self.assertEqual(events, expected) + + # "The result object is returned to run's caller" + def test_run__returns_given_result(self): + + class Foo(unittest.TestCase): + def test(self): + pass + + result = unittest.TestResult() + + retval = Foo('test').run(result) + self.assertIs(retval, result) + + + # "The same effect [as method run] may be had by simply calling the + # TestCase instance." + def test_call__invoking_an_instance_delegates_to_run(self): + resultIn = unittest.TestResult() + resultOut = unittest.TestResult() + + class Foo(unittest.TestCase): + def test(self): + pass + + def run(self, result): + self.assertIs(result, resultIn) + return resultOut + + retval = Foo('test')(resultIn) + + self.assertIs(retval, resultOut) + + def testShortDescriptionWithoutDocstring(self): self.assertIsNone(self.shortDescription()) diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/urllib/request.py --- a/Lib/urllib/request.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/urllib/request.py Wed Mar 16 19:19:36 2011 -0400 @@ -2208,68 +2208,76 @@ return 0 +# This code tests an OSX specific data structure but is testable on all +# platforms +def _proxy_bypass_macosx_sysconf(host, proxy_settings): + """ + Return True iff this host shouldn't be accessed using a proxy + + This function uses the MacOSX framework SystemConfiguration + to fetch the proxy information. + + proxy_settings come from _scproxy._get_proxy_settings or get mocked ie: + { 'exclude_simple': bool, + 'exceptions': ['foo.bar', '*.bar.com', '127.0.0.1', '10.1', '10.0/16'] + } + """ + import re + import socket + from fnmatch import fnmatch + + hostonly, port = splitport(host) + + def ip2num(ipAddr): + parts = ipAddr.split('.') + parts = list(map(int, parts)) + if len(parts) != 4: + parts = (parts + [0, 0, 0, 0])[:4] + return (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8) | parts[3] + + # Check for simple host names: + if '.' not in host: + if proxy_settings['exclude_simple']: + return True + + hostIP = None + + for value in proxy_settings.get('exceptions', ()): + # Items in the list are strings like these: *.local, 169.254/16 + if not value: continue + + m = re.match(r"(\d+(?:\.\d+)*)(/\d+)?", value) + if m is not None: + if hostIP is None: + try: + hostIP = socket.gethostbyname(hostonly) + hostIP = ip2num(hostIP) + except socket.error: + continue + + base = ip2num(m.group(1)) + mask = m.group(2) + if mask is None: + mask = 8 * (m.group(1).count('.') + 1) + else: + mask = int(mask[1:]) + mask = 32 - mask + + if (hostIP >> mask) == (base >> mask): + return True + + elif fnmatch(host, value): + return True + + return False + + if sys.platform == 'darwin': from _scproxy import _get_proxy_settings, _get_proxies def proxy_bypass_macosx_sysconf(host): - """ - Return True iff this host shouldn't be accessed using a proxy - - This function uses the MacOSX framework SystemConfiguration - to fetch the proxy information. - """ - import re - import socket - from fnmatch import fnmatch - - hostonly, port = splitport(host) - - def ip2num(ipAddr): - parts = ipAddr.split('.') - parts = list(map(int, parts)) - if len(parts) != 4: - parts = (parts + [0, 0, 0, 0])[:4] - return (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8) | parts[3] - proxy_settings = _get_proxy_settings() - - # Check for simple host names: - if '.' not in host: - if proxy_settings['exclude_simple']: - return True - - hostIP = None - - for value in proxy_settings.get('exceptions', ()): - # Items in the list are strings like these: *.local, 169.254/16 - if not value: continue - - m = re.match(r"(\d+(?:\.\d+)*)(/\d+)?", value) - if m is not None: - if hostIP is None: - try: - hostIP = socket.gethostbyname(hostonly) - hostIP = ip2num(hostIP) - except socket.error: - continue - - base = ip2num(m.group(1)) - mask = m.group(2) - if mask is None: - mask = 8 * (m.group(1).count('.') + 1) - - else: - mask = int(mask[1:]) - mask = 32 - mask - - if (hostIP >> mask) == (base >> mask): - return True - - elif fnmatch(host, value): - return True - - return False - + return _proxy_bypass_macosx_sysconf(host, proxy_settings) def getproxies_macosx_sysconf(): """Return a dictionary of scheme -> proxy server URL mappings. diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/urllib/response.py --- a/Lib/urllib/response.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/urllib/response.py Wed Mar 16 19:19:36 2011 -0400 @@ -33,12 +33,15 @@ id(self), self.fp) def close(self): + if self.fp: + self.fp.close() + self.fp = None self.read = None self.readline = None self.readlines = None self.fileno = None - if self.fp: self.fp.close() - self.fp = None + self.__iter__ = None + self.__next__ = None def __enter__(self): if self.fp is None: diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/webbrowser.py --- a/Lib/webbrowser.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/webbrowser.py Wed Mar 16 19:19:36 2011 -0400 @@ -228,15 +228,9 @@ else: # for TTY browsers, we need stdin/out inout = None - # if possible, put browser in separate process group, so - # keyboard interrupts don't affect browser as well as Python - setsid = getattr(os, 'setsid', None) - if not setsid: - setsid = getattr(os, 'setpgrp', None) - p = subprocess.Popen(cmdline, close_fds=True, stdin=inout, stdout=(self.redirect_stdout and inout or None), - stderr=inout, preexec_fn=setsid) + stderr=inout, start_new_session=True) if remote: # wait five secons. If the subprocess is not finished, the # remote invocation has (hopefully) started a new instance. diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/xml/dom/minicompat.py --- a/Lib/xml/dom/minicompat.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/xml/dom/minicompat.py Wed Mar 16 19:19:36 2011 -0400 @@ -6,7 +6,7 @@ # # NodeList -- lightest possible NodeList implementation # -# EmptyNodeList -- lightest possible NodeList that is guarateed to +# EmptyNodeList -- lightest possible NodeList that is guaranteed to # remain empty (immutable) # # StringTypes -- tuple of defined string types diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/xml/dom/minidom.py --- a/Lib/xml/dom/minidom.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/xml/dom/minidom.py Wed Mar 16 19:19:36 2011 -0400 @@ -1476,7 +1476,7 @@ return False def isId(self, aname): - """Returns true iff the named attribte is a DTD-style ID.""" + """Returns true iff the named attribute is a DTD-style ID.""" return False def isIdNS(self, namespaceURI, localName): @@ -1905,7 +1905,7 @@ e._call_user_data_handler(operation, n, entity) else: # Note the cloning of Document and DocumentType nodes is - # implemenetation specific. minidom handles those cases + # implementation specific. minidom handles those cases # directly in the cloneNode() methods. raise xml.dom.NotSupportedErr("Cannot clone node %s" % repr(node)) diff -r e34b09c69dd3 -r f1bd5468dae6 Lib/xmlrpc/server.py --- a/Lib/xmlrpc/server.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/xmlrpc/server.py Wed Mar 16 19:19:36 2011 -0400 @@ -240,7 +240,7 @@ marshalled data. For backwards compatibility, a dispatch function can be provided as an argument (see comment in SimpleXMLRPCRequestHandler.do_POST) but overriding the - existing method through subclassing is the prefered means + existing method through subclassing is the preferred means of changing method dispatch behavior. """ diff -r e34b09c69dd3 -r f1bd5468dae6 Mac/BuildScript/build-installer.py --- a/Mac/BuildScript/build-installer.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Mac/BuildScript/build-installer.py Wed Mar 16 19:19:36 2011 -0400 @@ -100,7 +100,7 @@ ARCHLIST = universal_opts_map[UNIVERSALARCHS] -# Source directory (asume we're in Mac/BuildScript) +# Source directory (assume we're in Mac/BuildScript) SRCDIR = os.path.dirname( os.path.dirname( os.path.dirname( @@ -362,7 +362,7 @@ def runCommand(commandline): """ - Run a command and raise RuntimeError if it fails. Output is surpressed + Run a command and raise RuntimeError if it fails. Output is suppressed unless the command fails. """ fd = os.popen(commandline, 'r') diff -r e34b09c69dd3 -r f1bd5468dae6 Mac/Tools/pythonw.c --- a/Mac/Tools/pythonw.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Mac/Tools/pythonw.c Wed Mar 16 19:19:36 2011 -0400 @@ -105,8 +105,8 @@ count = 1; - /* Run the real python executable using the same architure as this - * executable, this allows users to controle the architecture using + /* Run the real python executable using the same architecture as this + * executable, this allows users to control the architecture using * "arch -ppc python" */ diff -r e34b09c69dd3 -r f1bd5468dae6 Makefile.pre.in --- a/Makefile.pre.in Sat Mar 12 22:31:06 2011 -0500 +++ b/Makefile.pre.in Wed Mar 16 19:19:36 2011 -0400 @@ -486,18 +486,12 @@ $(LIBRARY) \ $(RESSRCDIR)/Info.plist $(INSTALL) -d -m $(DIRMODE) $(PYTHONFRAMEWORKDIR)/Versions/$(VERSION) - if test "${UNIVERSALSDK}"; then \ - $(CC) -o $(LDLIBRARY) @UNIVERSAL_ARCH_FLAGS@ -dynamiclib \ - -isysroot "${UNIVERSALSDK}" \ - -all_load $(LIBRARY) -Wl,-single_module \ - -install_name $(DESTDIR)$(PYTHONFRAMEWORKINSTALLDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK) \ - -compatibility_version $(VERSION) \ - -current_version $(VERSION) \ - -framework CoreFoundation $(LIBS); \ - else \ - /usr/bin/libtool -o $(LDLIBRARY) -dynamic $(OTHER_LIBTOOL_OPT) $(LIBRARY) \ - @LIBTOOL_CRUFT@ -framework CoreFoundation $(LIBS);\ - fi + $(CC) -o $(LDLIBRARY) $(PY_LDFLAGS) -dynamiclib \ + -all_load $(LIBRARY) -Wl,-single_module \ + -install_name $(DESTDIR)$(PYTHONFRAMEWORKINSTALLDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK) \ + -compatibility_version $(VERSION) \ + -current_version $(VERSION) \ + -framework CoreFoundation $(LIBS); $(INSTALL) -d -m $(DIRMODE) \ $(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/Resources/English.lproj $(INSTALL_DATA) $(RESSRCDIR)/Info.plist \ diff -r e34b09c69dd3 -r f1bd5468dae6 Misc/ACKS --- a/Misc/ACKS Sat Mar 12 22:31:06 2011 -0500 +++ b/Misc/ACKS Wed Mar 16 19:19:36 2011 -0400 @@ -32,6 +32,7 @@ Ross Andrus Jon Anglin Éric Araujo +Alicia Arlen Jason Asbahr David Ascher Chris AtLee @@ -80,6 +81,7 @@ Steven Bethard Stephen Bevan Ron Bickers +Natalia B. Bidart Adrian von Bidder David Binger Dominic Binks @@ -98,6 +100,7 @@ Forest Bond Gawain Bolton Gregory Bond +Matias Bordese Jurjen Bos Peter Bosch Eric Bouck @@ -170,6 +173,7 @@ Jeffery Collins Robert Collins Paul Colomiets +Denver Coneybeare Geremy Condra Juan José Conti Matt Conway @@ -197,6 +201,7 @@ Lisandro Dalcin Andrew Dalke Lars Damerow +Evan Dandrea Eric Daniel Scott David Daniels Ben Darnell @@ -222,6 +227,7 @@ Ismail Donmez Marcos Donolo Dima Dorfman +Yves Dorfsman Cesar Douady Dean Draayer Fred L. Drake, Jr. @@ -348,6 +354,7 @@ Derek Harland Jason Harper Brian Harring +Jonathan Hartley Larry Hastings Shane Hathaway Rycharde Hawkes @@ -370,6 +377,7 @@ Jason Hildebrand Richie Hindle Konrad Hinsen +Michael Henry David Hobley Tim Hochberg Joerg-Cyril Hoehle diff -r e34b09c69dd3 -r f1bd5468dae6 Misc/NEWS --- a/Misc/NEWS Sat Mar 12 22:31:06 2011 -0500 +++ b/Misc/NEWS Wed Mar 16 19:19:36 2011 -0400 @@ -12,6 +12,10 @@ - _ast.__version__ is now a Mercurial integer and hex revision. +- Issue #11432: A bug was introduced in subprocess.Popen on posix systems with + 3.2.0 where the stdout or stderr file descriptor being the same as the stdin + file descriptor would raise an exception. webbrowser.open would fail. fixed. + - Issue #9856: Change object.__format__ with a non-empty format string to be a DeprecationWarning. In 3.2 it was a PendingDeprecationWarning. In 3.4 it will be a TypeError. @@ -68,6 +72,51 @@ Library ------- +- Issue #11401: fix handling of headers with no value; this fixes a regression + relative to Python2 and the result is now the same as it was in Python2. + +- Issue #9298: base64 bodies weren't being folded to line lengths less than 78, + which was a regression relative to Python2. Unlike Python2, the last line + of the folded body now ends with a carriage return. + +- Issue #11560: shutil.unpack_archive now correctly handles the format + parameter. Patch by Evan Dandrea. + +- Issue #5870: Add `subprocess.DEVNULL` constant. + +- Issue #11133: fix two cases where inspect.getattr_static can trigger code + execution. Patch by Andreas Stührk. + +- Issue #11569: use absolute path to the sysctl command in multiprocessing to + ensure that it will be found regardless of the shell PATH. This ensures + that multiprocessing.cpu_count works on default installs of MacOSX. + +- Issue #11501: disutils.archive_utils.make_zipfile no longer fails if zlib is + not installed. Instead, the zipfile.ZIP_STORED compression is used to create + the ZipFile. Patch by Natalia B. Bidart. + +- Issue #11289: `smtp.SMTP` class becomes a context manager so it can be used + in a `with` statement. Contributed by Giampaolo Rodola. + +- Issue #11554: Fixed support for Japanese codecs; previously the body output + encoding was not done if euc-jp or shift-jis was specified as the charset. + +- Issue #11509: Significantly increase test coverage of fileinput. + Patch by Denver Coneybeare at PyCon 2011 Sprints. + +- Issue #11407: `TestCase.run` returns the result object used or created. + Contributed by Janathan Hartley. + +- Issue #11500: Fixed a bug in the os x proxy bypass code for fully qualified + IP addresses in the proxy exception list. + +- Issue #11491: dbm.error is no longer raised when dbm.open is called with + the "n" as the flag argument and the file exists. The behavior matches + the documentation and general logic. + +- Issue #1162477: Postel Principal adjustment to email date parsing: handle the + fact that some non-compliant MUAs use '.' instead of ':' in time specs. + - Issue #11131: Fix sign of zero in decimal.Decimal plus and minus operations when the rounding mode is ROUND_FLOOR. @@ -180,6 +229,8 @@ - Issue #11268: Prevent Mac OS X Installer failure if Documentation package had previously been installed. +- Issue #11495: OSF support is eliminated. It was deprecated in Python 3.2. + Tools/Demos ----------- @@ -188,6 +239,27 @@ Tests ----- +- Issue #11578: added test for the timeit module. Patch Michael Henry. + +- Issue #11503: improve test coverage of posixpath.py. Patch by Evan Dandrea. + +- Issue #11505: improves test coverage of string.py. Patch by Alicia + Arlen. + +- Issue #11548: Improve test coverage of the shutil module. Patch by + Evan Dandrea. + +- Issue #11554: Reactivated test_email_codecs. + +- Issue #11505: improves test coverage of string.py. Patch by Alicia + Arlen + +- Issue #11490: test_subprocess:test_leaking_fds_on_error no longer gives a + false positive if the last directory in the path is inaccessible. + +- Issue #11223: Fix test_threadsignals to fail, not hang, when the + non-semaphore implementation of locks is used under POSIX. + - Issue #10911: Add tests on CGI with non-ASCII characters. Patch written by Pierre Quentel. @@ -203,6 +275,11 @@ - Issue #10990: Prevent tests from clobbering a set trace function. +C-API +----- + +- PY_PATCHLEVEL_REVISION has been removed, since it's meaningless with Mercurial. + What's New in Python 3.2? ========================= @@ -612,6 +689,9 @@ support now looks for "__powerpc__" as well as "__ppc__": the latter seems to only be present on OS X; the former is the correct one for Linux with GCC. +- Issue #1099: Fix the build on MacOSX when building a framework with pydebug + using GCC 4.0. + Tools/Demos ----------- diff -r e34b09c69dd3 -r f1bd5468dae6 Misc/python-wing4.wpr --- a/Misc/python-wing4.wpr Sat Mar 12 22:31:06 2011 -0500 +++ b/Misc/python-wing4.wpr Wed Mar 16 19:19:36 2011 -0400 @@ -5,11 +5,12 @@ ################################################################## [project attributes] proj.directory-list = [{'dirloc': loc('..'), - 'excludes': [u'Lib/unittest/test/__pycache__', + 'excludes': [u'.hg', + u'Lib/unittest/__pycache__', + u'Lib/unittest/test/__pycache__', u'Lib/__pycache__', - u'Doc/build', - u'Lib/unittest/__pycache__', - u'build'], + u'build', + u'Doc/build'], 'filter': '*', 'include_hidden': False, 'recursive': True, diff -r e34b09c69dd3 -r f1bd5468dae6 Modules/_ctypes/_ctypes.c --- a/Modules/_ctypes/_ctypes.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Modules/_ctypes/_ctypes.c Wed Mar 16 19:19:36 2011 -0400 @@ -3317,7 +3317,7 @@ /* XXX XXX This would allow to pass additional options. For COM method *implementations*, we would probably want different behaviour than in 'normal' callback functions: return a HRESULT if - an exception occurrs in the callback, and print the traceback not + an exception occurs in the callback, and print the traceback not only on the console, but also to OutputDebugString() or something like that. */ diff -r e34b09c69dd3 -r f1bd5468dae6 Modules/_ctypes/callbacks.c --- a/Modules/_ctypes/callbacks.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Modules/_ctypes/callbacks.c Wed Mar 16 19:19:36 2011 -0400 @@ -202,7 +202,7 @@ /* XXX XXX XX We have the problem that c_byte or c_short have dict->size of 1 resp. 4, but these parameters are pushed as sizeof(int) bytes. - BTW, the same problem occurrs when they are pushed as parameters + BTW, the same problem occurs when they are pushed as parameters */ } else if (dict) { /* Hm, shouldn't we use PyCData_AtAddress() or something like that instead? */ diff -r e34b09c69dd3 -r f1bd5468dae6 Modules/_ctypes/callproc.c --- a/Modules/_ctypes/callproc.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Modules/_ctypes/callproc.c Wed Mar 16 19:19:36 2011 -0400 @@ -29,7 +29,7 @@ 4. _ctypes_callproc is then called with the 'callargs' tuple. _ctypes_callproc first allocates two arrays. The first is an array of 'struct argument' items, the - second array has 'void *' entried. + second array has 'void *' entries. 5. If 'converters' are present (converters is a sequence of argtypes' from_param methods), for each item in 'callargs' converter is called and the @@ -49,7 +49,7 @@ So, there are 4 data structures holding processed arguments: - the inargs tuple (in PyCFuncPtr_call) - the callargs tuple (in PyCFuncPtr_call) - - the 'struct argguments' array + - the 'struct arguments' array - the 'void *' array */ diff -r e34b09c69dd3 -r f1bd5468dae6 Modules/_cursesmodule.c --- a/Modules/_cursesmodule.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Modules/_cursesmodule.c Wed Mar 16 19:19:36 2011 -0400 @@ -105,10 +105,6 @@ #include "Python.h" -#ifdef __osf__ -#define STRICT_SYSV_CURSES /* Don't use ncurses extensions */ -#endif - #ifdef __hpux #define STRICT_SYSV_CURSES #endif diff -r e34b09c69dd3 -r f1bd5468dae6 Modules/_functoolsmodule.c --- a/Modules/_functoolsmodule.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Modules/_functoolsmodule.c Wed Mar 16 19:19:36 2011 -0400 @@ -242,7 +242,7 @@ __reduce__ by itself doesn't support getting kwargs in the unpickle operation so we define a __setstate__ that replaces all the information about the partial. If we only replaced part of it someone would use - it as a hook to do stange things. + it as a hook to do strange things. */ static PyObject * diff -r e34b09c69dd3 -r f1bd5468dae6 Modules/_io/iobase.c --- a/Modules/_io/iobase.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Modules/_io/iobase.c Wed Mar 16 19:19:36 2011 -0400 @@ -50,7 +50,7 @@ "stream.\n" "\n" "IOBase also supports the :keyword:`with` statement. In this example,\n" - "fp is closed after the suite of the with statment is complete:\n" + "fp is closed after the suite of the with statement is complete:\n" "\n" "with open('spam.txt', 'r') as fp:\n" " fp.write('Spam and eggs!')\n"); diff -r e34b09c69dd3 -r f1bd5468dae6 Modules/_io/stringio.c --- a/Modules/_io/stringio.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Modules/_io/stringio.c Wed Mar 16 19:19:36 2011 -0400 @@ -157,7 +157,7 @@ 0 lo string_size hi | |<---used--->|<----------available----------->| | | <--to pad-->|<---to write---> | - 0 buf positon + 0 buf position */ memset(self->buf + self->string_size, '\0', diff -r e34b09c69dd3 -r f1bd5468dae6 Modules/_pickle.c --- a/Modules/_pickle.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Modules/_pickle.c Wed Mar 16 19:19:36 2011 -0400 @@ -6259,7 +6259,7 @@ goto error; if (!PyDict_CheckExact(name_mapping_3to2)) { PyErr_Format(PyExc_RuntimeError, - "_compat_pickle.REVERSE_NAME_MAPPING shouldbe a dict, " + "_compat_pickle.REVERSE_NAME_MAPPING should be a dict, " "not %.200s", Py_TYPE(name_mapping_3to2)->tp_name); goto error; } diff -r e34b09c69dd3 -r f1bd5468dae6 Modules/_posixsubprocess.c --- a/Modules/_posixsubprocess.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Modules/_posixsubprocess.c Wed Mar 16 19:19:36 2011 -0400 @@ -99,10 +99,10 @@ if (p2cread > 2) { POSIX_CALL(close(p2cread)); } - if (c2pwrite > 2) { + if (c2pwrite > 2 && c2pwrite != p2cread) { POSIX_CALL(close(c2pwrite)); } - if (errwrite != c2pwrite && errwrite > 2) { + if (errwrite != c2pwrite && errwrite != p2cread && errwrite > 2) { POSIX_CALL(close(errwrite)); } diff -r e34b09c69dd3 -r f1bd5468dae6 Modules/_sqlite/connection.h --- a/Modules/_sqlite/connection.h Sat Mar 12 22:31:06 2011 -0500 +++ b/Modules/_sqlite/connection.h Wed Mar 16 19:19:36 2011 -0400 @@ -55,7 +55,7 @@ /* None for autocommit, otherwise a PyString with the isolation level */ PyObject* isolation_level; - /* NULL for autocommit, otherwise a string with the BEGIN statment; will be + /* NULL for autocommit, otherwise a string with the BEGIN statement; will be * freed in connection destructor */ char* begin_statement; diff -r e34b09c69dd3 -r f1bd5468dae6 Modules/_struct.c --- a/Modules/_struct.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Modules/_struct.c Wed Mar 16 19:19:36 2011 -0400 @@ -1111,7 +1111,7 @@ case '>': case '!': /* Network byte order is big-endian */ return bigendian_table; - case '=': { /* Host byte order -- different from native in aligment! */ + case '=': { /* Host byte order -- different from native in alignment! */ int n = 1; char *p = (char *) &n; if (*p == 1) diff -r e34b09c69dd3 -r f1bd5468dae6 Modules/_threadmodule.c --- a/Modules/_threadmodule.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Modules/_threadmodule.c Wed Mar 16 19:19:36 2011 -0400 @@ -824,7 +824,7 @@ self->args, self->kw) < 0) { /* we need to get rid of ldict from thread so we create a new one the next time we do an attr - acces */ + access */ PyDict_DelItem(tdict, self->key); return NULL; } diff -r e34b09c69dd3 -r f1bd5468dae6 Modules/cmathmodule.c --- a/Modules/cmathmodule.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Modules/cmathmodule.c Wed Mar 16 19:19:36 2011 -0400 @@ -23,7 +23,7 @@ /* CM_LARGE_DOUBLE is used to avoid spurious overflow in the sqrt, log, inverse trig and inverse hyperbolic trig functions. Its log is used in the - evaluation of exp, cos, cosh, sin, sinh, tan, and tanh to avoid unecessary + evaluation of exp, cos, cosh, sin, sinh, tan, and tanh to avoid unnecessary overflow. */ diff -r e34b09c69dd3 -r f1bd5468dae6 Modules/fpectlmodule.c --- a/Modules/fpectlmodule.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Modules/fpectlmodule.c Wed Mar 16 19:19:36 2011 -0400 @@ -174,17 +174,6 @@ fp_enable(TRP_INVALID | TRP_DIV_BY_ZERO | TRP_OVERFLOW); PyOS_setsig(SIGFPE, handler); -/*-- DEC ALPHA OSF --------------------------------------------------------*/ -#elif defined(__alpha) && defined(__osf__) - /* References: exception_intro, ieee man pages */ - /* cc -c -I/usr/local/python/include fpectlmodule.c */ - /* ld -shared -o fpectlmodule.so fpectlmodule.o */ -#include - unsigned long fp_control = - IEEE_TRAP_ENABLE_INV | IEEE_TRAP_ENABLE_DZE | IEEE_TRAP_ENABLE_OVF; - ieee_set_fp_control(fp_control); - PyOS_setsig(SIGFPE, handler); - /*-- DEC ALPHA LINUX ------------------------------------------------------*/ #elif defined(__alpha) && defined(linux) #include diff -r e34b09c69dd3 -r f1bd5468dae6 Modules/mathmodule.c --- a/Modules/mathmodule.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Modules/mathmodule.c Wed Mar 16 19:19:36 2011 -0400 @@ -55,11 +55,6 @@ #include "Python.h" #include "_math.h" -#ifdef _OSF_SOURCE -/* OSF1 5.1 doesn't make this available with XOPEN_SOURCE_EXTENDED defined */ -extern double copysign(double, double); -#endif - /* sin(pi*x), giving accurate results for all finite x (especially x integral or close to an integer). This is here for use in the diff -r e34b09c69dd3 -r f1bd5468dae6 Modules/parsermodule.c --- a/Modules/parsermodule.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Modules/parsermodule.c Wed Mar 16 19:19:36 2011 -0400 @@ -1569,7 +1569,7 @@ || strcmp(s, ">>=") == 0 || strcmp(s, "**=") == 0); if (!res) - err_string("illegal augmmented assignment operator"); + err_string("illegal augmented assignment operator"); } } else { diff -r e34b09c69dd3 -r f1bd5468dae6 Modules/posixmodule.c --- a/Modules/posixmodule.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Modules/posixmodule.c Wed Mar 16 19:19:36 2011 -0400 @@ -1308,7 +1308,7 @@ win32_stat will first explicitly resolve the symlink target and then will call win32_lstat on that result. - The _w represent Unicode equivalents of the aformentioned ANSI functions. */ + The _w represent Unicode equivalents of the aforementioned ANSI functions. */ static int win32_lstat(const char* path, struct win32_stat *result) diff -r e34b09c69dd3 -r f1bd5468dae6 Modules/socketmodule.c --- a/Modules/socketmodule.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Modules/socketmodule.c Wed Mar 16 19:19:36 2011 -0400 @@ -155,7 +155,7 @@ #endif #ifdef HAVE_GETHOSTBYNAME_R -# if defined(_AIX) || defined(__osf__) +# if defined(_AIX) # define HAVE_GETHOSTBYNAME_R_3_ARG # elif defined(__sun) || defined(__sgi) # define HAVE_GETHOSTBYNAME_R_5_ARG @@ -2242,7 +2242,7 @@ * This is the guts of the recv() and recv_into() methods, which reads into a * char buffer. If you have any inc/dec ref to do to the objects that contain * the buffer, do it in the caller. This function returns the number of bytes - * succesfully read. If there was an error, it returns -1. Note that it is + * successfully read. If there was an error, it returns -1. Note that it is * also possible that we return a number of bytes smaller than the request * bytes. */ @@ -2446,7 +2446,7 @@ * This is the guts of the recvfrom() and recvfrom_into() methods, which reads * into a char buffer. If you have any inc/def ref to do to the objects that * contain the buffer, do it in the caller. This function returns the number - * of bytes succesfully read. If there was an error, it returns -1. Note + * of bytes successfully read. If there was an error, it returns -1. Note * that it is also possible that we return a number of bytes smaller than the * request bytes. * @@ -2541,9 +2541,9 @@ if (outlen != recvlen) { /* We did not read as many bytes as we anticipated, resize the - string if possible and be succesful. */ + string if possible and be successful. */ if (_PyBytes_Resize(&buf, outlen) < 0) - /* Oopsy, not so succesful after all. */ + /* Oopsy, not so successful after all. */ goto finally; } @@ -4372,7 +4372,7 @@ return 0; /* Failure */ #else - /* No need to initialise sockets with GCC/EMX */ + /* No need to initialize sockets with GCC/EMX */ return 1; /* Success */ #endif } @@ -4406,7 +4406,7 @@ "socket.py" which implements some additional functionality. The import of "_socket" may fail with an ImportError exception if os-specific initialization fails. On Windows, this does WINSOCK - initialization. When WINSOCK is initialized succesfully, a call to + initialization. When WINSOCK is initialized successfully, a call to WSACleanup() is scheduled to be made at exit time. */ diff -r e34b09c69dd3 -r f1bd5468dae6 Modules/termios.c --- a/Modules/termios.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Modules/termios.c Wed Mar 16 19:19:36 2011 -0400 @@ -9,11 +9,6 @@ #endif #include -#ifdef __osf__ -/* On OSF, sys/ioctl.h requires that struct termio already be defined, - * so this needs to be included first on that platform. */ -#include -#endif #include /* HP-UX requires that this be included to pick up MDCD, MCTS, MDSR, diff -r e34b09c69dd3 -r f1bd5468dae6 Modules/timemodule.c --- a/Modules/timemodule.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Modules/timemodule.c Wed Mar 16 19:19:36 2011 -0400 @@ -697,7 +697,7 @@ buf.tm_wday = -1; /* sentinel; original value ignored */ tt = mktime(&buf); /* Return value of -1 does not necessarily mean an error, but tm_wday - * cannot remain set to -1 if mktime succedded. */ + * cannot remain set to -1 if mktime succeeded. */ if (tt == (time_t)(-1) && buf.tm_wday == -1) { PyErr_SetString(PyExc_OverflowError, "mktime argument out of range"); diff -r e34b09c69dd3 -r f1bd5468dae6 Modules/zipimport.c --- a/Modules/zipimport.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Modules/zipimport.c Wed Mar 16 19:19:36 2011 -0400 @@ -1120,7 +1120,7 @@ } /* Given a path to a .pyc or .pyo file in the archive, return the - modifictaion time of the matching .py file, or 0 if no source + modification time of the matching .py file, or 0 if no source is available. */ static time_t get_mtime_of_source(ZipImporter *self, char *path) @@ -1172,7 +1172,7 @@ return code; } -/* Get the code object assoiciated with the module specified by +/* Get the code object associated with the module specified by 'fullname'. */ static PyObject * get_module_code(ZipImporter *self, char *fullname, diff -r e34b09c69dd3 -r f1bd5468dae6 Objects/bytearrayobject.c --- a/Objects/bytearrayobject.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Objects/bytearrayobject.c Wed Mar 16 19:19:36 2011 -0400 @@ -2245,7 +2245,7 @@ if (it == NULL) return NULL; - /* Try to determine the length of the argument. 32 is abitrary. */ + /* Try to determine the length of the argument. 32 is arbitrary. */ buf_size = _PyObject_LengthHint(arg, 32); if (buf_size == -1) { Py_DECREF(it); diff -r e34b09c69dd3 -r f1bd5468dae6 Objects/bytesobject.c --- a/Objects/bytesobject.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Objects/bytesobject.c Wed Mar 16 19:19:36 2011 -0400 @@ -487,7 +487,7 @@ default: *p++ = '\\'; s--; - goto non_esc; /* an arbitry number of unescaped + goto non_esc; /* an arbitrary number of unescaped UTF-8 bytes may follow. */ } } diff -r e34b09c69dd3 -r f1bd5468dae6 Objects/dictobject.c --- a/Objects/dictobject.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Objects/dictobject.c Wed Mar 16 19:19:36 2011 -0400 @@ -2080,7 +2080,7 @@ assert(d->ma_table == NULL && d->ma_fill == 0 && d->ma_used == 0); INIT_NONZERO_DICT_SLOTS(d); d->ma_lookup = lookdict_unicode; - /* The object has been implicitely tracked by tp_alloc */ + /* The object has been implicitly tracked by tp_alloc */ if (type == &PyDict_Type) _PyObject_GC_UNTRACK(d); #ifdef SHOW_CONVERSION_COUNTS diff -r e34b09c69dd3 -r f1bd5468dae6 Objects/floatobject.c --- a/Objects/floatobject.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Objects/floatobject.c Wed Mar 16 19:19:36 2011 -0400 @@ -15,11 +15,6 @@ #define MIN(x, y) ((x) < (y) ? (x) : (y)) -#ifdef _OSF_SOURCE -/* OSF1 5.1 doesn't make this available with XOPEN_SOURCE_EXTENDED defined */ -extern int finite(double); -#endif - /* Special free list Since some Python programs can spend much of their time allocating diff -r e34b09c69dd3 -r f1bd5468dae6 Objects/listobject.c --- a/Objects/listobject.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Objects/listobject.c Wed Mar 16 19:19:36 2011 -0400 @@ -11,7 +11,7 @@ /* Ensure ob_item has room for at least newsize elements, and set * ob_size to newsize. If newsize > ob_size on entry, the content * of the new slots at exit is undefined heap trash; it's the caller's - * responsiblity to overwrite them with sane values. + * responsibility to overwrite them with sane values. * The number of allocated elements may grow, shrink, or stay the same. * Failure is impossible if newsize <= self.allocated on entry, although * that partly relies on an assumption that the system realloc() never diff -r e34b09c69dd3 -r f1bd5468dae6 Objects/longobject.c --- a/Objects/longobject.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Objects/longobject.c Wed Mar 16 19:19:36 2011 -0400 @@ -709,7 +709,7 @@ is_signed = *pendbyte >= 0x80; /* Compute numsignificantbytes. This consists of finding the most - significant byte. Leading 0 bytes are insignficant if the number + significant byte. Leading 0 bytes are insignificant if the number is positive, and leading 0xff bytes if negative. */ { size_t i; @@ -3120,7 +3120,7 @@ * of slices, each with a->ob_size digits, and multiply the slices by a, * one at a time. This gives k_mul balanced inputs to work with, and is * also cache-friendly (we compute one double-width slice of the result - * at a time, then move on, never bactracking except for the helpful + * at a time, then move on, never backtracking except for the helpful * single-width slice overlap between successive partial sums). */ static PyLongObject * diff -r e34b09c69dd3 -r f1bd5468dae6 Objects/stringlib/string_format.h --- a/Objects/stringlib/string_format.h Sat Mar 12 22:31:06 2011 -0500 +++ b/Objects/stringlib/string_format.h Wed Mar 16 19:19:36 2011 -0400 @@ -6,7 +6,7 @@ */ -/* Defines for Python 2.6 compatability */ +/* Defines for Python 2.6 compatibility */ #if PY_VERSION_HEX < 0x03000000 #define PyLong_FromSsize_t _PyLong_FromSsize_t #endif diff -r e34b09c69dd3 -r f1bd5468dae6 Objects/typeobject.c --- a/Objects/typeobject.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Objects/typeobject.c Wed Mar 16 19:19:36 2011 -0400 @@ -1008,7 +1008,7 @@ self has a refcount of 0, and if gc ever gets its hands on it (which can happen if any weakref callback gets invoked), it looks like trash to gc too, and gc also tries to delete self - then. But we're already deleting self. Double dealloction is + then. But we're already deleting self. Double deallocation is a subtle disaster. Q. Why the bizarre (net-zero) manipulation of @@ -5955,7 +5955,7 @@ slots compete for the same descriptor (for example both sq_item and mp_subscript generate a __getitem__ descriptor). - In the latter case, the first slotdef entry encoutered wins. Since + In the latter case, the first slotdef entry encountered wins. Since slotdef entries are sorted by the offset of the slot in the PyHeapTypeObject, this gives us some control over disambiguating between competing slots: the members of PyHeapTypeObject are listed diff -r e34b09c69dd3 -r f1bd5468dae6 Objects/typeslots.inc --- a/Objects/typeslots.inc Sat Mar 12 22:31:06 2011 -0500 +++ b/Objects/typeslots.inc Wed Mar 16 19:19:36 2011 -0400 @@ -1,4 +1,4 @@ -/* Generated by typeslots.py $Revision: 87806 $ */ +/* Generated by typeslots.py $Revision$ */ 0, 0, offsetof(PyHeapTypeObject, as_mapping.mp_ass_subscript), diff -r e34b09c69dd3 -r f1bd5468dae6 PC/_subprocess.c --- a/PC/_subprocess.c Sat Mar 12 22:31:06 2011 -0500 +++ b/PC/_subprocess.c Wed Mar 16 19:19:36 2011 -0400 @@ -682,6 +682,7 @@ defint(d, "SW_HIDE", SW_HIDE); defint(d, "INFINITE", INFINITE); defint(d, "WAIT_OBJECT_0", WAIT_OBJECT_0); + defint(d, "WAIT_TIMEOUT", WAIT_TIMEOUT); defint(d, "CREATE_NEW_CONSOLE", CREATE_NEW_CONSOLE); defint(d, "CREATE_NEW_PROCESS_GROUP", CREATE_NEW_PROCESS_GROUP); diff -r e34b09c69dd3 -r f1bd5468dae6 PC/bdist_wininst/extract.c --- a/PC/bdist_wininst/extract.c Sat Mar 12 22:31:06 2011 -0500 +++ b/PC/bdist_wininst/extract.c Wed Mar 16 19:19:36 2011 -0400 @@ -54,7 +54,7 @@ return TRUE; } -/* XXX Should better explicitely specify +/* XXX Should better explicitly specify * uncomp_size and file_times instead of pfhdr! */ char *map_new_file(DWORD flags, char *filename, @@ -164,7 +164,7 @@ zstream.avail_out = uncomp_size; /* Apparently an undocumented feature of zlib: Set windowsize - to negative values to supress the gzip header and be compatible with + to negative values to suppress the gzip header and be compatible with zip! */ result = TRUE; if (Z_OK != (x = inflateInit2(&zstream, -15))) { diff -r e34b09c69dd3 -r f1bd5468dae6 PC/bdist_wininst/install.c --- a/PC/bdist_wininst/install.c Sat Mar 12 22:31:06 2011 -0500 +++ b/PC/bdist_wininst/install.c Wed Mar 16 19:19:36 2011 -0400 @@ -62,7 +62,7 @@ * instead showing the user an empty listbox to select something from. * * Finish the code so that we can use other python installations - * additionaly to those found in the registry, + * additionally to those found in the registry, * and then #define USE_OTHER_PYTHON_VERSIONS * * - install a help-button, which will display something meaningful @@ -148,7 +148,7 @@ the permissions of the current user. */ HKEY hkey_root = (HKEY)-1; -BOOL success; /* Installation successfull? */ +BOOL success; /* Installation successful? */ char *failure_reason = NULL; HANDLE hBitmap; @@ -797,7 +797,7 @@ tempname = tempnam(NULL, NULL); // We use a static CRT while the Python version we load uses - // the CRT from one of various possibile DLLs. As a result we + // the CRT from one of various possible DLLs. As a result we // need to redirect the standard handles using the API rather // than the CRT. redirected = CreateFile( diff -r e34b09c69dd3 -r f1bd5468dae6 PC/os2emx/dlfcn.c --- a/PC/os2emx/dlfcn.c Sat Mar 12 22:31:06 2011 -0500 +++ b/PC/os2emx/dlfcn.c Wed Mar 16 19:19:36 2011 -0400 @@ -188,7 +188,7 @@ return NULL; } -/* free dynamicaly-linked library */ +/* free dynamically-linked library */ int dlclose(void *handle) { int rc; diff -r e34b09c69dd3 -r f1bd5468dae6 PC/os2emx/dlfcn.h --- a/PC/os2emx/dlfcn.h Sat Mar 12 22:31:06 2011 -0500 +++ b/PC/os2emx/dlfcn.h Wed Mar 16 19:19:36 2011 -0400 @@ -42,7 +42,7 @@ /* return a pointer to the `symbol' in DLL */ void *dlsym(void *handle, char *symbol); -/* free dynamicaly-linked library */ +/* free dynamically-linked library */ int dlclose(void *handle); /* return a string describing last occurred dl error */ diff -r e34b09c69dd3 -r f1bd5468dae6 Parser/asdl_c.py --- a/Parser/asdl_c.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Parser/asdl_c.py Wed Mar 16 19:19:36 2011 -0400 @@ -1138,7 +1138,7 @@ def get_file_revision(f): """Fish out the last change to a file in hg.""" - args = ["hg", "log", "--template", "{rev}:{node|short}", "--limit", "1", f] + args = ["hg", "log", "--template", "{node|short}", "--limit", "1", f] p = subprocess.Popen(args, stdout=subprocess.PIPE) out = p.communicate()[0] if p.returncode: diff -r e34b09c69dd3 -r f1bd5468dae6 Parser/spark.py --- a/Parser/spark.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Parser/spark.py Wed Mar 16 19:19:36 2011 -0400 @@ -23,7 +23,7 @@ import re -# Compatability with older pythons. +# Compatibility with older pythons. def output(string='', end='\n'): sys.stdout.write(string + end) diff -r e34b09c69dd3 -r f1bd5468dae6 Python/Python-ast.c --- a/Python/Python-ast.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Python/Python-ast.c Wed Mar 16 19:19:36 2011 -0400 @@ -2,7 +2,7 @@ /* - __version__ 68410:0daa6ba25d9b. + __version__ 0daa6ba25d9b. This module must be committed separately after each AST grammar change; The __version__ number is set to the revision number of the commit @@ -6739,8 +6739,7 @@ NULL; if (PyModule_AddIntConstant(m, "PyCF_ONLY_AST", PyCF_ONLY_AST) < 0) return NULL; - if (PyModule_AddStringConstant(m, "__version__", "68410:0daa6ba25d9b") - < 0) + if (PyModule_AddStringConstant(m, "__version__", "0daa6ba25d9b") < 0) return NULL; if (PyDict_SetItemString(d, "mod", (PyObject*)mod_type) < 0) return NULL; diff -r e34b09c69dd3 -r f1bd5468dae6 Python/_warnings.c --- a/Python/_warnings.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Python/_warnings.c Wed Mar 16 19:19:36 2011 -0400 @@ -764,7 +764,7 @@ return ret; } -/* PyErr_Warn is only for backwards compatability and will be removed. +/* PyErr_Warn is only for backwards compatibility and will be removed. Use PyErr_WarnEx instead. */ #undef PyErr_Warn diff -r e34b09c69dd3 -r f1bd5468dae6 Python/ceval.c --- a/Python/ceval.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Python/ceval.c Wed Mar 16 19:19:36 2011 -0400 @@ -26,7 +26,7 @@ typedef unsigned long long uint64; -/* PowerPC suppport. +/* PowerPC support. "__ppc__" appears to be the preprocessor definition to detect on OS X, whereas "__powerpc__" appears to be the correct one for Linux with GCC */ @@ -1266,7 +1266,7 @@ if (_Py_atomic_load_relaxed(&eval_breaker)) { if (*next_instr == SETUP_FINALLY) { /* Make the last opcode before - a try: finally: block uninterruptable. */ + a try: finally: block uninterruptible. */ goto fast_next_opcode; } tstate->tick_counter++; diff -r e34b09c69dd3 -r f1bd5468dae6 Python/peephole.c --- a/Python/peephole.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Python/peephole.c Wed Mar 16 19:19:36 2011 -0400 @@ -535,7 +535,8 @@ } if (codestr[i+3] != UNPACK_SEQUENCE || !ISBASICBLOCK(blocks,i,6) || - j != GETARG(codestr, i+3)) + j != GETARG(codestr, i+3) || + opcode == BUILD_SET) continue; if (j == 1) { memset(codestr+i, NOP, 6); diff -r e34b09c69dd3 -r f1bd5468dae6 Python/pystate.c --- a/Python/pystate.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Python/pystate.c Wed Mar 16 19:19:36 2011 -0400 @@ -512,7 +512,7 @@ /* for i in all interpreters: * for t in all of i's thread states: * if t's frame isn't NULL, map t's id to its frame - * Because these lists can mutute even when the GIL is held, we + * Because these lists can mutate even when the GIL is held, we * need to grab head_mutex for the duration. */ HEAD_LOCK(); diff -r e34b09c69dd3 -r f1bd5468dae6 Python/sysmodule.c --- a/Python/sysmodule.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Python/sysmodule.c Wed Mar 16 19:19:36 2011 -0400 @@ -686,7 +686,7 @@ Return information about the running version of Windows as a named tuple.\n\ The members are named: major, minor, build, platform, service_pack,\n\ service_pack_major, service_pack_minor, suite_mask, and product_type. For\n\ -backward compatibiliy, only the first 5 items are available by indexing.\n\ +backward compatibility, only the first 5 items are available by indexing.\n\ All elements are numbers, except service_pack which is a string. Platform\n\ may be 0 for win32s, 1 for Windows 9x/ME, 2 for Windows NT/2000/XP/Vista/7,\n\ 3 for Windows CE. Product_type may be 1 for a workstation, 2 for a domain\n\ diff -r e34b09c69dd3 -r f1bd5468dae6 Python/thread.c --- a/Python/thread.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Python/thread.c Wed Mar 16 19:19:36 2011 -0400 @@ -40,7 +40,7 @@ #endif /* Check if we're running on HP-UX and _SC_THREADS is defined. If so, then - enough of the Posix threads package is implimented to support python + enough of the Posix threads package is implemented to support python threads. This is valid for HP-UX 11.23 running on an ia64 system. If needed, add diff -r e34b09c69dd3 -r f1bd5468dae6 Python/thread_pth.h --- a/Python/thread_pth.h Sat Mar 12 22:31:06 2011 -0500 +++ b/Python/thread_pth.h Wed Mar 16 19:19:36 2011 -0400 @@ -69,9 +69,8 @@ volatile pth_t threadid; if (!initialized) PyThread_init_thread(); - /* Jump through some hoops for Alpha OSF/1 */ threadid = pth_self(); - return (long) *(long *) &threadid; + return (long) threadid; } void PyThread_exit_thread(void) diff -r e34b09c69dd3 -r f1bd5468dae6 Python/thread_pthread.h --- a/Python/thread_pthread.h Sat Mar 12 22:31:06 2011 -0500 +++ b/Python/thread_pthread.h Wed Mar 16 19:19:36 2011 -0400 @@ -228,8 +228,7 @@ hosed" because: - It does not guarantee the promise that a non-zero integer is returned. - The cast to long is inherently unsafe. - - It is not clear that the 'volatile' (for AIX?) and ugly casting in the - latter return statement (for Alpha OSF/1) are any longer necessary. + - It is not clear that the 'volatile' (for AIX?) are any longer necessary. */ long PyThread_get_thread_ident(void) @@ -237,13 +236,8 @@ volatile pthread_t threadid; if (!initialized) PyThread_init_thread(); - /* Jump through some hoops for Alpha OSF/1 */ threadid = pthread_self(); -#if SIZEOF_PTHREAD_T <= SIZEOF_LONG return (long) threadid; -#else - return (long) *(long *) &threadid; -#endif } void diff -r e34b09c69dd3 -r f1bd5468dae6 Tools/demo/ss1.py --- a/Tools/demo/ss1.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Tools/demo/ss1.py Wed Mar 16 19:19:36 2011 -0400 @@ -586,7 +586,7 @@ cell = Tk.Label(self.cellgrid, relief='raised') cell.grid_configure(column=0, row=0, sticky='NSWE') cell.bind("", self.selectall) - # Create the top row of labels, and confiure the grid columns + # Create the top row of labels, and configure the grid columns for x in range(1, columns+1): self.cellgrid.grid_columnconfigure(x, minsize=64) cell = Tk.Label(self.cellgrid, text=colnum2name(x), relief='raised') diff -r e34b09c69dd3 -r f1bd5468dae6 Tools/freeze/checkextensions_win32.py --- a/Tools/freeze/checkextensions_win32.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Tools/freeze/checkextensions_win32.py Wed Mar 16 19:19:36 2011 -0400 @@ -7,7 +7,7 @@ we get it just right, a specific freeze application may have specific compiler options anyway (eg, to enable or disable specific functionality) -So my basic stragtegy is: +So my basic strategy is: * Have some Windows INI files which "describe" one or more extension modules. (Freeze comes with a default one for all known modules - but you can specify diff -r e34b09c69dd3 -r f1bd5468dae6 Tools/msi/msi.py --- a/Tools/msi/msi.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Tools/msi/msi.py Wed Mar 16 19:19:36 2011 -0400 @@ -178,7 +178,7 @@ have_mingw = build_mingw_lib(lib_file, def_file, dll_file, mingw_lib) -# Determine the target architechture +# Determine the target architecture dll_path = os.path.join(srcdir, PCBUILD, dll_file) msilib.set_arch_from_file(dll_path) if msilib.pe_type(dll_path) != msilib.pe_type("msisupport.dll"): diff -r e34b09c69dd3 -r f1bd5468dae6 Tools/pybench/pybench.py --- a/Tools/pybench/pybench.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Tools/pybench/pybench.py Wed Mar 16 19:19:36 2011 -0400 @@ -682,7 +682,7 @@ other_total_avg_time = other_total_avg_time + other_avg_time if (benchmarks_compatible and test.compatible(other)): - # Both benchmark and tests are comparible + # Both benchmark and tests are comparable min_diff = ((min_time * self.warp) / (other_min_time * other.warp) - 1.0) avg_diff = ((avg_time * self.warp) / @@ -696,7 +696,7 @@ else: avg_diff = '%+5.1f%%' % (avg_diff * PERCENT) else: - # Benchmark or tests are not comparible + # Benchmark or tests are not comparable min_diff, avg_diff = 'n/a', 'n/a' tests_compatible = 0 print('%30s: %5.0fms %5.0fms %7s %5.0fms %5.0fms %7s' % \ diff -r e34b09c69dd3 -r f1bd5468dae6 Tools/scripts/fixcid.py --- a/Tools/scripts/fixcid.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Tools/scripts/fixcid.py Wed Mar 16 19:19:36 2011 -0400 @@ -188,7 +188,7 @@ except os.error as msg: err(filename + ': rename failed (' + str(msg) + ')\n') return 1 - # Return succes + # Return success return 0 # Tokenizing ANSI C (partly) diff -r e34b09c69dd3 -r f1bd5468dae6 Tools/unicode/makeunicodedata.py --- a/Tools/unicode/makeunicodedata.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Tools/unicode/makeunicodedata.py Wed Mar 16 19:19:36 2011 -0400 @@ -1002,7 +1002,7 @@ poly = size + poly break else: - raise AssertionError("ran out of polynominals") + raise AssertionError("ran out of polynomials") print(size, "slots in hash table") diff -r e34b09c69dd3 -r f1bd5468dae6 configure --- a/configure Sat Mar 12 22:31:06 2011 -0500 +++ b/configure Wed Mar 16 19:19:36 2011 -0400 @@ -754,7 +754,6 @@ enable_loadable_sqlite_extensions with_dbmliborder with_signal_module -with_dec_threads with_threads with_thread enable_ipv6 @@ -777,7 +776,8 @@ LDFLAGS LIBS CPPFLAGS -CPP' +CPP +CPPFLAGS' # Initialize some variables set by options. @@ -1426,7 +1426,6 @@ colon separated string with the backend names `ndbm', `gdbm' and `bdb'. --with-signal-module disable/enable signal module - --with-dec-threads use DEC Alpha/OSF1 thread-safe libraries --with(out)-threads[=DIRECTORY] disable/enable thread support --with(out)-thread[=DIRECTORY] @@ -4951,11 +4950,6 @@ BLDLIBRARY='-Wl,+b,$(LIBDIR) -L. -lpython$(LDVERSION)' RUNSHARED=SHLIB_PATH=`pwd`:${SHLIB_PATH} ;; - OSF*) - LDLIBRARY='libpython$(LDVERSION).so' - BLDLIBRARY='-rpath $(LIBDIR) -L. -lpython$(LDVERSION)' - RUNSHARED=LD_LIBRARY_PATH=`pwd`:${LD_LIBRARY_PATH} - ;; Darwin*) LDLIBRARY='libpython$(LDVERSION).dylib' BLDLIBRARY='-L. -lpython$(LDVERSION)' @@ -5594,9 +5588,6 @@ EXPORT_MACOSX_DEPLOYMENT_TARGET='' ;; - OSF*) - BASECFLAGS="$BASECFLAGS -mieee" - ;; esac ;; @@ -5605,9 +5596,6 @@ OpenUNIX*|UnixWare*) BASECFLAGS="$BASECFLAGS -K pentium,host,inline,loop_unroll,alloca " ;; - OSF*) - BASECFLAGS="$BASECFLAGS -ieee -std" - ;; SCO_SV*) BASECFLAGS="$BASECFLAGS -belf -Ki486 -DSCO5" ;; @@ -6315,7 +6303,6 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $was_it_defined" >&5 $as_echo "$was_it_defined" >&6; } -# Check whether using makedev requires defining _OSF_SOURCE { $as_echo "$as_me:${as_lineno-$LINENO}: checking for makedev" >&5 $as_echo_n "checking for makedev... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -6346,35 +6333,6 @@ fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext -if test "$ac_cv_has_makedev" = "no"; then - # we didn't link, try if _OSF_SOURCE will allow us to link - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#define _OSF_SOURCE 1 -#include - -int -main () -{ - makedev(0, 0) - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_has_makedev=yes -else - ac_cv_has_makedev=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - if test "$ac_cv_has_makedev" = "yes"; then - -$as_echo "#define _OSF_SOURCE 1" >>confdefs.h - - fi -fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_has_makedev" >&5 $as_echo "$ac_cv_has_makedev" >&6; } if test "$ac_cv_has_makedev" = "yes"; then @@ -7462,7 +7420,6 @@ else LDSHARED='ld -b' fi ;; - OSF*) LDSHARED="ld -shared -expect_unresolved \"*\"";; Darwin/1.3*) LDSHARED='$(CC) -bundle' LDCXXSHARED='$(CXX) -bundle' @@ -8281,23 +8238,6 @@ USE_THREAD_MODULE="" -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-dec-threads" >&5 -$as_echo_n "checking for --with-dec-threads... " >&6; } - - -# Check whether --with-dec-threads was given. -if test "${with_dec_threads+set}" = set; then : - withval=$with_dec_threads; -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $withval" >&5 -$as_echo "$withval" >&6; } -LDLAST=-threads -if test "${with_thread+set}" != set; then - with_thread="$withval"; -fi -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi # Templates for things AC_DEFINEd more than once. @@ -8761,15 +8701,6 @@ fi fi - - if test "$USE_THREAD_MODULE" != "#" - then - # If the above checks didn't disable threads, (at least) OSF1 - # needs this '-threads' argument during linking. - case $ac_sys_system in - OSF1) LDLAST=-threads;; - esac - fi fi if test "$posix_threads" = "yes"; then @@ -13811,10 +13742,6 @@ esac -case $ac_sys_system in - OSF*) as_fn_error $? "OSF* systems are deprecated unless somebody volunteers. Check http://bugs.python.org/issue8606" "$LINENO" 5 ;; -esac - ac_fn_c_check_func "$LINENO" "pipe2" "ac_cv_func_pipe2" if test "x$ac_cv_func_pipe2" = xyes; then : diff -r e34b09c69dd3 -r f1bd5468dae6 configure.in --- a/configure.in Sat Mar 12 22:31:06 2011 -0500 +++ b/configure.in Wed Mar 16 19:19:36 2011 -0400 @@ -763,11 +763,6 @@ BLDLIBRARY='-Wl,+b,$(LIBDIR) -L. -lpython$(LDVERSION)' RUNSHARED=SHLIB_PATH=`pwd`:${SHLIB_PATH} ;; - OSF*) - LDLIBRARY='libpython$(LDVERSION).so' - BLDLIBRARY='-rpath $(LIBDIR) -L. -lpython$(LDVERSION)' - RUNSHARED=LD_LIBRARY_PATH=`pwd`:${LD_LIBRARY_PATH} - ;; Darwin*) LDLIBRARY='libpython$(LDVERSION).dylib' BLDLIBRARY='-L. -lpython$(LDVERSION)' @@ -1068,9 +1063,6 @@ EXPORT_MACOSX_DEPLOYMENT_TARGET='' ;; - OSF*) - BASECFLAGS="$BASECFLAGS -mieee" - ;; esac ;; @@ -1079,9 +1071,6 @@ OpenUNIX*|UnixWare*) BASECFLAGS="$BASECFLAGS -K pentium,host,inline,loop_unroll,alloca " ;; - OSF*) - BASECFLAGS="$BASECFLAGS -ieee -std" - ;; SCO_SV*) BASECFLAGS="$BASECFLAGS -belf -Ki486 -DSCO5" ;; @@ -1322,7 +1311,6 @@ ]) AC_MSG_RESULT($was_it_defined) -# Check whether using makedev requires defining _OSF_SOURCE AC_MSG_CHECKING(for makedev) AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #if defined(MAJOR_IN_MKDEV) @@ -1335,19 +1323,6 @@ ]], [[ makedev(0, 0) ]]) ],[ac_cv_has_makedev=yes],[ac_cv_has_makedev=no]) -if test "$ac_cv_has_makedev" = "no"; then - # we didn't link, try if _OSF_SOURCE will allow us to link - AC_LINK_IFELSE([AC_LANG_PROGRAM([[ -#define _OSF_SOURCE 1 -#include - ]], - [[ makedev(0, 0) ]])], - [ac_cv_has_makedev=yes], - [ac_cv_has_makedev=no]) - if test "$ac_cv_has_makedev" = "yes"; then - AC_DEFINE(_OSF_SOURCE, 1, [Define _OSF_SOURCE to get the makedev macro.]) - fi -fi AC_MSG_RESULT($ac_cv_has_makedev) if test "$ac_cv_has_makedev" = "yes"; then AC_DEFINE(HAVE_MAKEDEV, 1, [Define this if you have the makedev macro.]) @@ -1667,7 +1642,6 @@ else LDSHARED='ld -b' fi ;; - OSF*) LDSHARED="ld -shared -expect_unresolved \"*\"";; Darwin/1.3*) LDSHARED='$(CC) -bundle' LDCXXSHARED='$(CXX) -bundle' @@ -2022,17 +1996,7 @@ AC_SUBST(USE_THREAD_MODULE) USE_THREAD_MODULE="" -AC_MSG_CHECKING(for --with-dec-threads) AC_SUBST(LDLAST) -AC_ARG_WITH(dec-threads, - AS_HELP_STRING([--with-dec-threads], [use DEC Alpha/OSF1 thread-safe libraries]), -[ -AC_MSG_RESULT($withval) -LDLAST=-threads -if test "${with_thread+set}" != set; then - with_thread="$withval"; -fi], -[AC_MSG_RESULT(no)]) # Templates for things AC_DEFINEd more than once. # For a single AC_DEFINE, no template is needed. @@ -2177,15 +2141,6 @@ THREADOBJ="Python/thread.o" USE_THREAD_MODULE=""]) fi - - if test "$USE_THREAD_MODULE" != "#" - then - # If the above checks didn't disable threads, (at least) OSF1 - # needs this '-threads' argument during linking. - case $ac_sys_system in - OSF1) LDLAST=-threads;; - esac - fi fi if test "$posix_threads" = "yes"; then @@ -4247,10 +4202,6 @@ esac -case $ac_sys_system in - OSF*) AC_MSG_ERROR(OSF* systems are deprecated unless somebody volunteers. Check http://bugs.python.org/issue8606) ;; -esac - AC_CHECK_FUNC(pipe2, AC_DEFINE(HAVE_PIPE2, 1, [Define if the OS supports pipe2()]), ) AC_SUBST(THREADHEADERS) diff -r e34b09c69dd3 -r f1bd5468dae6 pyconfig.h.in --- a/pyconfig.h.in Sat Mar 12 22:31:06 2011 -0500 +++ b/pyconfig.h.in Wed Mar 16 19:19:36 2011 -0400 @@ -1227,9 +1227,6 @@ /* Define on NetBSD to activate all library features */ #undef _NETBSD_SOURCE -/* Define _OSF_SOURCE to get the makedev macro. */ -#undef _OSF_SOURCE - /* Define to 2 if the system does not provide POSIX.1 features except with this defined. */ #undef _POSIX_1_SOURCE diff -r e34b09c69dd3 -r f1bd5468dae6 setup.py --- a/setup.py Sat Mar 12 22:31:06 2011 -0500 +++ b/setup.py Wed Mar 16 19:19:36 2011 -0400 @@ -901,7 +901,7 @@ db_dirs_to_check = tmp - # Look for a version specific db-X.Y before an ambiguoius dbX + # Look for a version specific db-X.Y before an ambiguous dbX # XXX should we -ever- look for a dbX name? Do any # systems really not name their library by version and # symlink to more general names? @@ -1017,8 +1017,8 @@ if sys.platform == 'darwin': # In every directory on the search path search for a dynamic # library and then a static library, instead of first looking - # for dynamic libraries on the entiry path. - # This way a staticly linked custom sqlite gets picked up + # for dynamic libraries on the entire path. + # This way a statically linked custom sqlite gets picked up # before the dynamic library in /usr/lib. sqlite_extra_link_args = ('-Wl,-search_paths_first',) else: