diff -Nru bzr-2.6.0+bzr6591/bzrlib/email_message.py bzr-2.6.0+bzr6593/bzrlib/email_message.py --- bzr-2.6.0+bzr6591/bzrlib/email_message.py 2011-12-19 13:23:58.000000000 +0000 +++ bzr-2.6.0+bzr6593/bzrlib/email_message.py 2014-04-09 08:00:39.000000000 +0000 @@ -149,7 +149,7 @@ @staticmethod def send(config, from_address, to_address, subject, body, attachment=None, - attachment_filename=None, attachment_mime_subtype='plain'): + attachment_filename=None, attachment_mime_subtype='plain'): """Create an email message and send it with SMTPConnection. :param config: config object to pass to SMTPConnection constructor. diff -Nru bzr-2.6.0+bzr6591/bzrlib/tests/test_email_message.py bzr-2.6.0+bzr6593/bzrlib/tests/test_email_message.py --- bzr-2.6.0+bzr6591/bzrlib/tests/test_email_message.py 2011-12-16 19:18:39.000000000 +0000 +++ bzr-2.6.0+bzr6593/bzrlib/tests/test_email_message.py 2014-04-09 08:00:39.000000000 +0000 @@ -14,13 +14,14 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +import sys from email.Header import decode_header from bzrlib import __version__ as _bzrlib_version from bzrlib.email_message import EmailMessage from bzrlib.errors import BzrBadParameterNotUnicode from bzrlib.smtp_connection import SMTPConnection -from bzrlib.tests import TestCase +from bzrlib import tests EMPTY_MESSAGE = '''\ From: from@from.com @@ -65,9 +66,22 @@ body ''' % { 'version': _bzrlib_version, 'boundary': BOUNDARY } -SIMPLE_MULTIPART_MESSAGE = _MULTIPART_HEAD + '--%s--' % BOUNDARY -COMPLEX_MULTIPART_MESSAGE = _MULTIPART_HEAD + '''\ +def final_newline_or_not(msg): + if sys.version_info >= (2, 7, 6): + # Some internals of python's email module changed in an (minor) + # incompatible way: a final newline is appended in 2.7.6... + msg += '\n' + return msg + + +def simple_multipart_message(): + msg = _MULTIPART_HEAD + '--%s--' % BOUNDARY + return final_newline_or_not(msg) + + +def complex_multipart_message(typ): + msg = _MULTIPART_HEAD + '''\ --%(boundary)s MIME-Version: 1.0 Content-Type: text/%%s; charset="us-ascii"; name="lines.txt" @@ -81,9 +95,11 @@ e --%(boundary)s--''' % { 'boundary': BOUNDARY } + msg = final_newline_or_not(msg) + return msg % (typ,) -class TestEmailMessage(TestCase): +class TestEmailMessage(tests.TestCase): def test_empty_message(self): msg = EmailMessage('from@from.com', 'to@to.com', 'subject') @@ -100,15 +116,18 @@ msg = EmailMessage('from@from.com', 'to@to.com', 'subject', body) self.assertEqualDiff(expected, msg.as_string()) - def test_multipart_message(self): + def test_multipart_message_simple(self): msg = EmailMessage('from@from.com', 'to@to.com', 'subject') msg.add_inline_attachment('body') - self.assertEqualDiff(SIMPLE_MULTIPART_MESSAGE, msg.as_string(BOUNDARY)) + self.assertEqualDiff(simple_multipart_message(), + msg.as_string(BOUNDARY)) + + def test_multipart_message_complex(self): msg = EmailMessage('from@from.com', 'to@to.com', 'subject', 'body') msg.add_inline_attachment(u'a\nb\nc\nd\ne\n', 'lines.txt', 'x-subtype') - self.assertEqualDiff(COMPLEX_MULTIPART_MESSAGE % 'x-subtype', - msg.as_string(BOUNDARY)) + self.assertEqualDiff(complex_multipart_message('x-subtype'), + msg.as_string(BOUNDARY)) def test_headers_accept_unicode_and_utf8(self): for user in [ u'Pepe P\xe9rez ', @@ -148,40 +167,6 @@ self.assertEqual('to2@to.com', msg['To']) self.assertEqual('cc@cc.com', msg['Cc']) - def test_send(self): - class FakeConfig: - def get(self, option): - return None - - messages = [] - - def send_as_append(_self, msg): - messages.append(msg.as_string(BOUNDARY)) - - old_send_email = SMTPConnection.send_email - try: - SMTPConnection.send_email = send_as_append - - EmailMessage.send(FakeConfig(), 'from@from.com', 'to@to.com', - 'subject', 'body', u'a\nb\nc\nd\ne\n', 'lines.txt') - self.assertEqualDiff(COMPLEX_MULTIPART_MESSAGE % 'plain', - messages[0]) - messages[:] = [] - - EmailMessage.send(FakeConfig(), 'from@from.com', 'to@to.com', - 'subject', 'body', u'a\nb\nc\nd\ne\n', 'lines.txt', - 'x-patch') - self.assertEqualDiff(COMPLEX_MULTIPART_MESSAGE % 'x-patch', - messages[0]) - messages[:] = [] - - EmailMessage.send(FakeConfig(), 'from@from.com', 'to@to.com', - 'subject', 'body') - self.assertEqualDiff(SIMPLE_MESSAGE_ASCII , messages[0]) - messages[:] = [] - finally: - SMTPConnection.send_email = old_send_email - def test_address_to_encoded_header(self): def decode(s): """Convert a RFC2047-encoded string to a unicode string.""" @@ -224,3 +209,46 @@ } for string_, pair in pairs.items(): self.assertEqual(pair, EmailMessage.string_with_encoding(string_)) + + +class TestSend(tests.TestCase): + + def setUp(self): + super(TestSend, self).setUp() + self.messages = [] + + def send_as_append(_self, msg): + self.messages.append(msg.as_string(BOUNDARY)) + + self.overrideAttr(SMTPConnection, 'send_email', send_as_append) + + + + def send_email(self, attachment=None, attachment_filename=None, + attachment_mime_subtype='plain'): + class FakeConfig: + def get(self, option): + return None + + EmailMessage.send(FakeConfig(), 'from@from.com', 'to@to.com', + 'subject', 'body', + attachment=attachment, + attachment_filename=attachment_filename, + attachment_mime_subtype=attachment_mime_subtype) + + def assertMessage(self, expected): + self.assertLength(1, self.messages) + self.assertEqualDiff(expected, self.messages[0]) + + def test_send_plain(self): + self.send_email(u'a\nb\nc\nd\ne\n', 'lines.txt') + self.assertMessage(complex_multipart_message('plain')) + + def test_send_patch(self): + self.send_email(u'a\nb\nc\nd\ne\n', 'lines.txt', 'x-patch') + self.assertMessage(complex_multipart_message('x-patch')) + + def test_send_simple(self): + self.send_email() + self.assertMessage(SIMPLE_MESSAGE_ASCII) + diff -Nru bzr-2.6.0+bzr6591/bzrlib/tests/test_osutils.py bzr-2.6.0+bzr6593/bzrlib/tests/test_osutils.py --- bzr-2.6.0+bzr6591/bzrlib/tests/test_osutils.py 2013-06-24 12:03:12.000000000 +0000 +++ bzr-2.6.0+bzr6593/bzrlib/tests/test_osutils.py 2014-04-09 08:05:23.000000000 +0000 @@ -943,9 +943,15 @@ osutils._win32_pathjoin('path/to', 'C:/foo')) self.assertEqual('path/to/foo', osutils._win32_pathjoin('path/to/', 'foo')) - self.assertEqual('/foo', + + def test_pathjoin_late_bugfix(self): + if sys.version_info < (2, 7, 6): + expected = '/foo' + else: + expected = 'C:/foo' + self.assertEqual(expected, osutils._win32_pathjoin('C:/path/to/', '/foo')) - self.assertEqual('/foo', + self.assertEqual(expected, osutils._win32_pathjoin('C:\\path\\to\\', '\\foo')) def test_normpath(self): diff -Nru bzr-2.6.0+bzr6591/bzrlib/tests/test_setup.py bzr-2.6.0+bzr6593/bzrlib/tests/test_setup.py --- bzr-2.6.0+bzr6591/bzrlib/tests/test_setup.py 2012-03-29 11:24:16.000000000 +0000 +++ bzr-2.6.0+bzr6593/bzrlib/tests/test_setup.py 2014-04-02 16:12:44.000000000 +0000 @@ -16,6 +16,7 @@ """Test for setup.py build process""" +from distutils import version import os import sys import subprocess @@ -79,3 +80,13 @@ self.log('stderr: %r', stderr) self.assertEqual(0, p.returncode, 'invocation of %r failed' % args) + + +class TestDistutilsVersion(tests.TestCase): + + def test_version_with_string(self): + # We really care about two pyrex specific versions and our ability to + # detect them + lv = version.LooseVersion + self.assertTrue(lv("0.9.4.1") < lv('0.17.beta1')) + self.assertTrue(lv("0.9.6.3") < lv('0.10')) diff -Nru bzr-2.6.0+bzr6591/debian/changelog bzr-2.6.0+bzr6593/debian/changelog --- bzr-2.6.0+bzr6591/debian/changelog 2014-02-13 03:56:40.000000000 +0000 +++ bzr-2.6.0+bzr6593/debian/changelog 2014-04-10 01:37:29.000000000 +0000 @@ -1,3 +1,21 @@ +bzr (2.6.0+bzr6593-1ubuntu1) trusty; urgency=medium + + * Merge from Debian unstable. Remaining changes: + - Drop non-main build dependencies on python-{meliae,lzma,medusa} + + -- Andrew Starr-Bochicchio Wed, 09 Apr 2014 21:36:21 -0400 + +bzr (2.6.0+bzr6593-1) unstable; urgency=medium + + * New upstream snapshot: + - Use LooseVersion from distutils to check Pyrex/Cython version + in order to handle non-integers in the version string. + Closes: #743096, #683130, LP: #1030521 + - Fix test failures with python-2.7.6 (LP: #1303879). + * debian/control: No longer suggest bzr-svn (Closes: #709290). + + -- Andrew Starr-Bochicchio Wed, 09 Apr 2014 20:26:48 -0400 + bzr (2.6.0+bzr6591-1ubuntu1) trusty; urgency=medium * Merge from Debian unstable. Remaining changes: diff -Nru bzr-2.6.0+bzr6591/debian/control bzr-2.6.0+bzr6593/debian/control --- bzr-2.6.0+bzr6591/debian/control 2014-02-12 22:11:04.000000000 +0000 +++ bzr-2.6.0+bzr6593/debian/control 2014-04-10 01:38:25.000000000 +0000 @@ -37,7 +37,6 @@ bzr-xmloutput (<< 0.8.8+bzr160), python-bzrlib (<< 2.4.0~beta3~) Suggests: bzr-doc, - bzr-svn, bzrtools, python-bzrlib.tests Description: easy to use distributed version control system diff -Nru bzr-2.6.0+bzr6591/doc/en/release-notes/bzr-2.7.txt bzr-2.6.0+bzr6593/doc/en/release-notes/bzr-2.7.txt --- bzr-2.6.0+bzr6591/doc/en/release-notes/bzr-2.7.txt 2014-02-07 10:20:38.000000000 +0000 +++ bzr-2.6.0+bzr6593/doc/en/release-notes/bzr-2.7.txt 2014-04-09 08:05:23.000000000 +0000 @@ -36,6 +36,9 @@ ignore invalid references (i.e. using invalid option names) while expanding option values. (Vincent Ladeuil, #1235099) +* Fix pyrex version checking to be more robust. + (Andrew Starr-Bochicchio, #1030521 ) + Documentation ************* @@ -60,6 +63,12 @@ suite. This can include new facilities for writing tests, fixes to spurious test failures and changes to the way things should be tested. +* Handle (minor) incompatible change in python 2.7.6 leading to test + failures. Only tests are affected. (Vincent Ladeuil, #1303879) + +* Take python 2.7.6 late (better than never) bugfix in ntpath.py into + account. Only tests are affected (Vincent Ladeuil, #1303879). + * Remove wrong assumption about how TCP server and client interact when run inside the same process. (Vincent Ladeuil, #1269886). diff -Nru bzr-2.6.0+bzr6591/setup.py bzr-2.6.0+bzr6593/setup.py --- bzr-2.6.0+bzr6591/setup.py 2012-02-29 12:35:23.000000000 +0000 +++ bzr-2.6.0+bzr6593/setup.py 2014-03-30 17:59:29.000000000 +0000 @@ -105,6 +105,7 @@ from distutils import log from distutils.core import setup +from distutils.version import LooseVersion from distutils.command.install_scripts import install_scripts from distutils.command.install_data import install_data from distutils.command.build import build @@ -202,7 +203,7 @@ from distutils.command.build_ext import build_ext else: have_pyrex = True - pyrex_version_info = tuple(map(int, pyrex_version.rstrip("+").split('.'))) + pyrex_version_info = LooseVersion(pyrex_version) class build_ext_if_possible(build_ext): @@ -299,7 +300,7 @@ libraries=['Ws2_32']) add_pyrex_extension('bzrlib._walkdirs_win32') else: - if have_pyrex and pyrex_version_info[:3] == (0,9,4): + if have_pyrex and pyrex_version_info == LooseVersion("0.9.4.1"): # Pyrex 0.9.4.1 fails to compile this extension correctly # The code it generates re-uses a "local" pointer and # calls "PY_DECREF" after having set it to NULL. (It mixes PY_XDECREF @@ -317,7 +318,7 @@ add_pyrex_extension('bzrlib._chk_map_pyx') ext_modules.append(Extension('bzrlib._patiencediff_c', ['bzrlib/_patiencediff_c.c'])) -if have_pyrex and pyrex_version_info < (0, 9, 6, 3): +if have_pyrex and pyrex_version_info < LooseVersion("0.9.6.3"): print("") print('Your Pyrex/Cython version %s is too old to build the simple_set' % ( pyrex_version))