← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~cjwatson/launchpad/archiveuploader-tests-future-imports into lp:launchpad

 

Colin Watson has proposed merging lp:~cjwatson/launchpad/archiveuploader-tests-future-imports into lp:launchpad.

Commit message:
Convert lp.archiveuploader.tests to Launchpad's preferred __future__ imports.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/archiveuploader-tests-future-imports/+merge/345044

This requires a little more care with encodings in a few places, especially when reading control data from .debs.  python-apt >= 0.8.5 (which we're already using) provides the extra control we need here.

I stopped bothering to remove "u" prefixes from strings, as it was far too noisy for little benefit.
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~cjwatson/launchpad/archiveuploader-tests-future-imports into lp:launchpad.
=== modified file 'lib/lp/archiveuploader/dscfile.py'
--- lib/lp/archiveuploader/dscfile.py	2018-03-02 16:17:35 +0000
+++ lib/lp/archiveuploader/dscfile.py	2018-05-03 15:20:31 +0000
@@ -1,4 +1,4 @@
-# Copyright 2009-2017 Canonical Ltd.  This software is licensed under the
+# Copyright 2009-2018 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
 """ DSCFile and related.
@@ -125,7 +125,7 @@
         if self.signingkey is not None:
             return self.signingkey.owner
 
-    def parse(self, verify_signature=True):
+    def parse(self, verify_signature=True, as_bytes=False):
         """Parse the tag file, optionally verifying the signature.
 
         If verify_signature is True, signingkey will be set to the signing
@@ -167,7 +167,7 @@
             self.parsed_content = self.raw_content
         try:
             self._dict = parse_tagfile_content(
-                self.parsed_content, filename=self.filepath)
+                self.parsed_content, filename=self.filepath, as_bytes=as_bytes)
         except TagFileParseError as error:
             raise UploadError(
                 "Unable to parse %s: %s" % (self.filename, error))
@@ -293,7 +293,7 @@
         SourceUploadFile.__init__(
             self, filepath, checksums, size, component_and_section, priority,
             package, version, changes, policy, logger)
-        self.parse(verify_signature=not policy.unsigned_dsc_ok)
+        self.parse(verify_signature=not policy.unsigned_dsc_ok, as_bytes=True)
 
         self.logger.debug("Performing DSC verification.")
         for mandatory_field in self.mandatory_fields:

=== modified file 'lib/lp/archiveuploader/nascentuploadfile.py'
--- lib/lp/archiveuploader/nascentuploadfile.py	2016-11-08 20:22:59 +0000
+++ lib/lp/archiveuploader/nascentuploadfile.py	2018-05-03 15:20:31 +0000
@@ -1,4 +1,4 @@
-# Copyright 2009-2016 Canonical Ltd.  This software is licensed under the
+# Copyright 2009-2018 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
 """Specific models for uploaded files"""
@@ -554,7 +554,7 @@
         try:
             deb_file = apt_inst.DebFile(self.filepath)
             control_file = deb_file.control.extractdata("control")
-            control_lines = apt_pkg.TagSection(control_file)
+            control_lines = apt_pkg.TagSection(control_file, bytes=True)
         except (SystemExit, KeyboardInterrupt):
             raise
         except:

=== modified file 'lib/lp/archiveuploader/tagfiles.py'
--- lib/lp/archiveuploader/tagfiles.py	2017-01-13 12:24:45 +0000
+++ lib/lp/archiveuploader/tagfiles.py	2018-05-03 15:20:31 +0000
@@ -1,4 +1,4 @@
-# Copyright 2009-2017 Canonical Ltd.  This software is licensed under the
+# Copyright 2009-2018 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
 """Utility classes for parsing Debian tag files."""
@@ -22,7 +22,7 @@
     pass
 
 
