launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #27383
[Merge] ~cjwatson/launchpad:py3only-version-detection into launchpad:master
Colin Watson has proposed merging ~cjwatson/launchpad:py3only-version-detection into launchpad:master.
Commit message:
Remove simple cases of Python 2 version detection
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/+git/launchpad/+merge/406806
--
Your team Launchpad code reviewers is requested to review the proposed merge of ~cjwatson/launchpad:py3only-version-detection into launchpad:master.
diff --git a/lib/lp/app/security.py b/lib/lp/app/security.py
index 6fae684..08fe1e5 100644
--- a/lib/lp/app/security.py
+++ b/lib/lp/app/security.py
@@ -13,7 +13,6 @@ __all__ = [
from itertools import repeat
-import six
from six.moves import zip as izip
from zope.component import queryAdapter
from zope.interface import implementer
@@ -128,9 +127,6 @@ class non_boolean_izip(izip):
"DelegatedAuthorization results can't be used in boolean "
"expressions.")
- if six.PY2:
- __nonzero__ = __bool__
-
class DelegatedAuthorization(AuthorizationBase):
diff --git a/lib/lp/bugs/externalbugtracker/bugzilla.py b/lib/lp/bugs/externalbugtracker/bugzilla.py
index 830f680..2f941e8 100644
--- a/lib/lp/bugs/externalbugtracker/bugzilla.py
+++ b/lib/lp/bugs/externalbugtracker/bugzilla.py
@@ -13,7 +13,6 @@ __all__ = [
from email.utils import parseaddr
import re
-import string
import xml.parsers.expat
from defusedxml import minidom
@@ -190,8 +189,7 @@ class Bugzilla(ExternalBugTracker):
bad_chars = b''.join(six.int2byte(i) for i in range(0, 32))
for char in b'\n', b'\r', b'\t':
bad_chars = bad_chars.replace(char, b'')
- maketrans = bytes.maketrans if six.PY3 else string.maketrans
- trans_map = maketrans(bad_chars, b' ' * len(bad_chars))
+ trans_map = bytes.maketrans(bad_chars, b' ' * len(bad_chars))
contents = contents.translate(trans_map)
# Don't use forbid_dtd=True here; Bugzilla XML responses seem to
# include DOCTYPE declarations.
diff --git a/lib/lp/bugs/mail/handler.py b/lib/lp/bugs/mail/handler.py
index 3a151e2..fdf9a31 100644
--- a/lib/lp/bugs/mail/handler.py
+++ b/lib/lp/bugs/mail/handler.py
@@ -13,7 +13,6 @@ import os
from lazr.lifecycle.event import ObjectCreatedEvent
from lazr.lifecycle.interfaces import IObjectCreatedEvent
-import six
import transaction
from zope.component import getUtility
from zope.event import notify
@@ -69,9 +68,6 @@ class BugTaskCommandGroup:
def __bool__(self):
return len(self._commands) > 0
- if six.PY2:
- __nonzero__ = __bool__
-
def __str__(self):
text_commands = [str(cmd) for cmd in self.commands]
return '\n'.join(text_commands).strip()
@@ -98,9 +94,6 @@ class BugCommandGroup(BugTaskCommandGroup):
else:
return super(BugCommandGroup, self).__bool__()
- if six.PY2:
- __nonzero__ = __bool__
-
def __str__(self):
text_commands = [super(BugCommandGroup, self).__str__()]
for group in self.groups:
diff --git a/lib/lp/bugs/scripts/bugexport.py b/lib/lp/bugs/scripts/bugexport.py
index 70e340c..b607f40 100644
--- a/lib/lp/bugs/scripts/bugexport.py
+++ b/lib/lp/bugs/scripts/bugexport.py
@@ -8,7 +8,6 @@ __all__ = [
]
import base64
-import sys
try:
@@ -28,12 +27,6 @@ from lp.services.librarian.browser import ProxiedLibraryFileAlias
BUGS_XMLNS = 'https://launchpad.net/xmlns/2006/bugs'
-if sys.version_info[0] >= 3:
- encodebytes = base64.encodebytes
-else:
- encodebytes = base64.encodestring
-
-
def addnode(parent, elementname, content, **attrs):
node = ET.SubElement(parent, elementname, attrs)
node.text = content
@@ -104,7 +97,8 @@ def serialise_bugtask(bugtask):
attachment.libraryfile.mimetype)
# Attach the attachment file contents, base 64 encoded.
addnode(attachment_node, 'contents',
- encodebytes(attachment.libraryfile.read()).decode('ASCII'))
+ base64.encodebytes(
+ attachment.libraryfile.read()).decode('ASCII'))
return bug_node
diff --git a/lib/lp/bugs/scripts/tests/test_bugsummaryrebuild.py b/lib/lp/bugs/scripts/tests/test_bugsummaryrebuild.py
index 70ae789..f7530e2 100644
--- a/lib/lp/bugs/scripts/tests/test_bugsummaryrebuild.py
+++ b/lib/lp/bugs/scripts/tests/test_bugsummaryrebuild.py
@@ -3,8 +3,6 @@
__metaclass__ = type
-import sys
-
from testtools.content import text_content
from testtools.matchers import MatchesRegex
import transaction
@@ -153,12 +151,10 @@ class TestBugSummaryRebuild(TestCaseWithFactory):
rebuild_bugsummary_for_target(product, log)
self.assertEqual(1, get_bugsummary_rows(product).count())
self.assertEqual(0, get_bugsummaryjournal_rows(product).count())
- long_type = int if sys.version_info[0] >= 3 else long
self.assertThat(
log.getLogBufferAndClear(),
MatchesRegex(
- 'DEBUG Rebuilding %s\nDEBUG Added {.*: %r}' %
- (product.name, long_type(1))))
+ 'DEBUG Rebuilding %s\nDEBUG Added {.*: 1}' % product.name))
def test_script(self):
product = self.factory.makeProduct()
diff --git a/lib/lp/code/browser/tests/test_branchmergeproposal.py b/lib/lp/code/browser/tests/test_branchmergeproposal.py
index c4a776d..5f21254 100644
--- a/lib/lp/code/browser/tests/test_branchmergeproposal.py
+++ b/lib/lp/code/browser/tests/test_branchmergeproposal.py
@@ -13,9 +13,11 @@ from datetime import (
datetime,
timedelta,
)
-from difflib import unified_diff
+from difflib import (
+ diff_bytes,
+ unified_diff,
+ )
import doctest
-from functools import partial
import hashlib
import re
@@ -144,14 +146,6 @@ from lp.testing.views import (
)
-if six.PY3:
- from difflib import diff_bytes
-
- unified_diff_bytes = partial(diff_bytes, unified_diff)
-else:
- unified_diff_bytes = unified_diff
-
-
class GitHostingClientMixin:
def setUp(self):
@@ -1427,22 +1421,21 @@ class TestBranchMergeProposalView(TestCaseWithFactory):
def test_preview_diff_utf8(self):
"""A preview_diff in utf-8 should be decoded as utf-8."""
text = ''.join(six.unichr(x) for x in range(255))
- diff_bytes = ''.join(unified_diff([''], [text])).encode('utf-8')
- self.setPreviewDiff(diff_bytes)
+ diff = ''.join(unified_diff([''], [text])).encode('utf-8')
+ self.setPreviewDiff(diff)
transaction.commit()
view = create_initialized_view(self.bmp, '+index')
- self.assertEqual(diff_bytes.decode('utf-8'),
- view.preview_diff_text)
+ self.assertEqual(diff.decode('utf-8'), view.preview_diff_text)
self.assertTrue(view.diff_available)
def test_preview_diff_all_chars(self):
"""preview_diff should work on diffs containing all possible bytes."""
text = b''.join(six.int2byte(x) for x in range(255))
- diff_bytes = b''.join(unified_diff_bytes([b''], [text]))
- self.setPreviewDiff(diff_bytes)
+ diff = b''.join(diff_bytes(unified_diff, [b''], [text]))
+ self.setPreviewDiff(diff)
transaction.commit()
view = create_initialized_view(self.bmp, '+index')
- self.assertEqual(diff_bytes.decode('windows-1252', 'replace'),
+ self.assertEqual(diff.decode('windows-1252', 'replace'),
view.preview_diff_text)
self.assertTrue(view.diff_available)
@@ -1450,8 +1443,8 @@ class TestBranchMergeProposalView(TestCaseWithFactory):
# The preview_diff will recover from a timeout set to get the
# librarian content.
text = b''.join(six.int2byte(x) for x in range(255))
- diff_bytes = b''.join(unified_diff_bytes([b''], [text]))
- preview_diff = self.setPreviewDiff(diff_bytes)
+ diff = b''.join(diff_bytes(unified_diff, [b''], [text]))
+ preview_diff = self.setPreviewDiff(diff)
transaction.commit()
def fake_open(*args):
@@ -1470,8 +1463,8 @@ class TestBranchMergeProposalView(TestCaseWithFactory):
# librarian content. (This can happen e.g. on staging replicas of
# the production database.)
text = b''.join(six.int2byte(x) for x in range(255))
- diff_bytes = b''.join(unified_diff_bytes([b''], [text]))
- preview_diff = self.setPreviewDiff(diff_bytes)
+ diff = b''.join(diff_bytes(unified_diff, [b''], [text]))
+ preview_diff = self.setPreviewDiff(diff)
transaction.commit()
def fake_open(*args):
diff --git a/lib/lp/registry/browser/person.py b/lib/lp/registry/browser/person.py
index 28239d7..2cb78bc 100644
--- a/lib/lp/registry/browser/person.py
+++ b/lib/lp/registry/browser/person.py
@@ -4296,9 +4296,6 @@ class ContactViaWebNotificationRecipientSet:
"""See `INotificationRecipientSet`."""
return len(self) > 0
- if six.PY2:
- __nonzero__ = __bool__
-
def getReason(self, person_or_email):
"""See `INotificationRecipientSet`."""
if person_or_email not in self:
diff --git a/lib/lp/registry/interfaces/sourcepackagename.py b/lib/lp/registry/interfaces/sourcepackagename.py
index 89c0a8c..1d07542 100644
--- a/lib/lp/registry/interfaces/sourcepackagename.py
+++ b/lib/lp/registry/interfaces/sourcepackagename.py
@@ -10,7 +10,6 @@ __all__ = [
'ISourcePackageNameSet',
]
-import six
from zope.interface import (
Attribute,
Interface,
@@ -40,10 +39,6 @@ class ISourcePackageName(Interface):
def __str__():
"""Return the name"""
- if six.PY2:
- def __unicode__():
- """Return the name"""
-
class ISourcePackageNameSet(Interface):
"""A set of SourcePackageName."""
diff --git a/lib/lp/registry/model/productrelease.py b/lib/lp/registry/model/productrelease.py
index 7ae8b4b..6dfc8b3 100644
--- a/lib/lp/registry/model/productrelease.py
+++ b/lib/lp/registry/model/productrelease.py
@@ -14,7 +14,6 @@ from io import (
BytesIO,
)
import os
-import sys
from sqlobject import (
ForeignKey,
@@ -137,10 +136,7 @@ class ProductRelease(SQLBase):
file_size = len(file_or_data)
file_obj = BytesIO(file_or_data)
else:
- file_types = [BufferedIOBase]
- if sys.version_info[0] < 3:
- file_types.append(file)
- assert isinstance(file_or_data, tuple(file_types)), (
+ assert isinstance(file_or_data, BufferedIOBase), (
"file_or_data is not an expected type")
file_obj = file_or_data
start = file_obj.tell()
diff --git a/lib/lp/registry/tests/test_nickname.py b/lib/lp/registry/tests/test_nickname.py
index dbe5c45..6ca86bb 100644
--- a/lib/lp/registry/tests/test_nickname.py
+++ b/lib/lp/registry/tests/test_nickname.py
@@ -5,8 +5,6 @@
__metaclass__ = type
-import sys
-
from zope.component import getUtility
from lp.registry.interfaces.person import IPersonSet
@@ -45,26 +43,17 @@ class TestNicknameGeneration(TestCaseWithFactory):
# adding random suffixes to the required length.
self.assertIs(None, getUtility(IPersonSet).getByName('i'))
nick = generate_nick('i@xxxxxxxxxxx')
- if sys.version_info[0] >= 3:
- self.assertEqual('i-d', nick)
- else:
- self.assertEqual('i-b', nick)
+ self.assertEqual('i-d', nick)
def test_can_create_noncolliding_nicknames(self):
# Given the same email address, generate_nick doesn't recreate the
# same nick once that nick is used.
self.factory.makePerson(name='bar')
nick = generate_nick('bar@xxxxxxxxxxx')
- if sys.version_info[0] >= 3:
- self.assertEqual('bar-1', nick)
- else:
- self.assertEqual('bar-3', nick)
+ self.assertEqual('bar-1', nick)
# If we used the previously created nick and get another bar@ email
# address, another new nick is generated.
self.factory.makePerson(name=nick)
nick = generate_nick('bar@xxxxxxxxxxx')
- if sys.version_info[0] >= 3:
- self.assertEqual('3-bar', nick)
- else:
- self.assertEqual('5-bar', nick)
+ self.assertEqual('3-bar', nick)
diff --git a/lib/lp/registry/tests/test_ssh.py b/lib/lp/registry/tests/test_ssh.py
index 2f3e700..006e185 100644
--- a/lib/lp/registry/tests/test_ssh.py
+++ b/lib/lp/registry/tests/test_ssh.py
@@ -5,8 +5,6 @@
__metaclass__ = type
-import sys
-
from testtools.matchers import StartsWith
from zope.component import getUtility
from zope.security.proxy import removeSecurityProxy
@@ -205,14 +203,10 @@ class TestSSHKeySet(TestCaseWithFactory):
keyset.new,
person, 'ssh-rsa badkeytext comment'
)
- if sys.version_info[0] >= 3:
- expected_message = "unknown blob type: b'\\xc7_'"
- else:
- expected_message = "unknown blob type: \\xc7_"
self.assertRaisesWithContent(
SSHKeyAdditionError,
"Invalid SSH key data: 'ssh-rsa asdfasdf comment' "
- "(%s)" % expected_message,
+ "(unknown blob type: b'\\xc7_')",
keyset.new,
person, 'ssh-rsa asdfasdf comment'
)
diff --git a/lib/lp/scripts/utilities/importpedant.py b/lib/lp/scripts/utilities/importpedant.py
index 5bf143e..93e7da9 100644
--- a/lib/lp/scripts/utilities/importpedant.py
+++ b/lib/lp/scripts/utilities/importpedant.py
@@ -7,7 +7,6 @@ from operator import attrgetter
import types
import warnings
-import six
from six.moves import builtins
@@ -174,8 +173,7 @@ class NotFoundPolicyViolation(PedantDisagreesError):
# The names of the arguments form part of the interface of __import__(...),
# and must not be changed, as code may choose to invoke __import__ using
# keyword arguments - e.g. the encodings module in Python 2.6.
-def import_pedant(name, globals={}, locals={}, fromlist=[],
- level=(0 if six.PY3 else -1)):
+def import_pedant(name, globals={}, locals={}, fromlist=[], level=0):
global naughty_imports
module = original_import(name, globals, locals, fromlist, level)
diff --git a/lib/lp/scripts/utilities/test.py b/lib/lp/scripts/utilities/test.py
index 375d70c..00795c2 100755
--- a/lib/lp/scripts/utilities/test.py
+++ b/lib/lp/scripts/utilities/test.py
@@ -91,7 +91,7 @@ def configure_environment():
# Suppress accessibility warning because the test runner does not have UI.
os.environ['GTK_MODULES'] = ''
- if six.PY3 and distro.linux_distribution()[:2] == ('Ubuntu', '18.04'):
+ if distro.linux_distribution()[:2] == ('Ubuntu', '18.04'):
# XXX cjwatson 2020-10-09: Certain versions of Python crash when
# importing readline into a process that has libedit loaded
# (https://bugs.python.org/issue38634,
diff --git a/lib/lp/services/compat.py b/lib/lp/services/compat.py
index 4d8ee9d..3673a45 100644
--- a/lib/lp/services/compat.py
+++ b/lib/lp/services/compat.py
@@ -32,19 +32,13 @@ try:
except ImportError:
from unittest import mock
-import six
-
-
-if six.PY3:
- def message_as_bytes(message):
- from email.generator import BytesGenerator
- from email.policy import compat32
-
- fp = io.BytesIO()
- g = BytesGenerator(
- fp, mangle_from_=False, maxheaderlen=0, policy=compat32)
- g.flatten(message)
- return fp.getvalue()
-else:
- def message_as_bytes(message):
- return message.as_string()
+
+def message_as_bytes(message):
+ from email.generator import BytesGenerator
+ from email.policy import compat32
+
+ fp = io.BytesIO()
+ g = BytesGenerator(
+ fp, mangle_from_=False, maxheaderlen=0, policy=compat32)
+ g.flatten(message)
+ return fp.getvalue()
diff --git a/lib/lp/services/encoding.py b/lib/lp/services/encoding.py
index 3c1728b..aa5f74e 100644
--- a/lib/lp/services/encoding.py
+++ b/lib/lp/services/encoding.py
@@ -228,7 +228,7 @@ def wsgi_native_string(s):
Python 2, we enforce this here.
"""
result = six.ensure_str(s, encoding='ISO-8859-1')
- if six.PY3 and isinstance(s, six.text_type):
+ if isinstance(s, six.text_type):
# Ensure we're limited to ISO-8859-1.
result.encode('ISO-8859-1')
return result
diff --git a/lib/lp/services/limitedlist.py b/lib/lp/services/limitedlist.py
index 9c9ca8b..1cb0db5 100644
--- a/lib/lp/services/limitedlist.py
+++ b/lib/lp/services/limitedlist.py
@@ -6,8 +6,6 @@ __all__ = [
'LimitedList',
]
-import sys
-
class LimitedList(list):
"""A mutable sequence that takes a limited number of elements."""
@@ -64,15 +62,6 @@ class LimitedList(list):
self._ensureLength()
return result
- if sys.version_info[0] < 3:
- # list.__setslice__ exists on Python 2, so we must override it in
- # this subclass. (If it didn't exist, as is the case on Python 3,
- # then __setitem__ above would be good enough.)
- def __setslice__(self, i, j, sequence):
- result = super(LimitedList, self).__setslice__(i, j, sequence)
- self._ensureLength()
- return result
-
def append(self, value):
result = super(LimitedList, self).append(value)
self._ensureLength()
diff --git a/lib/lp/services/mail/interfaces.py b/lib/lp/services/mail/interfaces.py
index 41818a4..59fdfec 100644
--- a/lib/lp/services/mail/interfaces.py
+++ b/lib/lp/services/mail/interfaces.py
@@ -19,7 +19,6 @@ __all__ = [
'UnknownRecipientError',
]
-import six
from zope.interface import (
Attribute,
Interface,
@@ -156,9 +155,6 @@ class INotificationRecipientSet(Interface):
def __bool__():
"""Return False when the set is empty, True when it's not."""
- if six.PY2:
- __nonzero__ = __bool__
-
def getReason(person_or_email):
"""Return a reason tuple containing (text, header) for an address.
diff --git a/lib/lp/services/mail/notificationrecipientset.py b/lib/lp/services/mail/notificationrecipientset.py
index 6004399..68f9014 100644
--- a/lib/lp/services/mail/notificationrecipientset.py
+++ b/lib/lp/services/mail/notificationrecipientset.py
@@ -88,9 +88,6 @@ class NotificationRecipientSet:
"""See `INotificationRecipientSet`."""
return bool(self._personToRationale)
- if six.PY2:
- __nonzero__ = __bool__
-
def getReason(self, person_or_email):
"""See `INotificationRecipientSet`."""
if zope_isinstance(person_or_email, six.string_types):
diff --git a/lib/lp/services/scripts/base.py b/lib/lp/services/scripts/base.py
index cd3f19b..989eab6 100644
--- a/lib/lp/services/scripts/base.py
+++ b/lib/lp/services/scripts/base.py
@@ -468,11 +468,7 @@ def cronscript_enabled(control_url, name, log):
# traceback and continue on using the defaults.
try:
with response:
- if sys.version_info[:2] >= (3, 2):
- read_file = cron_config.read_file
- else:
- read_file = cron_config.readfp
- read_file(io.StringIO(response.text))
+ cron_config.read_file(io.StringIO(response.text))
except Exception:
log.exception("Error parsing %s", control_url)
diff --git a/lib/lp/services/tests/test_encoding.py b/lib/lp/services/tests/test_encoding.py
index 4a0e235..ed44acc 100644
--- a/lib/lp/services/tests/test_encoding.py
+++ b/lib/lp/services/tests/test_encoding.py
@@ -7,8 +7,6 @@ from doctest import (
)
import unittest
-import six
-
import lp.services.encoding
from lp.services.encoding import wsgi_native_string
from lp.testing import TestCase
@@ -16,22 +14,14 @@ from lp.testing import TestCase
class TestWSGINativeString(TestCase):
- def _toNative(self, s):
- if six.PY3:
- return s
- else:
- return s.encode('ISO-8859-1')
-
def test_not_bytes_or_unicode(self):
self.assertRaises(TypeError, wsgi_native_string, object())
def test_bytes_iso_8859_1(self):
- self.assertEqual(
- self._toNative(u'foo\xfe'), wsgi_native_string(b'foo\xfe'))
+ self.assertEqual(u'foo\xfe', wsgi_native_string(b'foo\xfe'))
def test_unicode_iso_8859_1(self):
- self.assertEqual(
- self._toNative(u'foo\xfe'), wsgi_native_string(u'foo\xfe'))
+ self.assertEqual(u'foo\xfe', wsgi_native_string(u'foo\xfe'))
def test_unicode_not_iso_8859_1(self):
self.assertRaises(UnicodeEncodeError, wsgi_native_string, u'foo\u2014')
diff --git a/lib/lp/services/twistedsupport/tests/test_xmlrpc.py b/lib/lp/services/twistedsupport/tests/test_xmlrpc.py
index 126d275..59e45fc 100644
--- a/lib/lp/services/twistedsupport/tests/test_xmlrpc.py
+++ b/lib/lp/services/twistedsupport/tests/test_xmlrpc.py
@@ -5,12 +5,6 @@
__metaclass__ = type
-import sys
-
-from testtools.matchers import (
- LessThan,
- Not,
- )
from twisted.python.failure import Failure
from lp.services.twistedsupport import extract_result
@@ -58,11 +52,7 @@ class TestTrapFault(TestCase):
def assertRaisesFailure(self, failure, function, *args, **kwargs):
try:
function(*args, **kwargs)
- except Failure as raised_failure:
- self.assertThat(sys.version_info, LessThan((3, 0)))
- self.assertEqual(failure, raised_failure)
except Exception as raised_exception:
- self.assertThat(sys.version_info, Not(LessThan((3, 0))))
self.assertEqual(failure.value, raised_exception)
def test_raises_non_faults(self):
diff --git a/lib/lp/services/twistedsupport/xmlrpc.py b/lib/lp/services/twistedsupport/xmlrpc.py
index 3521641..70f5598 100644
--- a/lib/lp/services/twistedsupport/xmlrpc.py
+++ b/lib/lp/services/twistedsupport/xmlrpc.py
@@ -10,8 +10,6 @@ __all__ = [
'trap_fault',
]
-import sys
-
from twisted.internet import defer
from twisted.web import xmlrpc
@@ -68,7 +66,4 @@ def trap_fault(failure, *fault_classes):
fault = failure.value
if fault.faultCode in [cls.error_code for cls in fault_classes]:
return fault
- if sys.version_info >= (3, 0):
- failure.raiseException()
- else:
- raise failure
+ failure.raiseException()
diff --git a/lib/lp/services/webapp/pgsession.py b/lib/lp/services/webapp/pgsession.py
index 0a5c664..de05da4 100644
--- a/lib/lp/services/webapp/pgsession.py
+++ b/lib/lp/services/webapp/pgsession.py
@@ -32,33 +32,30 @@ HOURS = 60 * MINUTES
DAYS = 24 * HOURS
-if six.PY3:
- class Python2FriendlyUnpickler(pickle._Unpickler):
- """An unpickler that handles Python 2 datetime objects.
-
- Python 3 versions before 3.6 fail to unpickle Python 2 datetime
- objects (https://bugs.python.org/issue22005); even in Python >= 3.6
- they require passing a different encoding to pickle.loads, which may
- have undesirable effects on other objects being unpickled. Work
- around this by instead patching in a different encoding just for the
- argument to datetime.datetime.
- """
+class Python2FriendlyUnpickler(pickle._Unpickler):
+ """An unpickler that handles Python 2 datetime objects.
+
+ Python 3 versions before 3.6 fail to unpickle Python 2 datetime objects
+ (https://bugs.python.org/issue22005); even in Python >= 3.6 they require
+ passing a different encoding to pickle.loads, which may have undesirable
+ effects on other objects being unpickled. Work around this by instead
+ patching in a different encoding just for the argument to
+ datetime.datetime.
+ """
- def find_class(self, module, name):
- if module == 'datetime' and name == 'datetime':
- original_encoding = self.encoding
- self.encoding = 'bytes'
+ def find_class(self, module, name):
+ if module == 'datetime' and name == 'datetime':
+ original_encoding = self.encoding
+ self.encoding = 'bytes'
- def datetime_factory(pickle_data):
- self.encoding = original_encoding
- return datetime(pickle_data)
+ def datetime_factory(pickle_data):
+ self.encoding = original_encoding
+ return datetime(pickle_data)
- return datetime_factory
- else:
- return super(Python2FriendlyUnpickler, self).find_class(
- module, name)
-else:
- Python2FriendlyUnpickler = pickle.Unpickler
+ return datetime_factory
+ else:
+ return super(Python2FriendlyUnpickler, self).find_class(
+ module, name)
class PGSessionBase:
diff --git a/lib/lp/services/webapp/publisher.py b/lib/lp/services/webapp/publisher.py
index 168b22e..f4d42cd 100644
--- a/lib/lp/services/webapp/publisher.py
+++ b/lib/lp/services/webapp/publisher.py
@@ -632,11 +632,6 @@ class CanonicalAbsoluteURL:
self.context = context
self.request = request
- if six.PY2:
- def __unicode__(self):
- """Returns the URL as a unicode string."""
- raise NotImplementedError()
-
def __str__(self):
"""Returns an ASCII string with all unicode characters url quoted."""
return canonical_url(self.context, self.request)
diff --git a/lib/lp/services/webapp/servers.py b/lib/lp/services/webapp/servers.py
index d637916..a2ef356 100644
--- a/lib/lp/services/webapp/servers.py
+++ b/lib/lp/services/webapp/servers.py
@@ -211,9 +211,6 @@ class StepsToGo(six.Iterator):
def __bool__(self):
return bool(self._stack)
- if six.PY2:
- __nonzero__ = __bool__
-
class ApplicationServerSettingRequestFactory:
"""Create a request and call its setApplicationServer method.
@@ -527,20 +524,9 @@ def get_query_string_params(request):
if query_string is None:
query_string = ''
- kwargs = {}
- if not six.PY2:
- kwargs['encoding'] = 'UTF-8'
- kwargs['errors'] = 'replace'
- parsed_qs = parse_qs(query_string, keep_blank_values=True, **kwargs)
- if six.PY2:
- decoded_qs = {}
- for key, values in six.iteritems(parsed_qs):
- decoded_qs[key] = [
- (value.decode('UTF-8', 'replace') if isinstance(value, bytes)
- else value)
- for value in values]
- parsed_qs = decoded_qs
- return parsed_qs
+ return parse_qs(
+ query_string, keep_blank_values=True,
+ encoding='UTF-8', errors='replace')
class LaunchpadBrowserRequestMixin:
diff --git a/lib/lp/services/webapp/tests/test_servers.py b/lib/lp/services/webapp/tests/test_servers.py
index ed66bfa..1b09775 100644
--- a/lib/lp/services/webapp/tests/test_servers.py
+++ b/lib/lp/services/webapp/tests/test_servers.py
@@ -21,7 +21,6 @@ from lazr.restful.testing.webservice import (
IGenericEntry,
WebServiceTestCase,
)
-import six
from talisker.context import Context
from talisker.logs import logging_context
from zope.component import (
@@ -441,15 +440,12 @@ class TestBasicLaunchpadRequest(TestCase):
def test_request_with_invalid_query_string_recovers(self):
# When the query string has invalid utf-8, it is decoded with
# replacement.
- if six.PY2:
- env = {'QUERY_STRING': 'field.title=subproc\xe9s '}
- else:
- # PEP 3333 requires environment variables to be native strings,
- # so we can't actually get a bytes object in here on Python 3
- # (both because the WSGI runner will never put it there, and
- # because parse_qs would crash if we did). Test the next best
- # thing, namely percent-encoded invalid UTF-8.
- env = {'QUERY_STRING': 'field.title=subproc%E9s '}
+ # PEP 3333 requires environment variables to be native strings, so
+ # we can't actually get a bytes object in here on Python 3 (both
+ # because the WSGI runner will never put it there, and because
+ # parse_qs would crash if we did). Test the next best thing, namely
+ # percent-encoded invalid UTF-8.
+ env = {'QUERY_STRING': 'field.title=subproc%E9s '}
request = LaunchpadBrowserRequest(io.BytesIO(b''), env)
self.assertEqual(
[u'subproc\ufffds '], request.query_string_params['field.title'])
diff --git a/lib/lp/services/webapp/url.py b/lib/lp/services/webapp/url.py
index e438fd9..3a05c33 100644
--- a/lib/lp/services/webapp/url.py
+++ b/lib/lp/services/webapp/url.py
@@ -6,7 +6,6 @@
__metaclass__ = type
__all__ = ['urlappend', 'urlparse', 'urlsplit']
-import six
import six.moves.urllib.parse as urlparse_module
from six.moves.urllib.parse import (
urljoin,
@@ -81,9 +80,7 @@ def urlappend(baseurl, path):
def _ensure_ascii_str(url):
"""Ensure that `url` only contains ASCII, and convert it to a `str`."""
- if six.PY2:
- url = url.encode('ascii')
- elif isinstance(url, bytes):
+ if isinstance(url, bytes):
url = url.decode('ascii')
else:
# Ignore the result; just check that `url` is pure ASCII.
diff --git a/lib/lp/services/webhooks/payload.py b/lib/lp/services/webhooks/payload.py
index f7c7e3d..d73cd1b 100644
--- a/lib/lp/services/webhooks/payload.py
+++ b/lib/lp/services/webhooks/payload.py
@@ -12,7 +12,6 @@ __all__ = [
from io import BytesIO
from lazr.restful.interfaces import IFieldMarshaller
-import six
from zope.component import getMultiAdapter
from zope.interface import implementer
from zope.traversing.browser.interfaces import IAbsoluteURL
@@ -43,11 +42,6 @@ class WebhookAbsoluteURL:
self.context = context
self.request = request
- if six.PY2:
- def __unicode__(self):
- """Returns the URL as a unicode string."""
- raise NotImplementedError()
-
def __str__(self):
"""Returns an ASCII string with all unicode characters url quoted."""
return canonical_url(self.context, force_local_path=True)
diff --git a/lib/lp/soyuz/adapters/archivesourcepublication.py b/lib/lp/soyuz/adapters/archivesourcepublication.py
index 34e4919..f04807d 100644
--- a/lib/lp/soyuz/adapters/archivesourcepublication.py
+++ b/lib/lp/soyuz/adapters/archivesourcepublication.py
@@ -17,7 +17,6 @@ __all__ = [
from collections import defaultdict
from lazr.delegates import delegate_to
-import six
from zope.component import getUtility
from lp.registry.model.distroseries import DistroSeries
@@ -104,9 +103,6 @@ class ArchiveSourcePublications:
"""Are there any sources to iterate?"""
return self.has_sources
- if six.PY2:
- __nonzero__ = __bool__
-
def __iter__(self):
"""`ArchiveSourcePublication` iterator."""
results = []
diff --git a/lib/lp/soyuz/interfaces/binarypackagename.py b/lib/lp/soyuz/interfaces/binarypackagename.py
index bfef027..69973c6 100644
--- a/lib/lp/soyuz/interfaces/binarypackagename.py
+++ b/lib/lp/soyuz/interfaces/binarypackagename.py
@@ -11,7 +11,6 @@ __all__ = [
'IBinaryPackageNameSet',
]
-import six
from zope.interface import Interface
from zope.schema import (
Int,
@@ -31,10 +30,6 @@ class IBinaryPackageName(Interface):
def __str__():
"""Return the name"""
- if six.PY2:
- def __unicode__():
- """Return the name"""
-
class IBinaryPackageNameSet(Interface):
diff --git a/lib/lp/testing/factory.py b/lib/lp/testing/factory.py
index 32c9923..084cee1 100644
--- a/lib/lp/testing/factory.py
+++ b/lib/lp/testing/factory.py
@@ -38,7 +38,6 @@ from itertools import count
import os
import sys
from textwrap import dedent
-import types
import uuid
import warnings
@@ -5210,7 +5209,7 @@ class BareLaunchpadObjectFactory(ObjectFactory):
# Some factory methods return simple Python types. We don't add
# security wrappers for them, as well as for objects created by
# other Python libraries.
-unwrapped_types = {
+unwrapped_types = frozenset({
BaseRecipeBranch,
DSCFile,
Message,
@@ -5218,10 +5217,7 @@ unwrapped_types = {
int,
str,
six.text_type,
- }
-if sys.version_info[0] < 3:
- unwrapped_types.add(types.InstanceType)
-unwrapped_types = frozenset(unwrapped_types)
+ })
def is_security_proxied_or_harmless(obj):
diff --git a/lib/lp/testing/systemdocs.py b/lib/lp/testing/systemdocs.py
index 5e9bdac..29bb200 100644
--- a/lib/lp/testing/systemdocs.py
+++ b/lib/lp/testing/systemdocs.py
@@ -232,19 +232,16 @@ class PrettyPrinter(pprint.PrettyPrinter, object):
return '"%s"' % obj, True, False
else:
return "'%s'" % obj.replace("'", "\\'"), True, False
- elif sys.version_info[0] < 3 and isinstance(obj, long):
- return repr(int(obj)), True, False
else:
return super(PrettyPrinter, self).format(
obj, contexts, maxlevels, level)
# Disable wrapping of long strings on Python >= 3.5, which is unhelpful
# in doctests. There seems to be no reasonable public API for this.
- if sys.version_info[:2] >= (3, 5):
- _dispatch = dict(pprint.PrettyPrinter._dispatch)
- del _dispatch[six.text_type.__repr__]
- del _dispatch[bytes.__repr__]
- del _dispatch[bytearray.__repr__]
+ _dispatch = dict(pprint.PrettyPrinter._dispatch)
+ del _dispatch[six.text_type.__repr__]
+ del _dispatch[bytes.__repr__]
+ del _dispatch[bytearray.__repr__]
# XXX cjwatson 2018-05-13: Once all doctests are made safe for the standard
diff --git a/lib/lp/translations/doc/poexport-queue.txt b/lib/lp/translations/doc/poexport-queue.txt
index 7854639..562eb08 100644
--- a/lib/lp/translations/doc/poexport-queue.txt
+++ b/lib/lp/translations/doc/poexport-queue.txt
@@ -139,14 +139,12 @@ It's not clear that it's possible to trigger this failure mode normally on
Python 3 at all, because bytes will just be formatted as b'...'. For now,
inject a mock exception in that case so that the test can pass.
- >>> if six.PY3:
- ... from lp.services.compat import mock
- ... patcher = mock.patch.object(result, 'failure')
- ... mock_failure = patcher.start()
- ... mock_failure.__str__.side_effect = lambda: b'\xc3'.decode('UTF-8')
+ >>> from lp.services.compat import mock
+ >>> patcher = mock.patch.object(result, 'failure')
+ >>> mock_failure = patcher.start()
+ >>> mock_failure.__str__.side_effect = lambda: b'\xc3'.decode('UTF-8')
>>> result.notify()
- >>> if six.PY3:
- ... patcher.stop()
+ >>> patcher.stop()
>>> test_emails = pop_notifications()
>>> len(test_emails)
diff --git a/lib/lp/translations/model/translatedlanguage.py b/lib/lp/translations/model/translatedlanguage.py
index e9d120a..7c7606c 100644
--- a/lib/lp/translations/model/translatedlanguage.py
+++ b/lib/lp/translations/model/translatedlanguage.py
@@ -4,7 +4,6 @@
__all__ = ['TranslatedLanguageMixin']
import pytz
-import six
from storm.expr import (
Coalesce,
Desc,
@@ -75,9 +74,6 @@ class POFilesByPOTemplates(object):
def __bool__(self):
return bool(self.templates_collection.select(POTemplate).any())
- if six.PY2:
- __nonzero__ = __bool__
-
@implementer(ITranslatedLanguage)
class TranslatedLanguageMixin(object):
diff --git a/lib/sqlobject/__init__.py b/lib/sqlobject/__init__.py
index 5450477..bc94046 100644
--- a/lib/sqlobject/__init__.py
+++ b/lib/sqlobject/__init__.py
@@ -51,8 +51,6 @@ def sqlrepr(value, dbname=None):
return "'f'"
elif isinstance(value, int):
return repr(int(value))
- elif six.PY2 and isinstance(value, long):
- return str(value)
elif isinstance(value, float):
return repr(value)
elif value is None:
diff --git a/scripts/process-one-mail.py b/scripts/process-one-mail.py
index 0fa7484..3cb8598 100755
--- a/scripts/process-one-mail.py
+++ b/scripts/process-one-mail.py
@@ -31,10 +31,8 @@ class ProcessMail(LaunchpadScript):
# with handling a mailbox, which we're avoiding here.
if len(self.args) >= 1:
from_file = open(self.args[0], 'rb')
- elif sys.version_info[0] >= 3:
- from_file = sys.stdin.buffer
else:
- from_file = sys.stdin
+ from_file = sys.stdin.buffer
self.logger.debug("reading message from %r" % (from_file,))
raw_mail = from_file.read()
if from_file != sys.stdin: