diff -r e34b09c69dd3 -r b9b7d4c10bc4 Doc/ACKS.txt --- a/Doc/ACKS.txt Sat Mar 12 22:31:06 2011 -0500 +++ b/Doc/ACKS.txt Tue Mar 15 12:42:39 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 b9b7d4c10bc4 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 Tue Mar 15 12:42:39 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 b9b7d4c10bc4 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 Tue Mar 15 12:42:39 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 @@ -540,8 +539,7 @@ .. index:: single: Py_Initialize() - This is a no-op when called for a second time. It is safe to call this function - before calling :c:func:`Py_Initialize`. + This is a no-op when called for a second time. .. index:: module: _thread diff -r e34b09c69dd3 -r b9b7d4c10bc4 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 Tue Mar 15 12:42:39 2011 -0400 @@ -222,12 +222,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 b9b7d4c10bc4 Doc/library/multiprocessing.rst --- a/Doc/library/multiprocessing.rst Sat Mar 12 22:31:06 2011 -0500 +++ b/Doc/library/multiprocessing.rst Tue Mar 15 12:42:39 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 b9b7d4c10bc4 Doc/library/subprocess.rst --- a/Doc/library/subprocess.rst Sat Mar 12 22:31:06 2011 -0500 +++ b/Doc/library/subprocess.rst Tue Mar 15 12:42:39 2011 -0400 @@ -249,15 +249,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 +271,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 +320,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 +383,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 :ext:`SubprocessError`. + + .. versionadded:: 3.3 + The :exc:`SubprocessError` base class was added. + Security ^^^^^^^^ @@ -380,11 +413,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 +429,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 +447,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 b9b7d4c10bc4 Doc/library/unittest.rst --- a/Doc/library/unittest.rst Sat Mar 12 22:31:06 2011 -0500 +++ b/Doc/library/unittest.rst Tue Mar 15 12:42:39 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 b9b7d4c10bc4 Include/pymath.h --- a/Include/pymath.h Sat Mar 12 22:31:06 2011 -0500 +++ b/Include/pymath.h Tue Mar 15 12:42:39 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 b9b7d4c10bc4 Lib/collections/__init__.py --- a/Lib/collections/__init__.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/collections/__init__.py Tue Mar 15 12:42:39 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 b9b7d4c10bc4 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 Tue Mar 15 12:42:39 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 b9b7d4c10bc4 Lib/dbm/__init__.py --- a/Lib/dbm/__init__.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/dbm/__init__.py Tue Mar 15 12:42:39 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 b9b7d4c10bc4 Lib/decimal.py --- a/Lib/decimal.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/decimal.py Tue Mar 15 12:42:39 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 b9b7d4c10bc4 Lib/email/_parseaddr.py --- a/Lib/email/_parseaddr.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/email/_parseaddr.py Tue Mar 15 12:42:39 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 b9b7d4c10bc4 Lib/email/charset.py --- a/Lib/email/charset.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/email/charset.py Tue Mar 15 12:42:39 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 b9b7d4c10bc4 Lib/email/encoders.py --- a/Lib/email/encoders.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/email/encoders.py Tue Mar 15 12:42:39 2011 -0400 @@ -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 b9b7d4c10bc4 Lib/email/generator.py --- a/Lib/email/generator.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/email/generator.py Tue Mar 15 12:42:39 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 b9b7d4c10bc4 Lib/email/header.py --- a/Lib/email/header.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/email/header.py Tue Mar 15 12:42:39 2011 -0400 @@ -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 diff -r e34b09c69dd3 -r b9b7d4c10bc4 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 Tue Mar 15 12:42:39 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 b9b7d4c10bc4 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 Tue Mar 15 12:42:39 2011 -0400 @@ -725,6 +725,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('') @@ -2328,6 +2342,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 +3372,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') diff -r e34b09c69dd3 -r b9b7d4c10bc4 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 Tue Mar 15 12:42:39 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 b9b7d4c10bc4 Lib/ftplib.py --- a/Lib/ftplib.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/ftplib.py Tue Mar 15 12:42:39 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 b9b7d4c10bc4 Lib/gettext.py --- a/Lib/gettext.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/gettext.py Tue Mar 15 12:42:39 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 b9b7d4c10bc4 Lib/http/client.py --- a/Lib/http/client.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/http/client.py Tue Mar 15 12:42:39 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 b9b7d4c10bc4 Lib/idlelib/EditorWindow.py --- a/Lib/idlelib/EditorWindow.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/idlelib/EditorWindow.py Tue Mar 15 12:42:39 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 b9b7d4c10bc4 Lib/idlelib/HISTORY.txt --- a/Lib/idlelib/HISTORY.txt Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/idlelib/HISTORY.txt Tue Mar 15 12:42:39 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 b9b7d4c10bc4 Lib/importlib/_bootstrap.py --- a/Lib/importlib/_bootstrap.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/importlib/_bootstrap.py Tue Mar 15 12:42:39 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 b9b7d4c10bc4 Lib/nntplib.py --- a/Lib/nntplib.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/nntplib.py Tue Mar 15 12:42:39 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 b9b7d4c10bc4 Lib/socketserver.py --- a/Lib/socketserver.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/socketserver.py Tue Mar 15 12:42:39 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 b9b7d4c10bc4 Lib/subprocess.py --- a/Lib/subprocess.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/subprocess.py Tue Mar 15 12:42:39 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,19 @@ 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, output=None): + self.cmd = cmd + self.output = output + + def __str__(self): + return ("Command '%s' timed out after %s seconds" % + (self.cmd, self.timeout)) + + if mswindows: import threading import msvcrt @@ -449,15 +468,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 +491,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 +504,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 +527,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, 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 +666,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 +702,7 @@ raise ValueError("creationflags is only supported on Windows " "platforms") + self.args = args self.stdin = None self.stdout = None self.stderr = None @@ -771,7 +801,7 @@ _active.append(self) - 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 +810,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 +838,36 @@ self.wait() return (stdout, stderr) - return self._communicate(input) + try: + stdout, stderr = self._communicate(input, endtime) + 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): + """Convenience for checking if a timeout has expired.""" + if endtime is None: + return + if time.time() > endtime: + raise TimeoutExpired(self.args) + + if mswindows: # # Windows methods @@ -987,12 +1050,17 @@ return self.returncode - def wait(self): + def wait(self, timeout=None): """Wait for child process to terminate. Returns returncode attribute.""" + 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) self.returncode = _subprocess.GetExitCodeProcess(self._handle) return self.returncode @@ -1002,32 +1070,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): + # 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 +1122,6 @@ if stderr is not None: stderr = stderr[0] - self.wait() return (stdout, stderr) def send_signal(self, sig): @@ -1365,25 +1451,52 @@ 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 timeout was passed but not endtime, compute endtime in terms of + # timeout. + if endtime is None and timeout is not None: + endtime = time.time() + timeout + if self.returncode is not None: + return self.returncode + elif 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) + 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): + 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 +1504,11 @@ self.stdin.close() if _has_poll: - stdout, stderr = self._communicate_with_poll(input) + stdout, stderr = self._communicate_with_poll(input, endtime) else: - stdout, stderr = self._communicate_with_select(input) + stdout, stderr = self._communicate_with_select(input, endtime) + + self.wait(timeout=self._remaining_time(endtime)) # All data exchanged. Translate lists into strings. if stdout is not None: @@ -1411,60 +1526,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): 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) # 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 +1604,76 @@ return (stdout, stderr) - def _communicate_with_select(self, input): - read_set = [] - write_set = [] + def _communicate_with_select(self, input, endtime): + 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) + # We also check what time it is ourselves for good measure. + self._check_timeout(endtime) + # 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 b9b7d4c10bc4 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 Tue Mar 15 12:42:39 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 b9b7d4c10bc4 Lib/test/test_binop.py --- a/Lib/test/test_binop.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/test/test_binop.py Tue Mar 15 12:42:39 2011 -0400 @@ -1,4 +1,6 @@ -"""Tests for binary operators on subtypes of built-in types.""" +"""Tests for binary operators on subtypes of built-in types and other + details of the binop implementation +""" import unittest from test import support @@ -373,6 +375,105 @@ self.assertEqual(op_sequence(le, B, C), ['C.__ge__', 'B.__le__']) self.assertEqual(op_sequence(le, C, B), ['C.__le__', 'B.__ge__']) + def test_issue11477_sequence_concatenation(self): + # Check overloading for A + B and A += B + # when A only implements sq_concat (but not nb_add) + testcase = self + class RHS: + def __init__(self): + self.allow_radd = True + def __iter__(self): + yield "Excellent!" + def __radd__(self, other): + if not self.allow_radd: + testcase.fail("RHS __radd__ called!") + return other + type(other)(self) + lhs = [] + rhs = RHS() + self.assertEqual(lhs.__add__(rhs), NotImplemented) + self.assertEqual(lhs + rhs, ["Excellent!"]) + with self.assertRaises(TypeError): + lhs + 1 + rhs.allow_radd = False + orig_lhs = lhs + lhs += rhs + self.assertIs(lhs, orig_lhs) + self.assertEqual(lhs, ["Excellent!"]) + with self.assertRaises(TypeError): + lhs += 1 + + def test_issue11477_sequence_concatenation_subclass(self): + # Check overloading for A + B and A += B + # when A only implements sq_concat (but not nb_add) + # and B is a subclass of A + testcase = self + # NOTE: We *cannot* create another subclass of list for the LHS + # here, since doing so moves the __add__ implementation from + # sq_concat to nb_add, bypassing the underlying behaviour + # we're trying to exercise. So we craft a test that can work + # with the standard behaviour of list.__add__ + class RHS(list): + def __init__(self): + list.__init__(self, ["Excellent!"]) + def __radd__(self, other): + return [] + lhs = [] + rhs = RHS() + self.assertEqual(lhs.__add__(rhs), ["Excellent!"]) + self.assertEqual(lhs + rhs, []) + orig_lhs = lhs + lhs += rhs + self.assertIs(lhs, orig_lhs) + self.assertEqual(lhs, ["Excellent!"]) + + def test_issue11477_sequence_repetition(self): + # Check overloading for A * B and A *= B + # when A only implements sq_repeat (but not nb_mul) + testcase = self + class Scalar: + def __index__(self): + return 2 + def __mul__(self, other): + return NotImplemented + def __rmul__(self, other): + testcase.fail("RHS __rmul__ called!") + seq = [None] + scalar = Scalar() + self.assertEqual(seq * scalar, [None, None]) + self.assertEqual(scalar * seq, [None, None]) + with self.assertRaises(TypeError): + seq * object() + orig_seq = seq + seq *= scalar + self.assertIs(seq, orig_seq) + self.assertEqual(seq, [None, None]) + with self.assertRaises(TypeError): + seq *= object() + + def test_issue11477_sequence_repetition_subclass(self): + # Check overloading for A * B and A *= B + # when A only implements sq_repeat (but not nb_mul) + # and B is a subclass of A + # This case may seem unlikely, but may arise for something + # like a 0-d matrix/scalar + testcase = self + class Scalar(list): + def __index__(self): + return 2 + def __mul__(self, other): + return NotImplemented + def __rmul__(self, other): + return 3 * other + seq = [None] + scalar = Scalar() + self.assertEqual(seq * scalar, [None, None, None]) + self.assertEqual(scalar * seq, [None, None]) + orig_seq = seq + seq *= scalar + self.assertIs(seq, orig_seq) + self.assertEqual(seq, [None, None]) + + def test_main(): support.run_unittest(RatTestCase, OperationOrderTests) diff -r e34b09c69dd3 -r b9b7d4c10bc4 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 Tue Mar 15 12:42:39 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 b9b7d4c10bc4 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 Tue Mar 15 12:42:39 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 b9b7d4c10bc4 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 Tue Mar 15 12:42:39 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 diff -r e34b09c69dd3 -r b9b7d4c10bc4 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 Tue Mar 15 12:42:39 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 b9b7d4c10bc4 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 Tue Mar 15 12:42:39 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.assertEquals(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.assertEquals(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.assertEquals(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 b9b7d4c10bc4 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 Tue Mar 15 12:42:39 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 b9b7d4c10bc4 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 Tue Mar 15 12:42:39 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 b9b7d4c10bc4 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 Tue Mar 15 12:42:39 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: diff -r e34b09c69dd3 -r b9b7d4c10bc4 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 Tue Mar 15 12:42:39 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 b9b7d4c10bc4 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 Tue Mar 15 12:42:39 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 b9b7d4c10bc4 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 Tue Mar 15 12:42:39 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 b9b7d4c10bc4 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 Tue Mar 15 12:42:39 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 b9b7d4c10bc4 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 Tue Mar 15 12:42:39 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 b9b7d4c10bc4 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 Tue Mar 15 12:42:39 2011 -0400 @@ -11,6 +11,7 @@ import sysconfig import warnings import select +import shutil try: import gc except ImportError: @@ -56,6 +57,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 +70,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 +121,18 @@ 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"], + timeout=1.5) + 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() @@ -366,6 +390,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 +547,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 +577,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']), @@ -561,6 +622,13 @@ self.assertEqual(p.wait(), 0) + def test_wait_timeout(self): + p = subprocess.Popen([sys.executable, + "-c", "import time; time.sleep(0.1)"]) + self.assertRaises(subprocess.TimeoutExpired, p.wait, timeout=0.01) + self.assertEqual(p.wait(timeout=2), 0) + + def test_invalid_bufsize(self): # an invalid type of the bufsize argument should raise # TypeError. @@ -587,7 +655,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): diff -r e34b09c69dd3 -r b9b7d4c10bc4 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 Tue Mar 15 12:42:39 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 b9b7d4c10bc4 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 Tue Mar 15 12:42:39 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 b9b7d4c10bc4 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 Tue Mar 15 12:42:39 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 b9b7d4c10bc4 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 Tue Mar 15 12:42:39 2011 -0400 @@ -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 b9b7d4c10bc4 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 Tue Mar 15 12:42:39 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 b9b7d4c10bc4 Lib/tkinter/__init__.py --- a/Lib/tkinter/__init__.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/tkinter/__init__.py Tue Mar 15 12:42:39 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 b9b7d4c10bc4 Lib/tkinter/tix.py --- a/Lib/tkinter/tix.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/tkinter/tix.py Tue Mar 15 12:42:39 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. diff -r e34b09c69dd3 -r b9b7d4c10bc4 Lib/tkinter/ttk.py --- a/Lib/tkinter/ttk.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/tkinter/ttk.py Tue Mar 15 12:42:39 2011 -0400 @@ -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 b9b7d4c10bc4 Lib/turtle.py --- a/Lib/turtle.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/turtle.py Tue Mar 15 12:42:39 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. @@ -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 diff -r e34b09c69dd3 -r b9b7d4c10bc4 Lib/unittest/case.py --- a/Lib/unittest/case.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/unittest/case.py Tue Mar 15 12:42:39 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 b9b7d4c10bc4 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 Tue Mar 15 12:42:39 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 b9b7d4c10bc4 Lib/urllib/request.py --- a/Lib/urllib/request.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Lib/urllib/request.py Tue Mar 15 12:42:39 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 b9b7d4c10bc4 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 Tue Mar 15 12:42:39 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): diff -r e34b09c69dd3 -r b9b7d4c10bc4 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 Tue Mar 15 12:42:39 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( diff -r e34b09c69dd3 -r b9b7d4c10bc4 Mac/Tools/pythonw.c --- a/Mac/Tools/pythonw.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Mac/Tools/pythonw.c Tue Mar 15 12:42:39 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 b9b7d4c10bc4 Makefile.pre.in --- a/Makefile.pre.in Sat Mar 12 22:31:06 2011 -0500 +++ b/Makefile.pre.in Tue Mar 15 12:42:39 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 b9b7d4c10bc4 Misc/ACKS --- a/Misc/ACKS Sat Mar 12 22:31:06 2011 -0500 +++ b/Misc/ACKS Tue Mar 15 12:42:39 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 @@ -170,6 +172,7 @@ Jeffery Collins Robert Collins Paul Colomiets +Denver Coneybeare Geremy Condra Juan José Conti Matt Conway @@ -197,6 +200,7 @@ Lisandro Dalcin Andrew Dalke Lars Damerow +Evan Dandrea Eric Daniel Scott David Daniels Ben Darnell @@ -348,6 +352,7 @@ Derek Harland Jason Harper Brian Harring +Jonathan Hartley Larry Hastings Shane Hathaway Rycharde Hawkes @@ -370,6 +375,7 @@ Jason Hildebrand Richie Hindle Konrad Hinsen +Michael Henry David Hobley Tim Hochberg Joerg-Cyril Hoehle diff -r e34b09c69dd3 -r b9b7d4c10bc4 Misc/NEWS --- a/Misc/NEWS Sat Mar 12 22:31:06 2011 -0500 +++ b/Misc/NEWS Tue Mar 15 12:42:39 2011 -0400 @@ -68,6 +68,25 @@ Library ------- +- 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 +199,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 +209,16 @@ Tests ----- +- Issue #11554: Reactivated test_email_codecs. + +- Issue #11505: improves test coverage of string.py + +- 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. @@ -612,6 +643,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 b9b7d4c10bc4 Modules/_ctypes/callproc.c --- a/Modules/_ctypes/callproc.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Modules/_ctypes/callproc.c Tue Mar 15 12:42:39 2011 -0400 @@ -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 b9b7d4c10bc4 Modules/_ctypes/libffi/ChangeLog --- a/Modules/_ctypes/libffi/ChangeLog Sat Mar 12 22:31:06 2011 -0500 +++ b/Modules/_ctypes/libffi/ChangeLog Tue Mar 15 12:42:39 2011 -0400 @@ -3084,7 +3084,7 @@ 2003-09-18 Kaz Kojima - * src/sh/ffi.c (ffi_prep_args): Take account into the alignement + * src/sh/ffi.c (ffi_prep_args): Take account into the alignment for the register size. (ffi_closure_helper_SYSV): Handle the structure return value address correctly. @@ -3344,7 +3344,7 @@ 2003-02-06 Andreas Tobler * libffi/src/powerpc/darwin_closure.S: - Fix alignement bug, allocate 8 bytes for the result. + Fix alignment bug, allocate 8 bytes for the result. * libffi/src/powerpc/aix_closure.S: Likewise. * libffi/src/powerpc/ffi_darwin.c: diff -r e34b09c69dd3 -r b9b7d4c10bc4 Modules/_ctypes/libffi/src/dlmalloc.c --- a/Modules/_ctypes/libffi/src/dlmalloc.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Modules/_ctypes/libffi/src/dlmalloc.c Tue Mar 15 12:42:39 2011 -0400 @@ -1326,7 +1326,7 @@ return (ptr != 0)? ptr: MFAIL; } -/* This function supports releasing coalesed segments */ +/* This function supports releasing coalesced segments */ static int win32munmap(void* ptr, size_t size) { MEMORY_BASIC_INFORMATION minfo; char* cptr = ptr; @@ -1362,7 +1362,7 @@ #define CALL_MORECORE(S) MFAIL #endif /* HAVE_MORECORE */ -/* mstate bit set if continguous morecore disabled or failed */ +/* mstate bit set if contiguous morecore disabled or failed */ #define USE_NONCONTIGUOUS_BIT (4U) /* segment bit set in create_mspace_with_base */ diff -r e34b09c69dd3 -r b9b7d4c10bc4 Modules/_ctypes/libffi/src/powerpc/ffi_darwin.c --- a/Modules/_ctypes/libffi/src/powerpc/ffi_darwin.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Modules/_ctypes/libffi/src/powerpc/ffi_darwin.c Tue Mar 15 12:42:39 2011 -0400 @@ -592,7 +592,7 @@ +---------------------------------------+ 160 | result area 8 | +---------------------------------------+ 168 - | alignement to the next multiple of 16 | + | alignment to the next multiple of 16 | SP current --> +---------------------------------------+ 176 <- parent frame | back chain to caller 4 | +---------------------------------------+ 180 diff -r e34b09c69dd3 -r b9b7d4c10bc4 Modules/_ctypes/libffi_osx/powerpc/ppc-ffi_darwin.c --- a/Modules/_ctypes/libffi_osx/powerpc/ppc-ffi_darwin.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Modules/_ctypes/libffi_osx/powerpc/ppc-ffi_darwin.c Tue Mar 15 12:42:39 2011 -0400 @@ -650,7 +650,7 @@ +---------------------------------------+ 160 | result area 8 | +---------------------------------------+ 168 - | alignement to the next multiple of 16 | + | alignment to the next multiple of 16 | SP current --> +---------------------------------------+ 176 <- parent frame | back chain to caller 4 | +---------------------------------------+ 180 diff -r e34b09c69dd3 -r b9b7d4c10bc4 Modules/_cursesmodule.c --- a/Modules/_cursesmodule.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Modules/_cursesmodule.c Tue Mar 15 12:42:39 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 b9b7d4c10bc4 Modules/_struct.c --- a/Modules/_struct.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Modules/_struct.c Tue Mar 15 12:42:39 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 b9b7d4c10bc4 Modules/_threadmodule.c --- a/Modules/_threadmodule.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Modules/_threadmodule.c Tue Mar 15 12:42:39 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 b9b7d4c10bc4 Modules/fpectlmodule.c --- a/Modules/fpectlmodule.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Modules/fpectlmodule.c Tue Mar 15 12:42:39 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 b9b7d4c10bc4 Modules/mathmodule.c --- a/Modules/mathmodule.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Modules/mathmodule.c Tue Mar 15 12:42:39 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 b9b7d4c10bc4 Modules/parsermodule.c --- a/Modules/parsermodule.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Modules/parsermodule.c Tue Mar 15 12:42:39 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 b9b7d4c10bc4 Modules/posixmodule.c --- a/Modules/posixmodule.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Modules/posixmodule.c Tue Mar 15 12:42:39 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 b9b7d4c10bc4 Modules/socketmodule.c --- a/Modules/socketmodule.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Modules/socketmodule.c Tue Mar 15 12:42:39 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 diff -r e34b09c69dd3 -r b9b7d4c10bc4 Modules/termios.c --- a/Modules/termios.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Modules/termios.c Tue Mar 15 12:42:39 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 b9b7d4c10bc4 Modules/zipimport.c --- a/Modules/zipimport.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Modules/zipimport.c Tue Mar 15 12:42:39 2011 -0400 @@ -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 b9b7d4c10bc4 Objects/abstract.c --- a/Objects/abstract.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Objects/abstract.c Tue Mar 15 12:42:39 2011 -0400 @@ -917,14 +917,36 @@ PyObject * PyNumber_Add(PyObject *v, PyObject *w) { - PyObject *result = binary_op1(v, w, NB_SLOT(nb_add)); - if (result == Py_NotImplemented) { - PySequenceMethods *m = v->ob_type->tp_as_sequence; - Py_DECREF(result); - if (m && m->sq_concat) { - return (*m->sq_concat)(v, w); + PyNumberMethods *m_num = v->ob_type->tp_as_number; + PySequenceMethods *m_seq = v->ob_type->tp_as_sequence; + PyObject *result = NULL; + /* We do a tapdance here so sq_concat is tried on the LH + * operand before __radd__ is tried on the RH operand. + * If the LH implements both nb_add and sq_concat,only nb_add + * is tried. + */ + int try_binop = 1; + int have_add = m_num && m_num->nb_add; + int have_concat = m_seq && m_seq->sq_concat; + if (have_add || !have_concat || + PyType_IsSubtype(w->ob_type, v->ob_type)) { + try_binop = 0; + result = binary_op1(v, w, NB_SLOT(nb_add)); + } + if (try_binop || result == Py_NotImplemented) { + if (!have_add && have_concat) { + Py_XDECREF(result); + result = (*m_seq->sq_concat)(v, w); + try_binop = result == Py_NotImplemented; } - result = binop_type_error(v, w, "+"); + if (try_binop) { + Py_XDECREF(result); + result = binary_op1(v, w, NB_SLOT(nb_add)); + } + if (result == Py_NotImplemented) { + Py_DECREF(result); + result = binop_type_error(v, w, "+"); + } } return result; } @@ -948,20 +970,46 @@ PyObject * PyNumber_Multiply(PyObject *v, PyObject *w) { - PyObject *result = binary_op1(v, w, NB_SLOT(nb_multiply)); - if (result == Py_NotImplemented) { - PySequenceMethods *mv = v->ob_type->tp_as_sequence; - PySequenceMethods *mw = w->ob_type->tp_as_sequence; - Py_DECREF(result); - if (mv && mv->sq_repeat) { - return sequence_repeat(mv->sq_repeat, v, w); + PyNumberMethods *m_num = v->ob_type->tp_as_number; + PySequenceMethods *m_seq = v->ob_type->tp_as_sequence; + PyObject *result = NULL; + /* We do a tapdance here so sq_repeat is tried on the LH + * operand before __rmul__ is tried on the RH operand. + * If the LH implements both nb_multiply and sq_repeat,only + * nb_multiply is tried. + */ + int try_binop = 1; + int have_mul = m_num && m_num->nb_multiply; + int have_repeat = m_seq && m_seq->sq_repeat; + if (have_mul || !have_repeat || + PyType_IsSubtype(w->ob_type, v->ob_type)) { + try_binop = 0; + result = binary_op1(v, w, NB_SLOT(nb_multiply)); + } + if (try_binop || result == Py_NotImplemented) { + if (!have_mul && have_repeat) { + Py_XDECREF(result); + result = sequence_repeat(m_seq->sq_repeat, v, w); + try_binop = result == Py_NotImplemented; } - else if (mw && mw->sq_repeat) { - return sequence_repeat(mw->sq_repeat, w, v); + if (try_binop) { + Py_XDECREF(result); + result = binary_op1(v, w, NB_SLOT(nb_multiply)); } - result = binop_type_error(v, w, "*"); + if (result == Py_NotImplemented) { + PySequenceMethods *m_seq_rhs = w->ob_type->tp_as_sequence; + if (m_seq_rhs && m_seq_rhs->sq_repeat) { + Py_DECREF(result); + result = sequence_repeat(m_seq_rhs->sq_repeat, w, v); + } + } + if (result == Py_NotImplemented) { + Py_DECREF(result); + result = binop_type_error(v, w, "*"); + } } return result; + } PyObject * @@ -1063,20 +1111,41 @@ PyObject * PyNumber_InPlaceAdd(PyObject *v, PyObject *w) { - PyObject *result = binary_iop1(v, w, NB_SLOT(nb_inplace_add), - NB_SLOT(nb_add)); - if (result == Py_NotImplemented) { - PySequenceMethods *m = v->ob_type->tp_as_sequence; - Py_DECREF(result); - if (m != NULL) { - binaryfunc f = NULL; - f = m->sq_inplace_concat; - if (f == NULL) - f = m->sq_concat; - if (f != NULL) - return (*f)(v, w); + PyNumberMethods *m_num = v->ob_type->tp_as_number; + PySequenceMethods *m_seq = v->ob_type->tp_as_sequence; + PyObject *result = NULL; + /* Similar tapdance to PyNumber_Add, but with extra checks to + * handle the in-place versions of the nb_* and sq_* methods + */ + int try_binop = 1; + int have_add = m_num && m_num->nb_add; + int have_inplace_add = m_num && m_num->nb_inplace_add; + int have_concat = m_seq && m_seq->sq_concat; + int have_inplace_concat = m_seq && m_seq->sq_inplace_concat; + if (have_inplace_add || (!have_inplace_concat && !have_concat)) { + try_binop = 0; + result = binary_iop1(v, w, NB_SLOT(nb_inplace_add), + NB_SLOT(nb_add)); + } + if (try_binop || result == Py_NotImplemented) { + if (!have_inplace_add && have_inplace_concat) { + Py_XDECREF(result); + result = (*m_seq->sq_inplace_concat)(v, w); + try_binop = result == Py_NotImplemented; } - result = binop_type_error(v, w, "+="); + if (try_binop) { + Py_XDECREF(result); + result = binary_iop1(v, w, NB_SLOT(nb_inplace_add), + NB_SLOT(nb_add)); + } + if (!have_add && have_concat && result == Py_NotImplemented) { + Py_DECREF(result); + result = (*m_seq->sq_concat)(v, w); + } + if (result == Py_NotImplemented) { + Py_DECREF(result); + result = binop_type_error(v, w, "+="); + } } return result; } @@ -1084,28 +1153,51 @@ PyObject * PyNumber_InPlaceMultiply(PyObject *v, PyObject *w) { - PyObject *result = binary_iop1(v, w, NB_SLOT(nb_inplace_multiply), - NB_SLOT(nb_multiply)); - if (result == Py_NotImplemented) { - ssizeargfunc f = NULL; - PySequenceMethods *mv = v->ob_type->tp_as_sequence; - PySequenceMethods *mw = w->ob_type->tp_as_sequence; - Py_DECREF(result); - if (mv != NULL) { - f = mv->sq_inplace_repeat; - if (f == NULL) - f = mv->sq_repeat; - if (f != NULL) - return sequence_repeat(f, v, w); + PyNumberMethods *m_num = v->ob_type->tp_as_number; + PySequenceMethods *m_seq = v->ob_type->tp_as_sequence; + PyObject *result = NULL; + /* Similar tapdance to PyNumber_Multiply, but with extra checks to + * handle the in-place versions of the nb_* and sq_* methods + */ + int try_binop = 1; + int have_mul = m_num && m_num->nb_multiply; + int have_inplace_mul = m_num && m_num->nb_inplace_multiply; + int have_repeat = m_seq && m_seq->sq_repeat; + int have_inplace_repeat = m_seq && m_seq->sq_inplace_repeat; + if (have_inplace_mul || (!have_inplace_repeat && !have_repeat)) { + try_binop = 0; + result = binary_iop1(v, w, NB_SLOT(nb_inplace_multiply), + NB_SLOT(nb_multiply)); + } + if (try_binop || result == Py_NotImplemented) { + if (!have_inplace_mul && have_inplace_repeat) { + Py_XDECREF(result); + result = sequence_repeat(m_seq->sq_inplace_repeat, v, w); + try_binop = result == Py_NotImplemented; } - else if (mw != NULL) { + if (try_binop) { + Py_XDECREF(result); + result = binary_iop1(v, w, NB_SLOT(nb_inplace_multiply), + NB_SLOT(nb_multiply)); + } + if (!have_mul && have_repeat && result == Py_NotImplemented) { + Py_DECREF(result); + result = sequence_repeat(m_seq->sq_repeat, v, w); + } + if (result == Py_NotImplemented) { /* Note that the right hand operand should not be * mutated in this case so sq_inplace_repeat is not - * used. */ - if (mw->sq_repeat) - return sequence_repeat(mw->sq_repeat, w, v); + * tried. */ + PySequenceMethods *m_seq_rhs = w->ob_type->tp_as_sequence; + if (m_seq_rhs && m_seq_rhs->sq_repeat) { + Py_DECREF(result); + result = sequence_repeat(m_seq_rhs->sq_repeat, w, v); + } } - result = binop_type_error(v, w, "*="); + if (result == Py_NotImplemented) { + Py_DECREF(result); + result = binop_type_error(v, w, "*="); + } } return result; } diff -r e34b09c69dd3 -r b9b7d4c10bc4 Objects/bytearrayobject.c --- a/Objects/bytearrayobject.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Objects/bytearrayobject.c Tue Mar 15 12:42:39 2011 -0400 @@ -228,14 +228,14 @@ { Py_ssize_t size; Py_buffer va, vb; - PyByteArrayObject *result = NULL; + PyObject *result = NULL; va.len = -1; vb.len = -1; if (_getbuffer(a, &va) < 0 || _getbuffer(b, &vb) < 0) { - PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s", - Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name); + result = Py_NotImplemented; + Py_INCREF(result); goto done; } @@ -245,10 +245,11 @@ goto done; } - result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, size); + result = PyByteArray_FromStringAndSize(NULL, size); if (result != NULL) { - memcpy(result->ob_bytes, va.buf, va.len); - memcpy(result->ob_bytes + va.len, vb.buf, vb.len); + void * data = ((PyByteArrayObject *) result)->ob_bytes; + memcpy(data, va.buf, va.len); + memcpy(data + va.len, vb.buf, vb.len); } done: @@ -2245,7 +2246,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 b9b7d4c10bc4 Objects/bytesobject.c --- a/Objects/bytesobject.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Objects/bytesobject.c Tue Mar 15 12:42:39 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. */ } } @@ -675,8 +675,8 @@ vb.len = -1; if (_getbuffer(a, &va) < 0 || _getbuffer(b, &vb) < 0) { - PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s", - Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name); + result = Py_NotImplemented; + Py_INCREF(result); goto done; } diff -r e34b09c69dd3 -r b9b7d4c10bc4 Objects/floatobject.c --- a/Objects/floatobject.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Objects/floatobject.c Tue Mar 15 12:42:39 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 b9b7d4c10bc4 Objects/listobject.c --- a/Objects/listobject.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Objects/listobject.c Tue Mar 15 12:42:39 2011 -0400 @@ -469,10 +469,8 @@ PyObject **src, **dest; PyListObject *np; if (!PyList_Check(bb)) { - PyErr_Format(PyExc_TypeError, - "can only concatenate list (not \"%.200s\") to list", - bb->ob_type->tp_name); - return NULL; + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; } #define b ((PyListObject *)bb) size = Py_SIZE(a) + Py_SIZE(b); diff -r e34b09c69dd3 -r b9b7d4c10bc4 Objects/longobject.c --- a/Objects/longobject.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Objects/longobject.c Tue Mar 15 12:42:39 2011 -0400 @@ -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 b9b7d4c10bc4 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 Tue Mar 15 12:42:39 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 b9b7d4c10bc4 Objects/typeobject.c --- a/Objects/typeobject.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Objects/typeobject.c Tue Mar 15 12:42:39 2011 -0400 @@ -5466,10 +5466,8 @@ SQSLOT("__len__", sq_length, slot_sq_length, wrap_lenfunc, "x.__len__() <==> len(x)"), /* Heap types defining __add__/__mul__ have sq_concat/sq_repeat == NULL. - The logic in abstract.c always falls back to nb_add/nb_multiply in - this case. Defining both the nb_* and the sq_* slots to call the - user-defined methods has unexpected side-effects, as shown by - test_descr.notimplemented() */ + The logic in abstract.c ignores them if nb_add/nb_multiply are + defined anyway. */ SQSLOT("__add__", sq_concat, NULL, wrap_binaryfunc, "x.__add__(y) <==> x+y"), SQSLOT("__mul__", sq_repeat, NULL, wrap_indexargfunc, diff -r e34b09c69dd3 -r b9b7d4c10bc4 Objects/typeslots.inc --- a/Objects/typeslots.inc Sat Mar 12 22:31:06 2011 -0500 +++ b/Objects/typeslots.inc Tue Mar 15 12:42:39 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 b9b7d4c10bc4 Objects/unicodeobject.c --- a/Objects/unicodeobject.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Objects/unicodeobject.c Tue Mar 15 12:42:39 2011 -0400 @@ -7444,11 +7444,22 @@ /* Coerce the two arguments */ u = (PyUnicodeObject *)PyUnicode_FromObject(left); - if (u == NULL) - goto onError; + if (u == NULL) { + PyObject *ni = Py_NotImplemented; + /* XXX: PyErr_Matches check??? */ + PyErr_Clear(); + Py_INCREF(ni); + return ni; + } v = (PyUnicodeObject *)PyUnicode_FromObject(right); - if (v == NULL) - goto onError; + if (v == NULL) { + PyObject *ni = Py_NotImplemented; + /* XXX: PyErr_Matches check??? */ + PyErr_Clear(); + Py_DECREF(u); + Py_INCREF(ni); + return ni; + } /* Shortcuts */ if (v == unicode_empty) { diff -r e34b09c69dd3 -r b9b7d4c10bc4 PC/_subprocess.c --- a/PC/_subprocess.c Sat Mar 12 22:31:06 2011 -0500 +++ b/PC/_subprocess.c Tue Mar 15 12:42:39 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 b9b7d4c10bc4 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 Tue Mar 15 12:42:39 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 diff -r e34b09c69dd3 -r b9b7d4c10bc4 Parser/asdl_c.py --- a/Parser/asdl_c.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Parser/asdl_c.py Tue Mar 15 12:42:39 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 b9b7d4c10bc4 Parser/spark.py --- a/Parser/spark.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Parser/spark.py Tue Mar 15 12:42:39 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 b9b7d4c10bc4 Python/Python-ast.c --- a/Python/Python-ast.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Python/Python-ast.c Tue Mar 15 12:42:39 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 b9b7d4c10bc4 Python/_warnings.c --- a/Python/_warnings.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Python/_warnings.c Tue Mar 15 12:42:39 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 b9b7d4c10bc4 Python/sysmodule.c --- a/Python/sysmodule.c Sat Mar 12 22:31:06 2011 -0500 +++ b/Python/sysmodule.c Tue Mar 15 12:42:39 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 b9b7d4c10bc4 Python/thread_pth.h --- a/Python/thread_pth.h Sat Mar 12 22:31:06 2011 -0500 +++ b/Python/thread_pth.h Tue Mar 15 12:42:39 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 b9b7d4c10bc4 Python/thread_pthread.h --- a/Python/thread_pthread.h Sat Mar 12 22:31:06 2011 -0500 +++ b/Python/thread_pthread.h Tue Mar 15 12:42:39 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 b9b7d4c10bc4 Tools/demo/ss1.py --- a/Tools/demo/ss1.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Tools/demo/ss1.py Tue Mar 15 12:42:39 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 b9b7d4c10bc4 Tools/msi/msi.py --- a/Tools/msi/msi.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Tools/msi/msi.py Tue Mar 15 12:42:39 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 b9b7d4c10bc4 Tools/pybench/pybench.py --- a/Tools/pybench/pybench.py Sat Mar 12 22:31:06 2011 -0500 +++ b/Tools/pybench/pybench.py Tue Mar 15 12:42:39 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 b9b7d4c10bc4 configure --- a/configure Sat Mar 12 22:31:06 2011 -0500 +++ b/configure Tue Mar 15 12:42:39 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 b9b7d4c10bc4 configure.in --- a/configure.in Sat Mar 12 22:31:06 2011 -0500 +++ b/configure.in Tue Mar 15 12:42:39 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 b9b7d4c10bc4 pyconfig.h.in --- a/pyconfig.h.in Sat Mar 12 22:31:06 2011 -0500 +++ b/pyconfig.h.in Tue Mar 15 12:42:39 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 b9b7d4c10bc4 setup.py --- a/setup.py Sat Mar 12 22:31:06 2011 -0500 +++ b/setup.py Tue Mar 15 12:42:39 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?