-def parse_tagfile_content(content, filename=None):
+def parse_tagfile_content(content, filename=None, as_bytes=False):
     """Parses a tag file and returns a dictionary where each field is a key.
 
     The mandatory first argument is the contents of the tag file as a
@@ -36,7 +36,7 @@
         f.write(strip_pgp_signature(content))
         f.seek(0)
         try:
-            stanzas = list(apt_pkg.TagFile(f))
+            stanzas = list(apt_pkg.TagFile(f, bytes=as_bytes))
         except SystemError as e:
             raise TagFileParseError("%s: %s" % (filename, e))
     if len(stanzas) != 1:

=== modified file 'lib/lp/archiveuploader/tests/__init__.py'
--- lib/lp/archiveuploader/tests/__init__.py	2017-03-29 09:28:09 +0000
+++ lib/lp/archiveuploader/tests/__init__.py	2018-05-03 15:20:31 +0000
@@ -1,8 +1,13 @@
-# Copyright 2009-2017 Canonical Ltd.  This software is licensed under the
+# Copyright 2009-2018 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
 """Tests for the archive uploader."""
 
+# XXX cjwatson 2018-05-03: We should use unicode_literals too, but this
+# requires a version of zope.configuration that includes
+# https://github.com/zopefoundation/zope.configuration/pull/19.
+from __future__ import absolute_import, print_function
+
 __metaclass__ = type
 
 __all__ = [

=== modified file 'lib/lp/archiveuploader/tests/test_buildduploads.py'
--- lib/lp/archiveuploader/tests/test_buildduploads.py	2015-04-20 09:48:57 +0000
+++ lib/lp/archiveuploader/tests/test_buildduploads.py	2018-05-03 15:20:31 +0000
@@ -1,8 +1,10 @@
-# Copyright 2009-2012 Canonical Ltd.  This software is licensed under the
+# Copyright 2009-2018 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
 """Test buildd uploads use-cases."""
 
+from __future__ import absolute_import, print_function, unicode_literals
+
 __metaclass__ = type
 
 import os

=== modified file 'lib/lp/archiveuploader/tests/test_changesfile.py'
--- lib/lp/archiveuploader/tests/test_changesfile.py	2018-01-02 16:10:26 +0000
+++ lib/lp/archiveuploader/tests/test_changesfile.py	2018-05-03 15:20:31 +0000
@@ -1,8 +1,10 @@
-# Copyright 2010-2017 Canonical Ltd.  This software is licensed under the
+# Copyright 2010-2018 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
 """Test ChangesFile functionality."""
 
+from __future__ import absolute_import, print_function, unicode_literals
+
 __metaclass__ = type
 
 import os

=== modified file 'lib/lp/archiveuploader/tests/test_dscfile.py'
--- lib/lp/archiveuploader/tests/test_dscfile.py	2018-01-02 16:10:26 +0000
+++ lib/lp/archiveuploader/tests/test_dscfile.py	2018-05-03 15:20:31 +0000
@@ -1,8 +1,10 @@
-# Copyright 2010-2016 Canonical Ltd.  This software is licensed under the
+# Copyright 2010-2018 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
 """Test dscfile.py"""
 
+from __future__ import absolute_import, print_function, unicode_literals
+
 __metaclass__ = type
 
 from collections import namedtuple
@@ -192,7 +194,7 @@
         name = u'B\u0105r'
         email = u'bar@xxxxxxxxxxx'
         results = self.makeSignableTagFile().parseAddress(
-            '%s <%s>' % (name.encode('utf-8'), email.encode('utf-8')))
+            (u'%s <%s>' % (name, email)).encode('utf-8'))
         self.assertEqual(email, results['email'])
         self.assertEqual(name, results['name'])
         self.assertEqual(name, results['person'].displayname)

=== modified file 'lib/lp/archiveuploader/tests/test_livefsupload.py'
--- lib/lp/archiveuploader/tests/test_livefsupload.py	2014-05-08 14:40:02 +0000
+++ lib/lp/archiveuploader/tests/test_livefsupload.py	2018-05-03 15:20:31 +0000
@@ -1,8 +1,10 @@
-# Copyright 2014 Canonical Ltd.  This software is licensed under the
+# Copyright 2014-2018 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
 """Test uploads of LiveFSBuilds."""
 
+from __future__ import absolute_import, print_function, unicode_literals
+
 __metaclass__ = type
 
 import os

=== modified file 'lib/lp/archiveuploader/tests/test_nascentupload.py'
--- lib/lp/archiveuploader/tests/test_nascentupload.py	2018-01-02 16:10:26 +0000
+++ lib/lp/archiveuploader/tests/test_nascentupload.py	2018-05-03 15:20:31 +0000
@@ -1,8 +1,10 @@
-# Copyright 2010-2014 Canonical Ltd.  This software is licensed under the
+# Copyright 2010-2018 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
 """Test NascentUpload functionality."""
 
+from __future__ import absolute_import, print_function, unicode_literals
+
 __metaclass__ = type
 
 from testtools import TestCase

=== modified file 'lib/lp/archiveuploader/tests/test_nascentupload_documentation.py'
--- lib/lp/archiveuploader/tests/test_nascentupload_documentation.py	2012-01-20 15:42:44 +0000
+++ lib/lp/archiveuploader/tests/test_nascentupload_documentation.py	2018-05-03 15:20:31 +0000
@@ -1,8 +1,10 @@
-# Copyright 2009 Canonical Ltd.  This software is licensed under the
+# Copyright 2009-2018 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
 """Runs the doctests for archiveuploader module."""
 
+from __future__ import absolute_import, print_function, unicode_literals
+
 __metaclass__ = type
 
 import os

=== modified file 'lib/lp/archiveuploader/tests/test_nascentuploadfile.py'
--- lib/lp/archiveuploader/tests/test_nascentuploadfile.py	2018-01-02 16:10:26 +0000
+++ lib/lp/archiveuploader/tests/test_nascentuploadfile.py	2018-05-03 15:20:31 +0000
@@ -1,8 +1,10 @@
-# Copyright 2010-2016 Canonical Ltd.  This software is licensed under the
+# Copyright 2010-2018 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
 """Test NascentUploadFile functionality."""
 
+from __future__ import absolute_import, print_function, unicode_literals
+
 __metaclass__ = type
 
 import hashlib
@@ -346,20 +348,20 @@
 
     def getBaseControl(self):
         return {
-            "Package": "python-dulwich",
-            "Source": "dulwich",
-            "Version": "0.42",
-            "Architecture": "i386",
-            "Maintainer": "Jelmer Vernooij <jelmer@xxxxxxxxxx>",
-            "Installed-Size": "524",
-            "Depends": "python (<< 2.7), python (>= 2.5)",
-            "Provides": "python2.5-dulwich, python2.6-dulwich",
-            "Section": "python",
-            "Priority": "optional",
-            "Homepage": "http://samba.org/~jelmer/dulwich";,
-            "Description": "Pure-python Git library\n"
-                "Dulwich is a Python implementation of the file formats and "
-                "protocols",
+            "Package": b"python-dulwich",
+            "Source": b"dulwich",
+            "Version": b"0.42",
+            "Architecture": b"i386",
+            "Maintainer": b"Jelmer Vernooij <jelmer@xxxxxxxxxx>",
+            "Installed-Size": b"524",
+            "Depends": b"python (<< 2.7), python (>= 2.5)",
+            "Provides": b"python2.5-dulwich, python2.6-dulwich",
+            "Section": b"python",
+            "Priority": b"optional",
+            "Homepage": b"http://samba.org/~jelmer/dulwich";,
+            "Description": b"Pure-python Git library\n"
+                b"Dulwich is a Python implementation of the file formats and "
+                b"protocols",
             }
 
     def createDeb(self, filename, control_format, data_format, members=None):
@@ -468,7 +470,7 @@
             "foo_0.42_i386.deb", "main/python", "unknown", "mypkg", "0.42",
             None)
         control = self.getBaseControl()
-        control["Python-Version"] = "2.5"
+        control["Python-Version"] = b"2.5"
         uploadfile.parseControl(control)
         build = self.factory.makeBinaryPackageBuild()
         bpr = uploadfile.storeInDatabase(build)
@@ -481,7 +483,7 @@
             "foo_0.42_i386.deb", "main/python", "unknown", "mypkg", "0.42",
             None)
         control = self.getBaseControl()
-        control["RandomData"] = "Foo\nbar\nbla\n"
+        control["RandomData"] = b"Foo\nbar\nbla\n"
         uploadfile.parseControl(control)
         build = self.factory.makeBinaryPackageBuild()
         bpr = uploadfile.storeInDatabase(build)
@@ -496,7 +498,7 @@
             "foo_0.42_i386.deb", "main/python", "unknown", "mypkg", "0.42",
             None)
         control = self.getBaseControl()
-        control["Python-Version"] = "2.5"
+        control["Python-Version"] = b"2.5"
         uploadfile.parseControl(control)
         build = self.factory.makeBinaryPackageBuild()
         bpr = uploadfile.storeInDatabase(build)
@@ -547,7 +549,7 @@
             distroseries=self.policy.distroseries,
             version="0.42", archive=self.policy.archive)
         control = self.getBaseControl()
-        control["Source"] = "foo"
+        control["Source"] = b"foo"
         uploadfile.parseControl(control)
         self.assertEqual(
             spph.sourcepackagerelease, uploadfile.findSourcePackageRelease())
@@ -564,7 +566,7 @@
             "foo_0.42_i386.deb", "main/python", "unknown", "mypkg", "0.42",
             None)
         control = self.getBaseControl()
-        control["Source"] = "foo"
+        control["Source"] = b"foo"
         uploadfile.parseControl(control)
         self.assertRaises(UploadError, uploadfile.findSourcePackageRelease)
 
@@ -592,7 +594,7 @@
             version="0.42", archive=self.policy.archive,
             status=PackagePublishingStatus.PENDING)
         control = self.getBaseControl()
-        control["Source"] = "foo"
+        control["Source"] = b"foo"
         uploadfile.parseControl(control)
         self.assertEqual(
             spph2.sourcepackagerelease, uploadfile.findSourcePackageRelease())

=== modified file 'lib/lp/archiveuploader/tests/test_ppauploadprocessor.py'
--- lib/lp/archiveuploader/tests/test_ppauploadprocessor.py	2018-01-02 16:10:26 +0000
+++ lib/lp/archiveuploader/tests/test_ppauploadprocessor.py	2018-05-03 15:20:31 +0000
@@ -2,11 +2,13 @@
 # NOTE: The first line above must stay first; do not move the copyright
 # notice to the top.  See http://www.python.org/dev/peps/pep-0263/.
 #
-# Copyright 2009-2015 Canonical Ltd.  This software is licensed under the
+# Copyright 2009-2018 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
 """Functional tests for uploadprocessor.py."""
 
+from __future__ import absolute_import, print_function, unicode_literals
+
 __metaclass__ = type
 
 from operator import itemgetter
@@ -97,7 +99,7 @@
 
             # This is now a non-multipart message.
             self.assertFalse(msg.is_multipart())
-            body = msg.get_payload(decode=True)
+            body = msg.get_payload(decode=True).decode("UTF-8")
 
             self.assertEqual(recipient, msg['X-Envelope-To'])
 
@@ -986,7 +988,7 @@
         # Also, the email generated should be sane.  Any of the multiple
         # notifications will do.
         msg = pop_notifications()[-1]
-        body = msg.get_payload(decode=True)
+        body = msg.get_payload(decode=True).decode("UTF-8")
 
         self.assertTrue(
             "File bar_1.0.orig.tar.gz already exists in unicode PPA name: "
@@ -1008,7 +1010,7 @@
 
         # The email generated should be sane.
         [msg] = pop_notifications()
-        body = msg.get_payload(decode=True)
+        body = msg.get_payload(decode=True).decode("UTF-8")
 
         self.assertTrue(
             "Rejected:\n"

=== modified file 'lib/lp/archiveuploader/tests/test_private_maintainers.py'
--- lib/lp/archiveuploader/tests/test_private_maintainers.py	2012-01-05 08:48:13 +0000
+++ lib/lp/archiveuploader/tests/test_private_maintainers.py	2018-05-03 15:20:31 +0000
@@ -1,6 +1,8 @@
-# Copyright 2012 Canonical Ltd.  This software is licensed under the
+# Copyright 2012-2018 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
+from __future__ import absolute_import, print_function, unicode_literals
+
 __metaclass__ = type
 
 from lp.archiveuploader.dscfile import SignableTagFile

=== modified file 'lib/lp/archiveuploader/tests/test_processupload.py'
--- lib/lp/archiveuploader/tests/test_processupload.py	2015-01-23 17:57:59 +0000
+++ lib/lp/archiveuploader/tests/test_processupload.py	2018-05-03 15:20:31 +0000
@@ -1,6 +1,8 @@
-# Copyright 2009-2015 Canonical Ltd.  This software is licensed under the
+# Copyright 2009-2018 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
+from __future__ import absolute_import, print_function, unicode_literals
+
 __metaclass__ = type
 
 import os

=== modified file 'lib/lp/archiveuploader/tests/test_recipeuploads.py'
--- lib/lp/archiveuploader/tests/test_recipeuploads.py	2018-01-02 16:10:26 +0000
+++ lib/lp/archiveuploader/tests/test_recipeuploads.py	2018-05-03 15:20:31 +0000
@@ -1,8 +1,10 @@
-# Copyright 2010 Canonical Ltd.  This software is licensed under the
+# Copyright 2010-2018 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
 """Test uploads of SourcePackageRecipeBuilds."""
 
+from __future__ import absolute_import, print_function, unicode_literals
+
 __metaclass__ = type
 
 import os

=== modified file 'lib/lp/archiveuploader/tests/test_snapupload.py'
--- lib/lp/archiveuploader/tests/test_snapupload.py	2017-02-06 15:19:26 +0000
+++ lib/lp/archiveuploader/tests/test_snapupload.py	2018-05-03 15:20:31 +0000
@@ -1,8 +1,10 @@
-# Copyright 2015-2017 Canonical Ltd.  This software is licensed under the
+# Copyright 2015-2018 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
 """Test uploads of SnapBuilds."""
 
+from __future__ import absolute_import, print_function, unicode_literals
+
 __metaclass__ = type
 
 import os

=== modified file 'lib/lp/archiveuploader/tests/test_sync_notification.py'
--- lib/lp/archiveuploader/tests/test_sync_notification.py	2016-11-17 16:46:04 +0000
+++ lib/lp/archiveuploader/tests/test_sync_notification.py	2018-05-03 15:20:31 +0000
@@ -1,8 +1,10 @@
-# Copyright 2012-2016 Canonical Ltd.  This software is licensed under the
+# Copyright 2012-2018 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
 """Test notification behaviour for cross-distro package syncs."""
 
+from __future__ import absolute_import, print_function, unicode_literals
+
 __metaclass__ = type
 
 import os.path

=== modified file 'lib/lp/archiveuploader/tests/test_tagfiles.py'
--- lib/lp/archiveuploader/tests/test_tagfiles.py	2011-12-14 11:58:56 +0000
+++ lib/lp/archiveuploader/tests/test_tagfiles.py	2018-05-03 15:20:31 +0000
@@ -1,9 +1,9 @@
 #!/usr/bin/python
 #
-# Copyright 2009-2010 Canonical Ltd.  This software is licensed under the
+# Copyright 2009-2018 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
-# arch-tag: 52e0c871-49a3-4186-beb8-9817d02d5465
+from __future__ import absolute_import, print_function, unicode_literals
 
 import unittest
 

=== modified file 'lib/lp/archiveuploader/tests/test_uploadpolicy.py'
--- lib/lp/archiveuploader/tests/test_uploadpolicy.py	2018-01-02 16:10:26 +0000
+++ lib/lp/archiveuploader/tests/test_uploadpolicy.py	2018-05-03 15:20:31 +0000
@@ -1,8 +1,10 @@
 #!/usr/bin/python
 #
-# Copyright 2010-2017 Canonical Ltd.  This software is licensed under the
+# Copyright 2010-2018 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
+from __future__ import absolute_import, print_function, unicode_literals
+
 from zope.component import getUtility
 from zope.component.interfaces import ComponentLookupError
 

=== modified file 'lib/lp/archiveuploader/tests/test_uploadprocessor.py'
--- lib/lp/archiveuploader/tests/test_uploadprocessor.py	2018-03-02 16:17:35 +0000
+++ lib/lp/archiveuploader/tests/test_uploadprocessor.py	2018-05-03 15:20:31 +0000
@@ -1,8 +1,10 @@
-# Copyright 2009-2017 Canonical Ltd.  This software is licensed under the
+# Copyright 2009-2018 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
 """Functional tests for uploadprocessor.py."""
 
+from __future__ import absolute_import, print_function, unicode_literals
+
 __metaclass__ = type
 __all__ = [
     "MockOptions",
@@ -372,7 +374,7 @@
 
             # This is now a MIMEMultipart message.
             body = msg.get_payload(0)
-            body = body.get_payload(decode=True)
+            body = body.get_payload(decode=True).decode("UTF-8")
 
             # Only check the recipient if the caller didn't explicitly pass
             # "recipient": None.
@@ -565,7 +567,7 @@
         [msg] = pop_notifications()
         # This is now a MIMEMultipart message.
         body = msg.get_payload(0)
-        body = body.get_payload(decode=True)
+        body = body.get_payload(decode=True).decode("UTF-8")
 
         self.assertEqual(
             "daniel.silverstone@xxxxxxxxxxxxx", msg["X-Envelope-To"])
@@ -976,7 +978,7 @@
         msg = pop_notifications()[-1]
         # This is now a MIMEMultipart message.
         body = msg.get_payload(0)
-        body = body.get_payload(decode=True)
+        body = body.get_payload(decode=True).decode("UTF-8")
 
         self.assertEqual(
             '[ubuntu/partner/breezy] foocomm 1.0-3 (Accepted)', msg['Subject'])
@@ -2374,7 +2376,7 @@
         # Unfold continuation lines.
         subject = mail['Subject'].replace('\n ', ' ')
         self.assertIn('Failed to upload', subject)
-        body = mail.get_payload(decode=True)
+        body = mail.get_payload(decode=True).decode('UTF-8')
         self.assertIn('Upload Log: http', body)
 
     def doDeletedRecipeBuild(self):

=== modified file 'lib/lp/archiveuploader/tests/test_utils.py'
--- lib/lp/archiveuploader/tests/test_utils.py	2018-01-02 16:10:26 +0000
+++ lib/lp/archiveuploader/tests/test_utils.py	2018-05-03 15:20:31 +0000
@@ -1,9 +1,9 @@
 #!/usr/bin/python
 #
-# Copyright 2009-2016 Canonical Ltd.  This software is licensed under the
+# Copyright 2009-2018 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
-# arch-tag: 90e6eb79-83a2-47e8-9f8b-3c687079c923
+from __future__ import absolute_import, print_function, unicode_literals
 
 import os
 import re
@@ -171,12 +171,12 @@
             rfc822_encode_address,
             )
         cases = (
-            ("No\xc3\xa8l K\xc3\xb6the <noel@xxxxxxxxxx>",
+            (b"No\xc3\xa8l K\xc3\xb6the <noel@xxxxxxxxxx>",
              u"No\xe8l K\xf6the <noel@xxxxxxxxxx>",
              u"No\xe8l K\xf6the",
              u"noel@xxxxxxxxxx"),
 
-            ("No\xe8l K\xf6the <noel@xxxxxxxxxx>",
+            (b"No\xe8l K\xf6the <noel@xxxxxxxxxx>",
              u"No\xe8l K\xf6the <noel@xxxxxxxxxx>",
              u"No\xe8l K\xf6the",
              u"noel@xxxxxxxxxx"),
@@ -240,9 +240,10 @@
             "James Troup",
             "James Troup <james>",
             "James Troup <james@xxxxxxxxxx",
-            "No\xc3\xa8l K\xc3\xb6the")
+            b"No\xc3\xa8l K\xc3\xb6the")
         for case in cases:
-            with ExpectedException(ParseMaintError, '^%s: ' % re.escape(case)):
+            with ExpectedException(
+                    ParseMaintError, b'^%s: ' % re.escape(case)):
                 parse_maintainer_bytes(case, 'Maintainer')
 
 

=== modified file 'lib/lp/archiveuploader/uploadprocessor.py'
--- lib/lp/archiveuploader/uploadprocessor.py	2018-03-02 16:17:35 +0000
+++ lib/lp/archiveuploader/uploadprocessor.py	2018-05-03 15:20:31 +0000
@@ -1,4 +1,4 @@
-# Copyright 2009-2017 Canonical Ltd.  This software is licensed under the
+# Copyright 2009-2018 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
 """Code for 'processing' 'uploads'. Also see nascentupload.py.
@@ -741,7 +741,7 @@
         % '/'.join(parts))
 
     # Uploads with undefined distribution defaults to 'ubuntu'.
-    if len(parts) == 0 or parts[0] is '':
+    if len(parts) == 0 or parts[0] == '':
         ubuntu = getUtility(IDistributionSet).getByName('ubuntu')
         return (ubuntu, None)
 


References