Merge ~cjwatson/launchpad:six-dict-iter into launchpad:master
- Git
- lp:~cjwatson/launchpad
- six-dict-iter
- Merge into master
Status: | Merged |
---|---|
Approved by: | Colin Watson |
Approved revision: | 41b7c40b4fb1d1e98de3754b3cd7f38c34eaf8c2 |
Merge reported by: | Otto Co-Pilot |
Merged at revision: | not available |
Proposed branch: | ~cjwatson/launchpad:six-dict-iter |
Merge into: | launchpad:master |
Diff against target: |
2251 lines (+249/-155) 90 files modified
brzplugins/lpserve/__init__.py (+3/-2) brzplugins/lpserve/test_lpserve.py (+4/-3) database/schema/security.py (+10/-8) lib/contrib/oauth.py (+7/-4) lib/lp/app/browser/launchpadform.py (+2/-1) lib/lp/app/browser/tales.py (+3/-2) lib/lp/archivepublisher/domination.py (+3/-2) lib/lp/archivepublisher/model/ftparchive.py (+4/-3) lib/lp/archivepublisher/publishing.py (+2/-1) lib/lp/archivepublisher/scripts/publish_ftpmaster.py (+12/-11) lib/lp/archivepublisher/tests/test_dominator.py (+3/-2) lib/lp/archivepublisher/tests/test_publish_ftpmaster.py (+3/-4) lib/lp/archiveuploader/dscfile.py (+1/-1) lib/lp/archiveuploader/nascentuploadfile.py (+3/-2) lib/lp/archiveuploader/utils.py (+3/-1) lib/lp/bugs/browser/bugalsoaffects.py (+3/-2) lib/lp/bugs/browser/bugtarget.py (+2/-1) lib/lp/bugs/interfaces/bugtaskfilter.py (+3/-1) lib/lp/bugs/model/bugtask.py (+2/-1) lib/lp/bugs/model/structuralsubscription.py (+3/-2) lib/lp/bugs/model/tests/test_bugsubscriptioninfo.py (+3/-2) lib/lp/bugs/scripts/bugsummaryrebuild.py (+7/-5) lib/lp/bugs/scripts/bugtasktargetnamecaches.py (+2/-1) lib/lp/bugs/scripts/bzremotecomponentfinder.py (+2/-1) lib/lp/bugs/tests/externalbugtracker.py (+2/-1) lib/lp/buildmaster/browser/builder.py (+2/-1) lib/lp/buildmaster/manager.py (+2/-1) lib/lp/buildmaster/model/builder.py (+2/-1) lib/lp/buildmaster/queuedepth.py (+2/-1) lib/lp/buildmaster/tests/test_queuedepth.py (+2/-1) lib/lp/code/browser/branch.py (+3/-2) lib/lp/code/browser/branchlisting.py (+3/-2) lib/lp/code/browser/branchmergeproposal.py (+2/-1) lib/lp/code/browser/gitrepository.py (+3/-3) lib/lp/code/model/branchcollection.py (+2/-1) lib/lp/code/model/branchjob.py (+1/-1) lib/lp/code/model/codereviewinlinecomment.py (+2/-1) lib/lp/code/model/revision.py (+3/-2) lib/lp/codehosting/inmemory.py (+1/-1) lib/lp/codehosting/scanner/buglinks.py (+2/-1) lib/lp/codehosting/sshserver/session.py (+2/-1) lib/lp/codehosting/vfs/branchfsclient.py (+2/-1) lib/lp/registry/model/distroseriesdifference.py (+5/-4) lib/lp/registry/scripts/tests/test_populate_distroseriesdiff.py (+3/-1) lib/lp/registry/services/sharingservice.py (+2/-1) lib/lp/scripts/utilities/warninghandler.py (+3/-1) lib/lp/services/command_spawner.py (+1/-1) lib/lp/services/config/__init__.py (+2/-1) lib/lp/services/database/bulk.py (+2/-1) lib/lp/services/features/testing.py (+2/-1) lib/lp/services/librarianserver/testing/fake.py (+3/-2) lib/lp/services/mail/basemailer.py (+2/-1) lib/lp/services/messaging/tests/test_rabbit.py (+2/-1) lib/lp/services/osutils.py (+3/-1) lib/lp/services/testing/customresult.py (+2/-1) lib/lp/services/utils.py (+2/-1) lib/lp/services/webapp/escaping.py (+2/-1) lib/lp/services/webapp/login.py (+1/-1) lib/lp/services/webapp/servers.py (+1/-1) lib/lp/services/webhooks/interfaces.py (+2/-1) lib/lp/soyuz/browser/tests/archive-views.txt (+3/-1) lib/lp/soyuz/model/packagediff.py (+2/-1) lib/lp/soyuz/model/publishing.py (+2/-1) lib/lp/soyuz/scripts/custom_uploads_copier.py (+3/-1) lib/lp/soyuz/scripts/gina/handlers.py (+2/-1) lib/lp/soyuz/scripts/gina/runner.py (+2/-2) lib/lp/testing/__init__.py (+4/-3) lib/lp/testing/swift/fakeswift.py (+2/-1) lib/lp/translations/browser/translationlinksaggregator.py (+4/-2) lib/lp/translations/browser/translationmessage.py (+3/-2) lib/lp/translations/doc/translationimportqueue.txt (+3/-1) lib/lp/translations/model/potemplate.py (+2/-1) lib/lp/translations/model/potmsgset.py (+4/-3) lib/lp/translations/model/translationimportqueue.py (+3/-1) lib/lp/translations/model/translationsharingjob.py (+2/-2) lib/lp/translations/scripts/po_import.py (+2/-1) lib/lp/translations/scripts/tests/test_reupload_translations.py (+3/-2) lib/lp/translations/scripts/tests/test_translations_to_branch.py (+4/-3) lib/lp/translations/stories/webservice/xx-translationimportqueue.txt (+1/-1) lib/lp/translations/tests/test_potemplate.py (+3/-2) lib/lp/translations/tests/test_side.py (+3/-2) lib/lp/translations/utilities/gettext_po_parser.py (+3/-2) lib/lp/translations/utilities/pluralforms.py (+3/-1) lib/lp/translations/utilities/tests/test_translation_importer.py (+2/-1) lib/lp/translations/utilities/translation_import.py (+3/-2) lib/lp/translations/utilities/translationmerger.py (+3/-3) lib/lp/translations/utilities/validate.py (+2/-1) utilities/findimports.py (+3/-1) utilities/generate-external-bug-status-docs (+3/-1) utilities/list-pages (+2/-1) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Thiago F. Pappacena (community) | Approve | ||
Review via email: mp+383369@code.launchpad.net |
Commit message
Use six for dict iteration
Description of the change
`dict.iterkeys()` can just be replaced with `dict` if the result is being iterated over, since `iter(dict)` iterates over its keys. Otherwise, `dict.iter{
Thiago F. Pappacena (pappacena) wrote : | # |
Colin Watson (cjwatson) wrote : | # |
Well, but that last isn't true; on Python 2, six.itervalues(
Mainly I wanted to use a reasonably obvious mechanical transformation that didn't require me to reason about whether there might be a real performance implication in any of the >130 cases here. A secondary benefit was that it means that we don't lose information as part of this commit: we can still look at the existing calls to dict.values and consider whether those might need to take a copy (I've certainly run across some that do, for example because the loop body deletes items from the dict). Doing that across the whole tree is a large chunk of work that I haven't tackled yet.
So, it's true it's not strictly necessary to use six.iter*, but I did think that it was worthwhile and better than reverting to bare .values() etc. in a systematic way.
Thiago F. Pappacena (pappacena) wrote : | # |
Fair enough. In that case, LGTM.
Preview Diff
1 | diff --git a/brzplugins/lpserve/__init__.py b/brzplugins/lpserve/__init__.py |
2 | index b956568..3ce2081 100644 |
3 | --- a/brzplugins/lpserve/__init__.py |
4 | +++ b/brzplugins/lpserve/__init__.py |
5 | @@ -48,6 +48,7 @@ from breezy.transport import ( |
6 | get_transport, |
7 | transport_server_registry, |
8 | ) |
9 | +import six |
10 | |
11 | |
12 | class cmd_launchpad_server(Command): |
13 | @@ -591,7 +592,7 @@ class LPForkingService(object): |
14 | pid = os.getpid() |
15 | trace.mutter('%d spawned' % (pid,)) |
16 | self._server_socket.close() |
17 | - for env_var, value in env.iteritems(): |
18 | + for env_var, value in six.iteritems(env): |
19 | osutils.set_or_unset_env(env_var, value) |
20 | # See [Decision #3] |
21 | self._create_child_file_descriptors(temp_name) |
22 | @@ -769,7 +770,7 @@ class LPForkingService(object): |
23 | # We sent the SIGKILL signal, see if they exited |
24 | self._wait_for_children(self.SLEEP_FOR_CHILDREN_TIMEOUT) |
25 | if self._child_processes: |
26 | - for c_id, (c_path, sock) in self._child_processes.iteritems(): |
27 | + for c_id, (c_path, sock) in six.iteritems(self._child_processes): |
28 | # TODO: We should probably put something into this message? |
29 | # However, the likelyhood is very small that this isn't |
30 | # already closed because of SIGKILL + _wait_for_children |
31 | diff --git a/brzplugins/lpserve/test_lpserve.py b/brzplugins/lpserve/test_lpserve.py |
32 | index 3801df4..1420ed7 100644 |
33 | --- a/brzplugins/lpserve/test_lpserve.py |
34 | +++ b/brzplugins/lpserve/test_lpserve.py |
35 | @@ -18,6 +18,7 @@ from breezy import ( |
36 | trace, |
37 | ) |
38 | from breezy.plugins import lpserve |
39 | +import six |
40 | from testtools import content |
41 | |
42 | from lp.codehosting import ( |
43 | @@ -336,11 +337,11 @@ class TestCaseWithSubprocess(tests.TestCaseWithTransport): |
44 | old_env = {} |
45 | |
46 | def cleanup_environment(): |
47 | - for env_var, value in env_changes.iteritems(): |
48 | + for env_var, value in six.iteritems(env_changes): |
49 | old_env[env_var] = osutils.set_or_unset_env(env_var, value) |
50 | |
51 | def restore_environment(): |
52 | - for env_var, value in old_env.iteritems(): |
53 | + for env_var, value in six.iteritems(old_env): |
54 | osutils.set_or_unset_env(env_var, value) |
55 | |
56 | cwd = None |
57 | @@ -406,7 +407,7 @@ class TestCaseWithLPForkingServiceSubprocess(TestCaseWithSubprocess): |
58 | def send_fork_request(self, command, env=None): |
59 | if env is not None: |
60 | request_lines = ['fork-env %s\n' % (command,)] |
61 | - for key, value in env.iteritems(): |
62 | + for key, value in six.iteritems(env): |
63 | request_lines.append('%s: %s\n' % (key, value)) |
64 | request_lines.append('end\n') |
65 | request = ''.join(request_lines) |
66 | diff --git a/database/schema/security.py b/database/schema/security.py |
67 | index 1c53659..274bb03 100755 |
68 | --- a/database/schema/security.py |
69 | +++ b/database/schema/security.py |
70 | @@ -13,6 +13,8 @@ import os |
71 | import re |
72 | import sys |
73 | |
74 | +import six |
75 | + |
76 | from fti import quote_identifier |
77 | from lp.services.compat import SafeConfigParser |
78 | from lp.services.database.sqlbase import connect |
79 | @@ -302,8 +304,8 @@ class PermissionGatherer: |
80 | to grant or revoke for. Each is a string. |
81 | """ |
82 | result = [] |
83 | - for permission, parties in self.permissions.iteritems(): |
84 | - for principal, entities in parties.iteritems(): |
85 | + for permission, parties in six.iteritems(self.permissions): |
86 | + for principal, entities in six.iteritems(parties): |
87 | result.append( |
88 | (permission, ", ".join(entities), principal)) |
89 | return result |
90 | @@ -315,8 +317,8 @@ class PermissionGatherer: |
91 | def countEntities(self): |
92 | """Count the number of different entities.""" |
93 | entities = set() |
94 | - for entities_and_entities in self.permissions.itervalues(): |
95 | - for extra_entities in entities_and_entities.itervalues(): |
96 | + for entities_and_entities in six.itervalues(self.permissions): |
97 | + for extra_entities in six.itervalues(entities_and_entities): |
98 | entities.update(extra_entities) |
99 | return len(entities) |
100 | |
101 | @@ -324,7 +326,7 @@ class PermissionGatherer: |
102 | """Count the number of different principals.""" |
103 | return len(set(sum([ |
104 | principals.keys() |
105 | - for principals in self.permissions.itervalues()], []))) |
106 | + for principals in six.itervalues(self.permissions)], []))) |
107 | |
108 | def grant(self, cur): |
109 | """Grant all gathered permissions. |
110 | @@ -480,7 +482,7 @@ def reset_permissions(con, config, options): |
111 | |
112 | log.debug('Updating group memberships') |
113 | existing_memberships = list_role_members(cur, memberships.keys()) |
114 | - for group, users in memberships.iteritems(): |
115 | + for group, users in six.iteritems(memberships): |
116 | cur_users = managed_roles.intersection(existing_memberships[group]) |
117 | to_grant = users - cur_users |
118 | if to_grant: |
119 | @@ -517,7 +519,7 @@ def reset_permissions(con, config, options): |
120 | # Set permissions as per config file |
121 | desired_permissions = defaultdict(lambda: defaultdict(set)) |
122 | |
123 | - valid_objs = set(schema.iterkeys()) |
124 | + valid_objs = set(schema) |
125 | |
126 | # Any object with permissions granted is accessible to the 'read' |
127 | # role. Some (eg. the lp_* replicated tables and internal or trigger |
128 | @@ -618,7 +620,7 @@ def reset_permissions(con, config, options): |
129 | new = desired_permissions[obj][role] |
130 | old_privs = obj.acl.get(role, {}) |
131 | old = set(old_privs) |
132 | - if any(old_privs.itervalues()): |
133 | + if any(six.itervalues(old_privs)): |
134 | log.warning("%s has grant option on %s", role, obj.fullname) |
135 | if new == old: |
136 | continue |
137 | diff --git a/lib/contrib/oauth.py b/lib/contrib/oauth.py |
138 | index 47a821d..2d11e6c 100644 |
139 | --- a/lib/contrib/oauth.py |
140 | +++ b/lib/contrib/oauth.py |
141 | @@ -3,6 +3,7 @@ import hmac |
142 | import random |
143 | import time |
144 | |
145 | +import six |
146 | from six.moves.urllib.parse import ( |
147 | parse_qs, |
148 | quote, |
149 | @@ -118,7 +119,7 @@ class OAuthRequest(object): |
150 | # get any non-oauth parameters |
151 | def get_nonoauth_parameters(self): |
152 | parameters = {} |
153 | - for k, v in self.parameters.iteritems(): |
154 | + for k, v in six.iteritems(self.parameters): |
155 | # ignore oauth parameters |
156 | if k.find('oauth_') < 0: |
157 | parameters[k] = v |
158 | @@ -129,13 +130,15 @@ class OAuthRequest(object): |
159 | auth_header = 'OAuth realm="%s"' % realm |
160 | # add the oauth parameters |
161 | if self.parameters: |
162 | - for k, v in self.parameters.iteritems(): |
163 | + for k, v in six.iteritems(self.parameters): |
164 | auth_header += ', %s="%s"' % (k, v) |
165 | return {'Authorization': auth_header} |
166 | |
167 | # serialize as post data for a POST request |
168 | def to_postdata(self): |
169 | - return '&'.join('%s=%s' % (escape(str(k)), escape(str(v))) for k, v in self.parameters.iteritems()) |
170 | + return '&'.join( |
171 | + '%s=%s' % (escape(str(k)), escape(str(v))) |
172 | + for k, v in six.iteritems(self.parameters)) |
173 | |
174 | # serialize as a url for a GET request |
175 | def to_url(self): |
176 | @@ -269,7 +272,7 @@ class OAuthRequest(object): |
177 | @staticmethod |
178 | def _split_url_string(param_str): |
179 | parameters = parse_qs(param_str, keep_blank_values=False) |
180 | - for k, v in parameters.iteritems(): |
181 | + for k, v in six.iteritems(parameters): |
182 | parameters[k] = unquote(v[0]) |
183 | return parameters |
184 | |
185 | diff --git a/lib/lp/app/browser/launchpadform.py b/lib/lp/app/browser/launchpadform.py |
186 | index ac6dd15..8899cbd 100644 |
187 | --- a/lib/lp/app/browser/launchpadform.py |
188 | +++ b/lib/lp/app/browser/launchpadform.py |
189 | @@ -19,6 +19,7 @@ __all__ = [ |
190 | from lazr.lifecycle.event import ObjectModifiedEvent |
191 | from lazr.lifecycle.snapshot import Snapshot |
192 | import simplejson |
193 | +import six |
194 | import transaction |
195 | from zope.event import notify |
196 | from zope.formlib import form |
197 | @@ -213,7 +214,7 @@ class LaunchpadFormView(LaunchpadView): |
198 | self.form_fields, self.prefix, context, self.request, |
199 | data=self.initial_values, adapters=self.adapters, |
200 | ignore_request=False) |
201 | - for field_name, help_link in self.help_links.iteritems(): |
202 | + for field_name, help_link in six.iteritems(self.help_links): |
203 | self.widgets[field_name].help_link = help_link |
204 | |
205 | @property |
206 | diff --git a/lib/lp/app/browser/tales.py b/lib/lp/app/browser/tales.py |
207 | index df20fcb..8e4921e 100644 |
208 | --- a/lib/lp/app/browser/tales.py |
209 | +++ b/lib/lp/app/browser/tales.py |
210 | @@ -23,6 +23,7 @@ from lazr.enum import enumerated_type_registry |
211 | from lazr.restful.utils import get_current_browser_request |
212 | from lazr.uri import URI |
213 | import pytz |
214 | +import six |
215 | from six.moves.urllib.parse import quote |
216 | from zope.browserpage import ViewPageTemplateFile |
217 | from zope.component import ( |
218 | @@ -1418,7 +1419,7 @@ class CustomizableFormatter(ObjectFormatterAPI): |
219 | """ |
220 | values = dict( |
221 | (k, v if v is not None else '') |
222 | - for k, v in self._link_summary_values().iteritems()) |
223 | + for k, v in six.iteritems(self._link_summary_values())) |
224 | return structured(self._link_summary_template, **values).escapedtext |
225 | |
226 | def _title_values(self): |
227 | @@ -1440,7 +1441,7 @@ class CustomizableFormatter(ObjectFormatterAPI): |
228 | return None |
229 | values = dict( |
230 | (k, v if v is not None else '') |
231 | - for k, v in self._title_values().iteritems()) |
232 | + for k, v in six.iteritems(self._title_values())) |
233 | return structured(title_template, **values).escapedtext |
234 | |
235 | def sprite_css(self): |
236 | diff --git a/lib/lp/archivepublisher/domination.py b/lib/lp/archivepublisher/domination.py |
237 | index a02fd78..356a2ee 100644 |
238 | --- a/lib/lp/archivepublisher/domination.py |
239 | +++ b/lib/lp/archivepublisher/domination.py |
240 | @@ -60,6 +60,7 @@ from operator import ( |
241 | ) |
242 | |
243 | import apt_pkg |
244 | +import six |
245 | from six.moves import ( |
246 | filter as ifilter, |
247 | filterfalse as ifilterfalse, |
248 | @@ -669,7 +670,7 @@ class Dominator: |
249 | bins = self.findBinariesForDomination(distroarchseries, pocket) |
250 | sorted_packages = self._sortPackages(bins, generalization) |
251 | self.logger.info("Planning domination of binaries...") |
252 | - for name, pubs in sorted_packages.iteritems(): |
253 | + for name, pubs in six.iteritems(sorted_packages): |
254 | self.logger.debug("Planning domination of %s" % name) |
255 | assert len(pubs) > 0, "Dominating zero binaries!" |
256 | live_versions = find_live_binary_versions_pass_1(pubs) |
257 | @@ -774,7 +775,7 @@ class Dominator: |
258 | delete = [] |
259 | |
260 | self.logger.debug("Dominating sources...") |
261 | - for name, pubs in sorted_packages.iteritems(): |
262 | + for name, pubs in six.iteritems(sorted_packages): |
263 | self.logger.debug("Dominating %s" % name) |
264 | assert len(pubs) > 0, "Dominating zero sources!" |
265 | live_versions = find_live_source_versions(pubs) |
266 | diff --git a/lib/lp/archivepublisher/model/ftparchive.py b/lib/lp/archivepublisher/model/ftparchive.py |
267 | index 39e7d40..6fe3c3c 100644 |
268 | --- a/lib/lp/archivepublisher/model/ftparchive.py |
269 | +++ b/lib/lp/archivepublisher/model/ftparchive.py |
270 | @@ -8,6 +8,7 @@ from StringIO import StringIO |
271 | import time |
272 | |
273 | import scandir |
274 | +import six |
275 | from storm.expr import ( |
276 | Desc, |
277 | Join, |
278 | @@ -201,7 +202,7 @@ class FTPArchiveHandler: |
279 | stderr_handler.finalize() |
280 | failures = sorted([ |
281 | (tag, receiver.returncode) |
282 | - for tag, receiver in returncodes.iteritems() |
283 | + for tag, receiver in six.iteritems(returncodes) |
284 | if receiver.returncode != 0]) |
285 | if len(failures) > 0: |
286 | by_arch = ["%s (returned %d)" % failure for failure in failures] |
287 | @@ -694,8 +695,8 @@ class FTPArchiveHandler: |
288 | |
289 | self.log.debug("Writing file lists for %s" % suite) |
290 | series, pocket = self.distro.getDistroSeriesAndPocket(suite) |
291 | - for component, architectures in filelist.iteritems(): |
292 | - for architecture, file_names in architectures.iteritems(): |
293 | + for component, architectures in six.iteritems(filelist): |
294 | + for architecture, file_names in six.iteritems(architectures): |
295 | # XXX wgrant 2010-10-06: There must be a better place to do |
296 | # this. |
297 | if architecture == "source": |
298 | diff --git a/lib/lp/archivepublisher/publishing.py b/lib/lp/archivepublisher/publishing.py |
299 | index cd19ed8..f6246b0 100644 |
300 | --- a/lib/lp/archivepublisher/publishing.py |
301 | +++ b/lib/lp/archivepublisher/publishing.py |
302 | @@ -36,6 +36,7 @@ from debian.deb822 import ( |
303 | Release, |
304 | ) |
305 | import scandir |
306 | +import six |
307 | from storm.expr import Desc |
308 | from zope.component import getUtility |
309 | from zope.interface import ( |
310 | @@ -984,7 +985,7 @@ class Publisher(object): |
311 | translation_stanza.makeOutput().encode('utf-8') |
312 | + '\n\n') |
313 | |
314 | - for index in indices.itervalues(): |
315 | + for index in six.itervalues(indices): |
316 | index.close() |
317 | |
318 | if separate_long_descriptions: |
319 | diff --git a/lib/lp/archivepublisher/scripts/publish_ftpmaster.py b/lib/lp/archivepublisher/scripts/publish_ftpmaster.py |
320 | index 5fcd7d3..c307846 100644 |
321 | --- a/lib/lp/archivepublisher/scripts/publish_ftpmaster.py |
322 | +++ b/lib/lp/archivepublisher/scripts/publish_ftpmaster.py |
323 | @@ -15,6 +15,7 @@ import shutil |
324 | |
325 | from pytz import utc |
326 | import scandir |
327 | +import six |
328 | from zope.component import getUtility |
329 | |
330 | from lp.archivepublisher.config import getPubConfig |
331 | @@ -224,9 +225,7 @@ class PublishFTPMaster(LaunchpadCronScript): |
332 | return [] |
333 | |
334 | # May need indexes for this series. |
335 | - suites = [ |
336 | - distroseries.getSuite(pocket) |
337 | - for pocket in pocketsuffix.iterkeys()] |
338 | + suites = [distroseries.getSuite(pocket) for pocket in pocketsuffix] |
339 | return [ |
340 | suite for suite in suites |
341 | if not file_exists(self.locateIndexesMarker(distro, suite))] |
342 | @@ -289,7 +288,8 @@ class PublishFTPMaster(LaunchpadCronScript): |
343 | |
344 | :param archive_purpose: The (purpose of the) archive to copy. |
345 | """ |
346 | - for purpose, archive_config in self.configs[distribution].iteritems(): |
347 | + for purpose, archive_config in ( |
348 | + six.iteritems(self.configs[distribution])): |
349 | dists = get_dists(archive_config) |
350 | backup_dists = get_backup_dists(archive_config) |
351 | execute_subprocess( |
352 | @@ -319,14 +319,15 @@ class PublishFTPMaster(LaunchpadCronScript): |
353 | run died while in this state, restore the directory to its |
354 | permanent location. |
355 | """ |
356 | - for distro_configs in self.configs.itervalues(): |
357 | - for archive_config in distro_configs.itervalues(): |
358 | + for distro_configs in six.itervalues(self.configs): |
359 | + for archive_config in six.itervalues(distro_configs): |
360 | self.recoverArchiveWorkingDir(archive_config) |
361 | |
362 | def setUpDirs(self): |
363 | """Create archive roots and such if they did not yet exist.""" |
364 | - for distro_configs in self.configs.itervalues(): |
365 | - for archive_purpose, archive_config in distro_configs.iteritems(): |
366 | + for distro_configs in six.itervalues(self.configs): |
367 | + for archive_purpose, archive_config in ( |
368 | + six.iteritems(distro_configs)): |
369 | archiveroot = archive_config.archiveroot |
370 | if not file_exists(archiveroot): |
371 | self.logger.debug( |
372 | @@ -407,7 +408,7 @@ class PublishFTPMaster(LaunchpadCronScript): |
373 | backup dists directory around. |
374 | """ |
375 | self.logger.debug("Moving the new dists into place...") |
376 | - for archive_config in self.configs[distribution].itervalues(): |
377 | + for archive_config in six.itervalues(self.configs[distribution]): |
378 | # Use the dists "working location" as a temporary place to |
379 | # move the current dists out of the way for the switch. If |
380 | # we die in this state, the next run will know to move the |
381 | @@ -422,7 +423,7 @@ class PublishFTPMaster(LaunchpadCronScript): |
382 | |
383 | def clearEmptyDirs(self, distribution): |
384 | """Clear out any redundant empty directories.""" |
385 | - for archive_config in self.configs[distribution].itervalues(): |
386 | + for archive_config in six.itervalues(self.configs[distribution]): |
387 | execute_subprocess( |
388 | ["find", archive_config.archiveroot, "-type", "d", "-empty", |
389 | "-delete"], |
390 | @@ -432,7 +433,7 @@ class PublishFTPMaster(LaunchpadCronScript): |
391 | """Run the finalize.d parts to finalize publication.""" |
392 | archive_roots = ' '.join([ |
393 | archive_config.archiveroot |
394 | - for archive_config in self.configs[distribution].itervalues()]) |
395 | + for archive_config in six.itervalues(self.configs[distribution])]) |
396 | |
397 | env = { |
398 | 'SECURITY_UPLOAD_ONLY': 'yes' if security_only else 'no', |
399 | diff --git a/lib/lp/archivepublisher/tests/test_dominator.py b/lib/lp/archivepublisher/tests/test_dominator.py |
400 | index b88da56..4d073e0 100755 |
401 | --- a/lib/lp/archivepublisher/tests/test_dominator.py |
402 | +++ b/lib/lp/archivepublisher/tests/test_dominator.py |
403 | @@ -11,6 +11,7 @@ import datetime |
404 | from operator import attrgetter |
405 | |
406 | import apt_pkg |
407 | +import six |
408 | from testtools.matchers import ( |
409 | GreaterThan, |
410 | LessThan, |
411 | @@ -813,14 +814,14 @@ class TestDominatorMethods(TestCaseWithFactory): |
412 | # Actually the "oldest to newest" order on the publications only |
413 | # applies to their creation dates. Their creation orders are |
414 | # irrelevant. |
415 | - for pubs_list in pubs_by_version.itervalues(): |
416 | + for pubs_list in six.itervalues(pubs_by_version): |
417 | alter_creation_dates(pubs_list, ages) |
418 | pubs_list.sort(key=attrgetter('datecreated')) |
419 | |
420 | live_versions = ["1.1", "1.2"] |
421 | last_version_alive = sorted(live_versions)[-1] |
422 | |
423 | - all_pubs = sum(pubs_by_version.itervalues(), []) |
424 | + all_pubs = sum(six.itervalues(pubs_by_version), []) |
425 | dominator = Dominator(DevNullLogger(), series.main_archive) |
426 | supersede, _, delete = dominator.planPackageDomination( |
427 | generalization.sortPublications(all_pubs), live_versions, |
428 | diff --git a/lib/lp/archivepublisher/tests/test_publish_ftpmaster.py b/lib/lp/archivepublisher/tests/test_publish_ftpmaster.py |
429 | index 8c99b73..450da11 100644 |
430 | --- a/lib/lp/archivepublisher/tests/test_publish_ftpmaster.py |
431 | +++ b/lib/lp/archivepublisher/tests/test_publish_ftpmaster.py |
432 | @@ -121,8 +121,7 @@ def get_a_suite(distroseries): |
433 | |
434 | def get_marker_files(script, distroseries): |
435 | """Return filesystem paths for all indexes markers for `distroseries`.""" |
436 | - suites = [ |
437 | - distroseries.getSuite(pocket) for pocket in pocketsuffix.iterkeys()] |
438 | + suites = [distroseries.getSuite(pocket) for pocket in pocketsuffix] |
439 | distro = distroseries.distribution |
440 | return [script.locateIndexesMarker(distro, suite) for suite in suites] |
441 | |
442 | @@ -998,7 +997,7 @@ class TestCreateDistroSeriesIndexes(TestCaseWithFactory, HelpersMixin): |
443 | script = self.makeScript(series.distribution) |
444 | script.setUp() |
445 | self.assertContentEqual( |
446 | - [series.getSuite(pocket) for pocket in pocketsuffix.iterkeys()], |
447 | + [series.getSuite(pocket) for pocket in pocketsuffix], |
448 | script.listSuitesNeedingIndexes(series)) |
449 | |
450 | def test_listSuitesNeedingIndexes_is_empty_for_nonfrozen_series(self): |
451 | @@ -1133,7 +1132,7 @@ class TestCreateDistroSeriesIndexes(TestCaseWithFactory, HelpersMixin): |
452 | [((given_distro, given_suites), kwargs)] = script.createIndexes.calls |
453 | self.assertEqual(distro, given_distro) |
454 | self.assertContentEqual( |
455 | - [series.getSuite(pocket) for pocket in pocketsuffix.iterkeys()], |
456 | + [series.getSuite(pocket) for pocket in pocketsuffix], |
457 | given_suites) |
458 | |
459 | def test_createIndexes_ignores_other_series(self): |
460 | diff --git a/lib/lp/archiveuploader/dscfile.py b/lib/lp/archiveuploader/dscfile.py |
461 | index 604193c..fbe1e25 100644 |
462 | --- a/lib/lp/archiveuploader/dscfile.py |
463 | +++ b/lib/lp/archiveuploader/dscfile.py |
464 | @@ -684,7 +684,7 @@ class DSCFile(SourceUploadFile, SignableTagFile): |
465 | ISourcePackageNameSet).getOrCreateByName(self.source) |
466 | |
467 | user_defined_fields = self.extractUserDefinedFields([ |
468 | - (field, encoded[field]) for field in self._dict.iterkeys()]) |
469 | + (field, encoded[field]) for field in self._dict]) |
470 | |
471 | if self.changes.buildinfo is not None: |
472 | buildinfo_lfa = self.changes.buildinfo.storeInDatabase() |
473 | diff --git a/lib/lp/archiveuploader/nascentuploadfile.py b/lib/lp/archiveuploader/nascentuploadfile.py |
474 | index f28e43e..0791141 100644 |
475 | --- a/lib/lp/archiveuploader/nascentuploadfile.py |
476 | +++ b/lib/lp/archiveuploader/nascentuploadfile.py |
477 | @@ -26,6 +26,7 @@ import time |
478 | import apt_inst |
479 | import apt_pkg |
480 | from debian.deb822 import Deb822Dict |
481 | +import six |
482 | from zope.component import getUtility |
483 | |
484 | from lp.app.errors import NotFoundError |
485 | @@ -218,7 +219,7 @@ class NascentUploadFile: |
486 | ckfile = open(self.filepath, "r") |
487 | size = 0 |
488 | for chunk in filechunks(ckfile): |
489 | - for digester in digesters.itervalues(): |
490 | + for digester in six.itervalues(digesters): |
491 | digester.update(chunk) |
492 | size += len(chunk) |
493 | ckfile.close() |
494 | @@ -905,7 +906,7 @@ class BaseBinaryUploadFile(PackageUploadFile): |
495 | debug_package = None |
496 | |
497 | user_defined_fields = self.extractUserDefinedFields( |
498 | - [(field, encoded[field]) for field in self.control.iterkeys()]) |
499 | + [(field, encoded[field]) for field in self.control]) |
500 | |
501 | binary = build.createBinaryPackageRelease( |
502 | binarypackagename=binary_name, |
503 | diff --git a/lib/lp/archiveuploader/utils.py b/lib/lp/archiveuploader/utils.py |
504 | index ac8057d..67a009f 100644 |
505 | --- a/lib/lp/archiveuploader/utils.py |
506 | +++ b/lib/lp/archiveuploader/utils.py |
507 | @@ -39,6 +39,8 @@ import re |
508 | import signal |
509 | import subprocess |
510 | |
511 | +import six |
512 | + |
513 | from lp.services.encoding import guess as guess_encoding |
514 | from lp.soyuz.enums import BinaryPackageFileType |
515 | |
516 | @@ -333,7 +335,7 @@ def merge_file_lists(files, checksums_sha1, checksums_sha256, changes=True): |
517 | (filename, file_hashes[filename], size)) |
518 | |
519 | # Ensure that each filename was only listed in Files once. |
520 | - if set(file_counter.itervalues()) - set([1]): |
521 | + if set(six.itervalues(file_counter)) - set([1]): |
522 | raise UploadError("Duplicate filenames in Files field.") |
523 | |
524 | # Ensure that the Checksums-Sha1 and Checksums-Sha256 fields, if |
525 | diff --git a/lib/lp/bugs/browser/bugalsoaffects.py b/lib/lp/bugs/browser/bugalsoaffects.py |
526 | index 4fa3421..b4f5ea5 100644 |
527 | --- a/lib/lp/bugs/browser/bugalsoaffects.py |
528 | +++ b/lib/lp/bugs/browser/bugalsoaffects.py |
529 | @@ -16,6 +16,7 @@ from lazr.enum import ( |
530 | Item, |
531 | ) |
532 | from lazr.lifecycle.event import ObjectCreatedEvent |
533 | +import six |
534 | from zope.browserpage import ViewPageTemplateFile |
535 | from zope.component import getUtility |
536 | from zope.event import notify |
537 | @@ -605,7 +606,7 @@ class ProductBugTaskCreationStep(BugTaskCreationStep): |
538 | |
539 | # Don't request validation for text widgets that are not |
540 | # related to the current radio selection. |
541 | - for option, name in link_upstream_options.iteritems(): |
542 | + for option, name in six.iteritems(link_upstream_options): |
543 | if link_upstream_how != option: |
544 | names.discard(name) |
545 | elif self.widgets[name].hasValidInput(): |
546 | @@ -619,7 +620,7 @@ class ProductBugTaskCreationStep(BugTaskCreationStep): |
547 | else: |
548 | # Don't validate these widgets when we don't yet know how |
549 | # we intend to link upstream. |
550 | - names.difference_update(link_upstream_options.itervalues()) |
551 | + names.difference_update(six.itervalues(link_upstream_options)) |
552 | |
553 | return super(ProductBugTaskCreationStep, |
554 | self).validate_widgets(data, names) |
555 | diff --git a/lib/lp/bugs/browser/bugtarget.py b/lib/lp/bugs/browser/bugtarget.py |
556 | index 5755c1b..01b323d 100644 |
557 | --- a/lib/lp/bugs/browser/bugtarget.py |
558 | +++ b/lib/lp/bugs/browser/bugtarget.py |
559 | @@ -28,6 +28,7 @@ from lazr.restful.interface import copy_field |
560 | from lazr.restful.interfaces import IJSONRequestCache |
561 | from pytz import timezone |
562 | from simplejson import dumps |
563 | +import six |
564 | from six.moves import http_client |
565 | from six.moves.urllib.parse import ( |
566 | quote, |
567 | @@ -1235,7 +1236,7 @@ class BugTargetBugTagsView(LaunchpadView): |
568 | count=count, |
569 | url=self._getSearchURL(tag), |
570 | ) |
571 | - for (tag, count) in tags.iteritems()], |
572 | + for (tag, count) in six.iteritems(tags)], |
573 | key=itemgetter('count'), reverse=True) |
574 | |
575 | @property |
576 | diff --git a/lib/lp/bugs/interfaces/bugtaskfilter.py b/lib/lp/bugs/interfaces/bugtaskfilter.py |
577 | index e3407ed..898c955 100644 |
578 | --- a/lib/lp/bugs/interfaces/bugtaskfilter.py |
579 | +++ b/lib/lp/bugs/interfaces/bugtaskfilter.py |
580 | @@ -17,6 +17,8 @@ from collections import ( |
581 | ) |
582 | from operator import attrgetter |
583 | |
584 | +import six |
585 | + |
586 | from lp.bugs.interfaces.bugtarget import IHasBugs |
587 | |
588 | |
589 | @@ -67,5 +69,5 @@ def filter_bugtasks_by_context(context, bugtasks): |
590 | for task in bugtasks: |
591 | bug_mapping[task.bugID].append(weight_calculator(task)) |
592 | |
593 | - filtered = [sorted(tasks)[0].task for tasks in bug_mapping.itervalues()] |
594 | + filtered = [sorted(tasks)[0].task for tasks in six.itervalues(bug_mapping)] |
595 | return sorted(filtered, key=attrgetter('bugID')) |
596 | diff --git a/lib/lp/bugs/model/bugtask.py b/lib/lp/bugs/model/bugtask.py |
597 | index 2c3b6ef..fe7d366 100644 |
598 | --- a/lib/lp/bugs/model/bugtask.py |
599 | +++ b/lib/lp/bugs/model/bugtask.py |
600 | @@ -32,6 +32,7 @@ import re |
601 | |
602 | from lazr.lifecycle.event import ObjectDeletedEvent |
603 | import pytz |
604 | +import six |
605 | from sqlobject import ( |
606 | ForeignKey, |
607 | SQLObjectNotFound, |
608 | @@ -1138,7 +1139,7 @@ class BugTask(SQLBase): |
609 | new_key['sourcepackagename'] != self.sourcepackagename): |
610 | self._syncSourcePackages(new_key['sourcepackagename'], user) |
611 | |
612 | - for name, value in new_key.iteritems(): |
613 | + for name, value in six.iteritems(new_key): |
614 | setattr(self, name, value) |
615 | self.updateTargetNameCache() |
616 | self.bug._reconcileAccess() |
617 | diff --git a/lib/lp/bugs/model/structuralsubscription.py b/lib/lp/bugs/model/structuralsubscription.py |
618 | index aec76a8..c2834e3 100644 |
619 | --- a/lib/lp/bugs/model/structuralsubscription.py |
620 | +++ b/lib/lp/bugs/model/structuralsubscription.py |
621 | @@ -15,6 +15,7 @@ __all__ = [ |
622 | from collections import defaultdict |
623 | |
624 | import pytz |
625 | +import six |
626 | from storm.base import Storm |
627 | from storm.expr import ( |
628 | And, |
629 | @@ -137,7 +138,7 @@ class StructuralSubscription(Storm): |
630 | def __init__(self, subscriber, subscribed_by, **kwargs): |
631 | self.subscriber = subscriber |
632 | self.subscribed_by = subscribed_by |
633 | - for arg, value in kwargs.iteritems(): |
634 | + for arg, value in six.iteritems(kwargs): |
635 | setattr(self, arg, value) |
636 | |
637 | @property |
638 | @@ -463,7 +464,7 @@ class StructuralSubscriptionTargetMixin: |
639 | """See `IStructuralSubscriptionTarget`.""" |
640 | from lp.registry.model.person import Person |
641 | clauses = [StructuralSubscription.subscriberID == Person.id] |
642 | - for key, value in self._target_args.iteritems(): |
643 | + for key, value in six.iteritems(self._target_args): |
644 | clauses.append( |
645 | getattr(StructuralSubscription, key) == value) |
646 | |
647 | diff --git a/lib/lp/bugs/model/tests/test_bugsubscriptioninfo.py b/lib/lp/bugs/model/tests/test_bugsubscriptioninfo.py |
648 | index 89c5c0f..f261fcb 100644 |
649 | --- a/lib/lp/bugs/model/tests/test_bugsubscriptioninfo.py |
650 | +++ b/lib/lp/bugs/model/tests/test_bugsubscriptioninfo.py |
651 | @@ -7,6 +7,7 @@ __metaclass__ = type |
652 | |
653 | from contextlib import contextmanager |
654 | |
655 | +import six |
656 | from storm.store import Store |
657 | from testtools.matchers import Equals |
658 | from zope.component import queryAdapter |
659 | @@ -64,7 +65,7 @@ class TestSubscriptionRelatedSets(TestCaseWithFactory): |
660 | subscribers = dict( |
661 | (name_pair, make_person(*name_pair)) |
662 | for name_pair in self.name_pairs) |
663 | - self.subscribers_set = frozenset(subscribers.itervalues()) |
664 | + self.subscribers_set = frozenset(six.itervalues(subscribers)) |
665 | self.subscribers_sorted = tuple( |
666 | subscribers[name_pair] for name_pair in self.name_pairs_sorted) |
667 | |
668 | @@ -428,7 +429,7 @@ class TestBugSubscriptionInfoPermissions(TestCaseWithFactory): |
669 | self.assertEqual({}, checker.set_permissions) |
670 | |
671 | # All attributes require launchpad.View. |
672 | - permissions = set(checker.get_permissions.itervalues()) |
673 | + permissions = set(six.itervalues(checker.get_permissions)) |
674 | self.assertContentEqual(["launchpad.View"], permissions) |
675 | |
676 | # The security adapter for launchpad.View lets anyone reference the |
677 | diff --git a/lib/lp/bugs/scripts/bugsummaryrebuild.py b/lib/lp/bugs/scripts/bugsummaryrebuild.py |
678 | index f41d8c2..f000905 100644 |
679 | --- a/lib/lp/bugs/scripts/bugsummaryrebuild.py |
680 | +++ b/lib/lp/bugs/scripts/bugsummaryrebuild.py |
681 | @@ -3,6 +3,7 @@ |
682 | |
683 | __metaclass__ = type |
684 | |
685 | +import six |
686 | from storm.expr import ( |
687 | Alias, |
688 | And, |
689 | @@ -116,7 +117,7 @@ def get_bugsummary_constraint(target, cls=RawBugSummary): |
690 | # Map to ID columns to work around Storm bug #682989. |
691 | return [ |
692 | getattr(cls, k) == v |
693 | - for (k, v) in _get_bugsummary_constraint_bits(target).iteritems()] |
694 | + for (k, v) in six.iteritems(_get_bugsummary_constraint_bits(target))] |
695 | |
696 | |
697 | def get_bugtaskflat_constraint(target): |
698 | @@ -161,8 +162,8 @@ def calculate_bugsummary_changes(old, new): |
699 | from the old one. |
700 | """ |
701 | keys = set() |
702 | - keys.update(old.iterkeys()) |
703 | - keys.update(new.iterkeys()) |
704 | + keys.update(six.iterkeys(old)) |
705 | + keys.update(six.iterkeys(new)) |
706 | added = {} |
707 | updated = {} |
708 | removed = [] |
709 | @@ -198,7 +199,7 @@ def apply_bugsummary_changes(target, added, updated, removed): |
710 | RawBugSummary.access_policy_id) |
711 | |
712 | # Postgres doesn't do bulk updates, so do a delete+add. |
713 | - for key, count in updated.iteritems(): |
714 | + for key, count in six.iteritems(updated): |
715 | removed.append(key) |
716 | added[key] = count |
717 | |
718 | @@ -219,7 +220,8 @@ def apply_bugsummary_changes(target, added, updated, removed): |
719 | if added: |
720 | create( |
721 | target_cols + key_cols + (RawBugSummary.count,), |
722 | - [target_key + key + (count,) for key, count in added.iteritems()]) |
723 | + [target_key + key + (count,) |
724 | + for key, count in six.iteritems(added)]) |
725 | |
726 | |
727 | def rebuild_bugsummary_for_target(target, log): |
728 | diff --git a/lib/lp/bugs/scripts/bugtasktargetnamecaches.py b/lib/lp/bugs/scripts/bugtasktargetnamecaches.py |
729 | index 5d14052..429ff49 100644 |
730 | --- a/lib/lp/bugs/scripts/bugtasktargetnamecaches.py |
731 | +++ b/lib/lp/bugs/scripts/bugtasktargetnamecaches.py |
732 | @@ -8,6 +8,7 @@ __all__ = ['BugTaskTargetNameCacheUpdater'] |
733 | |
734 | from collections import defaultdict |
735 | |
736 | +import six |
737 | from zope.interface import implementer |
738 | |
739 | from lp.bugs.model.bugtask import ( |
740 | @@ -65,7 +66,7 @@ class BugTaskTargetNameCachesTunableLoop(object): |
741 | candidates = defaultdict(set) |
742 | for candidate in candidate_set: |
743 | candidates[candidate[:-1]].add(candidate[-1]) |
744 | - return list(candidates.iteritems()) |
745 | + return list(six.iteritems(candidates)) |
746 | |
747 | def isDone(self): |
748 | """See `ITunableLoop`.""" |
749 | diff --git a/lib/lp/bugs/scripts/bzremotecomponentfinder.py b/lib/lp/bugs/scripts/bzremotecomponentfinder.py |
750 | index 4dcb6cb..cf4246e 100644 |
751 | --- a/lib/lp/bugs/scripts/bzremotecomponentfinder.py |
752 | +++ b/lib/lp/bugs/scripts/bzremotecomponentfinder.py |
753 | @@ -12,6 +12,7 @@ __all__ = [ |
754 | import re |
755 | |
756 | import requests |
757 | +import six |
758 | import transaction |
759 | from zope.component import getUtility |
760 | |
761 | @@ -163,7 +164,7 @@ class BugzillaRemoteComponentFinder: |
762 | def storeRemoteProductsAndComponents(self, bz_bugtracker, lp_bugtracker): |
763 | """Stores parsed product/component data from bz_bugtracker""" |
764 | components_to_add = [] |
765 | - for product in bz_bugtracker.products.itervalues(): |
766 | + for product in six.itervalues(bz_bugtracker.products): |
767 | # Look up the component group id from Launchpad for the product |
768 | # if it already exists. Otherwise, add it. |
769 | lp_component_group = lp_bugtracker.getRemoteComponentGroup( |
770 | diff --git a/lib/lp/bugs/tests/externalbugtracker.py b/lib/lp/bugs/tests/externalbugtracker.py |
771 | index b8a5b9d..afb1d81 100644 |
772 | --- a/lib/lp/bugs/tests/externalbugtracker.py |
773 | +++ b/lib/lp/bugs/tests/externalbugtracker.py |
774 | @@ -17,6 +17,7 @@ import re |
775 | import time |
776 | |
777 | import responses |
778 | +import six |
779 | from six.moves import xmlrpc_client |
780 | from six.moves.urllib_parse import ( |
781 | parse_qs, |
782 | @@ -720,7 +721,7 @@ class TestBugzillaXMLRPCTransport(RequestsTransport): |
783 | def _copy_comment(self, comment, fields_to_return=None): |
784 | # Copy wanted fields. |
785 | return dict( |
786 | - (key, value) for (key, value) in comment.iteritems() |
787 | + (key, value) for (key, value) in six.iteritems(comment) |
788 | if fields_to_return is None or key in fields_to_return) |
789 | |
790 | def comments(self, arguments): |
791 | diff --git a/lib/lp/buildmaster/browser/builder.py b/lib/lp/buildmaster/browser/builder.py |
792 | index 0c5d05a..b378ea3 100644 |
793 | --- a/lib/lp/buildmaster/browser/builder.py |
794 | +++ b/lib/lp/buildmaster/browser/builder.py |
795 | @@ -20,6 +20,7 @@ from itertools import groupby |
796 | import operator |
797 | |
798 | from lazr.restful.utils import smartquote |
799 | +import six |
800 | from zope.component import getUtility |
801 | from zope.event import notify |
802 | from zope.formlib.widget import CustomWidgetFactory |
803 | @@ -273,7 +274,7 @@ class BuilderCategory: |
804 | else: |
805 | grouped_builders[processor] = [builder] |
806 | |
807 | - for processor, builders in grouped_builders.iteritems(): |
808 | + for processor, builders in six.iteritems(grouped_builders): |
809 | virt_str = 'virt' if self.virtualized else 'nonvirt' |
810 | processor_name = processor.name if processor else None |
811 | queue_size, duration = build_queue_sizes[virt_str].get( |
812 | diff --git a/lib/lp/buildmaster/manager.py b/lib/lp/buildmaster/manager.py |
813 | index ea29ff2..3c80622 100644 |
814 | --- a/lib/lp/buildmaster/manager.py |
815 | +++ b/lib/lp/buildmaster/manager.py |
816 | @@ -15,6 +15,7 @@ import datetime |
817 | import functools |
818 | import logging |
819 | |
820 | +import six |
821 | from storm.expr import LeftJoin |
822 | import transaction |
823 | from twisted.application import service |
824 | @@ -139,7 +140,7 @@ class PrefetchedBuilderFactory: |
825 | |
826 | def iterVitals(self): |
827 | """See `BuilderFactory`.""" |
828 | - return (b for n, b in sorted(self.vitals_map.iteritems())) |
829 | + return (b for n, b in sorted(six.iteritems(self.vitals_map))) |
830 | |
831 | |
832 | def judge_failure(builder_count, job_count, exc, retry=True): |
833 | diff --git a/lib/lp/buildmaster/model/builder.py b/lib/lp/buildmaster/model/builder.py |
834 | index 4d32dcf..a44e7fc 100644 |
835 | --- a/lib/lp/buildmaster/model/builder.py |
836 | +++ b/lib/lp/buildmaster/model/builder.py |
837 | @@ -11,6 +11,7 @@ __all__ = [ |
838 | |
839 | import logging |
840 | |
841 | +import six |
842 | from sqlobject import ( |
843 | BoolCol, |
844 | ForeignKey, |
845 | @@ -243,7 +244,7 @@ class Builder(SQLBase): |
846 | |
847 | job_type_conditions = [] |
848 | job_sources = specific_build_farm_job_sources() |
849 | - for job_type, job_source in job_sources.iteritems(): |
850 | + for job_type, job_source in six.iteritems(job_sources): |
851 | query = job_source.addCandidateSelectionCriteria( |
852 | self.processor, self.virtualized) |
853 | if query: |
854 | diff --git a/lib/lp/buildmaster/queuedepth.py b/lib/lp/buildmaster/queuedepth.py |
855 | index 1fdb151..66f1986 100644 |
856 | --- a/lib/lp/buildmaster/queuedepth.py |
857 | +++ b/lib/lp/buildmaster/queuedepth.py |
858 | @@ -14,6 +14,7 @@ from datetime import ( |
859 | ) |
860 | |
861 | from pytz import utc |
862 | +import six |
863 | from storm.expr import Count |
864 | |
865 | from lp.buildmaster.enums import BuildQueueStatus |
866 | @@ -275,7 +276,7 @@ def estimate_job_delay(bq, builder_stats): |
867 | |
868 | sum_of_delays = 0 |
869 | # Now devide the delays based on a jobs/builders comparison. |
870 | - for platform, duration in delays.iteritems(): |
871 | + for platform, duration in six.iteritems(delays): |
872 | jobs = job_counts[platform] |
873 | builders = builder_stats[platform] |
874 | # If there are less jobs than builders that can take them on, |
875 | diff --git a/lib/lp/buildmaster/tests/test_queuedepth.py b/lib/lp/buildmaster/tests/test_queuedepth.py |
876 | index 090fd11..b9198e1 100644 |
877 | --- a/lib/lp/buildmaster/tests/test_queuedepth.py |
878 | +++ b/lib/lp/buildmaster/tests/test_queuedepth.py |
879 | @@ -10,6 +10,7 @@ from datetime import ( |
880 | ) |
881 | |
882 | from pytz import utc |
883 | +import six |
884 | from zope.component import getUtility |
885 | from zope.security.proxy import removeSecurityProxy |
886 | |
887 | @@ -698,7 +699,7 @@ class TestMinTimeToNextBuilderMulti(MultiArchBuildsBase): |
888 | check_mintime_to_builder(self, job, 0) |
889 | |
890 | # Let's disable all builders. |
891 | - for builders in self.builders.itervalues(): |
892 | + for builders in six.itervalues(self.builders): |
893 | for builder in builders: |
894 | builder.builderok = False |
895 | |
896 | diff --git a/lib/lp/code/browser/branch.py b/lib/lp/code/browser/branch.py |
897 | index 404c272..6ea17ac 100644 |
898 | --- a/lib/lp/code/browser/branch.py |
899 | +++ b/lib/lp/code/browser/branch.py |
900 | @@ -36,6 +36,7 @@ from lazr.restful.interface import ( |
901 | from lazr.uri import URI |
902 | import pytz |
903 | import simplejson |
904 | +import six |
905 | from zope.component import getUtility |
906 | from zope.event import notify |
907 | from zope.formlib import form |
908 | @@ -954,8 +955,8 @@ class BranchDeletionView(LaunchpadFormView): |
909 | :return: A list of tuples of (item, action, reason, allowed) |
910 | """ |
911 | reqs = [] |
912 | - for item, (action, reason) in ( |
913 | - self.context.deletionRequirements(eager_load=True).iteritems()): |
914 | + for item, (action, reason) in six.iteritems( |
915 | + self.context.deletionRequirements(eager_load=True)): |
916 | allowed = check_permission('launchpad.Edit', item) |
917 | reqs.append((item, action, reason, allowed)) |
918 | return reqs |
919 | diff --git a/lib/lp/code/browser/branchlisting.py b/lib/lp/code/browser/branchlisting.py |
920 | index f472ef0..23a1e9c 100644 |
921 | --- a/lib/lp/code/browser/branchlisting.py |
922 | +++ b/lib/lp/code/browser/branchlisting.py |
923 | @@ -33,6 +33,7 @@ from lazr.enum import ( |
924 | EnumeratedType, |
925 | Item, |
926 | ) |
927 | +import six |
928 | from six.moves.urllib.parse import parse_qs |
929 | from storm.expr import Desc |
930 | from zope.browserpage import ViewPageTemplateFile |
931 | @@ -1306,7 +1307,7 @@ class GroupedDistributionSourcePackageBranchesView(LaunchpadView, |
932 | # For each distro series, we only want the "best" pocket if one branch |
933 | # is linked to more than one pocket. Best here means smaller value. |
934 | official_branches = {} |
935 | - for key, value in distro_links.iteritems(): |
936 | + for key, value in six.iteritems(distro_links): |
937 | ordered = sorted(value, key=attrgetter('pocket')) |
938 | seen_branches = set() |
939 | branches = [] |
940 | @@ -1363,7 +1364,7 @@ class GroupedDistributionSourcePackageBranchesView(LaunchpadView, |
941 | and merge proposal links for badges. |
942 | """ |
943 | visible_branches = [] |
944 | - for branches, count in self.series_branches_map.itervalues(): |
945 | + for branches, count in six.itervalues(self.series_branches_map): |
946 | visible_branches.extend(branches) |
947 | return visible_branches |
948 | |
949 | diff --git a/lib/lp/code/browser/branchmergeproposal.py b/lib/lp/code/browser/branchmergeproposal.py |
950 | index a1b41fb..6d33f97 100644 |
951 | --- a/lib/lp/code/browser/branchmergeproposal.py |
952 | +++ b/lib/lp/code/browser/branchmergeproposal.py |
953 | @@ -35,6 +35,7 @@ from lazr.restful.interfaces import ( |
954 | IWebServiceClientRequest, |
955 | ) |
956 | import simplejson |
957 | +import six |
958 | from zope.component import ( |
959 | adapter, |
960 | getMultiAdapter, |
961 | @@ -145,7 +146,7 @@ def latest_proposals_for_each_branch(proposals): |
962 | targets[target] = (proposal, date_created) |
963 | |
964 | return sorted( |
965 | - [proposal for proposal, date_created in targets.itervalues()], |
966 | + [proposal for proposal, date_created in six.itervalues(targets)], |
967 | key=operator.attrgetter('date_created'), reverse=True) |
968 | |
969 | |
970 | diff --git a/lib/lp/code/browser/gitrepository.py b/lib/lp/code/browser/gitrepository.py |
971 | index c05dcc1..4f38702 100644 |
972 | --- a/lib/lp/code/browser/gitrepository.py |
973 | +++ b/lib/lp/code/browser/gitrepository.py |
974 | @@ -31,6 +31,7 @@ from lazr.restful.interface import ( |
975 | copy_field, |
976 | use_template, |
977 | ) |
978 | +import six |
979 | from six.moves.urllib_parse import ( |
980 | urlsplit, |
981 | urlunsplit, |
982 | @@ -1273,9 +1274,8 @@ class GitRepositoryDeletionView(LaunchpadFormView): |
983 | :return: A list of tuples of (item, action, reason, allowed) |
984 | """ |
985 | reqs = [] |
986 | - for item, (action, reason) in ( |
987 | - self.context.getDeletionRequirements( |
988 | - eager_load=True).iteritems()): |
989 | + for item, (action, reason) in six.iteritems( |
990 | + self.context.getDeletionRequirements(eager_load=True)): |
991 | allowed = check_permission("launchpad.Edit", item) |
992 | reqs.append((item, action, reason, allowed)) |
993 | return reqs |
994 | diff --git a/lib/lp/code/model/branchcollection.py b/lib/lp/code/model/branchcollection.py |
995 | index 79411cc..9c0b097 100644 |
996 | --- a/lib/lp/code/model/branchcollection.py |
997 | +++ b/lib/lp/code/model/branchcollection.py |
998 | @@ -16,6 +16,7 @@ from lazr.uri import ( |
999 | InvalidURIError, |
1000 | URI, |
1001 | ) |
1002 | +import six |
1003 | from storm.expr import ( |
1004 | And, |
1005 | Asc, |
1006 | @@ -562,7 +563,7 @@ class GenericBranchCollection: |
1007 | bugtasks_for_branch[bugbranch.branch].append(bugtask) |
1008 | |
1009 | # Now filter those down to one bugtask per branch |
1010 | - for branch, tasks in bugtasks_for_branch.iteritems(): |
1011 | + for branch, tasks in six.iteritems(bugtasks_for_branch): |
1012 | linked_bugtasks[branch.id].extend( |
1013 | filter_bugtasks_by_context(branch.target.context, tasks)) |
1014 | |
1015 | diff --git a/lib/lp/code/model/branchjob.py b/lib/lp/code/model/branchjob.py |
1016 | index a26c47b..7067f8a 100644 |
1017 | --- a/lib/lp/code/model/branchjob.py |
1018 | +++ b/lib/lp/code/model/branchjob.py |
1019 | @@ -684,7 +684,7 @@ class RevisionsAddedJob(BranchJobDerived): |
1020 | proposals[source_id] = (proposal, date_created) |
1021 | |
1022 | return sorted( |
1023 | - [proposal for proposal, date_created in proposals.itervalues()], |
1024 | + [proposal for proposal, date_created in six.itervalues(proposals)], |
1025 | key=operator.attrgetter('date_created'), reverse=True) |
1026 | |
1027 | def getRevisionMessage(self, revision_id, revno): |
1028 | diff --git a/lib/lp/code/model/codereviewinlinecomment.py b/lib/lp/code/model/codereviewinlinecomment.py |
1029 | index 580eb44..2ac74b0 100644 |
1030 | --- a/lib/lp/code/model/codereviewinlinecomment.py |
1031 | +++ b/lib/lp/code/model/codereviewinlinecomment.py |
1032 | @@ -10,6 +10,7 @@ __all__ = [ |
1033 | 'CodeReviewInlineCommentSet', |
1034 | ] |
1035 | |
1036 | +import six |
1037 | from storm.expr import LeftJoin |
1038 | from storm.locals import ( |
1039 | Int, |
1040 | @@ -113,7 +114,7 @@ class CodeReviewInlineCommentSet: |
1041 | list(crics), key=lambda c: c.comment.date_created) |
1042 | inline_comments = [] |
1043 | for cric in sorted_crics: |
1044 | - for line_number, text in cric.comments.iteritems(): |
1045 | + for line_number, text in six.iteritems(cric.comments): |
1046 | comment = { |
1047 | 'line_number': line_number, |
1048 | 'person': cric.person, |
1049 | diff --git a/lib/lp/code/model/revision.py b/lib/lp/code/model/revision.py |
1050 | index 4895ebb..a979c74 100644 |
1051 | --- a/lib/lp/code/model/revision.py |
1052 | +++ b/lib/lp/code/model/revision.py |
1053 | @@ -18,6 +18,7 @@ import email |
1054 | |
1055 | from breezy.revision import NULL_REVISION |
1056 | import pytz |
1057 | +import six |
1058 | from sqlobject import ( |
1059 | BoolCol, |
1060 | ForeignKey, |
1061 | @@ -287,7 +288,7 @@ class RevisionSet: |
1062 | parent_id=parent_id) |
1063 | |
1064 | # Create revision properties. |
1065 | - for name, value in properties.iteritems(): |
1066 | + for name, value in six.iteritems(properties): |
1067 | RevisionProperty(revision=revision, name=name, value=value) |
1068 | |
1069 | return revision |
1070 | @@ -378,7 +379,7 @@ class RevisionSet: |
1071 | for bzr_revision in revisions: |
1072 | db_id = revision_db_id[bzr_revision.revision_id] |
1073 | # Property data: revision DB id, name, value. |
1074 | - for name, value in bzr_revision.properties.iteritems(): |
1075 | + for name, value in six.iteritems(bzr_revision.properties): |
1076 | # pristine-tar properties can be huge, and storing them |
1077 | # in the database provides no value. Exclude them. |
1078 | if name.startswith('deb-pristine-delta'): |
1079 | diff --git a/lib/lp/codehosting/inmemory.py b/lib/lp/codehosting/inmemory.py |
1080 | index a2a7103..2b704fd 100644 |
1081 | --- a/lib/lp/codehosting/inmemory.py |
1082 | +++ b/lib/lp/codehosting/inmemory.py |
1083 | @@ -131,7 +131,7 @@ class ObjectSet: |
1084 | del self._objects[db_object.id] |
1085 | |
1086 | def __iter__(self): |
1087 | - return self._objects.itervalues() |
1088 | + return six.itervalues(self._objects) |
1089 | |
1090 | def _find(self, **kwargs): |
1091 | [(key, value)] = kwargs.items() |
1092 | diff --git a/lib/lp/codehosting/scanner/buglinks.py b/lib/lp/codehosting/scanner/buglinks.py |
1093 | index f9609c3..116fb90 100644 |
1094 | --- a/lib/lp/codehosting/scanner/buglinks.py |
1095 | +++ b/lib/lp/codehosting/scanner/buglinks.py |
1096 | @@ -9,6 +9,7 @@ __all__ = [ |
1097 | ] |
1098 | |
1099 | from breezy.bugtracker import InvalidBugStatus |
1100 | +import six |
1101 | from six.moves.urllib.parse import urlsplit |
1102 | from zope.component import getUtility |
1103 | |
1104 | @@ -77,7 +78,7 @@ class BugBranchLinker: |
1105 | except InvalidBugStatus: |
1106 | return |
1107 | bug_set = getUtility(IBugSet) |
1108 | - for bug_id, status in bug_info.iteritems(): |
1109 | + for bug_id, status in six.iteritems(bug_info): |
1110 | try: |
1111 | bug = bug_set.get(bug_id) |
1112 | except NotFoundError: |
1113 | diff --git a/lib/lp/codehosting/sshserver/session.py b/lib/lp/codehosting/sshserver/session.py |
1114 | index 38bea68..a77855b 100644 |
1115 | --- a/lib/lp/codehosting/sshserver/session.py |
1116 | +++ b/lib/lp/codehosting/sshserver/session.py |
1117 | @@ -15,6 +15,7 @@ import sys |
1118 | |
1119 | from lazr.sshserver.events import AvatarEvent |
1120 | from lazr.sshserver.session import DoNothingSession |
1121 | +import six |
1122 | from six import reraise |
1123 | from six.moves.urllib.parse import urlparse |
1124 | from twisted.internet import ( |
1125 | @@ -144,7 +145,7 @@ class ForkedProcessTransport(process.BaseProcess): |
1126 | assert executable == 'brz', executable # Maybe .endswith() |
1127 | assert args[0] == 'brz', args[0] |
1128 | message = ['fork-env %s\n' % (' '.join(args[1:]),)] |
1129 | - for key, value in environment.iteritems(): |
1130 | + for key, value in six.iteritems(environment): |
1131 | # XXX: Currently we only pass BRZ_EMAIL, should we be passing |
1132 | # everything else? Note that many won't be handled properly, |
1133 | # since the process is already running. |
1134 | diff --git a/lib/lp/codehosting/vfs/branchfsclient.py b/lib/lp/codehosting/vfs/branchfsclient.py |
1135 | index b96d780..3307830 100644 |
1136 | --- a/lib/lp/codehosting/vfs/branchfsclient.py |
1137 | +++ b/lib/lp/codehosting/vfs/branchfsclient.py |
1138 | @@ -14,6 +14,7 @@ __all__ = [ |
1139 | |
1140 | import time |
1141 | |
1142 | +import six |
1143 | from twisted.internet import defer |
1144 | |
1145 | from lp.code.interfaces.codehosting import BRANCH_TRANSPORT |
1146 | @@ -84,7 +85,7 @@ class BranchFileSystemClient: |
1147 | def _getFromCache(self, path): |
1148 | """Get the cached 'transport_tuple' for 'path'.""" |
1149 | split_path = path.strip('/').split('/') |
1150 | - for object_path, value in self._cache.iteritems(): |
1151 | + for object_path, value in six.iteritems(self._cache): |
1152 | transport_type, data, inserted_time = value |
1153 | split_object_path = object_path.strip('/').split('/') |
1154 | # Do a segment-by-segment comparison. Python sucks, lists should |
1155 | diff --git a/lib/lp/registry/model/distroseriesdifference.py b/lib/lp/registry/model/distroseriesdifference.py |
1156 | index e0ee875..0672584 100644 |
1157 | --- a/lib/lp/registry/model/distroseriesdifference.py |
1158 | +++ b/lib/lp/registry/model/distroseriesdifference.py |
1159 | @@ -19,6 +19,7 @@ from debian.changelog import ( |
1160 | Version, |
1161 | ) |
1162 | from lazr.enum import DBItem |
1163 | +import six |
1164 | from sqlobject import StringCol |
1165 | from storm.expr import ( |
1166 | And, |
1167 | @@ -279,10 +280,10 @@ def eager_load_dsds(dsds): |
1168 | # referred to. |
1169 | sprs = bulk.load_related( |
1170 | SourcePackageRelease, chain( |
1171 | - source_pubs.itervalues(), |
1172 | - parent_source_pubs.itervalues(), |
1173 | - source_pubs_for_release.itervalues(), |
1174 | - parent_source_pubs_for_release.itervalues()), |
1175 | + six.itervalues(source_pubs), |
1176 | + six.itervalues(parent_source_pubs), |
1177 | + six.itervalues(source_pubs_for_release), |
1178 | + six.itervalues(parent_source_pubs_for_release)), |
1179 | ("sourcepackagereleaseID",)) |
1180 | |
1181 | # Get packagesets and parent_packagesets for each DSD. |
1182 | diff --git a/lib/lp/registry/scripts/tests/test_populate_distroseriesdiff.py b/lib/lp/registry/scripts/tests/test_populate_distroseriesdiff.py |
1183 | index a8acf8a..84f9f74 100644 |
1184 | --- a/lib/lp/registry/scripts/tests/test_populate_distroseriesdiff.py |
1185 | +++ b/lib/lp/registry/scripts/tests/test_populate_distroseriesdiff.py |
1186 | @@ -5,6 +5,7 @@ |
1187 | |
1188 | __metaclass__ = type |
1189 | |
1190 | +import six |
1191 | from storm.store import Store |
1192 | import transaction |
1193 | from zope.security.proxy import removeSecurityProxy |
1194 | @@ -171,7 +172,8 @@ class TestFindLatestSourcePackageReleases(TestCaseWithFactory, FactoryHelper): |
1195 | for status in active_publishing_status) |
1196 | query = compose_sql_find_latest_source_package_releases(distroseries) |
1197 | self.assertContentEqual( |
1198 | - [self.getExpectedResultFor(spph) for spph in spphs.itervalues()], |
1199 | + [self.getExpectedResultFor(spph) |
1200 | + for spph in six.itervalues(spphs)], |
1201 | Store.of(distroseries).execute(query)) |
1202 | |
1203 | def test_does_not_find_inactive_publication(self): |
1204 | diff --git a/lib/lp/registry/services/sharingservice.py b/lib/lp/registry/services/sharingservice.py |
1205 | index 68e33c3..09744ee 100644 |
1206 | --- a/lib/lp/registry/services/sharingservice.py |
1207 | +++ b/lib/lp/registry/services/sharingservice.py |
1208 | @@ -13,6 +13,7 @@ from operator import attrgetter |
1209 | |
1210 | from lazr.restful.interfaces import IWebBrowserOriginatingRequest |
1211 | from lazr.restful.utils import get_current_web_service_request |
1212 | +import six |
1213 | from storm.expr import ( |
1214 | And, |
1215 | Count, |
1216 | @@ -608,7 +609,7 @@ class SharingService: |
1217 | for (grantee, permissions, shared_artifact_types) in grant_permissions: |
1218 | some_things_shared = len(shared_artifact_types) > 0 |
1219 | grantee_permissions = {} |
1220 | - for (policy, permission) in permissions.iteritems(): |
1221 | + for (policy, permission) in six.iteritems(permissions): |
1222 | grantee_permissions[policy.type.name] = permission.name |
1223 | shared_artifact_type_names = [ |
1224 | info_type.name for info_type in shared_artifact_types] |
1225 | diff --git a/lib/lp/scripts/utilities/warninghandler.py b/lib/lp/scripts/utilities/warninghandler.py |
1226 | index 46b8a73..cb0c4ff 100644 |
1227 | --- a/lib/lp/scripts/utilities/warninghandler.py |
1228 | +++ b/lib/lp/scripts/utilities/warninghandler.py |
1229 | @@ -12,6 +12,8 @@ import StringIO |
1230 | import sys |
1231 | import warnings |
1232 | |
1233 | +import six |
1234 | + |
1235 | |
1236 | class WarningReport: |
1237 | |
1238 | @@ -211,7 +213,7 @@ def report_other_warnings(): |
1239 | if other_warnings: |
1240 | print(file=sys.stderr) |
1241 | print("General warnings.", file=sys.stderr) |
1242 | - for warninginfo in other_warnings.itervalues(): |
1243 | + for warninginfo in six.itervalues(other_warnings): |
1244 | print(file=sys.stderr) |
1245 | print(warninginfo, file=sys.stderr) |
1246 | |
1247 | diff --git a/lib/lp/services/command_spawner.py b/lib/lp/services/command_spawner.py |
1248 | index dcca28f..539a3fb 100644 |
1249 | --- a/lib/lp/services/command_spawner.py |
1250 | +++ b/lib/lp/services/command_spawner.py |
1251 | @@ -151,7 +151,7 @@ class CommandSpawner: |
1252 | processes are cleaned up. Until then, they will stay around as |
1253 | zombies. |
1254 | """ |
1255 | - for process in self.running_processes.iterkeys(): |
1256 | + for process in self.running_processes: |
1257 | process.terminate() |
1258 | |
1259 | def _spawn(self, command): |
1260 | diff --git a/lib/lp/services/config/__init__.py b/lib/lp/services/config/__init__.py |
1261 | index 3c6ad51..ebe9ebf 100644 |
1262 | --- a/lib/lp/services/config/__init__.py |
1263 | +++ b/lib/lp/services/config/__init__.py |
1264 | @@ -22,6 +22,7 @@ import sys |
1265 | |
1266 | from lazr.config import ImplicitTypeSchema |
1267 | from lazr.config.interfaces import ConfigErrors |
1268 | +import six |
1269 | from six.moves.urllib.parse import ( |
1270 | urlparse, |
1271 | urlunparse, |
1272 | @@ -459,7 +460,7 @@ class DatabaseConfig: |
1273 | |
1274 | Overriding a value to None removes the override. |
1275 | """ |
1276 | - for attr, value in kwargs.iteritems(): |
1277 | + for attr, value in six.iteritems(kwargs): |
1278 | assert attr in self._db_config_attrs, ( |
1279 | "%s cannot be overridden" % attr) |
1280 | if value is None: |
1281 | diff --git a/lib/lp/services/database/bulk.py b/lib/lp/services/database/bulk.py |
1282 | index f73bbf8..840e402 100644 |
1283 | --- a/lib/lp/services/database/bulk.py |
1284 | +++ b/lib/lp/services/database/bulk.py |
1285 | @@ -25,6 +25,7 @@ from operator import ( |
1286 | itemgetter, |
1287 | ) |
1288 | |
1289 | +import six |
1290 | from storm.databases.postgres import Returning |
1291 | from storm.expr import ( |
1292 | And, |
1293 | @@ -52,7 +53,7 @@ def collate(things, key): |
1294 | collection = defaultdict(list) |
1295 | for thing in things: |
1296 | collection[key(thing)].append(thing) |
1297 | - return collection.iteritems() |
1298 | + return six.iteritems(collection) |
1299 | |
1300 | |
1301 | def get_type(thing): |
1302 | diff --git a/lib/lp/services/features/testing.py b/lib/lp/services/features/testing.py |
1303 | index 998138d..3a2d69b 100644 |
1304 | --- a/lib/lp/services/features/testing.py |
1305 | +++ b/lib/lp/services/features/testing.py |
1306 | @@ -13,6 +13,7 @@ __all__ = [ |
1307 | from fixtures import Fixture |
1308 | from lazr.restful.utils import get_current_browser_request |
1309 | import psycopg2 |
1310 | +import six |
1311 | |
1312 | from lp.services.features import ( |
1313 | get_relevant_feature_controller, |
1314 | @@ -91,7 +92,7 @@ class FeatureFixtureMixin: |
1315 | scope='default', |
1316 | priority=999, |
1317 | value=unicode(value)) |
1318 | - for flag_name, value in self.desired_features.iteritems() |
1319 | + for flag_name, value in six.iteritems(self.desired_features) |
1320 | if value is not None] |
1321 | |
1322 | if self.full_feature_rules is not None: |
1323 | diff --git a/lib/lp/services/librarianserver/testing/fake.py b/lib/lp/services/librarianserver/testing/fake.py |
1324 | index 37d6bb6..e1e1f5e 100644 |
1325 | --- a/lib/lp/services/librarianserver/testing/fake.py |
1326 | +++ b/lib/lp/services/librarianserver/testing/fake.py |
1327 | @@ -19,6 +19,7 @@ import hashlib |
1328 | from StringIO import StringIO |
1329 | |
1330 | from fixtures import Fixture |
1331 | +import six |
1332 | from six.moves.urllib.parse import urljoin |
1333 | import transaction |
1334 | from transaction.interfaces import ISynchronizer |
1335 | @@ -138,7 +139,7 @@ class FakeLibrarian(Fixture): |
1336 | database transaction. |
1337 | """ |
1338 | # Note that all files have been committed to storage. |
1339 | - for alias in self.aliases.itervalues(): |
1340 | + for alias in six.itervalues(self.aliases): |
1341 | alias.file_committed = True |
1342 | |
1343 | def _makeAlias(self, file_id, name, content, content_type): |
1344 | @@ -175,7 +176,7 @@ class FakeLibrarian(Fixture): |
1345 | |
1346 | def findBySHA256(self, sha256): |
1347 | "See `ILibraryFileAliasSet`.""" |
1348 | - for alias in self.aliases.itervalues(): |
1349 | + for alias in six.itervalues(self.aliases): |
1350 | if alias.content.sha256 == sha256: |
1351 | return alias |
1352 | |
1353 | diff --git a/lib/lp/services/mail/basemailer.py b/lib/lp/services/mail/basemailer.py |
1354 | index a2f8a40..280ab78 100644 |
1355 | --- a/lib/lp/services/mail/basemailer.py |
1356 | +++ b/lib/lp/services/mail/basemailer.py |
1357 | @@ -12,6 +12,7 @@ import logging |
1358 | from smtplib import SMTPException |
1359 | import sys |
1360 | |
1361 | +import six |
1362 | from zope.component import getUtility |
1363 | from zope.error.interfaces import IErrorReportingUtility |
1364 | from zope.security.management import getSecurityPolicy |
1365 | @@ -79,7 +80,7 @@ class BaseMailer: |
1366 | self._subject_template = subject |
1367 | self._template_name = template_name |
1368 | self._recipients = NotificationRecipientSet() |
1369 | - for recipient, reason in recipients.iteritems(): |
1370 | + for recipient, reason in six.iteritems(recipients): |
1371 | self._recipients.add(recipient, reason, reason.mail_header) |
1372 | self.from_address = from_address |
1373 | self.delta = delta |
1374 | diff --git a/lib/lp/services/messaging/tests/test_rabbit.py b/lib/lp/services/messaging/tests/test_rabbit.py |
1375 | index 6cd9f99..dfd48af 100644 |
1376 | --- a/lib/lp/services/messaging/tests/test_rabbit.py |
1377 | +++ b/lib/lp/services/messaging/tests/test_rabbit.py |
1378 | @@ -9,6 +9,7 @@ from functools import partial |
1379 | from itertools import count |
1380 | import socket |
1381 | |
1382 | +import six |
1383 | from testtools.testcase import ExpectedException |
1384 | import transaction |
1385 | from transaction._transaction import Status as TransactionStatus |
1386 | @@ -396,7 +397,7 @@ class TestRabbit(RabbitTestCase): |
1387 | return set() |
1388 | else: |
1389 | return set( |
1390 | - sync.session for sync in syncs_set.data.itervalues() |
1391 | + sync.session for sync in six.itervalues(syncs_set.data) |
1392 | if isinstance(sync, RabbitSessionTransactionSync)) |
1393 | |
1394 | def test_global_session(self): |
1395 | diff --git a/lib/lp/services/osutils.py b/lib/lp/services/osutils.py |
1396 | index b487165..7eafc40 100644 |
1397 | --- a/lib/lp/services/osutils.py |
1398 | +++ b/lib/lp/services/osutils.py |
1399 | @@ -28,6 +28,8 @@ from signal import ( |
1400 | ) |
1401 | import time |
1402 | |
1403 | +import six |
1404 | + |
1405 | |
1406 | def remove_tree(path): |
1407 | """Remove the tree at 'path' from disk.""" |
1408 | @@ -41,7 +43,7 @@ def set_environ(new_values): |
1409 | :return: a dict of the old values |
1410 | """ |
1411 | old_values = {} |
1412 | - for name, value in new_values.iteritems(): |
1413 | + for name, value in six.iteritems(new_values): |
1414 | old_values[name] = os.environ.get(name) |
1415 | if value is None: |
1416 | if old_values[name] is not None: |
1417 | diff --git a/lib/lp/services/testing/customresult.py b/lib/lp/services/testing/customresult.py |
1418 | index 2164f3d..5862f84 100644 |
1419 | --- a/lib/lp/services/testing/customresult.py |
1420 | +++ b/lib/lp/services/testing/customresult.py |
1421 | @@ -11,6 +11,7 @@ __all__ = [ |
1422 | |
1423 | from unittest import TestSuite |
1424 | |
1425 | +import six |
1426 | from zope.testrunner import find |
1427 | |
1428 | |
1429 | @@ -65,7 +66,7 @@ def filter_tests(list_name, reorder_tests=False): |
1430 | test_lookup = {} |
1431 | # Multiple unique testcases can be represented by a single id and they |
1432 | # must be tracked separately. |
1433 | - for layer_name, suite in tests_by_layer_name.iteritems(): |
1434 | + for layer_name, suite in six.iteritems(tests_by_layer_name): |
1435 | for testcase in suite: |
1436 | layer_to_tests = test_lookup.setdefault( |
1437 | testcase.id(), {}) |
1438 | diff --git a/lib/lp/services/utils.py b/lib/lp/services/utils.py |
1439 | index beda118..ea661c5 100644 |
1440 | --- a/lib/lp/services/utils.py |
1441 | +++ b/lib/lp/services/utils.py |
1442 | @@ -52,6 +52,7 @@ from fixtures import ( |
1443 | ) |
1444 | from lazr.enum import BaseItem |
1445 | import pytz |
1446 | +import six |
1447 | from six.moves import cPickle as pickle |
1448 | from twisted.python.util import mergeFunctionMetadata |
1449 | from zope.security.proxy import isinstance as zope_isinstance |
1450 | @@ -388,7 +389,7 @@ def obfuscate_structure(o): |
1451 | elif isinstance(o, (dict)): |
1452 | return dict( |
1453 | (obfuscate_structure(key), obfuscate_structure(value)) |
1454 | - for key, value in o.iteritems()) |
1455 | + for key, value in six.iteritems(o)) |
1456 | else: |
1457 | return o |
1458 | |
1459 | diff --git a/lib/lp/services/webapp/escaping.py b/lib/lp/services/webapp/escaping.py |
1460 | index 8c4d965..bce499e 100644 |
1461 | --- a/lib/lp/services/webapp/escaping.py |
1462 | +++ b/lib/lp/services/webapp/escaping.py |
1463 | @@ -9,6 +9,7 @@ __all__ = [ |
1464 | ] |
1465 | |
1466 | from lazr.restful.utils import get_current_browser_request |
1467 | +import six |
1468 | from zope.i18n import ( |
1469 | Message, |
1470 | translate, |
1471 | @@ -95,7 +96,7 @@ class structured: |
1472 | self.escapedtext = text % tuple(html_escape(rep) for rep in reps) |
1473 | elif kwreps: |
1474 | self.escapedtext = text % dict( |
1475 | - (k, html_escape(v)) for k, v in kwreps.iteritems()) |
1476 | + (k, html_escape(v)) for k, v in six.iteritems(kwreps)) |
1477 | else: |
1478 | self.escapedtext = text |
1479 | |
1480 | diff --git a/lib/lp/services/webapp/login.py b/lib/lp/services/webapp/login.py |
1481 | index 43eb478..fdbd079 100644 |
1482 | --- a/lib/lp/services/webapp/login.py |
1483 | +++ b/lib/lp/services/webapp/login.py |
1484 | @@ -290,7 +290,7 @@ class OpenIDCallbackView(OpenIDLogin): |
1485 | |
1486 | def _gather_params(self, request): |
1487 | params = dict(request.form) |
1488 | - for key, value in request.query_string_params.iteritems(): |
1489 | + for key, value in six.iteritems(request.query_string_params): |
1490 | if len(value) > 1: |
1491 | raise ValueError( |
1492 | 'Did not expect multi-valued fields.') |
1493 | diff --git a/lib/lp/services/webapp/servers.py b/lib/lp/services/webapp/servers.py |
1494 | index 8b85df8..1f77b76 100644 |
1495 | --- a/lib/lp/services/webapp/servers.py |
1496 | +++ b/lib/lp/services/webapp/servers.py |
1497 | @@ -529,7 +529,7 @@ def get_query_string_params(request): |
1498 | parsed_qs = parse_qs(query_string, keep_blank_values=True) |
1499 | # Use BrowserRequest._decode() for decoding the received parameters. |
1500 | decoded_qs = {} |
1501 | - for key, values in parsed_qs.iteritems(): |
1502 | + for key, values in six.iteritems(parsed_qs): |
1503 | decoded_qs[key] = [ |
1504 | request._decode(value) for value in values] |
1505 | return decoded_qs |
1506 | diff --git a/lib/lp/services/webhooks/interfaces.py b/lib/lp/services/webhooks/interfaces.py |
1507 | index d4d20e3..ad01625 100644 |
1508 | --- a/lib/lp/services/webhooks/interfaces.py |
1509 | +++ b/lib/lp/services/webhooks/interfaces.py |
1510 | @@ -40,6 +40,7 @@ from lazr.restful.fields import ( |
1511 | Reference, |
1512 | ) |
1513 | from lazr.restful.interface import copy_field |
1514 | +import six |
1515 | from six.moves import http_client |
1516 | from zope.interface import ( |
1517 | Attribute, |
1518 | @@ -105,7 +106,7 @@ class AnyWebhookEventTypeVocabulary(SimpleVocabulary): |
1519 | def __init__(self, context): |
1520 | terms = [ |
1521 | self.createTerm(key, key, value) |
1522 | - for key, value in WEBHOOK_EVENT_TYPES.iteritems()] |
1523 | + for key, value in six.iteritems(WEBHOOK_EVENT_TYPES)] |
1524 | super(AnyWebhookEventTypeVocabulary, self).__init__(terms) |
1525 | |
1526 | |
1527 | diff --git a/lib/lp/soyuz/browser/tests/archive-views.txt b/lib/lp/soyuz/browser/tests/archive-views.txt |
1528 | index 8f440d7..72c1392 100644 |
1529 | --- a/lib/lp/soyuz/browser/tests/archive-views.txt |
1530 | +++ b/lib/lp/soyuz/browser/tests/archive-views.txt |
1531 | @@ -105,8 +105,10 @@ usage details in a dictionary containing: |
1532 | We will use a helper function for printing the returned dictionary |
1533 | contents. |
1534 | |
1535 | + >>> import six |
1536 | + |
1537 | >>> def print_repository_usage(repository_usage): |
1538 | - ... for key, value in sorted(repository_usage.iteritems()): |
1539 | + ... for key, value in sorted(six.iteritems(repository_usage)): |
1540 | ... print('%s: %s' % (key, value)) |
1541 | |
1542 | Celso PPA has some packages, but still below the quota. |
1543 | diff --git a/lib/lp/soyuz/model/packagediff.py b/lib/lp/soyuz/model/packagediff.py |
1544 | index 6933c31..12437cd 100644 |
1545 | --- a/lib/lp/soyuz/model/packagediff.py |
1546 | +++ b/lib/lp/soyuz/model/packagediff.py |
1547 | @@ -16,6 +16,7 @@ import shutil |
1548 | import subprocess |
1549 | import tempfile |
1550 | |
1551 | +import six |
1552 | from sqlobject import ForeignKey |
1553 | from storm.expr import Desc |
1554 | from storm.store import EmptyResultSet |
1555 | @@ -215,7 +216,7 @@ class PackageDiff(SQLBase): |
1556 | zip(directions, (self.from_source, self.to_source))) |
1557 | |
1558 | # Iterate over the packages to be diff'ed. |
1559 | - for direction, package in packages.iteritems(): |
1560 | + for direction, package in six.iteritems(packages): |
1561 | # Create distinct directory locations for |
1562 | # 'from' and 'to' files. |
1563 | absolute_path = os.path.join(tmp_dir, direction) |
1564 | diff --git a/lib/lp/soyuz/model/publishing.py b/lib/lp/soyuz/model/publishing.py |
1565 | index fafd7f9..1c5d384 100644 |
1566 | --- a/lib/lp/soyuz/model/publishing.py |
1567 | +++ b/lib/lp/soyuz/model/publishing.py |
1568 | @@ -22,6 +22,7 @@ import os |
1569 | import sys |
1570 | |
1571 | import pytz |
1572 | +import six |
1573 | from sqlobject import ( |
1574 | ForeignKey, |
1575 | IntCol, |
1576 | @@ -1012,7 +1013,7 @@ def expand_binary_requests(distroseries, binaries): |
1577 | arch_map = dict((arch.architecturetag, arch) for arch in archs) |
1578 | |
1579 | expanded = [] |
1580 | - for bpr, overrides in binaries.iteritems(): |
1581 | + for bpr, overrides in six.iteritems(binaries): |
1582 | if bpr.architecturespecific: |
1583 | # Find the DAS in this series corresponding to the original |
1584 | # build arch tag. If it does not exist or is disabled, we should |
1585 | diff --git a/lib/lp/soyuz/scripts/custom_uploads_copier.py b/lib/lp/soyuz/scripts/custom_uploads_copier.py |
1586 | index e6f7e83..21cc1f2 100644 |
1587 | --- a/lib/lp/soyuz/scripts/custom_uploads_copier.py |
1588 | +++ b/lib/lp/soyuz/scripts/custom_uploads_copier.py |
1589 | @@ -14,6 +14,8 @@ __all__ = [ |
1590 | |
1591 | from operator import attrgetter |
1592 | |
1593 | +import six |
1594 | + |
1595 | from lp.archivepublisher.ddtp_tarball import DdtpTarballUpload |
1596 | from lp.archivepublisher.debian_installer import DebianInstallerUpload |
1597 | from lp.archivepublisher.dist_upgrader import DistUpgraderUpload |
1598 | @@ -163,7 +165,7 @@ class CustomUploadsCopier: |
1599 | self.target_series, source_pocket=self.target_pocket) |
1600 | source_uploads = self.getLatestUploads( |
1601 | source_series, source_pocket=source_pocket) |
1602 | - for upload in source_uploads.itervalues(): |
1603 | + for upload in six.itervalues(source_uploads): |
1604 | if (not self.isObsolete(upload, target_uploads) and |
1605 | self.isForValidDAS(upload)): |
1606 | self.copyUpload(upload) |
1607 | diff --git a/lib/lp/soyuz/scripts/gina/handlers.py b/lib/lp/soyuz/scripts/gina/handlers.py |
1608 | index 54539a4..597e5aa 100644 |
1609 | --- a/lib/lp/soyuz/scripts/gina/handlers.py |
1610 | +++ b/lib/lp/soyuz/scripts/gina/handlers.py |
1611 | @@ -24,6 +24,7 @@ from cStringIO import StringIO |
1612 | import os |
1613 | import re |
1614 | |
1615 | +import six |
1616 | from sqlobject import ( |
1617 | SQLObjectMoreThanOneResultError, |
1618 | SQLObjectNotFound, |
1619 | @@ -504,7 +505,7 @@ class SourcePackageHandler: |
1620 | dsc_contents = parse_tagfile(dsc_path) |
1621 | dsc_contents = dict([ |
1622 | (name.lower(), value) for |
1623 | - (name, value) in dsc_contents.iteritems()]) |
1624 | + (name, value) in six.iteritems(dsc_contents)]) |
1625 | |
1626 | # Since the dsc doesn't know, we add in the directory, package |
1627 | # component and section |
1628 | diff --git a/lib/lp/soyuz/scripts/gina/runner.py b/lib/lp/soyuz/scripts/gina/runner.py |
1629 | index d9edd1f..631323f 100644 |
1630 | --- a/lib/lp/soyuz/scripts/gina/runner.py |
1631 | +++ b/lib/lp/soyuz/scripts/gina/runner.py |
1632 | @@ -157,7 +157,7 @@ def import_sourcepackages(distro, packages_map, package_root, |
1633 | npacks = len(packages_map.src_map) |
1634 | log.info('%i Source Packages to be imported', npacks) |
1635 | |
1636 | - for package in sorted(packages_map.src_map.iterkeys()): |
1637 | + for package in sorted(packages_map.src_map): |
1638 | for source in packages_map.src_map[package]: |
1639 | attempt_source_package_import( |
1640 | distro, source, package_root, importer_handler) |
1641 | @@ -193,7 +193,7 @@ def import_binarypackages(distro, packages_map, package_root, |
1642 | log.info( |
1643 | '%i Binary Packages to be imported for %s', npacks, archtag) |
1644 | # Go over binarypackages importing them for this architecture |
1645 | - for package_name in sorted(packages_map.bin_map[archtag].iterkeys()): |
1646 | + for package_name in sorted(packages_map.bin_map[archtag]): |
1647 | binary = packages_map.bin_map[archtag][package_name] |
1648 | try: |
1649 | try: |
1650 | diff --git a/lib/lp/testing/__init__.py b/lib/lp/testing/__init__.py |
1651 | index 20a50d9..81e86f1 100644 |
1652 | --- a/lib/lp/testing/__init__.py |
1653 | +++ b/lib/lp/testing/__init__.py |
1654 | @@ -96,6 +96,7 @@ import oops_datedir_repo.serializer_rfc822 |
1655 | import pytz |
1656 | import scandir |
1657 | import simplejson |
1658 | +import six |
1659 | from storm.store import Store |
1660 | import subunit |
1661 | import testtools |
1662 | @@ -697,7 +698,7 @@ class TestCase(testtools.TestCase, fixtures.TestWithFixtures): |
1663 | The config values will be restored during test tearDown. |
1664 | """ |
1665 | name = self.factory.getUniqueString() |
1666 | - body = '\n'.join("%s: %s" % (k, v) for k, v in kwargs.iteritems()) |
1667 | + body = '\n'.join("%s: %s" % (k, v) for k, v in six.iteritems(kwargs)) |
1668 | config.push(name, "\n[%s]\n%s\n" % (section, body)) |
1669 | self.addCleanup(config.pop, name) |
1670 | |
1671 | @@ -1527,13 +1528,13 @@ def monkey_patch(context, **kwargs): |
1672 | """ |
1673 | old_values = {} |
1674 | not_set = object() |
1675 | - for name, value in kwargs.iteritems(): |
1676 | + for name, value in six.iteritems(kwargs): |
1677 | old_values[name] = getattr(context, name, not_set) |
1678 | setattr(context, name, value) |
1679 | try: |
1680 | yield |
1681 | finally: |
1682 | - for name, value in old_values.iteritems(): |
1683 | + for name, value in six.iteritems(old_values): |
1684 | if value is not_set: |
1685 | delattr(context, name) |
1686 | else: |
1687 | diff --git a/lib/lp/testing/swift/fakeswift.py b/lib/lp/testing/swift/fakeswift.py |
1688 | index 0712e7a..c90dc0d 100644 |
1689 | --- a/lib/lp/testing/swift/fakeswift.py |
1690 | +++ b/lib/lp/testing/swift/fakeswift.py |
1691 | @@ -22,6 +22,7 @@ import sys |
1692 | import time |
1693 | import uuid |
1694 | |
1695 | +import six |
1696 | from twisted.web import ( |
1697 | http, |
1698 | resource, |
1699 | @@ -77,7 +78,7 @@ class FakeKeystone(resource.Resource): |
1700 | if self._isValidToken(token, tenant_name): |
1701 | return token |
1702 | else: |
1703 | - for id, token in self.tokens.iteritems(): |
1704 | + for id, token in six.iteritems(self.tokens): |
1705 | if self._isValidToken(token, tenant_name): |
1706 | return token |
1707 | |
1708 | diff --git a/lib/lp/translations/browser/translationlinksaggregator.py b/lib/lp/translations/browser/translationlinksaggregator.py |
1709 | index 3f196bc..4b06509 100644 |
1710 | --- a/lib/lp/translations/browser/translationlinksaggregator.py |
1711 | +++ b/lib/lp/translations/browser/translationlinksaggregator.py |
1712 | @@ -7,6 +7,8 @@ __all__ = [ |
1713 | 'TranslationLinksAggregator', |
1714 | ] |
1715 | |
1716 | +import six |
1717 | + |
1718 | from lp.services.webapp import canonical_url |
1719 | from lp.translations.interfaces.pofile import IPOFile |
1720 | from lp.translations.model.productserieslanguage import ProductSeriesLanguage |
1721 | @@ -177,10 +179,10 @@ class TranslationLinksAggregator: |
1722 | returns for the sensible chunks. |
1723 | """ |
1724 | links = [] |
1725 | - for target, sheets in self._bundle(sheets).iteritems(): |
1726 | + for target, sheets in six.iteritems(self._bundle(sheets)): |
1727 | assert sheets, "Translation target has no POFiles or templates." |
1728 | links_and_sheets = self._circumscribe(sheets) |
1729 | - for link, covered_sheets in links_and_sheets.iteritems(): |
1730 | + for link, covered_sheets in six.iteritems(links_and_sheets): |
1731 | links.append(self.describe(target, link, covered_sheets)) |
1732 | |
1733 | return links |
1734 | diff --git a/lib/lp/translations/browser/translationmessage.py b/lib/lp/translations/browser/translationmessage.py |
1735 | index ef75f6c..dbdf1d1 100644 |
1736 | --- a/lib/lp/translations/browser/translationmessage.py |
1737 | +++ b/lib/lp/translations/browser/translationmessage.py |
1738 | @@ -23,6 +23,7 @@ import operator |
1739 | import re |
1740 | |
1741 | import pytz |
1742 | +import six |
1743 | from six.moves.urllib.parse import ( |
1744 | parse_qsl, |
1745 | urlencode, |
1746 | @@ -96,7 +97,7 @@ def revert_unselected_translations(translations, current_message, |
1747 | original_translations = dict(enumerate(current_message.translations)) |
1748 | |
1749 | output = {} |
1750 | - for plural_form, translation in translations.iteritems(): |
1751 | + for plural_form, translation in six.iteritems(translations): |
1752 | if plural_form in plural_indices_to_store: |
1753 | output[plural_form] = translation |
1754 | elif original_translations.get(plural_form) is None: |
1755 | @@ -113,7 +114,7 @@ def contains_translations(translations): |
1756 | :param translations: a dict mapping plural forms to their respective |
1757 | translation strings. |
1758 | """ |
1759 | - for text in translations.itervalues(): |
1760 | + for text in six.itervalues(translations): |
1761 | if text is not None and len(text) != 0: |
1762 | return True |
1763 | return False |
1764 | diff --git a/lib/lp/translations/doc/translationimportqueue.txt b/lib/lp/translations/doc/translationimportqueue.txt |
1765 | index 9f7d8c9..c62423b 100644 |
1766 | --- a/lib/lp/translations/doc/translationimportqueue.txt |
1767 | +++ b/lib/lp/translations/doc/translationimportqueue.txt |
1768 | @@ -1223,9 +1223,11 @@ bug 138650 for an example). |
1769 | If such bad requests do end up on the import queue, the import queue code will |
1770 | raise errors about them. |
1771 | |
1772 | + >>> import six |
1773 | + |
1774 | >>> def print_import_failures(import_script): |
1775 | ... """List failures recorded in an import script instance.""" |
1776 | - ... for reason, entries in script.failures.iteritems(): |
1777 | + ... for reason, entries in six.iteritems(script.failures): |
1778 | ... print(reason) |
1779 | ... for entry in entries: |
1780 | ... print("-> " + entry) |
1781 | diff --git a/lib/lp/translations/model/potemplate.py b/lib/lp/translations/model/potemplate.py |
1782 | index ba0a632..70dedd2 100644 |
1783 | --- a/lib/lp/translations/model/potemplate.py |
1784 | +++ b/lib/lp/translations/model/potemplate.py |
1785 | @@ -19,6 +19,7 @@ import operator |
1786 | import os |
1787 | |
1788 | from psycopg2.extensions import TransactionRollbackError |
1789 | +import six |
1790 | from sqlobject import ( |
1791 | BoolCol, |
1792 | ForeignKey, |
1793 | @@ -1560,7 +1561,7 @@ class POTemplateSharingSubset(object): |
1794 | equivalents[key] = [] |
1795 | equivalents[key].append(template) |
1796 | |
1797 | - for equivalence_list in equivalents.itervalues(): |
1798 | + for equivalence_list in six.itervalues(equivalents): |
1799 | # Sort potemplates from "most representative" to "least |
1800 | # representative." |
1801 | equivalence_list.sort(key=POTemplate.sharingKey, reverse=True) |
1802 | diff --git a/lib/lp/translations/model/potmsgset.py b/lib/lp/translations/model/potmsgset.py |
1803 | index 12f9f05..f256384 100644 |
1804 | --- a/lib/lp/translations/model/potmsgset.py |
1805 | +++ b/lib/lp/translations/model/potmsgset.py |
1806 | @@ -14,6 +14,7 @@ from collections import ( |
1807 | import logging |
1808 | import re |
1809 | |
1810 | +import six |
1811 | from sqlobject import ( |
1812 | ForeignKey, |
1813 | SQLObjectNotFound, |
1814 | @@ -122,7 +123,7 @@ def dictify_translations(translations): |
1815 | # Filter out None values. |
1816 | return dict( |
1817 | (form, translation) |
1818 | - for form, translation in translations.iteritems() |
1819 | + for form, translation in six.iteritems(translations) |
1820 | if translation is not None) |
1821 | |
1822 | |
1823 | @@ -611,7 +612,7 @@ class POTMsgSet(SQLBase): |
1824 | |
1825 | forms = dict( |
1826 | ('msgstr%d' % form, potranslation) |
1827 | - for form, potranslation in potranslations.iteritems()) |
1828 | + for form, potranslation in six.iteritems(potranslations)) |
1829 | |
1830 | if from_import: |
1831 | origin = RosettaTranslationOrigin.SCM |
1832 | @@ -748,7 +749,7 @@ class POTMsgSet(SQLBase): |
1833 | |
1834 | translation_args = dict( |
1835 | ('msgstr%d' % form, translation) |
1836 | - for form, translation in translations.iteritems()) |
1837 | + for form, translation in six.iteritems(translations)) |
1838 | |
1839 | return TranslationMessage( |
1840 | potmsgset=self, |
1841 | diff --git a/lib/lp/translations/model/translationimportqueue.py b/lib/lp/translations/model/translationimportqueue.py |
1842 | index 3ded490..483a4c3 100644 |
1843 | --- a/lib/lp/translations/model/translationimportqueue.py |
1844 | +++ b/lib/lp/translations/model/translationimportqueue.py |
1845 | @@ -19,6 +19,7 @@ from textwrap import dedent |
1846 | |
1847 | import posixpath |
1848 | import pytz |
1849 | +import six |
1850 | from sqlobject import ( |
1851 | BoolCol, |
1852 | ForeignKey, |
1853 | @@ -1457,7 +1458,8 @@ class TranslationImportQueue: |
1854 | """ |
1855 | now = datetime.datetime.now(pytz.UTC) |
1856 | deletion_clauses = [] |
1857 | - for status, max_age in translation_import_queue_entry_age.iteritems(): |
1858 | + for status, max_age in six.iteritems( |
1859 | + translation_import_queue_entry_age): |
1860 | cutoff = now - max_age |
1861 | deletion_clauses.append(And( |
1862 | TranslationImportQueueEntry.status == status, |
1863 | diff --git a/lib/lp/translations/model/translationsharingjob.py b/lib/lp/translations/model/translationsharingjob.py |
1864 | index 8a60008..313e8db 100644 |
1865 | --- a/lib/lp/translations/model/translationsharingjob.py |
1866 | +++ b/lib/lp/translations/model/translationsharingjob.py |
1867 | @@ -170,7 +170,7 @@ class TranslationSharingJobDerived( |
1868 | for. |
1869 | :param event: The event itself. |
1870 | """ |
1871 | - for event_type, job_classes in cls._event_types.iteritems(): |
1872 | + for event_type, job_classes in six.iteritems(cls._event_types): |
1873 | if not event_type.providedBy(event): |
1874 | continue |
1875 | for job_class in job_classes: |
1876 | @@ -191,7 +191,7 @@ class TranslationSharingJobDerived( |
1877 | # Ignore changes to POTemplates that are neither renames, |
1878 | # nor moves to a different package/project. |
1879 | return |
1880 | - for event_type, job_classes in cls._event_types.iteritems(): |
1881 | + for event_type, job_classes in six.iteritems(cls._event_types): |
1882 | if not event_type.providedBy(event): |
1883 | continue |
1884 | for job_class in job_classes: |
1885 | diff --git a/lib/lp/translations/scripts/po_import.py b/lib/lp/translations/scripts/po_import.py |
1886 | index 3e97f8c..9c9779e 100644 |
1887 | --- a/lib/lp/translations/scripts/po_import.py |
1888 | +++ b/lib/lp/translations/scripts/po_import.py |
1889 | @@ -17,6 +17,7 @@ from datetime import ( |
1890 | import sys |
1891 | |
1892 | import pytz |
1893 | +import six |
1894 | from zope.component import getUtility |
1895 | |
1896 | from lp.app.interfaces.launchpad import ILaunchpadCelebrities |
1897 | @@ -212,5 +213,5 @@ class TranslationsImport(LaunchpadCronScript): |
1898 | |
1899 | def _reportFailures(self): |
1900 | """Bulk-report deferred failures as oopses.""" |
1901 | - for reason, entries in self.failures.iteritems(): |
1902 | + for reason, entries in six.iteritems(self.failures): |
1903 | self._reportOops(reason, entries) |
1904 | diff --git a/lib/lp/translations/scripts/tests/test_reupload_translations.py b/lib/lp/translations/scripts/tests/test_reupload_translations.py |
1905 | index f2a449f..2ec0cee 100644 |
1906 | --- a/lib/lp/translations/scripts/tests/test_reupload_translations.py |
1907 | +++ b/lib/lp/translations/scripts/tests/test_reupload_translations.py |
1908 | @@ -11,6 +11,7 @@ import re |
1909 | from StringIO import StringIO |
1910 | import tarfile |
1911 | |
1912 | +import six |
1913 | import transaction |
1914 | from zope.security.proxy import removeSecurityProxy |
1915 | |
1916 | @@ -61,7 +62,7 @@ def upload_tarball(translation_files): |
1917 | """ |
1918 | buf = StringIO() |
1919 | tarball = tarfile.open('', 'w:gz', buf) |
1920 | - for name, contents in translation_files.iteritems(): |
1921 | + for name, contents in six.iteritems(translation_files): |
1922 | pseudofile = StringIO(contents) |
1923 | tarinfo = tarfile.TarInfo() |
1924 | tarinfo.name = name |
1925 | @@ -93,7 +94,7 @@ def filter_paths(files_dict): |
1926 | applied to each file's path, and non-Ubuntu files left out. |
1927 | """ |
1928 | filtered_dict = {} |
1929 | - for original_path, content in files_dict.iteritems(): |
1930 | + for original_path, content in six.iteritems(files_dict): |
1931 | new_path = _filter_ubuntu_translation_file(original_path) |
1932 | if new_path: |
1933 | filtered_dict[new_path] = content |
1934 | diff --git a/lib/lp/translations/scripts/tests/test_translations_to_branch.py b/lib/lp/translations/scripts/tests/test_translations_to_branch.py |
1935 | index 248b2e0..0cd058a 100644 |
1936 | --- a/lib/lp/translations/scripts/tests/test_translations_to_branch.py |
1937 | +++ b/lib/lp/translations/scripts/tests/test_translations_to_branch.py |
1938 | @@ -9,6 +9,7 @@ from textwrap import dedent |
1939 | |
1940 | from breezy.errors import NotBranchError |
1941 | import pytz |
1942 | +import six |
1943 | from testtools.matchers import MatchesRegex |
1944 | import transaction |
1945 | from zope.component import getUtility |
1946 | @@ -116,8 +117,8 @@ class TestExportTranslationsToBranch(TestCaseWithFactory): |
1947 | msgstr "Hallo Wereld"\n""", |
1948 | } |
1949 | |
1950 | - branch_filenames = set(branch_contents.iterkeys()) |
1951 | - expected_filenames = set(expected_contents.iterkeys()) |
1952 | + branch_filenames = set(branch_contents) |
1953 | + expected_filenames = set(expected_contents) |
1954 | |
1955 | unexpected_filenames = branch_filenames - expected_filenames |
1956 | self.assertEqual(set(), unexpected_filenames) |
1957 | @@ -125,7 +126,7 @@ class TestExportTranslationsToBranch(TestCaseWithFactory): |
1958 | missing_filenames = expected_filenames - branch_filenames |
1959 | self.assertEqual(set(), missing_filenames) |
1960 | |
1961 | - for filename, expected in expected_contents.iteritems(): |
1962 | + for filename, expected in six.iteritems(expected_contents): |
1963 | contents = branch_contents[filename].lstrip('\n') |
1964 | pattern = dedent(expected.lstrip('\n')) |
1965 | if not re.match(pattern, contents, re.MULTILINE): |
1966 | diff --git a/lib/lp/translations/stories/webservice/xx-translationimportqueue.txt b/lib/lp/translations/stories/webservice/xx-translationimportqueue.txt |
1967 | index ca3f633..4b668ed 100644 |
1968 | --- a/lib/lp/translations/stories/webservice/xx-translationimportqueue.txt |
1969 | +++ b/lib/lp/translations/stories/webservice/xx-translationimportqueue.txt |
1970 | @@ -29,7 +29,7 @@ to be cleaned up. |
1971 | ... shown. If omitted, all keys are shown. |
1972 | ... """ |
1973 | ... print('Entry:') |
1974 | - ... for key in sorted(a_dict.iterkeys()): |
1975 | + ... for key in sorted(a_dict): |
1976 | ... if shown_keys is None or key in shown_keys: |
1977 | ... print('', key, a_dict[key]) |
1978 | |
1979 | diff --git a/lib/lp/translations/tests/test_potemplate.py b/lib/lp/translations/tests/test_potemplate.py |
1980 | index 4ebb735..d08826e 100644 |
1981 | --- a/lib/lp/translations/tests/test_potemplate.py |
1982 | +++ b/lib/lp/translations/tests/test_potemplate.py |
1983 | @@ -5,6 +5,7 @@ __metaclass__ = type |
1984 | |
1985 | from operator import methodcaller |
1986 | |
1987 | +import six |
1988 | from zope.component import getUtility |
1989 | from zope.security.proxy import removeSecurityProxy |
1990 | |
1991 | @@ -193,8 +194,8 @@ class EquivalenceClassTestMixin: |
1992 | This ignores the ordering of templates in an equivalence class. |
1993 | A separate test looks at ordering. |
1994 | """ |
1995 | - self.assertEqual(set(actual.iterkeys()), set(expected.iterkeys())) |
1996 | - for key, value in actual.iteritems(): |
1997 | + self.assertEqual(set(actual), set(expected)) |
1998 | + for key, value in six.iteritems(actual): |
1999 | self.assertEqual(set(value), set(expected[key])) |
2000 | |
2001 | |
2002 | diff --git a/lib/lp/translations/tests/test_side.py b/lib/lp/translations/tests/test_side.py |
2003 | index f5807d0..c7ab892 100644 |
2004 | --- a/lib/lp/translations/tests/test_side.py |
2005 | +++ b/lib/lp/translations/tests/test_side.py |
2006 | @@ -5,6 +5,7 @@ |
2007 | |
2008 | __metaclass__ = type |
2009 | |
2010 | +import six |
2011 | from zope.component import getUtility |
2012 | from zope.interface.verify import verifyObject |
2013 | |
2014 | @@ -23,7 +24,7 @@ class TestTranslationSideTraitsSet(TestCaseWithFactory): |
2015 | def test_baseline(self): |
2016 | utility = getUtility(ITranslationSideTraitsSet) |
2017 | self.assertTrue(verifyObject(ITranslationSideTraitsSet, utility)) |
2018 | - for traits in utility.getAllTraits().itervalues(): |
2019 | + for traits in six.itervalues(utility.getAllTraits()): |
2020 | self.assertTrue(verifyObject(ITranslationSideTraits, traits)) |
2021 | |
2022 | def test_other_sides(self): |
2023 | @@ -64,7 +65,7 @@ class TestTranslationSideTraitsSet(TestCaseWithFactory): |
2024 | [TranslationSide.UPSTREAM, TranslationSide.UBUNTU], |
2025 | traits_dict.keys()) |
2026 | |
2027 | - for side, traits in traits_dict.iteritems(): |
2028 | + for side, traits in six.iteritems(traits_dict): |
2029 | self.assertEqual(side, traits.side) |
2030 | self.assertEqual(traits, utility.getTraits(side)) |
2031 | |
2032 | diff --git a/lib/lp/translations/utilities/gettext_po_parser.py b/lib/lp/translations/utilities/gettext_po_parser.py |
2033 | index c087ef9..78de456 100644 |
2034 | --- a/lib/lp/translations/utilities/gettext_po_parser.py |
2035 | +++ b/lib/lp/translations/utilities/gettext_po_parser.py |
2036 | @@ -20,6 +20,7 @@ import logging |
2037 | import re |
2038 | |
2039 | import pytz |
2040 | +import six |
2041 | from zope import datetime as zope_datetime |
2042 | from zope.interface import implementer |
2043 | |
2044 | @@ -230,7 +231,7 @@ class POHeader: |
2045 | |
2046 | def _parseHeaderFields(self): |
2047 | """Return plural form values based on the parsed header.""" |
2048 | - for key, value in self._header_dictionary.iteritems(): |
2049 | + for key, value in six.iteritems(self._header_dictionary): |
2050 | if key == 'plural-forms': |
2051 | parts = self._parseAssignments(value) |
2052 | nplurals = parts.get('nplurals') |
2053 | @@ -362,7 +363,7 @@ class POHeader: |
2054 | raise AssertionError('key %s is not being handled!' % value) |
2055 | |
2056 | # Now, we copy any other header information in the original .po file. |
2057 | - for key, value in self._header_dictionary.iteritems(): |
2058 | + for key, value in six.iteritems(self._header_dictionary): |
2059 | if key in self._handled_keys_mapping: |
2060 | # It's already handled, skip it. |
2061 | continue |
2062 | diff --git a/lib/lp/translations/utilities/pluralforms.py b/lib/lp/translations/utilities/pluralforms.py |
2063 | index 680ba14..8a82685 100644 |
2064 | --- a/lib/lp/translations/utilities/pluralforms.py |
2065 | +++ b/lib/lp/translations/utilities/pluralforms.py |
2066 | @@ -12,6 +12,8 @@ __all__ = [ |
2067 | import gettext |
2068 | import re |
2069 | |
2070 | +import six |
2071 | + |
2072 | from lp.translations.interfaces.translations import TranslationConstants |
2073 | |
2074 | |
2075 | @@ -47,7 +49,7 @@ def make_friendly_plural_forms(expression, expected_forms): |
2076 | |
2077 | return [ |
2078 | {'form': form, 'examples': examples} |
2079 | - for (form, examples) in forms.iteritems() |
2080 | + for (form, examples) in six.iteritems(forms) |
2081 | ] |
2082 | |
2083 | |
2084 | diff --git a/lib/lp/translations/utilities/tests/test_translation_importer.py b/lib/lp/translations/utilities/tests/test_translation_importer.py |
2085 | index dcf203b..2d47d01 100644 |
2086 | --- a/lib/lp/translations/utilities/tests/test_translation_importer.py |
2087 | +++ b/lib/lp/translations/utilities/tests/test_translation_importer.py |
2088 | @@ -7,6 +7,7 @@ __metaclass__ = type |
2089 | |
2090 | from io import BytesIO |
2091 | |
2092 | +import six |
2093 | import transaction |
2094 | |
2095 | from lp.services.log.logger import DevNullLogger |
2096 | @@ -96,7 +97,7 @@ class TranslationImporterTestCase(TestCaseWithFactory): |
2097 | exactly the same priority.""" |
2098 | for file_extension in TranslationImporter().supported_file_extensions: |
2099 | priorities = [] |
2100 | - for format, importer in importers.iteritems(): |
2101 | + for format, importer in six.iteritems(importers): |
2102 | if file_extension in importer.file_extensions: |
2103 | self.assertNotIn(importer.priority, priorities) |
2104 | priorities.append(importer.priority) |
2105 | diff --git a/lib/lp/translations/utilities/translation_import.py b/lib/lp/translations/utilities/translation_import.py |
2106 | index 197153d..f9af932 100644 |
2107 | --- a/lib/lp/translations/utilities/translation_import.py |
2108 | +++ b/lib/lp/translations/utilities/translation_import.py |
2109 | @@ -14,6 +14,7 @@ from operator import attrgetter |
2110 | |
2111 | import posixpath |
2112 | import pytz |
2113 | +import six |
2114 | from storm.exceptions import TimeoutError |
2115 | import transaction |
2116 | from zope.component import getUtility |
2117 | @@ -274,7 +275,7 @@ class TranslationImporter: |
2118 | """See `ITranslationImporter`.""" |
2119 | file_extensions = [] |
2120 | |
2121 | - for importer in importers.itervalues(): |
2122 | + for importer in six.itervalues(importers): |
2123 | file_extensions.extend(importer.file_extensions) |
2124 | |
2125 | return sorted(set(file_extensions)) |
2126 | @@ -290,7 +291,7 @@ class TranslationImporter: |
2127 | |
2128 | def isTemplateName(self, path): |
2129 | """See `ITranslationImporter`.""" |
2130 | - for importer in importers.itervalues(): |
2131 | + for importer in six.itervalues(importers): |
2132 | if path.endswith(importer.template_suffix): |
2133 | return True |
2134 | return False |
2135 | diff --git a/lib/lp/translations/utilities/translationmerger.py b/lib/lp/translations/utilities/translationmerger.py |
2136 | index 044d058..b507fb6 100644 |
2137 | --- a/lib/lp/translations/utilities/translationmerger.py |
2138 | +++ b/lib/lp/translations/utilities/translationmerger.py |
2139 | @@ -283,7 +283,7 @@ class MessageSharingMerge(LaunchpadScript): |
2140 | log.info("Merging %d template equivalence classes." % class_count) |
2141 | |
2142 | tm = TransactionManager(self.txn, self.options.dry_run) |
2143 | - for number, name in enumerate(sorted(equivalence_classes.iterkeys())): |
2144 | + for number, name in enumerate(sorted(equivalence_classes)): |
2145 | templates = equivalence_classes[name] |
2146 | log.info( |
2147 | "Merging equivalence class '%s': %d template(s) (%d / %d)" % ( |
2148 | @@ -429,7 +429,7 @@ class TranslationMerger: |
2149 | |
2150 | self.tm.endTransaction(intermediate=True) |
2151 | |
2152 | - for representative_id in representatives.itervalues(): |
2153 | + for representative_id in six.itervalues(representatives): |
2154 | representative = POTMsgSet.get(representative_id) |
2155 | self._scrubPOTMsgSetTranslations(representative) |
2156 | self.tm.endTransaction(intermediate=True) |
2157 | @@ -484,7 +484,7 @@ class TranslationMerger: |
2158 | num_representatives = len(subordinates) |
2159 | representative_num = 0 |
2160 | |
2161 | - for representative, potmsgsets in subordinates.iteritems(): |
2162 | + for representative, potmsgsets in six.iteritems(subordinates): |
2163 | representative_num += 1 |
2164 | log.debug("Message %d/%d: %d subordinate(s)." % ( |
2165 | representative_num, num_representatives, len(potmsgsets))) |
2166 | diff --git a/lib/lp/translations/utilities/validate.py b/lib/lp/translations/utilities/validate.py |
2167 | index 0b9e8df..371a060 100644 |
2168 | --- a/lib/lp/translations/utilities/validate.py |
2169 | +++ b/lib/lp/translations/utilities/validate.py |
2170 | @@ -9,6 +9,7 @@ __all__ = [ |
2171 | ] |
2172 | |
2173 | import gettextpo |
2174 | +import six |
2175 | |
2176 | |
2177 | class GettextValidationError(ValueError): |
2178 | @@ -37,7 +38,7 @@ def validate_translation(original_singular, original_plural, |
2179 | else: |
2180 | # Message with plural forms. |
2181 | msg.set_msgid_plural(original_plural) |
2182 | - for form, translation in translations.iteritems(): |
2183 | + for form, translation in six.iteritems(translations): |
2184 | msg.set_msgstr_plural(form, translation) |
2185 | |
2186 | for flag in flags: |
2187 | diff --git a/utilities/findimports.py b/utilities/findimports.py |
2188 | index b5615a8..09e0cf1 100755 |
2189 | --- a/utilities/findimports.py |
2190 | +++ b/utilities/findimports.py |
2191 | @@ -46,6 +46,8 @@ import linecache |
2192 | import os |
2193 | import sys |
2194 | |
2195 | +import six |
2196 | + |
2197 | |
2198 | class ImportFinder(ASTVisitor): |
2199 | """AST visitor that collects all imported names in its imports attribute. |
2200 | @@ -285,7 +287,7 @@ class ModuleGraph(object): |
2201 | def printUnusedImports(self): |
2202 | for module in self.listModules(): |
2203 | names = [(unused.lineno, unused.name) |
2204 | - for unused in module.unused_names.itervalues()] |
2205 | + for unused in six.itervalues(module.unused_names)] |
2206 | names.sort() |
2207 | for lineno, name in names: |
2208 | if not self.all_unused: |
2209 | diff --git a/utilities/generate-external-bug-status-docs b/utilities/generate-external-bug-status-docs |
2210 | index a2d28e8..43e0263 100755 |
2211 | --- a/utilities/generate-external-bug-status-docs |
2212 | +++ b/utilities/generate-external-bug-status-docs |
2213 | @@ -26,6 +26,8 @@ from itertools import chain |
2214 | from optparse import OptionParser |
2215 | import sys |
2216 | |
2217 | +import six |
2218 | + |
2219 | from lp.bugs.externalbugtracker import BUG_TRACKER_CLASSES |
2220 | |
2221 | |
2222 | @@ -85,7 +87,7 @@ def generate_table(typ, cls): |
2223 | |
2224 | def generate_documentable_classes(): |
2225 | """Yield each class that has a mapping table defined.""" |
2226 | - for typ, cls in BUG_TRACKER_CLASSES.iteritems(): |
2227 | + for typ, cls in six.iteritems(BUG_TRACKER_CLASSES): |
2228 | if getattr(cls, '_status_lookup', None) is not None: |
2229 | yield typ, cls |
2230 | |
2231 | diff --git a/utilities/list-pages b/utilities/list-pages |
2232 | index 9989cf6..bf08d0a 100755 |
2233 | --- a/utilities/list-pages |
2234 | +++ b/utilities/list-pages |
2235 | @@ -49,6 +49,7 @@ import _pythonpath |
2236 | from inspect import getmro |
2237 | import os |
2238 | |
2239 | +import six |
2240 | from zope.app.wsgi.testlayer import BrowserLayer |
2241 | from zope.browserpage.simpleviewclass import simple |
2242 | from zope.component import adapter, getGlobalSiteManager |
2243 | @@ -191,7 +192,7 @@ class Whatever(object): |
2244 | |
2245 | def __call__(self, *args, **kwargs): |
2246 | args = map(repr, args) |
2247 | - args.extend('%s=%r' % (k, v) for k, v in kwargs.iteritems()) |
2248 | + args.extend('%s=%r' % (k, v) for k, v in six.iteritems(kwargs)) |
2249 | # If we're being called with no args, assume this is part of crazy |
2250 | # TALES stuff: |
2251 | # webapp/metazcml.py(365)path() |
I totally agree with iterating over the dict instead of doing dict.iterkeys(), but is it really necessary to use `six.iter{ keys,values, items}` ?
I mean, under the hood six's methods are basically `return iter(dict. values( ))` (for values, keys and items), and `keys.values()` works fine both on python2 and python3.
The only downside of using directly `dict.values` on Python2 that I can spot is the overhead of creating a copy list of all values, but that's exactly what six does anyway.