Merge ~cjwatson/launchpad:py3only-version-detection into launchpad:master
- Git
- lp:~cjwatson/launchpad
- py3only-version-detection
- Merge into master
Proposed by
Colin Watson
Status: | Merged |
---|---|
Approved by: | Colin Watson |
Approved revision: | f20f13a3d5fa1ee1104b1ae141f33747b302f3f2 |
Merge reported by: | Otto Co-Pilot |
Merged at revision: | not available |
Proposed branch: | ~cjwatson/launchpad:py3only-version-detection |
Merge into: | launchpad:master |
Diff against target: |
983 lines (+83/-258) 36 files modified
lib/lp/app/security.py (+0/-4) lib/lp/bugs/externalbugtracker/bugzilla.py (+1/-3) lib/lp/bugs/mail/handler.py (+0/-7) lib/lp/bugs/scripts/bugexport.py (+2/-8) lib/lp/bugs/scripts/tests/test_bugsummaryrebuild.py (+1/-5) lib/lp/code/browser/tests/test_branchmergeproposal.py (+14/-21) lib/lp/registry/browser/person.py (+0/-3) lib/lp/registry/interfaces/sourcepackagename.py (+0/-5) lib/lp/registry/model/productrelease.py (+1/-5) lib/lp/registry/tests/test_nickname.py (+3/-14) lib/lp/registry/tests/test_ssh.py (+1/-7) lib/lp/scripts/utilities/importpedant.py (+1/-3) lib/lp/scripts/utilities/test.py (+1/-1) lib/lp/services/compat.py (+10/-16) lib/lp/services/encoding.py (+1/-1) lib/lp/services/limitedlist.py (+0/-11) lib/lp/services/mail/interfaces.py (+0/-4) lib/lp/services/mail/notificationrecipientset.py (+0/-3) lib/lp/services/scripts/base.py (+1/-5) lib/lp/services/tests/test_encoding.py (+2/-12) lib/lp/services/twistedsupport/tests/test_xmlrpc.py (+0/-10) lib/lp/services/twistedsupport/xmlrpc.py (+1/-6) lib/lp/services/webapp/pgsession.py (+21/-24) lib/lp/services/webapp/publisher.py (+0/-5) lib/lp/services/webapp/servers.py (+3/-17) lib/lp/services/webapp/tests/test_servers.py (+6/-10) lib/lp/services/webapp/url.py (+1/-4) lib/lp/services/webhooks/payload.py (+0/-6) lib/lp/soyuz/adapters/archivesourcepublication.py (+0/-4) lib/lp/soyuz/interfaces/binarypackagename.py (+0/-5) lib/lp/testing/factory.py (+2/-6) lib/lp/testing/systemdocs.py (+4/-7) lib/lp/translations/doc/poexport-queue.txt (+5/-7) lib/lp/translations/model/translatedlanguage.py (+0/-4) lib/sqlobject/__init__.py (+0/-2) scripts/process-one-mail.py (+1/-3) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Cristian Gonzalez (community) | Approve | ||
Review via email: mp+406806@code.launchpad.net |
Commit message
Remove simple cases of Python 2 version detection
Description of the change
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | diff --git a/lib/lp/app/security.py b/lib/lp/app/security.py | |||
2 | index 6fae684..08fe1e5 100644 | |||
3 | --- a/lib/lp/app/security.py | |||
4 | +++ b/lib/lp/app/security.py | |||
5 | @@ -13,7 +13,6 @@ __all__ = [ | |||
6 | 13 | 13 | ||
7 | 14 | from itertools import repeat | 14 | from itertools import repeat |
8 | 15 | 15 | ||
9 | 16 | import six | ||
10 | 17 | from six.moves import zip as izip | 16 | from six.moves import zip as izip |
11 | 18 | from zope.component import queryAdapter | 17 | from zope.component import queryAdapter |
12 | 19 | from zope.interface import implementer | 18 | from zope.interface import implementer |
13 | @@ -128,9 +127,6 @@ class non_boolean_izip(izip): | |||
14 | 128 | "DelegatedAuthorization results can't be used in boolean " | 127 | "DelegatedAuthorization results can't be used in boolean " |
15 | 129 | "expressions.") | 128 | "expressions.") |
16 | 130 | 129 | ||
17 | 131 | if six.PY2: | ||
18 | 132 | __nonzero__ = __bool__ | ||
19 | 133 | |||
20 | 134 | 130 | ||
21 | 135 | class DelegatedAuthorization(AuthorizationBase): | 131 | class DelegatedAuthorization(AuthorizationBase): |
22 | 136 | 132 | ||
23 | diff --git a/lib/lp/bugs/externalbugtracker/bugzilla.py b/lib/lp/bugs/externalbugtracker/bugzilla.py | |||
24 | index 830f680..2f941e8 100644 | |||
25 | --- a/lib/lp/bugs/externalbugtracker/bugzilla.py | |||
26 | +++ b/lib/lp/bugs/externalbugtracker/bugzilla.py | |||
27 | @@ -13,7 +13,6 @@ __all__ = [ | |||
28 | 13 | 13 | ||
29 | 14 | from email.utils import parseaddr | 14 | from email.utils import parseaddr |
30 | 15 | import re | 15 | import re |
31 | 16 | import string | ||
32 | 17 | import xml.parsers.expat | 16 | import xml.parsers.expat |
33 | 18 | 17 | ||
34 | 19 | from defusedxml import minidom | 18 | from defusedxml import minidom |
35 | @@ -190,8 +189,7 @@ class Bugzilla(ExternalBugTracker): | |||
36 | 190 | bad_chars = b''.join(six.int2byte(i) for i in range(0, 32)) | 189 | bad_chars = b''.join(six.int2byte(i) for i in range(0, 32)) |
37 | 191 | for char in b'\n', b'\r', b'\t': | 190 | for char in b'\n', b'\r', b'\t': |
38 | 192 | bad_chars = bad_chars.replace(char, b'') | 191 | bad_chars = bad_chars.replace(char, b'') |
41 | 193 | maketrans = bytes.maketrans if six.PY3 else string.maketrans | 192 | trans_map = bytes.maketrans(bad_chars, b' ' * len(bad_chars)) |
40 | 194 | trans_map = maketrans(bad_chars, b' ' * len(bad_chars)) | ||
42 | 195 | contents = contents.translate(trans_map) | 193 | contents = contents.translate(trans_map) |
43 | 196 | # Don't use forbid_dtd=True here; Bugzilla XML responses seem to | 194 | # Don't use forbid_dtd=True here; Bugzilla XML responses seem to |
44 | 197 | # include DOCTYPE declarations. | 195 | # include DOCTYPE declarations. |
45 | diff --git a/lib/lp/bugs/mail/handler.py b/lib/lp/bugs/mail/handler.py | |||
46 | index 3a151e2..fdf9a31 100644 | |||
47 | --- a/lib/lp/bugs/mail/handler.py | |||
48 | +++ b/lib/lp/bugs/mail/handler.py | |||
49 | @@ -13,7 +13,6 @@ import os | |||
50 | 13 | 13 | ||
51 | 14 | from lazr.lifecycle.event import ObjectCreatedEvent | 14 | from lazr.lifecycle.event import ObjectCreatedEvent |
52 | 15 | from lazr.lifecycle.interfaces import IObjectCreatedEvent | 15 | from lazr.lifecycle.interfaces import IObjectCreatedEvent |
53 | 16 | import six | ||
54 | 17 | import transaction | 16 | import transaction |
55 | 18 | from zope.component import getUtility | 17 | from zope.component import getUtility |
56 | 19 | from zope.event import notify | 18 | from zope.event import notify |
57 | @@ -69,9 +68,6 @@ class BugTaskCommandGroup: | |||
58 | 69 | def __bool__(self): | 68 | def __bool__(self): |
59 | 70 | return len(self._commands) > 0 | 69 | return len(self._commands) > 0 |
60 | 71 | 70 | ||
61 | 72 | if six.PY2: | ||
62 | 73 | __nonzero__ = __bool__ | ||
63 | 74 | |||
64 | 75 | def __str__(self): | 71 | def __str__(self): |
65 | 76 | text_commands = [str(cmd) for cmd in self.commands] | 72 | text_commands = [str(cmd) for cmd in self.commands] |
66 | 77 | return '\n'.join(text_commands).strip() | 73 | return '\n'.join(text_commands).strip() |
67 | @@ -98,9 +94,6 @@ class BugCommandGroup(BugTaskCommandGroup): | |||
68 | 98 | else: | 94 | else: |
69 | 99 | return super(BugCommandGroup, self).__bool__() | 95 | return super(BugCommandGroup, self).__bool__() |
70 | 100 | 96 | ||
71 | 101 | if six.PY2: | ||
72 | 102 | __nonzero__ = __bool__ | ||
73 | 103 | |||
74 | 104 | def __str__(self): | 97 | def __str__(self): |
75 | 105 | text_commands = [super(BugCommandGroup, self).__str__()] | 98 | text_commands = [super(BugCommandGroup, self).__str__()] |
76 | 106 | for group in self.groups: | 99 | for group in self.groups: |
77 | diff --git a/lib/lp/bugs/scripts/bugexport.py b/lib/lp/bugs/scripts/bugexport.py | |||
78 | index 70e340c..b607f40 100644 | |||
79 | --- a/lib/lp/bugs/scripts/bugexport.py | |||
80 | +++ b/lib/lp/bugs/scripts/bugexport.py | |||
81 | @@ -8,7 +8,6 @@ __all__ = [ | |||
82 | 8 | ] | 8 | ] |
83 | 9 | 9 | ||
84 | 10 | import base64 | 10 | import base64 |
85 | 11 | import sys | ||
86 | 12 | 11 | ||
87 | 13 | 12 | ||
88 | 14 | try: | 13 | try: |
89 | @@ -28,12 +27,6 @@ from lp.services.librarian.browser import ProxiedLibraryFileAlias | |||
90 | 28 | BUGS_XMLNS = 'https://launchpad.net/xmlns/2006/bugs' | 27 | BUGS_XMLNS = 'https://launchpad.net/xmlns/2006/bugs' |
91 | 29 | 28 | ||
92 | 30 | 29 | ||
93 | 31 | if sys.version_info[0] >= 3: | ||
94 | 32 | encodebytes = base64.encodebytes | ||
95 | 33 | else: | ||
96 | 34 | encodebytes = base64.encodestring | ||
97 | 35 | |||
98 | 36 | |||
99 | 37 | def addnode(parent, elementname, content, **attrs): | 30 | def addnode(parent, elementname, content, **attrs): |
100 | 38 | node = ET.SubElement(parent, elementname, attrs) | 31 | node = ET.SubElement(parent, elementname, attrs) |
101 | 39 | node.text = content | 32 | node.text = content |
102 | @@ -104,7 +97,8 @@ def serialise_bugtask(bugtask): | |||
103 | 104 | attachment.libraryfile.mimetype) | 97 | attachment.libraryfile.mimetype) |
104 | 105 | # Attach the attachment file contents, base 64 encoded. | 98 | # Attach the attachment file contents, base 64 encoded. |
105 | 106 | addnode(attachment_node, 'contents', | 99 | addnode(attachment_node, 'contents', |
107 | 107 | encodebytes(attachment.libraryfile.read()).decode('ASCII')) | 100 | base64.encodebytes( |
108 | 101 | attachment.libraryfile.read()).decode('ASCII')) | ||
109 | 108 | 102 | ||
110 | 109 | return bug_node | 103 | return bug_node |
111 | 110 | 104 | ||
112 | diff --git a/lib/lp/bugs/scripts/tests/test_bugsummaryrebuild.py b/lib/lp/bugs/scripts/tests/test_bugsummaryrebuild.py | |||
113 | index 70ae789..f7530e2 100644 | |||
114 | --- a/lib/lp/bugs/scripts/tests/test_bugsummaryrebuild.py | |||
115 | +++ b/lib/lp/bugs/scripts/tests/test_bugsummaryrebuild.py | |||
116 | @@ -3,8 +3,6 @@ | |||
117 | 3 | 3 | ||
118 | 4 | __metaclass__ = type | 4 | __metaclass__ = type |
119 | 5 | 5 | ||
120 | 6 | import sys | ||
121 | 7 | |||
122 | 8 | from testtools.content import text_content | 6 | from testtools.content import text_content |
123 | 9 | from testtools.matchers import MatchesRegex | 7 | from testtools.matchers import MatchesRegex |
124 | 10 | import transaction | 8 | import transaction |
125 | @@ -153,12 +151,10 @@ class TestBugSummaryRebuild(TestCaseWithFactory): | |||
126 | 153 | rebuild_bugsummary_for_target(product, log) | 151 | rebuild_bugsummary_for_target(product, log) |
127 | 154 | self.assertEqual(1, get_bugsummary_rows(product).count()) | 152 | self.assertEqual(1, get_bugsummary_rows(product).count()) |
128 | 155 | self.assertEqual(0, get_bugsummaryjournal_rows(product).count()) | 153 | self.assertEqual(0, get_bugsummaryjournal_rows(product).count()) |
129 | 156 | long_type = int if sys.version_info[0] >= 3 else long | ||
130 | 157 | self.assertThat( | 154 | self.assertThat( |
131 | 158 | log.getLogBufferAndClear(), | 155 | log.getLogBufferAndClear(), |
132 | 159 | MatchesRegex( | 156 | MatchesRegex( |
135 | 160 | 'DEBUG Rebuilding %s\nDEBUG Added {.*: %r}' % | 157 | 'DEBUG Rebuilding %s\nDEBUG Added {.*: 1}' % product.name)) |
134 | 161 | (product.name, long_type(1)))) | ||
136 | 162 | 158 | ||
137 | 163 | def test_script(self): | 159 | def test_script(self): |
138 | 164 | product = self.factory.makeProduct() | 160 | product = self.factory.makeProduct() |
139 | diff --git a/lib/lp/code/browser/tests/test_branchmergeproposal.py b/lib/lp/code/browser/tests/test_branchmergeproposal.py | |||
140 | index c4a776d..5f21254 100644 | |||
141 | --- a/lib/lp/code/browser/tests/test_branchmergeproposal.py | |||
142 | +++ b/lib/lp/code/browser/tests/test_branchmergeproposal.py | |||
143 | @@ -13,9 +13,11 @@ from datetime import ( | |||
144 | 13 | datetime, | 13 | datetime, |
145 | 14 | timedelta, | 14 | timedelta, |
146 | 15 | ) | 15 | ) |
148 | 16 | from difflib import unified_diff | 16 | from difflib import ( |
149 | 17 | diff_bytes, | ||
150 | 18 | unified_diff, | ||
151 | 19 | ) | ||
152 | 17 | import doctest | 20 | import doctest |
153 | 18 | from functools import partial | ||
154 | 19 | import hashlib | 21 | import hashlib |
155 | 20 | import re | 22 | import re |
156 | 21 | 23 | ||
157 | @@ -144,14 +146,6 @@ from lp.testing.views import ( | |||
158 | 144 | ) | 146 | ) |
159 | 145 | 147 | ||
160 | 146 | 148 | ||
161 | 147 | if six.PY3: | ||
162 | 148 | from difflib import diff_bytes | ||
163 | 149 | |||
164 | 150 | unified_diff_bytes = partial(diff_bytes, unified_diff) | ||
165 | 151 | else: | ||
166 | 152 | unified_diff_bytes = unified_diff | ||
167 | 153 | |||
168 | 154 | |||
169 | 155 | class GitHostingClientMixin: | 149 | class GitHostingClientMixin: |
170 | 156 | 150 | ||
171 | 157 | def setUp(self): | 151 | def setUp(self): |
172 | @@ -1427,22 +1421,21 @@ class TestBranchMergeProposalView(TestCaseWithFactory): | |||
173 | 1427 | def test_preview_diff_utf8(self): | 1421 | def test_preview_diff_utf8(self): |
174 | 1428 | """A preview_diff in utf-8 should be decoded as utf-8.""" | 1422 | """A preview_diff in utf-8 should be decoded as utf-8.""" |
175 | 1429 | text = ''.join(six.unichr(x) for x in range(255)) | 1423 | text = ''.join(six.unichr(x) for x in range(255)) |
178 | 1430 | diff_bytes = ''.join(unified_diff([''], [text])).encode('utf-8') | 1424 | diff = ''.join(unified_diff([''], [text])).encode('utf-8') |
179 | 1431 | self.setPreviewDiff(diff_bytes) | 1425 | self.setPreviewDiff(diff) |
180 | 1432 | transaction.commit() | 1426 | transaction.commit() |
181 | 1433 | view = create_initialized_view(self.bmp, '+index') | 1427 | view = create_initialized_view(self.bmp, '+index') |
184 | 1434 | self.assertEqual(diff_bytes.decode('utf-8'), | 1428 | self.assertEqual(diff.decode('utf-8'), view.preview_diff_text) |
183 | 1435 | view.preview_diff_text) | ||
185 | 1436 | self.assertTrue(view.diff_available) | 1429 | self.assertTrue(view.diff_available) |
186 | 1437 | 1430 | ||
187 | 1438 | def test_preview_diff_all_chars(self): | 1431 | def test_preview_diff_all_chars(self): |
188 | 1439 | """preview_diff should work on diffs containing all possible bytes.""" | 1432 | """preview_diff should work on diffs containing all possible bytes.""" |
189 | 1440 | text = b''.join(six.int2byte(x) for x in range(255)) | 1433 | text = b''.join(six.int2byte(x) for x in range(255)) |
192 | 1441 | diff_bytes = b''.join(unified_diff_bytes([b''], [text])) | 1434 | diff = b''.join(diff_bytes(unified_diff, [b''], [text])) |
193 | 1442 | self.setPreviewDiff(diff_bytes) | 1435 | self.setPreviewDiff(diff) |
194 | 1443 | transaction.commit() | 1436 | transaction.commit() |
195 | 1444 | view = create_initialized_view(self.bmp, '+index') | 1437 | view = create_initialized_view(self.bmp, '+index') |
197 | 1445 | self.assertEqual(diff_bytes.decode('windows-1252', 'replace'), | 1438 | self.assertEqual(diff.decode('windows-1252', 'replace'), |
198 | 1446 | view.preview_diff_text) | 1439 | view.preview_diff_text) |
199 | 1447 | self.assertTrue(view.diff_available) | 1440 | self.assertTrue(view.diff_available) |
200 | 1448 | 1441 | ||
201 | @@ -1450,8 +1443,8 @@ class TestBranchMergeProposalView(TestCaseWithFactory): | |||
202 | 1450 | # The preview_diff will recover from a timeout set to get the | 1443 | # The preview_diff will recover from a timeout set to get the |
203 | 1451 | # librarian content. | 1444 | # librarian content. |
204 | 1452 | text = b''.join(six.int2byte(x) for x in range(255)) | 1445 | text = b''.join(six.int2byte(x) for x in range(255)) |
207 | 1453 | diff_bytes = b''.join(unified_diff_bytes([b''], [text])) | 1446 | diff = b''.join(diff_bytes(unified_diff, [b''], [text])) |
208 | 1454 | preview_diff = self.setPreviewDiff(diff_bytes) | 1447 | preview_diff = self.setPreviewDiff(diff) |
209 | 1455 | transaction.commit() | 1448 | transaction.commit() |
210 | 1456 | 1449 | ||
211 | 1457 | def fake_open(*args): | 1450 | def fake_open(*args): |
212 | @@ -1470,8 +1463,8 @@ class TestBranchMergeProposalView(TestCaseWithFactory): | |||
213 | 1470 | # librarian content. (This can happen e.g. on staging replicas of | 1463 | # librarian content. (This can happen e.g. on staging replicas of |
214 | 1471 | # the production database.) | 1464 | # the production database.) |
215 | 1472 | text = b''.join(six.int2byte(x) for x in range(255)) | 1465 | text = b''.join(six.int2byte(x) for x in range(255)) |
218 | 1473 | diff_bytes = b''.join(unified_diff_bytes([b''], [text])) | 1466 | diff = b''.join(diff_bytes(unified_diff, [b''], [text])) |
219 | 1474 | preview_diff = self.setPreviewDiff(diff_bytes) | 1467 | preview_diff = self.setPreviewDiff(diff) |
220 | 1475 | transaction.commit() | 1468 | transaction.commit() |
221 | 1476 | 1469 | ||
222 | 1477 | def fake_open(*args): | 1470 | def fake_open(*args): |
223 | diff --git a/lib/lp/registry/browser/person.py b/lib/lp/registry/browser/person.py | |||
224 | index 28239d7..2cb78bc 100644 | |||
225 | --- a/lib/lp/registry/browser/person.py | |||
226 | +++ b/lib/lp/registry/browser/person.py | |||
227 | @@ -4296,9 +4296,6 @@ class ContactViaWebNotificationRecipientSet: | |||
228 | 4296 | """See `INotificationRecipientSet`.""" | 4296 | """See `INotificationRecipientSet`.""" |
229 | 4297 | return len(self) > 0 | 4297 | return len(self) > 0 |
230 | 4298 | 4298 | ||
231 | 4299 | if six.PY2: | ||
232 | 4300 | __nonzero__ = __bool__ | ||
233 | 4301 | |||
234 | 4302 | def getReason(self, person_or_email): | 4299 | def getReason(self, person_or_email): |
235 | 4303 | """See `INotificationRecipientSet`.""" | 4300 | """See `INotificationRecipientSet`.""" |
236 | 4304 | if person_or_email not in self: | 4301 | if person_or_email not in self: |
237 | diff --git a/lib/lp/registry/interfaces/sourcepackagename.py b/lib/lp/registry/interfaces/sourcepackagename.py | |||
238 | index 89c0a8c..1d07542 100644 | |||
239 | --- a/lib/lp/registry/interfaces/sourcepackagename.py | |||
240 | +++ b/lib/lp/registry/interfaces/sourcepackagename.py | |||
241 | @@ -10,7 +10,6 @@ __all__ = [ | |||
242 | 10 | 'ISourcePackageNameSet', | 10 | 'ISourcePackageNameSet', |
243 | 11 | ] | 11 | ] |
244 | 12 | 12 | ||
245 | 13 | import six | ||
246 | 14 | from zope.interface import ( | 13 | from zope.interface import ( |
247 | 15 | Attribute, | 14 | Attribute, |
248 | 16 | Interface, | 15 | Interface, |
249 | @@ -40,10 +39,6 @@ class ISourcePackageName(Interface): | |||
250 | 40 | def __str__(): | 39 | def __str__(): |
251 | 41 | """Return the name""" | 40 | """Return the name""" |
252 | 42 | 41 | ||
253 | 43 | if six.PY2: | ||
254 | 44 | def __unicode__(): | ||
255 | 45 | """Return the name""" | ||
256 | 46 | |||
257 | 47 | 42 | ||
258 | 48 | class ISourcePackageNameSet(Interface): | 43 | class ISourcePackageNameSet(Interface): |
259 | 49 | """A set of SourcePackageName.""" | 44 | """A set of SourcePackageName.""" |
260 | diff --git a/lib/lp/registry/model/productrelease.py b/lib/lp/registry/model/productrelease.py | |||
261 | index 7ae8b4b..6dfc8b3 100644 | |||
262 | --- a/lib/lp/registry/model/productrelease.py | |||
263 | +++ b/lib/lp/registry/model/productrelease.py | |||
264 | @@ -14,7 +14,6 @@ from io import ( | |||
265 | 14 | BytesIO, | 14 | BytesIO, |
266 | 15 | ) | 15 | ) |
267 | 16 | import os | 16 | import os |
268 | 17 | import sys | ||
269 | 18 | 17 | ||
270 | 19 | from sqlobject import ( | 18 | from sqlobject import ( |
271 | 20 | ForeignKey, | 19 | ForeignKey, |
272 | @@ -137,10 +136,7 @@ class ProductRelease(SQLBase): | |||
273 | 137 | file_size = len(file_or_data) | 136 | file_size = len(file_or_data) |
274 | 138 | file_obj = BytesIO(file_or_data) | 137 | file_obj = BytesIO(file_or_data) |
275 | 139 | else: | 138 | else: |
280 | 140 | file_types = [BufferedIOBase] | 139 | assert isinstance(file_or_data, BufferedIOBase), ( |
277 | 141 | if sys.version_info[0] < 3: | ||
278 | 142 | file_types.append(file) | ||
279 | 143 | assert isinstance(file_or_data, tuple(file_types)), ( | ||
281 | 144 | "file_or_data is not an expected type") | 140 | "file_or_data is not an expected type") |
282 | 145 | file_obj = file_or_data | 141 | file_obj = file_or_data |
283 | 146 | start = file_obj.tell() | 142 | start = file_obj.tell() |
284 | diff --git a/lib/lp/registry/tests/test_nickname.py b/lib/lp/registry/tests/test_nickname.py | |||
285 | index dbe5c45..6ca86bb 100644 | |||
286 | --- a/lib/lp/registry/tests/test_nickname.py | |||
287 | +++ b/lib/lp/registry/tests/test_nickname.py | |||
288 | @@ -5,8 +5,6 @@ | |||
289 | 5 | 5 | ||
290 | 6 | __metaclass__ = type | 6 | __metaclass__ = type |
291 | 7 | 7 | ||
292 | 8 | import sys | ||
293 | 9 | |||
294 | 10 | from zope.component import getUtility | 8 | from zope.component import getUtility |
295 | 11 | 9 | ||
296 | 12 | from lp.registry.interfaces.person import IPersonSet | 10 | from lp.registry.interfaces.person import IPersonSet |
297 | @@ -45,26 +43,17 @@ class TestNicknameGeneration(TestCaseWithFactory): | |||
298 | 45 | # adding random suffixes to the required length. | 43 | # adding random suffixes to the required length. |
299 | 46 | self.assertIs(None, getUtility(IPersonSet).getByName('i')) | 44 | self.assertIs(None, getUtility(IPersonSet).getByName('i')) |
300 | 47 | nick = generate_nick('i@example.com') | 45 | nick = generate_nick('i@example.com') |
305 | 48 | if sys.version_info[0] >= 3: | 46 | self.assertEqual('i-d', nick) |
302 | 49 | self.assertEqual('i-d', nick) | ||
303 | 50 | else: | ||
304 | 51 | self.assertEqual('i-b', nick) | ||
306 | 52 | 47 | ||
307 | 53 | def test_can_create_noncolliding_nicknames(self): | 48 | def test_can_create_noncolliding_nicknames(self): |
308 | 54 | # Given the same email address, generate_nick doesn't recreate the | 49 | # Given the same email address, generate_nick doesn't recreate the |
309 | 55 | # same nick once that nick is used. | 50 | # same nick once that nick is used. |
310 | 56 | self.factory.makePerson(name='bar') | 51 | self.factory.makePerson(name='bar') |
311 | 57 | nick = generate_nick('bar@example.com') | 52 | nick = generate_nick('bar@example.com') |
316 | 58 | if sys.version_info[0] >= 3: | 53 | self.assertEqual('bar-1', nick) |
313 | 59 | self.assertEqual('bar-1', nick) | ||
314 | 60 | else: | ||
315 | 61 | self.assertEqual('bar-3', nick) | ||
317 | 62 | 54 | ||
318 | 63 | # If we used the previously created nick and get another bar@ email | 55 | # If we used the previously created nick and get another bar@ email |
319 | 64 | # address, another new nick is generated. | 56 | # address, another new nick is generated. |
320 | 65 | self.factory.makePerson(name=nick) | 57 | self.factory.makePerson(name=nick) |
321 | 66 | nick = generate_nick('bar@example.com') | 58 | nick = generate_nick('bar@example.com') |
326 | 67 | if sys.version_info[0] >= 3: | 59 | self.assertEqual('3-bar', nick) |
323 | 68 | self.assertEqual('3-bar', nick) | ||
324 | 69 | else: | ||
325 | 70 | self.assertEqual('5-bar', nick) | ||
327 | diff --git a/lib/lp/registry/tests/test_ssh.py b/lib/lp/registry/tests/test_ssh.py | |||
328 | index 2f3e700..006e185 100644 | |||
329 | --- a/lib/lp/registry/tests/test_ssh.py | |||
330 | +++ b/lib/lp/registry/tests/test_ssh.py | |||
331 | @@ -5,8 +5,6 @@ | |||
332 | 5 | 5 | ||
333 | 6 | __metaclass__ = type | 6 | __metaclass__ = type |
334 | 7 | 7 | ||
335 | 8 | import sys | ||
336 | 9 | |||
337 | 10 | from testtools.matchers import StartsWith | 8 | from testtools.matchers import StartsWith |
338 | 11 | from zope.component import getUtility | 9 | from zope.component import getUtility |
339 | 12 | from zope.security.proxy import removeSecurityProxy | 10 | from zope.security.proxy import removeSecurityProxy |
340 | @@ -205,14 +203,10 @@ class TestSSHKeySet(TestCaseWithFactory): | |||
341 | 205 | keyset.new, | 203 | keyset.new, |
342 | 206 | person, 'ssh-rsa badkeytext comment' | 204 | person, 'ssh-rsa badkeytext comment' |
343 | 207 | ) | 205 | ) |
344 | 208 | if sys.version_info[0] >= 3: | ||
345 | 209 | expected_message = "unknown blob type: b'\\xc7_'" | ||
346 | 210 | else: | ||
347 | 211 | expected_message = "unknown blob type: \\xc7_" | ||
348 | 212 | self.assertRaisesWithContent( | 206 | self.assertRaisesWithContent( |
349 | 213 | SSHKeyAdditionError, | 207 | SSHKeyAdditionError, |
350 | 214 | "Invalid SSH key data: 'ssh-rsa asdfasdf comment' " | 208 | "Invalid SSH key data: 'ssh-rsa asdfasdf comment' " |
352 | 215 | "(%s)" % expected_message, | 209 | "(unknown blob type: b'\\xc7_')", |
353 | 216 | keyset.new, | 210 | keyset.new, |
354 | 217 | person, 'ssh-rsa asdfasdf comment' | 211 | person, 'ssh-rsa asdfasdf comment' |
355 | 218 | ) | 212 | ) |
356 | diff --git a/lib/lp/scripts/utilities/importpedant.py b/lib/lp/scripts/utilities/importpedant.py | |||
357 | index 5bf143e..93e7da9 100644 | |||
358 | --- a/lib/lp/scripts/utilities/importpedant.py | |||
359 | +++ b/lib/lp/scripts/utilities/importpedant.py | |||
360 | @@ -7,7 +7,6 @@ from operator import attrgetter | |||
361 | 7 | import types | 7 | import types |
362 | 8 | import warnings | 8 | import warnings |
363 | 9 | 9 | ||
364 | 10 | import six | ||
365 | 11 | from six.moves import builtins | 10 | from six.moves import builtins |
366 | 12 | 11 | ||
367 | 13 | 12 | ||
368 | @@ -174,8 +173,7 @@ class NotFoundPolicyViolation(PedantDisagreesError): | |||
369 | 174 | # The names of the arguments form part of the interface of __import__(...), | 173 | # The names of the arguments form part of the interface of __import__(...), |
370 | 175 | # and must not be changed, as code may choose to invoke __import__ using | 174 | # and must not be changed, as code may choose to invoke __import__ using |
371 | 176 | # keyword arguments - e.g. the encodings module in Python 2.6. | 175 | # keyword arguments - e.g. the encodings module in Python 2.6. |
374 | 177 | def import_pedant(name, globals={}, locals={}, fromlist=[], | 176 | def import_pedant(name, globals={}, locals={}, fromlist=[], level=0): |
373 | 178 | level=(0 if six.PY3 else -1)): | ||
375 | 179 | global naughty_imports | 177 | global naughty_imports |
376 | 180 | 178 | ||
377 | 181 | module = original_import(name, globals, locals, fromlist, level) | 179 | module = original_import(name, globals, locals, fromlist, level) |
378 | diff --git a/lib/lp/scripts/utilities/test.py b/lib/lp/scripts/utilities/test.py | |||
379 | index 375d70c..00795c2 100755 | |||
380 | --- a/lib/lp/scripts/utilities/test.py | |||
381 | +++ b/lib/lp/scripts/utilities/test.py | |||
382 | @@ -91,7 +91,7 @@ def configure_environment(): | |||
383 | 91 | # Suppress accessibility warning because the test runner does not have UI. | 91 | # Suppress accessibility warning because the test runner does not have UI. |
384 | 92 | os.environ['GTK_MODULES'] = '' | 92 | os.environ['GTK_MODULES'] = '' |
385 | 93 | 93 | ||
387 | 94 | if six.PY3 and distro.linux_distribution()[:2] == ('Ubuntu', '18.04'): | 94 | if distro.linux_distribution()[:2] == ('Ubuntu', '18.04'): |
388 | 95 | # XXX cjwatson 2020-10-09: Certain versions of Python crash when | 95 | # XXX cjwatson 2020-10-09: Certain versions of Python crash when |
389 | 96 | # importing readline into a process that has libedit loaded | 96 | # importing readline into a process that has libedit loaded |
390 | 97 | # (https://bugs.python.org/issue38634, | 97 | # (https://bugs.python.org/issue38634, |
391 | diff --git a/lib/lp/services/compat.py b/lib/lp/services/compat.py | |||
392 | index 4d8ee9d..3673a45 100644 | |||
393 | --- a/lib/lp/services/compat.py | |||
394 | +++ b/lib/lp/services/compat.py | |||
395 | @@ -32,19 +32,13 @@ try: | |||
396 | 32 | except ImportError: | 32 | except ImportError: |
397 | 33 | from unittest import mock | 33 | from unittest import mock |
398 | 34 | 34 | ||
415 | 35 | import six | 35 | |
416 | 36 | 36 | def message_as_bytes(message): | |
417 | 37 | 37 | from email.generator import BytesGenerator | |
418 | 38 | if six.PY3: | 38 | from email.policy import compat32 |
419 | 39 | def message_as_bytes(message): | 39 | |
420 | 40 | from email.generator import BytesGenerator | 40 | fp = io.BytesIO() |
421 | 41 | from email.policy import compat32 | 41 | g = BytesGenerator( |
422 | 42 | 42 | fp, mangle_from_=False, maxheaderlen=0, policy=compat32) | |
423 | 43 | fp = io.BytesIO() | 43 | g.flatten(message) |
424 | 44 | g = BytesGenerator( | 44 | return fp.getvalue() |
409 | 45 | fp, mangle_from_=False, maxheaderlen=0, policy=compat32) | ||
410 | 46 | g.flatten(message) | ||
411 | 47 | return fp.getvalue() | ||
412 | 48 | else: | ||
413 | 49 | def message_as_bytes(message): | ||
414 | 50 | return message.as_string() | ||
425 | diff --git a/lib/lp/services/encoding.py b/lib/lp/services/encoding.py | |||
426 | index 3c1728b..aa5f74e 100644 | |||
427 | --- a/lib/lp/services/encoding.py | |||
428 | +++ b/lib/lp/services/encoding.py | |||
429 | @@ -228,7 +228,7 @@ def wsgi_native_string(s): | |||
430 | 228 | Python 2, we enforce this here. | 228 | Python 2, we enforce this here. |
431 | 229 | """ | 229 | """ |
432 | 230 | result = six.ensure_str(s, encoding='ISO-8859-1') | 230 | result = six.ensure_str(s, encoding='ISO-8859-1') |
434 | 231 | if six.PY3 and isinstance(s, six.text_type): | 231 | if isinstance(s, six.text_type): |
435 | 232 | # Ensure we're limited to ISO-8859-1. | 232 | # Ensure we're limited to ISO-8859-1. |
436 | 233 | result.encode('ISO-8859-1') | 233 | result.encode('ISO-8859-1') |
437 | 234 | return result | 234 | return result |
438 | diff --git a/lib/lp/services/limitedlist.py b/lib/lp/services/limitedlist.py | |||
439 | index 9c9ca8b..1cb0db5 100644 | |||
440 | --- a/lib/lp/services/limitedlist.py | |||
441 | +++ b/lib/lp/services/limitedlist.py | |||
442 | @@ -6,8 +6,6 @@ __all__ = [ | |||
443 | 6 | 'LimitedList', | 6 | 'LimitedList', |
444 | 7 | ] | 7 | ] |
445 | 8 | 8 | ||
446 | 9 | import sys | ||
447 | 10 | |||
448 | 11 | 9 | ||
449 | 12 | class LimitedList(list): | 10 | class LimitedList(list): |
450 | 13 | """A mutable sequence that takes a limited number of elements.""" | 11 | """A mutable sequence that takes a limited number of elements.""" |
451 | @@ -64,15 +62,6 @@ class LimitedList(list): | |||
452 | 64 | self._ensureLength() | 62 | self._ensureLength() |
453 | 65 | return result | 63 | return result |
454 | 66 | 64 | ||
455 | 67 | if sys.version_info[0] < 3: | ||
456 | 68 | # list.__setslice__ exists on Python 2, so we must override it in | ||
457 | 69 | # this subclass. (If it didn't exist, as is the case on Python 3, | ||
458 | 70 | # then __setitem__ above would be good enough.) | ||
459 | 71 | def __setslice__(self, i, j, sequence): | ||
460 | 72 | result = super(LimitedList, self).__setslice__(i, j, sequence) | ||
461 | 73 | self._ensureLength() | ||
462 | 74 | return result | ||
463 | 75 | |||
464 | 76 | def append(self, value): | 65 | def append(self, value): |
465 | 77 | result = super(LimitedList, self).append(value) | 66 | result = super(LimitedList, self).append(value) |
466 | 78 | self._ensureLength() | 67 | self._ensureLength() |
467 | diff --git a/lib/lp/services/mail/interfaces.py b/lib/lp/services/mail/interfaces.py | |||
468 | index 41818a4..59fdfec 100644 | |||
469 | --- a/lib/lp/services/mail/interfaces.py | |||
470 | +++ b/lib/lp/services/mail/interfaces.py | |||
471 | @@ -19,7 +19,6 @@ __all__ = [ | |||
472 | 19 | 'UnknownRecipientError', | 19 | 'UnknownRecipientError', |
473 | 20 | ] | 20 | ] |
474 | 21 | 21 | ||
475 | 22 | import six | ||
476 | 23 | from zope.interface import ( | 22 | from zope.interface import ( |
477 | 24 | Attribute, | 23 | Attribute, |
478 | 25 | Interface, | 24 | Interface, |
479 | @@ -156,9 +155,6 @@ class INotificationRecipientSet(Interface): | |||
480 | 156 | def __bool__(): | 155 | def __bool__(): |
481 | 157 | """Return False when the set is empty, True when it's not.""" | 156 | """Return False when the set is empty, True when it's not.""" |
482 | 158 | 157 | ||
483 | 159 | if six.PY2: | ||
484 | 160 | __nonzero__ = __bool__ | ||
485 | 161 | |||
486 | 162 | def getReason(person_or_email): | 158 | def getReason(person_or_email): |
487 | 163 | """Return a reason tuple containing (text, header) for an address. | 159 | """Return a reason tuple containing (text, header) for an address. |
488 | 164 | 160 | ||
489 | diff --git a/lib/lp/services/mail/notificationrecipientset.py b/lib/lp/services/mail/notificationrecipientset.py | |||
490 | index 6004399..68f9014 100644 | |||
491 | --- a/lib/lp/services/mail/notificationrecipientset.py | |||
492 | +++ b/lib/lp/services/mail/notificationrecipientset.py | |||
493 | @@ -88,9 +88,6 @@ class NotificationRecipientSet: | |||
494 | 88 | """See `INotificationRecipientSet`.""" | 88 | """See `INotificationRecipientSet`.""" |
495 | 89 | return bool(self._personToRationale) | 89 | return bool(self._personToRationale) |
496 | 90 | 90 | ||
497 | 91 | if six.PY2: | ||
498 | 92 | __nonzero__ = __bool__ | ||
499 | 93 | |||
500 | 94 | def getReason(self, person_or_email): | 91 | def getReason(self, person_or_email): |
501 | 95 | """See `INotificationRecipientSet`.""" | 92 | """See `INotificationRecipientSet`.""" |
502 | 96 | if zope_isinstance(person_or_email, six.string_types): | 93 | if zope_isinstance(person_or_email, six.string_types): |
503 | diff --git a/lib/lp/services/scripts/base.py b/lib/lp/services/scripts/base.py | |||
504 | index cd3f19b..989eab6 100644 | |||
505 | --- a/lib/lp/services/scripts/base.py | |||
506 | +++ b/lib/lp/services/scripts/base.py | |||
507 | @@ -468,11 +468,7 @@ def cronscript_enabled(control_url, name, log): | |||
508 | 468 | # traceback and continue on using the defaults. | 468 | # traceback and continue on using the defaults. |
509 | 469 | try: | 469 | try: |
510 | 470 | with response: | 470 | with response: |
516 | 471 | if sys.version_info[:2] >= (3, 2): | 471 | cron_config.read_file(io.StringIO(response.text)) |
512 | 472 | read_file = cron_config.read_file | ||
513 | 473 | else: | ||
514 | 474 | read_file = cron_config.readfp | ||
515 | 475 | read_file(io.StringIO(response.text)) | ||
517 | 476 | except Exception: | 472 | except Exception: |
518 | 477 | log.exception("Error parsing %s", control_url) | 473 | log.exception("Error parsing %s", control_url) |
519 | 478 | 474 | ||
520 | diff --git a/lib/lp/services/tests/test_encoding.py b/lib/lp/services/tests/test_encoding.py | |||
521 | index 4a0e235..ed44acc 100644 | |||
522 | --- a/lib/lp/services/tests/test_encoding.py | |||
523 | +++ b/lib/lp/services/tests/test_encoding.py | |||
524 | @@ -7,8 +7,6 @@ from doctest import ( | |||
525 | 7 | ) | 7 | ) |
526 | 8 | import unittest | 8 | import unittest |
527 | 9 | 9 | ||
528 | 10 | import six | ||
529 | 11 | |||
530 | 12 | import lp.services.encoding | 10 | import lp.services.encoding |
531 | 13 | from lp.services.encoding import wsgi_native_string | 11 | from lp.services.encoding import wsgi_native_string |
532 | 14 | from lp.testing import TestCase | 12 | from lp.testing import TestCase |
533 | @@ -16,22 +14,14 @@ from lp.testing import TestCase | |||
534 | 16 | 14 | ||
535 | 17 | class TestWSGINativeString(TestCase): | 15 | class TestWSGINativeString(TestCase): |
536 | 18 | 16 | ||
537 | 19 | def _toNative(self, s): | ||
538 | 20 | if six.PY3: | ||
539 | 21 | return s | ||
540 | 22 | else: | ||
541 | 23 | return s.encode('ISO-8859-1') | ||
542 | 24 | |||
543 | 25 | def test_not_bytes_or_unicode(self): | 17 | def test_not_bytes_or_unicode(self): |
544 | 26 | self.assertRaises(TypeError, wsgi_native_string, object()) | 18 | self.assertRaises(TypeError, wsgi_native_string, object()) |
545 | 27 | 19 | ||
546 | 28 | def test_bytes_iso_8859_1(self): | 20 | def test_bytes_iso_8859_1(self): |
549 | 29 | self.assertEqual( | 21 | self.assertEqual(u'foo\xfe', wsgi_native_string(b'foo\xfe')) |
548 | 30 | self._toNative(u'foo\xfe'), wsgi_native_string(b'foo\xfe')) | ||
550 | 31 | 22 | ||
551 | 32 | def test_unicode_iso_8859_1(self): | 23 | def test_unicode_iso_8859_1(self): |
554 | 33 | self.assertEqual( | 24 | self.assertEqual(u'foo\xfe', wsgi_native_string(u'foo\xfe')) |
553 | 34 | self._toNative(u'foo\xfe'), wsgi_native_string(u'foo\xfe')) | ||
555 | 35 | 25 | ||
556 | 36 | def test_unicode_not_iso_8859_1(self): | 26 | def test_unicode_not_iso_8859_1(self): |
557 | 37 | self.assertRaises(UnicodeEncodeError, wsgi_native_string, u'foo\u2014') | 27 | self.assertRaises(UnicodeEncodeError, wsgi_native_string, u'foo\u2014') |
558 | diff --git a/lib/lp/services/twistedsupport/tests/test_xmlrpc.py b/lib/lp/services/twistedsupport/tests/test_xmlrpc.py | |||
559 | index 126d275..59e45fc 100644 | |||
560 | --- a/lib/lp/services/twistedsupport/tests/test_xmlrpc.py | |||
561 | +++ b/lib/lp/services/twistedsupport/tests/test_xmlrpc.py | |||
562 | @@ -5,12 +5,6 @@ | |||
563 | 5 | 5 | ||
564 | 6 | __metaclass__ = type | 6 | __metaclass__ = type |
565 | 7 | 7 | ||
566 | 8 | import sys | ||
567 | 9 | |||
568 | 10 | from testtools.matchers import ( | ||
569 | 11 | LessThan, | ||
570 | 12 | Not, | ||
571 | 13 | ) | ||
572 | 14 | from twisted.python.failure import Failure | 8 | from twisted.python.failure import Failure |
573 | 15 | 9 | ||
574 | 16 | from lp.services.twistedsupport import extract_result | 10 | from lp.services.twistedsupport import extract_result |
575 | @@ -58,11 +52,7 @@ class TestTrapFault(TestCase): | |||
576 | 58 | def assertRaisesFailure(self, failure, function, *args, **kwargs): | 52 | def assertRaisesFailure(self, failure, function, *args, **kwargs): |
577 | 59 | try: | 53 | try: |
578 | 60 | function(*args, **kwargs) | 54 | function(*args, **kwargs) |
579 | 61 | except Failure as raised_failure: | ||
580 | 62 | self.assertThat(sys.version_info, LessThan((3, 0))) | ||
581 | 63 | self.assertEqual(failure, raised_failure) | ||
582 | 64 | except Exception as raised_exception: | 55 | except Exception as raised_exception: |
583 | 65 | self.assertThat(sys.version_info, Not(LessThan((3, 0)))) | ||
584 | 66 | self.assertEqual(failure.value, raised_exception) | 56 | self.assertEqual(failure.value, raised_exception) |
585 | 67 | 57 | ||
586 | 68 | def test_raises_non_faults(self): | 58 | def test_raises_non_faults(self): |
587 | diff --git a/lib/lp/services/twistedsupport/xmlrpc.py b/lib/lp/services/twistedsupport/xmlrpc.py | |||
588 | index 3521641..70f5598 100644 | |||
589 | --- a/lib/lp/services/twistedsupport/xmlrpc.py | |||
590 | +++ b/lib/lp/services/twistedsupport/xmlrpc.py | |||
591 | @@ -10,8 +10,6 @@ __all__ = [ | |||
592 | 10 | 'trap_fault', | 10 | 'trap_fault', |
593 | 11 | ] | 11 | ] |
594 | 12 | 12 | ||
595 | 13 | import sys | ||
596 | 14 | |||
597 | 15 | from twisted.internet import defer | 13 | from twisted.internet import defer |
598 | 16 | from twisted.web import xmlrpc | 14 | from twisted.web import xmlrpc |
599 | 17 | 15 | ||
600 | @@ -68,7 +66,4 @@ def trap_fault(failure, *fault_classes): | |||
601 | 68 | fault = failure.value | 66 | fault = failure.value |
602 | 69 | if fault.faultCode in [cls.error_code for cls in fault_classes]: | 67 | if fault.faultCode in [cls.error_code for cls in fault_classes]: |
603 | 70 | return fault | 68 | return fault |
608 | 71 | if sys.version_info >= (3, 0): | 69 | failure.raiseException() |
605 | 72 | failure.raiseException() | ||
606 | 73 | else: | ||
607 | 74 | raise failure | ||
609 | diff --git a/lib/lp/services/webapp/pgsession.py b/lib/lp/services/webapp/pgsession.py | |||
610 | index 0a5c664..de05da4 100644 | |||
611 | --- a/lib/lp/services/webapp/pgsession.py | |||
612 | +++ b/lib/lp/services/webapp/pgsession.py | |||
613 | @@ -32,33 +32,30 @@ HOURS = 60 * MINUTES | |||
614 | 32 | DAYS = 24 * HOURS | 32 | DAYS = 24 * HOURS |
615 | 33 | 33 | ||
616 | 34 | 34 | ||
628 | 35 | if six.PY3: | 35 | class Python2FriendlyUnpickler(pickle._Unpickler): |
629 | 36 | class Python2FriendlyUnpickler(pickle._Unpickler): | 36 | """An unpickler that handles Python 2 datetime objects. |
630 | 37 | """An unpickler that handles Python 2 datetime objects. | 37 | |
631 | 38 | 38 | Python 3 versions before 3.6 fail to unpickle Python 2 datetime objects | |
632 | 39 | Python 3 versions before 3.6 fail to unpickle Python 2 datetime | 39 | (https://bugs.python.org/issue22005); even in Python >= 3.6 they require |
633 | 40 | objects (https://bugs.python.org/issue22005); even in Python >= 3.6 | 40 | passing a different encoding to pickle.loads, which may have undesirable |
634 | 41 | they require passing a different encoding to pickle.loads, which may | 41 | effects on other objects being unpickled. Work around this by instead |
635 | 42 | have undesirable effects on other objects being unpickled. Work | 42 | patching in a different encoding just for the argument to |
636 | 43 | around this by instead patching in a different encoding just for the | 43 | datetime.datetime. |
637 | 44 | argument to datetime.datetime. | 44 | """ |
627 | 45 | """ | ||
638 | 46 | 45 | ||
643 | 47 | def find_class(self, module, name): | 46 | def find_class(self, module, name): |
644 | 48 | if module == 'datetime' and name == 'datetime': | 47 | if module == 'datetime' and name == 'datetime': |
645 | 49 | original_encoding = self.encoding | 48 | original_encoding = self.encoding |
646 | 50 | self.encoding = 'bytes' | 49 | self.encoding = 'bytes' |
647 | 51 | 50 | ||
651 | 52 | def datetime_factory(pickle_data): | 51 | def datetime_factory(pickle_data): |
652 | 53 | self.encoding = original_encoding | 52 | self.encoding = original_encoding |
653 | 54 | return datetime(pickle_data) | 53 | return datetime(pickle_data) |
654 | 55 | 54 | ||
661 | 56 | return datetime_factory | 55 | return datetime_factory |
662 | 57 | else: | 56 | else: |
663 | 58 | return super(Python2FriendlyUnpickler, self).find_class( | 57 | return super(Python2FriendlyUnpickler, self).find_class( |
664 | 59 | module, name) | 58 | module, name) |
659 | 60 | else: | ||
660 | 61 | Python2FriendlyUnpickler = pickle.Unpickler | ||
665 | 62 | 59 | ||
666 | 63 | 60 | ||
667 | 64 | class PGSessionBase: | 61 | class PGSessionBase: |
668 | diff --git a/lib/lp/services/webapp/publisher.py b/lib/lp/services/webapp/publisher.py | |||
669 | index 168b22e..f4d42cd 100644 | |||
670 | --- a/lib/lp/services/webapp/publisher.py | |||
671 | +++ b/lib/lp/services/webapp/publisher.py | |||
672 | @@ -632,11 +632,6 @@ class CanonicalAbsoluteURL: | |||
673 | 632 | self.context = context | 632 | self.context = context |
674 | 633 | self.request = request | 633 | self.request = request |
675 | 634 | 634 | ||
676 | 635 | if six.PY2: | ||
677 | 636 | def __unicode__(self): | ||
678 | 637 | """Returns the URL as a unicode string.""" | ||
679 | 638 | raise NotImplementedError() | ||
680 | 639 | |||
681 | 640 | def __str__(self): | 635 | def __str__(self): |
682 | 641 | """Returns an ASCII string with all unicode characters url quoted.""" | 636 | """Returns an ASCII string with all unicode characters url quoted.""" |
683 | 642 | return canonical_url(self.context, self.request) | 637 | return canonical_url(self.context, self.request) |
684 | diff --git a/lib/lp/services/webapp/servers.py b/lib/lp/services/webapp/servers.py | |||
685 | index d637916..a2ef356 100644 | |||
686 | --- a/lib/lp/services/webapp/servers.py | |||
687 | +++ b/lib/lp/services/webapp/servers.py | |||
688 | @@ -211,9 +211,6 @@ class StepsToGo(six.Iterator): | |||
689 | 211 | def __bool__(self): | 211 | def __bool__(self): |
690 | 212 | return bool(self._stack) | 212 | return bool(self._stack) |
691 | 213 | 213 | ||
692 | 214 | if six.PY2: | ||
693 | 215 | __nonzero__ = __bool__ | ||
694 | 216 | |||
695 | 217 | 214 | ||
696 | 218 | class ApplicationServerSettingRequestFactory: | 215 | class ApplicationServerSettingRequestFactory: |
697 | 219 | """Create a request and call its setApplicationServer method. | 216 | """Create a request and call its setApplicationServer method. |
698 | @@ -527,20 +524,9 @@ def get_query_string_params(request): | |||
699 | 527 | if query_string is None: | 524 | if query_string is None: |
700 | 528 | query_string = '' | 525 | query_string = '' |
701 | 529 | 526 | ||
716 | 530 | kwargs = {} | 527 | return parse_qs( |
717 | 531 | if not six.PY2: | 528 | query_string, keep_blank_values=True, |
718 | 532 | kwargs['encoding'] = 'UTF-8' | 529 | encoding='UTF-8', errors='replace') |
705 | 533 | kwargs['errors'] = 'replace' | ||
706 | 534 | parsed_qs = parse_qs(query_string, keep_blank_values=True, **kwargs) | ||
707 | 535 | if six.PY2: | ||
708 | 536 | decoded_qs = {} | ||
709 | 537 | for key, values in six.iteritems(parsed_qs): | ||
710 | 538 | decoded_qs[key] = [ | ||
711 | 539 | (value.decode('UTF-8', 'replace') if isinstance(value, bytes) | ||
712 | 540 | else value) | ||
713 | 541 | for value in values] | ||
714 | 542 | parsed_qs = decoded_qs | ||
715 | 543 | return parsed_qs | ||
719 | 544 | 530 | ||
720 | 545 | 531 | ||
721 | 546 | class LaunchpadBrowserRequestMixin: | 532 | class LaunchpadBrowserRequestMixin: |
722 | diff --git a/lib/lp/services/webapp/tests/test_servers.py b/lib/lp/services/webapp/tests/test_servers.py | |||
723 | index ed66bfa..1b09775 100644 | |||
724 | --- a/lib/lp/services/webapp/tests/test_servers.py | |||
725 | +++ b/lib/lp/services/webapp/tests/test_servers.py | |||
726 | @@ -21,7 +21,6 @@ from lazr.restful.testing.webservice import ( | |||
727 | 21 | IGenericEntry, | 21 | IGenericEntry, |
728 | 22 | WebServiceTestCase, | 22 | WebServiceTestCase, |
729 | 23 | ) | 23 | ) |
730 | 24 | import six | ||
731 | 25 | from talisker.context import Context | 24 | from talisker.context import Context |
732 | 26 | from talisker.logs import logging_context | 25 | from talisker.logs import logging_context |
733 | 27 | from zope.component import ( | 26 | from zope.component import ( |
734 | @@ -441,15 +440,12 @@ class TestBasicLaunchpadRequest(TestCase): | |||
735 | 441 | def test_request_with_invalid_query_string_recovers(self): | 440 | def test_request_with_invalid_query_string_recovers(self): |
736 | 442 | # When the query string has invalid utf-8, it is decoded with | 441 | # When the query string has invalid utf-8, it is decoded with |
737 | 443 | # replacement. | 442 | # replacement. |
747 | 444 | if six.PY2: | 443 | # PEP 3333 requires environment variables to be native strings, so |
748 | 445 | env = {'QUERY_STRING': 'field.title=subproc\xe9s '} | 444 | # we can't actually get a bytes object in here on Python 3 (both |
749 | 446 | else: | 445 | # because the WSGI runner will never put it there, and because |
750 | 447 | # PEP 3333 requires environment variables to be native strings, | 446 | # parse_qs would crash if we did). Test the next best thing, namely |
751 | 448 | # so we can't actually get a bytes object in here on Python 3 | 447 | # percent-encoded invalid UTF-8. |
752 | 449 | # (both because the WSGI runner will never put it there, and | 448 | env = {'QUERY_STRING': 'field.title=subproc%E9s '} |
744 | 450 | # because parse_qs would crash if we did). Test the next best | ||
745 | 451 | # thing, namely percent-encoded invalid UTF-8. | ||
746 | 452 | env = {'QUERY_STRING': 'field.title=subproc%E9s '} | ||
753 | 453 | request = LaunchpadBrowserRequest(io.BytesIO(b''), env) | 449 | request = LaunchpadBrowserRequest(io.BytesIO(b''), env) |
754 | 454 | self.assertEqual( | 450 | self.assertEqual( |
755 | 455 | [u'subproc\ufffds '], request.query_string_params['field.title']) | 451 | [u'subproc\ufffds '], request.query_string_params['field.title']) |
756 | diff --git a/lib/lp/services/webapp/url.py b/lib/lp/services/webapp/url.py | |||
757 | index e438fd9..3a05c33 100644 | |||
758 | --- a/lib/lp/services/webapp/url.py | |||
759 | +++ b/lib/lp/services/webapp/url.py | |||
760 | @@ -6,7 +6,6 @@ | |||
761 | 6 | __metaclass__ = type | 6 | __metaclass__ = type |
762 | 7 | __all__ = ['urlappend', 'urlparse', 'urlsplit'] | 7 | __all__ = ['urlappend', 'urlparse', 'urlsplit'] |
763 | 8 | 8 | ||
764 | 9 | import six | ||
765 | 10 | import six.moves.urllib.parse as urlparse_module | 9 | import six.moves.urllib.parse as urlparse_module |
766 | 11 | from six.moves.urllib.parse import ( | 10 | from six.moves.urllib.parse import ( |
767 | 12 | urljoin, | 11 | urljoin, |
768 | @@ -81,9 +80,7 @@ def urlappend(baseurl, path): | |||
769 | 81 | 80 | ||
770 | 82 | def _ensure_ascii_str(url): | 81 | def _ensure_ascii_str(url): |
771 | 83 | """Ensure that `url` only contains ASCII, and convert it to a `str`.""" | 82 | """Ensure that `url` only contains ASCII, and convert it to a `str`.""" |
775 | 84 | if six.PY2: | 83 | if isinstance(url, bytes): |
773 | 85 | url = url.encode('ascii') | ||
774 | 86 | elif isinstance(url, bytes): | ||
776 | 87 | url = url.decode('ascii') | 84 | url = url.decode('ascii') |
777 | 88 | else: | 85 | else: |
778 | 89 | # Ignore the result; just check that `url` is pure ASCII. | 86 | # Ignore the result; just check that `url` is pure ASCII. |
779 | diff --git a/lib/lp/services/webhooks/payload.py b/lib/lp/services/webhooks/payload.py | |||
780 | index f7c7e3d..d73cd1b 100644 | |||
781 | --- a/lib/lp/services/webhooks/payload.py | |||
782 | +++ b/lib/lp/services/webhooks/payload.py | |||
783 | @@ -12,7 +12,6 @@ __all__ = [ | |||
784 | 12 | from io import BytesIO | 12 | from io import BytesIO |
785 | 13 | 13 | ||
786 | 14 | from lazr.restful.interfaces import IFieldMarshaller | 14 | from lazr.restful.interfaces import IFieldMarshaller |
787 | 15 | import six | ||
788 | 16 | from zope.component import getMultiAdapter | 15 | from zope.component import getMultiAdapter |
789 | 17 | from zope.interface import implementer | 16 | from zope.interface import implementer |
790 | 18 | from zope.traversing.browser.interfaces import IAbsoluteURL | 17 | from zope.traversing.browser.interfaces import IAbsoluteURL |
791 | @@ -43,11 +42,6 @@ class WebhookAbsoluteURL: | |||
792 | 43 | self.context = context | 42 | self.context = context |
793 | 44 | self.request = request | 43 | self.request = request |
794 | 45 | 44 | ||
795 | 46 | if six.PY2: | ||
796 | 47 | def __unicode__(self): | ||
797 | 48 | """Returns the URL as a unicode string.""" | ||
798 | 49 | raise NotImplementedError() | ||
799 | 50 | |||
800 | 51 | def __str__(self): | 45 | def __str__(self): |
801 | 52 | """Returns an ASCII string with all unicode characters url quoted.""" | 46 | """Returns an ASCII string with all unicode characters url quoted.""" |
802 | 53 | return canonical_url(self.context, force_local_path=True) | 47 | return canonical_url(self.context, force_local_path=True) |
803 | diff --git a/lib/lp/soyuz/adapters/archivesourcepublication.py b/lib/lp/soyuz/adapters/archivesourcepublication.py | |||
804 | index 34e4919..f04807d 100644 | |||
805 | --- a/lib/lp/soyuz/adapters/archivesourcepublication.py | |||
806 | +++ b/lib/lp/soyuz/adapters/archivesourcepublication.py | |||
807 | @@ -17,7 +17,6 @@ __all__ = [ | |||
808 | 17 | from collections import defaultdict | 17 | from collections import defaultdict |
809 | 18 | 18 | ||
810 | 19 | from lazr.delegates import delegate_to | 19 | from lazr.delegates import delegate_to |
811 | 20 | import six | ||
812 | 21 | from zope.component import getUtility | 20 | from zope.component import getUtility |
813 | 22 | 21 | ||
814 | 23 | from lp.registry.model.distroseries import DistroSeries | 22 | from lp.registry.model.distroseries import DistroSeries |
815 | @@ -104,9 +103,6 @@ class ArchiveSourcePublications: | |||
816 | 104 | """Are there any sources to iterate?""" | 103 | """Are there any sources to iterate?""" |
817 | 105 | return self.has_sources | 104 | return self.has_sources |
818 | 106 | 105 | ||
819 | 107 | if six.PY2: | ||
820 | 108 | __nonzero__ = __bool__ | ||
821 | 109 | |||
822 | 110 | def __iter__(self): | 106 | def __iter__(self): |
823 | 111 | """`ArchiveSourcePublication` iterator.""" | 107 | """`ArchiveSourcePublication` iterator.""" |
824 | 112 | results = [] | 108 | results = [] |
825 | diff --git a/lib/lp/soyuz/interfaces/binarypackagename.py b/lib/lp/soyuz/interfaces/binarypackagename.py | |||
826 | index bfef027..69973c6 100644 | |||
827 | --- a/lib/lp/soyuz/interfaces/binarypackagename.py | |||
828 | +++ b/lib/lp/soyuz/interfaces/binarypackagename.py | |||
829 | @@ -11,7 +11,6 @@ __all__ = [ | |||
830 | 11 | 'IBinaryPackageNameSet', | 11 | 'IBinaryPackageNameSet', |
831 | 12 | ] | 12 | ] |
832 | 13 | 13 | ||
833 | 14 | import six | ||
834 | 15 | from zope.interface import Interface | 14 | from zope.interface import Interface |
835 | 16 | from zope.schema import ( | 15 | from zope.schema import ( |
836 | 17 | Int, | 16 | Int, |
837 | @@ -31,10 +30,6 @@ class IBinaryPackageName(Interface): | |||
838 | 31 | def __str__(): | 30 | def __str__(): |
839 | 32 | """Return the name""" | 31 | """Return the name""" |
840 | 33 | 32 | ||
841 | 34 | if six.PY2: | ||
842 | 35 | def __unicode__(): | ||
843 | 36 | """Return the name""" | ||
844 | 37 | |||
845 | 38 | 33 | ||
846 | 39 | class IBinaryPackageNameSet(Interface): | 34 | class IBinaryPackageNameSet(Interface): |
847 | 40 | 35 | ||
848 | diff --git a/lib/lp/testing/factory.py b/lib/lp/testing/factory.py | |||
849 | index 32c9923..084cee1 100644 | |||
850 | --- a/lib/lp/testing/factory.py | |||
851 | +++ b/lib/lp/testing/factory.py | |||
852 | @@ -38,7 +38,6 @@ from itertools import count | |||
853 | 38 | import os | 38 | import os |
854 | 39 | import sys | 39 | import sys |
855 | 40 | from textwrap import dedent | 40 | from textwrap import dedent |
856 | 41 | import types | ||
857 | 42 | import uuid | 41 | import uuid |
858 | 43 | import warnings | 42 | import warnings |
859 | 44 | 43 | ||
860 | @@ -5210,7 +5209,7 @@ class BareLaunchpadObjectFactory(ObjectFactory): | |||
861 | 5210 | # Some factory methods return simple Python types. We don't add | 5209 | # Some factory methods return simple Python types. We don't add |
862 | 5211 | # security wrappers for them, as well as for objects created by | 5210 | # security wrappers for them, as well as for objects created by |
863 | 5212 | # other Python libraries. | 5211 | # other Python libraries. |
865 | 5213 | unwrapped_types = { | 5212 | unwrapped_types = frozenset({ |
866 | 5214 | BaseRecipeBranch, | 5213 | BaseRecipeBranch, |
867 | 5215 | DSCFile, | 5214 | DSCFile, |
868 | 5216 | Message, | 5215 | Message, |
869 | @@ -5218,10 +5217,7 @@ unwrapped_types = { | |||
870 | 5218 | int, | 5217 | int, |
871 | 5219 | str, | 5218 | str, |
872 | 5220 | six.text_type, | 5219 | six.text_type, |
877 | 5221 | } | 5220 | }) |
874 | 5222 | if sys.version_info[0] < 3: | ||
875 | 5223 | unwrapped_types.add(types.InstanceType) | ||
876 | 5224 | unwrapped_types = frozenset(unwrapped_types) | ||
878 | 5225 | 5221 | ||
879 | 5226 | 5222 | ||
880 | 5227 | def is_security_proxied_or_harmless(obj): | 5223 | def is_security_proxied_or_harmless(obj): |
881 | diff --git a/lib/lp/testing/systemdocs.py b/lib/lp/testing/systemdocs.py | |||
882 | index 5e9bdac..29bb200 100644 | |||
883 | --- a/lib/lp/testing/systemdocs.py | |||
884 | +++ b/lib/lp/testing/systemdocs.py | |||
885 | @@ -232,19 +232,16 @@ class PrettyPrinter(pprint.PrettyPrinter, object): | |||
886 | 232 | return '"%s"' % obj, True, False | 232 | return '"%s"' % obj, True, False |
887 | 233 | else: | 233 | else: |
888 | 234 | return "'%s'" % obj.replace("'", "\\'"), True, False | 234 | return "'%s'" % obj.replace("'", "\\'"), True, False |
889 | 235 | elif sys.version_info[0] < 3 and isinstance(obj, long): | ||
890 | 236 | return repr(int(obj)), True, False | ||
891 | 237 | else: | 235 | else: |
892 | 238 | return super(PrettyPrinter, self).format( | 236 | return super(PrettyPrinter, self).format( |
893 | 239 | obj, contexts, maxlevels, level) | 237 | obj, contexts, maxlevels, level) |
894 | 240 | 238 | ||
895 | 241 | # Disable wrapping of long strings on Python >= 3.5, which is unhelpful | 239 | # Disable wrapping of long strings on Python >= 3.5, which is unhelpful |
896 | 242 | # in doctests. There seems to be no reasonable public API for this. | 240 | # in doctests. There seems to be no reasonable public API for this. |
902 | 243 | if sys.version_info[:2] >= (3, 5): | 241 | _dispatch = dict(pprint.PrettyPrinter._dispatch) |
903 | 244 | _dispatch = dict(pprint.PrettyPrinter._dispatch) | 242 | del _dispatch[six.text_type.__repr__] |
904 | 245 | del _dispatch[six.text_type.__repr__] | 243 | del _dispatch[bytes.__repr__] |
905 | 246 | del _dispatch[bytes.__repr__] | 244 | del _dispatch[bytearray.__repr__] |
901 | 247 | del _dispatch[bytearray.__repr__] | ||
906 | 248 | 245 | ||
907 | 249 | 246 | ||
908 | 250 | # XXX cjwatson 2018-05-13: Once all doctests are made safe for the standard | 247 | # XXX cjwatson 2018-05-13: Once all doctests are made safe for the standard |
909 | diff --git a/lib/lp/translations/doc/poexport-queue.txt b/lib/lp/translations/doc/poexport-queue.txt | |||
910 | index 7854639..562eb08 100644 | |||
911 | --- a/lib/lp/translations/doc/poexport-queue.txt | |||
912 | +++ b/lib/lp/translations/doc/poexport-queue.txt | |||
913 | @@ -139,14 +139,12 @@ It's not clear that it's possible to trigger this failure mode normally on | |||
914 | 139 | Python 3 at all, because bytes will just be formatted as b'...'. For now, | 139 | Python 3 at all, because bytes will just be formatted as b'...'. For now, |
915 | 140 | inject a mock exception in that case so that the test can pass. | 140 | inject a mock exception in that case so that the test can pass. |
916 | 141 | 141 | ||
922 | 142 | >>> if six.PY3: | 142 | >>> from lp.services.compat import mock |
923 | 143 | ... from lp.services.compat import mock | 143 | >>> patcher = mock.patch.object(result, 'failure') |
924 | 144 | ... patcher = mock.patch.object(result, 'failure') | 144 | >>> mock_failure = patcher.start() |
925 | 145 | ... mock_failure = patcher.start() | 145 | >>> mock_failure.__str__.side_effect = lambda: b'\xc3'.decode('UTF-8') |
921 | 146 | ... mock_failure.__str__.side_effect = lambda: b'\xc3'.decode('UTF-8') | ||
926 | 147 | >>> result.notify() | 146 | >>> result.notify() |
929 | 148 | >>> if six.PY3: | 147 | >>> patcher.stop() |
928 | 149 | ... patcher.stop() | ||
930 | 150 | 148 | ||
931 | 151 | >>> test_emails = pop_notifications() | 149 | >>> test_emails = pop_notifications() |
932 | 152 | >>> len(test_emails) | 150 | >>> len(test_emails) |
933 | diff --git a/lib/lp/translations/model/translatedlanguage.py b/lib/lp/translations/model/translatedlanguage.py | |||
934 | index e9d120a..7c7606c 100644 | |||
935 | --- a/lib/lp/translations/model/translatedlanguage.py | |||
936 | +++ b/lib/lp/translations/model/translatedlanguage.py | |||
937 | @@ -4,7 +4,6 @@ | |||
938 | 4 | __all__ = ['TranslatedLanguageMixin'] | 4 | __all__ = ['TranslatedLanguageMixin'] |
939 | 5 | 5 | ||
940 | 6 | import pytz | 6 | import pytz |
941 | 7 | import six | ||
942 | 8 | from storm.expr import ( | 7 | from storm.expr import ( |
943 | 9 | Coalesce, | 8 | Coalesce, |
944 | 10 | Desc, | 9 | Desc, |
945 | @@ -75,9 +74,6 @@ class POFilesByPOTemplates(object): | |||
946 | 75 | def __bool__(self): | 74 | def __bool__(self): |
947 | 76 | return bool(self.templates_collection.select(POTemplate).any()) | 75 | return bool(self.templates_collection.select(POTemplate).any()) |
948 | 77 | 76 | ||
949 | 78 | if six.PY2: | ||
950 | 79 | __nonzero__ = __bool__ | ||
951 | 80 | |||
952 | 81 | 77 | ||
953 | 82 | @implementer(ITranslatedLanguage) | 78 | @implementer(ITranslatedLanguage) |
954 | 83 | class TranslatedLanguageMixin(object): | 79 | class TranslatedLanguageMixin(object): |
955 | diff --git a/lib/sqlobject/__init__.py b/lib/sqlobject/__init__.py | |||
956 | index 5450477..bc94046 100644 | |||
957 | --- a/lib/sqlobject/__init__.py | |||
958 | +++ b/lib/sqlobject/__init__.py | |||
959 | @@ -51,8 +51,6 @@ def sqlrepr(value, dbname=None): | |||
960 | 51 | return "'f'" | 51 | return "'f'" |
961 | 52 | elif isinstance(value, int): | 52 | elif isinstance(value, int): |
962 | 53 | return repr(int(value)) | 53 | return repr(int(value)) |
963 | 54 | elif six.PY2 and isinstance(value, long): | ||
964 | 55 | return str(value) | ||
965 | 56 | elif isinstance(value, float): | 54 | elif isinstance(value, float): |
966 | 57 | return repr(value) | 55 | return repr(value) |
967 | 58 | elif value is None: | 56 | elif value is None: |
968 | diff --git a/scripts/process-one-mail.py b/scripts/process-one-mail.py | |||
969 | index 0fa7484..3cb8598 100755 | |||
970 | --- a/scripts/process-one-mail.py | |||
971 | +++ b/scripts/process-one-mail.py | |||
972 | @@ -31,10 +31,8 @@ class ProcessMail(LaunchpadScript): | |||
973 | 31 | # with handling a mailbox, which we're avoiding here. | 31 | # with handling a mailbox, which we're avoiding here. |
974 | 32 | if len(self.args) >= 1: | 32 | if len(self.args) >= 1: |
975 | 33 | from_file = open(self.args[0], 'rb') | 33 | from_file = open(self.args[0], 'rb') |
976 | 34 | elif sys.version_info[0] >= 3: | ||
977 | 35 | from_file = sys.stdin.buffer | ||
978 | 36 | else: | 34 | else: |
980 | 37 | from_file = sys.stdin | 35 | from_file = sys.stdin.buffer |
981 | 38 | self.logger.debug("reading message from %r" % (from_file,)) | 36 | self.logger.debug("reading message from %r" % (from_file,)) |
982 | 39 | raw_mail = from_file.read() | 37 | raw_mail = from_file.read() |
983 | 40 | if from_file != sys.stdin: | 38 | if from_file != sys.stdin: |
Looks good!