Merge ~cjwatson/launchpad:six-dict-iter into launchpad:master

Proposed by Colin Watson
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)
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{keys,values,items}()` becomes `six.iter{keys,values,items}(dict)`.

To post a comment you must log in.
Revision history for this message
Thiago F. Pappacena (pappacena) wrote :

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.

review: Needs Information
Revision history for this message
Colin Watson (cjwatson) wrote :

Well, but that last isn't true; on Python 2, six.itervalues(dict) is implemented using dict.itervalues(), not using iter(d.values()) as it is on Python 3 (where .values() doesn't materialise the whole list).

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.

Revision history for this message
Thiago F. Pappacena (pappacena) wrote :

Fair enough. In that case, LGTM.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/brzplugins/lpserve/__init__.py b/brzplugins/lpserve/__init__.py
index b956568..3ce2081 100644
--- a/brzplugins/lpserve/__init__.py
+++ b/brzplugins/lpserve/__init__.py
@@ -48,6 +48,7 @@ from breezy.transport import (
48 get_transport,48 get_transport,
49 transport_server_registry,49 transport_server_registry,
50 )50 )
51import six
5152
5253
53class cmd_launchpad_server(Command):54class cmd_launchpad_server(Command):
@@ -591,7 +592,7 @@ class LPForkingService(object):
591 pid = os.getpid()592 pid = os.getpid()
592 trace.mutter('%d spawned' % (pid,))593 trace.mutter('%d spawned' % (pid,))
593 self._server_socket.close()594 self._server_socket.close()
594 for env_var, value in env.iteritems():595 for env_var, value in six.iteritems(env):
595 osutils.set_or_unset_env(env_var, value)596 osutils.set_or_unset_env(env_var, value)
596 # See [Decision #3]597 # See [Decision #3]
597 self._create_child_file_descriptors(temp_name)598 self._create_child_file_descriptors(temp_name)
@@ -769,7 +770,7 @@ class LPForkingService(object):
769 # We sent the SIGKILL signal, see if they exited770 # We sent the SIGKILL signal, see if they exited
770 self._wait_for_children(self.SLEEP_FOR_CHILDREN_TIMEOUT)771 self._wait_for_children(self.SLEEP_FOR_CHILDREN_TIMEOUT)
771 if self._child_processes:772 if self._child_processes:
772 for c_id, (c_path, sock) in self._child_processes.iteritems():773 for c_id, (c_path, sock) in six.iteritems(self._child_processes):
773 # TODO: We should probably put something into this message?774 # TODO: We should probably put something into this message?
774 # However, the likelyhood is very small that this isn't775 # However, the likelyhood is very small that this isn't
775 # already closed because of SIGKILL + _wait_for_children776 # already closed because of SIGKILL + _wait_for_children
diff --git a/brzplugins/lpserve/test_lpserve.py b/brzplugins/lpserve/test_lpserve.py
index 3801df4..1420ed7 100644
--- a/brzplugins/lpserve/test_lpserve.py
+++ b/brzplugins/lpserve/test_lpserve.py
@@ -18,6 +18,7 @@ from breezy import (
18 trace,18 trace,
19 )19 )
20from breezy.plugins import lpserve20from breezy.plugins import lpserve
21import six
21from testtools import content22from testtools import content
2223
23from lp.codehosting import (24from lp.codehosting import (
@@ -336,11 +337,11 @@ class TestCaseWithSubprocess(tests.TestCaseWithTransport):
336 old_env = {}337 old_env = {}
337338
338 def cleanup_environment():339 def cleanup_environment():
339 for env_var, value in env_changes.iteritems():340 for env_var, value in six.iteritems(env_changes):
340 old_env[env_var] = osutils.set_or_unset_env(env_var, value)341 old_env[env_var] = osutils.set_or_unset_env(env_var, value)
341342
342 def restore_environment():343 def restore_environment():
343 for env_var, value in old_env.iteritems():344 for env_var, value in six.iteritems(old_env):
344 osutils.set_or_unset_env(env_var, value)345 osutils.set_or_unset_env(env_var, value)
345346
346 cwd = None347 cwd = None
@@ -406,7 +407,7 @@ class TestCaseWithLPForkingServiceSubprocess(TestCaseWithSubprocess):
406 def send_fork_request(self, command, env=None):407 def send_fork_request(self, command, env=None):
407 if env is not None:408 if env is not None:
408 request_lines = ['fork-env %s\n' % (command,)]409 request_lines = ['fork-env %s\n' % (command,)]
409 for key, value in env.iteritems():410 for key, value in six.iteritems(env):
410 request_lines.append('%s: %s\n' % (key, value))411 request_lines.append('%s: %s\n' % (key, value))
411 request_lines.append('end\n')412 request_lines.append('end\n')
412 request = ''.join(request_lines)413 request = ''.join(request_lines)
diff --git a/database/schema/security.py b/database/schema/security.py
index 1c53659..274bb03 100755
--- a/database/schema/security.py
+++ b/database/schema/security.py
@@ -13,6 +13,8 @@ import os
13import re13import re
14import sys14import sys
1515
16import six
17
16from fti import quote_identifier18from fti import quote_identifier
17from lp.services.compat import SafeConfigParser19from lp.services.compat import SafeConfigParser
18from lp.services.database.sqlbase import connect20from lp.services.database.sqlbase import connect
@@ -302,8 +304,8 @@ class PermissionGatherer:
302 to grant or revoke for. Each is a string.304 to grant or revoke for. Each is a string.
303 """305 """
304 result = []306 result = []
305 for permission, parties in self.permissions.iteritems():307 for permission, parties in six.iteritems(self.permissions):
306 for principal, entities in parties.iteritems():308 for principal, entities in six.iteritems(parties):
307 result.append(309 result.append(
308 (permission, ", ".join(entities), principal))310 (permission, ", ".join(entities), principal))
309 return result311 return result
@@ -315,8 +317,8 @@ class PermissionGatherer:
315 def countEntities(self):317 def countEntities(self):
316 """Count the number of different entities."""318 """Count the number of different entities."""
317 entities = set()319 entities = set()
318 for entities_and_entities in self.permissions.itervalues():320 for entities_and_entities in six.itervalues(self.permissions):
319 for extra_entities in entities_and_entities.itervalues():321 for extra_entities in six.itervalues(entities_and_entities):
320 entities.update(extra_entities)322 entities.update(extra_entities)
321 return len(entities)323 return len(entities)
322324
@@ -324,7 +326,7 @@ class PermissionGatherer:
324 """Count the number of different principals."""326 """Count the number of different principals."""
325 return len(set(sum([327 return len(set(sum([
326 principals.keys()328 principals.keys()
327 for principals in self.permissions.itervalues()], [])))329 for principals in six.itervalues(self.permissions)], [])))
328330
329 def grant(self, cur):331 def grant(self, cur):
330 """Grant all gathered permissions.332 """Grant all gathered permissions.
@@ -480,7 +482,7 @@ def reset_permissions(con, config, options):
480482
481 log.debug('Updating group memberships')483 log.debug('Updating group memberships')
482 existing_memberships = list_role_members(cur, memberships.keys())484 existing_memberships = list_role_members(cur, memberships.keys())
483 for group, users in memberships.iteritems():485 for group, users in six.iteritems(memberships):
484 cur_users = managed_roles.intersection(existing_memberships[group])486 cur_users = managed_roles.intersection(existing_memberships[group])
485 to_grant = users - cur_users487 to_grant = users - cur_users
486 if to_grant:488 if to_grant:
@@ -517,7 +519,7 @@ def reset_permissions(con, config, options):
517 # Set permissions as per config file519 # Set permissions as per config file
518 desired_permissions = defaultdict(lambda: defaultdict(set))520 desired_permissions = defaultdict(lambda: defaultdict(set))
519521
520 valid_objs = set(schema.iterkeys())522 valid_objs = set(schema)
521523
522 # Any object with permissions granted is accessible to the 'read'524 # Any object with permissions granted is accessible to the 'read'
523 # role. Some (eg. the lp_* replicated tables and internal or trigger525 # role. Some (eg. the lp_* replicated tables and internal or trigger
@@ -618,7 +620,7 @@ def reset_permissions(con, config, options):
618 new = desired_permissions[obj][role]620 new = desired_permissions[obj][role]
619 old_privs = obj.acl.get(role, {})621 old_privs = obj.acl.get(role, {})
620 old = set(old_privs)622 old = set(old_privs)
621 if any(old_privs.itervalues()):623 if any(six.itervalues(old_privs)):
622 log.warning("%s has grant option on %s", role, obj.fullname)624 log.warning("%s has grant option on %s", role, obj.fullname)
623 if new == old:625 if new == old:
624 continue626 continue
diff --git a/lib/contrib/oauth.py b/lib/contrib/oauth.py
index 47a821d..2d11e6c 100644
--- a/lib/contrib/oauth.py
+++ b/lib/contrib/oauth.py
@@ -3,6 +3,7 @@ import hmac
3import random3import random
4import time4import time
55
6import six
6from six.moves.urllib.parse import (7from six.moves.urllib.parse import (
7 parse_qs,8 parse_qs,
8 quote,9 quote,
@@ -118,7 +119,7 @@ class OAuthRequest(object):
118 # get any non-oauth parameters119 # get any non-oauth parameters
119 def get_nonoauth_parameters(self):120 def get_nonoauth_parameters(self):
120 parameters = {}121 parameters = {}
121 for k, v in self.parameters.iteritems():122 for k, v in six.iteritems(self.parameters):
122 # ignore oauth parameters123 # ignore oauth parameters
123 if k.find('oauth_') < 0:124 if k.find('oauth_') < 0:
124 parameters[k] = v125 parameters[k] = v
@@ -129,13 +130,15 @@ class OAuthRequest(object):
129 auth_header = 'OAuth realm="%s"' % realm130 auth_header = 'OAuth realm="%s"' % realm
130 # add the oauth parameters131 # add the oauth parameters
131 if self.parameters:132 if self.parameters:
132 for k, v in self.parameters.iteritems():133 for k, v in six.iteritems(self.parameters):
133 auth_header += ', %s="%s"' % (k, v)134 auth_header += ', %s="%s"' % (k, v)
134 return {'Authorization': auth_header}135 return {'Authorization': auth_header}
135136
136 # serialize as post data for a POST request137 # serialize as post data for a POST request
137 def to_postdata(self):138 def to_postdata(self):
138 return '&'.join('%s=%s' % (escape(str(k)), escape(str(v))) for k, v in self.parameters.iteritems())139 return '&'.join(
140 '%s=%s' % (escape(str(k)), escape(str(v)))
141 for k, v in six.iteritems(self.parameters))
139142
140 # serialize as a url for a GET request143 # serialize as a url for a GET request
141 def to_url(self):144 def to_url(self):
@@ -269,7 +272,7 @@ class OAuthRequest(object):
269 @staticmethod272 @staticmethod
270 def _split_url_string(param_str):273 def _split_url_string(param_str):
271 parameters = parse_qs(param_str, keep_blank_values=False)274 parameters = parse_qs(param_str, keep_blank_values=False)
272 for k, v in parameters.iteritems():275 for k, v in six.iteritems(parameters):
273 parameters[k] = unquote(v[0])276 parameters[k] = unquote(v[0])
274 return parameters277 return parameters
275278
diff --git a/lib/lp/app/browser/launchpadform.py b/lib/lp/app/browser/launchpadform.py
index ac6dd15..8899cbd 100644
--- a/lib/lp/app/browser/launchpadform.py
+++ b/lib/lp/app/browser/launchpadform.py
@@ -19,6 +19,7 @@ __all__ = [
19from lazr.lifecycle.event import ObjectModifiedEvent19from lazr.lifecycle.event import ObjectModifiedEvent
20from lazr.lifecycle.snapshot import Snapshot20from lazr.lifecycle.snapshot import Snapshot
21import simplejson21import simplejson
22import six
22import transaction23import transaction
23from zope.event import notify24from zope.event import notify
24from zope.formlib import form25from zope.formlib import form
@@ -213,7 +214,7 @@ class LaunchpadFormView(LaunchpadView):
213 self.form_fields, self.prefix, context, self.request,214 self.form_fields, self.prefix, context, self.request,
214 data=self.initial_values, adapters=self.adapters,215 data=self.initial_values, adapters=self.adapters,
215 ignore_request=False)216 ignore_request=False)
216 for field_name, help_link in self.help_links.iteritems():217 for field_name, help_link in six.iteritems(self.help_links):
217 self.widgets[field_name].help_link = help_link218 self.widgets[field_name].help_link = help_link
218219
219 @property220 @property
diff --git a/lib/lp/app/browser/tales.py b/lib/lp/app/browser/tales.py
index df20fcb..8e4921e 100644
--- a/lib/lp/app/browser/tales.py
+++ b/lib/lp/app/browser/tales.py
@@ -23,6 +23,7 @@ from lazr.enum import enumerated_type_registry
23from lazr.restful.utils import get_current_browser_request23from lazr.restful.utils import get_current_browser_request
24from lazr.uri import URI24from lazr.uri import URI
25import pytz25import pytz
26import six
26from six.moves.urllib.parse import quote27from six.moves.urllib.parse import quote
27from zope.browserpage import ViewPageTemplateFile28from zope.browserpage import ViewPageTemplateFile
28from zope.component import (29from zope.component import (
@@ -1418,7 +1419,7 @@ class CustomizableFormatter(ObjectFormatterAPI):
1418 """1419 """
1419 values = dict(1420 values = dict(
1420 (k, v if v is not None else '')1421 (k, v if v is not None else '')
1421 for k, v in self._link_summary_values().iteritems())1422 for k, v in six.iteritems(self._link_summary_values()))
1422 return structured(self._link_summary_template, **values).escapedtext1423 return structured(self._link_summary_template, **values).escapedtext
14231424
1424 def _title_values(self):1425 def _title_values(self):
@@ -1440,7 +1441,7 @@ class CustomizableFormatter(ObjectFormatterAPI):
1440 return None1441 return None
1441 values = dict(1442 values = dict(
1442 (k, v if v is not None else '')1443 (k, v if v is not None else '')
1443 for k, v in self._title_values().iteritems())1444 for k, v in six.iteritems(self._title_values()))
1444 return structured(title_template, **values).escapedtext1445 return structured(title_template, **values).escapedtext
14451446
1446 def sprite_css(self):1447 def sprite_css(self):
diff --git a/lib/lp/archivepublisher/domination.py b/lib/lp/archivepublisher/domination.py
index a02fd78..356a2ee 100644
--- a/lib/lp/archivepublisher/domination.py
+++ b/lib/lp/archivepublisher/domination.py
@@ -60,6 +60,7 @@ from operator import (
60 )60 )
6161
62import apt_pkg62import apt_pkg
63import six
63from six.moves import (64from six.moves import (
64 filter as ifilter,65 filter as ifilter,
65 filterfalse as ifilterfalse,66 filterfalse as ifilterfalse,
@@ -669,7 +670,7 @@ class Dominator:
669 bins = self.findBinariesForDomination(distroarchseries, pocket)670 bins = self.findBinariesForDomination(distroarchseries, pocket)
670 sorted_packages = self._sortPackages(bins, generalization)671 sorted_packages = self._sortPackages(bins, generalization)
671 self.logger.info("Planning domination of binaries...")672 self.logger.info("Planning domination of binaries...")
672 for name, pubs in sorted_packages.iteritems():673 for name, pubs in six.iteritems(sorted_packages):
673 self.logger.debug("Planning domination of %s" % name)674 self.logger.debug("Planning domination of %s" % name)
674 assert len(pubs) > 0, "Dominating zero binaries!"675 assert len(pubs) > 0, "Dominating zero binaries!"
675 live_versions = find_live_binary_versions_pass_1(pubs)676 live_versions = find_live_binary_versions_pass_1(pubs)
@@ -774,7 +775,7 @@ class Dominator:
774 delete = []775 delete = []
775776
776 self.logger.debug("Dominating sources...")777 self.logger.debug("Dominating sources...")
777 for name, pubs in sorted_packages.iteritems():778 for name, pubs in six.iteritems(sorted_packages):
778 self.logger.debug("Dominating %s" % name)779 self.logger.debug("Dominating %s" % name)
779 assert len(pubs) > 0, "Dominating zero sources!"780 assert len(pubs) > 0, "Dominating zero sources!"
780 live_versions = find_live_source_versions(pubs)781 live_versions = find_live_source_versions(pubs)
diff --git a/lib/lp/archivepublisher/model/ftparchive.py b/lib/lp/archivepublisher/model/ftparchive.py
index 39e7d40..6fe3c3c 100644
--- a/lib/lp/archivepublisher/model/ftparchive.py
+++ b/lib/lp/archivepublisher/model/ftparchive.py
@@ -8,6 +8,7 @@ from StringIO import StringIO
8import time8import time
99
10import scandir10import scandir
11import six
11from storm.expr import (12from storm.expr import (
12 Desc,13 Desc,
13 Join,14 Join,
@@ -201,7 +202,7 @@ class FTPArchiveHandler:
201 stderr_handler.finalize()202 stderr_handler.finalize()
202 failures = sorted([203 failures = sorted([
203 (tag, receiver.returncode)204 (tag, receiver.returncode)
204 for tag, receiver in returncodes.iteritems()205 for tag, receiver in six.iteritems(returncodes)
205 if receiver.returncode != 0])206 if receiver.returncode != 0])
206 if len(failures) > 0:207 if len(failures) > 0:
207 by_arch = ["%s (returned %d)" % failure for failure in failures]208 by_arch = ["%s (returned %d)" % failure for failure in failures]
@@ -694,8 +695,8 @@ class FTPArchiveHandler:
694695
695 self.log.debug("Writing file lists for %s" % suite)696 self.log.debug("Writing file lists for %s" % suite)
696 series, pocket = self.distro.getDistroSeriesAndPocket(suite)697 series, pocket = self.distro.getDistroSeriesAndPocket(suite)
697 for component, architectures in filelist.iteritems():698 for component, architectures in six.iteritems(filelist):
698 for architecture, file_names in architectures.iteritems():699 for architecture, file_names in six.iteritems(architectures):
699 # XXX wgrant 2010-10-06: There must be a better place to do700 # XXX wgrant 2010-10-06: There must be a better place to do
700 # this.701 # this.
701 if architecture == "source":702 if architecture == "source":
diff --git a/lib/lp/archivepublisher/publishing.py b/lib/lp/archivepublisher/publishing.py
index cd19ed8..f6246b0 100644
--- a/lib/lp/archivepublisher/publishing.py
+++ b/lib/lp/archivepublisher/publishing.py
@@ -36,6 +36,7 @@ from debian.deb822 import (
36 Release,36 Release,
37 )37 )
38import scandir38import scandir
39import six
39from storm.expr import Desc40from storm.expr import Desc
40from zope.component import getUtility41from zope.component import getUtility
41from zope.interface import (42from zope.interface import (
@@ -984,7 +985,7 @@ class Publisher(object):
984 translation_stanza.makeOutput().encode('utf-8')985 translation_stanza.makeOutput().encode('utf-8')
985 + '\n\n')986 + '\n\n')
986987
987 for index in indices.itervalues():988 for index in six.itervalues(indices):
988 index.close()989 index.close()
989990
990 if separate_long_descriptions:991 if separate_long_descriptions:
diff --git a/lib/lp/archivepublisher/scripts/publish_ftpmaster.py b/lib/lp/archivepublisher/scripts/publish_ftpmaster.py
index 5fcd7d3..c307846 100644
--- a/lib/lp/archivepublisher/scripts/publish_ftpmaster.py
+++ b/lib/lp/archivepublisher/scripts/publish_ftpmaster.py
@@ -15,6 +15,7 @@ import shutil
1515
16from pytz import utc16from pytz import utc
17import scandir17import scandir
18import six
18from zope.component import getUtility19from zope.component import getUtility
1920
20from lp.archivepublisher.config import getPubConfig21from lp.archivepublisher.config import getPubConfig
@@ -224,9 +225,7 @@ class PublishFTPMaster(LaunchpadCronScript):
224 return []225 return []
225226
226 # May need indexes for this series.227 # May need indexes for this series.
227 suites = [228 suites = [distroseries.getSuite(pocket) for pocket in pocketsuffix]
228 distroseries.getSuite(pocket)
229 for pocket in pocketsuffix.iterkeys()]
230 return [229 return [
231 suite for suite in suites230 suite for suite in suites
232 if not file_exists(self.locateIndexesMarker(distro, suite))]231 if not file_exists(self.locateIndexesMarker(distro, suite))]
@@ -289,7 +288,8 @@ class PublishFTPMaster(LaunchpadCronScript):
289288
290 :param archive_purpose: The (purpose of the) archive to copy.289 :param archive_purpose: The (purpose of the) archive to copy.
291 """290 """
292 for purpose, archive_config in self.configs[distribution].iteritems():291 for purpose, archive_config in (
292 six.iteritems(self.configs[distribution])):
293 dists = get_dists(archive_config)293 dists = get_dists(archive_config)
294 backup_dists = get_backup_dists(archive_config)294 backup_dists = get_backup_dists(archive_config)
295 execute_subprocess(295 execute_subprocess(
@@ -319,14 +319,15 @@ class PublishFTPMaster(LaunchpadCronScript):
319 run died while in this state, restore the directory to its319 run died while in this state, restore the directory to its
320 permanent location.320 permanent location.
321 """321 """
322 for distro_configs in self.configs.itervalues():322 for distro_configs in six.itervalues(self.configs):
323 for archive_config in distro_configs.itervalues():323 for archive_config in six.itervalues(distro_configs):
324 self.recoverArchiveWorkingDir(archive_config)324 self.recoverArchiveWorkingDir(archive_config)
325325
326 def setUpDirs(self):326 def setUpDirs(self):
327 """Create archive roots and such if they did not yet exist."""327 """Create archive roots and such if they did not yet exist."""
328 for distro_configs in self.configs.itervalues():328 for distro_configs in six.itervalues(self.configs):
329 for archive_purpose, archive_config in distro_configs.iteritems():329 for archive_purpose, archive_config in (
330 six.iteritems(distro_configs)):
330 archiveroot = archive_config.archiveroot331 archiveroot = archive_config.archiveroot
331 if not file_exists(archiveroot):332 if not file_exists(archiveroot):
332 self.logger.debug(333 self.logger.debug(
@@ -407,7 +408,7 @@ class PublishFTPMaster(LaunchpadCronScript):
407 backup dists directory around.408 backup dists directory around.
408 """409 """
409 self.logger.debug("Moving the new dists into place...")410 self.logger.debug("Moving the new dists into place...")
410 for archive_config in self.configs[distribution].itervalues():411 for archive_config in six.itervalues(self.configs[distribution]):
411 # Use the dists "working location" as a temporary place to412 # Use the dists "working location" as a temporary place to
412 # move the current dists out of the way for the switch. If413 # move the current dists out of the way for the switch. If
413 # we die in this state, the next run will know to move the414 # we die in this state, the next run will know to move the
@@ -422,7 +423,7 @@ class PublishFTPMaster(LaunchpadCronScript):
422423
423 def clearEmptyDirs(self, distribution):424 def clearEmptyDirs(self, distribution):
424 """Clear out any redundant empty directories."""425 """Clear out any redundant empty directories."""
425 for archive_config in self.configs[distribution].itervalues():426 for archive_config in six.itervalues(self.configs[distribution]):
426 execute_subprocess(427 execute_subprocess(
427 ["find", archive_config.archiveroot, "-type", "d", "-empty",428 ["find", archive_config.archiveroot, "-type", "d", "-empty",
428 "-delete"],429 "-delete"],
@@ -432,7 +433,7 @@ class PublishFTPMaster(LaunchpadCronScript):
432 """Run the finalize.d parts to finalize publication."""433 """Run the finalize.d parts to finalize publication."""
433 archive_roots = ' '.join([434 archive_roots = ' '.join([
434 archive_config.archiveroot435 archive_config.archiveroot
435 for archive_config in self.configs[distribution].itervalues()])436 for archive_config in six.itervalues(self.configs[distribution])])
436437
437 env = {438 env = {
438 'SECURITY_UPLOAD_ONLY': 'yes' if security_only else 'no',439 'SECURITY_UPLOAD_ONLY': 'yes' if security_only else 'no',
diff --git a/lib/lp/archivepublisher/tests/test_dominator.py b/lib/lp/archivepublisher/tests/test_dominator.py
index b88da56..4d073e0 100755
--- a/lib/lp/archivepublisher/tests/test_dominator.py
+++ b/lib/lp/archivepublisher/tests/test_dominator.py
@@ -11,6 +11,7 @@ import datetime
11from operator import attrgetter11from operator import attrgetter
1212
13import apt_pkg13import apt_pkg
14import six
14from testtools.matchers import (15from testtools.matchers import (
15 GreaterThan,16 GreaterThan,
16 LessThan,17 LessThan,
@@ -813,14 +814,14 @@ class TestDominatorMethods(TestCaseWithFactory):
813 # Actually the "oldest to newest" order on the publications only814 # Actually the "oldest to newest" order on the publications only
814 # applies to their creation dates. Their creation orders are815 # applies to their creation dates. Their creation orders are
815 # irrelevant.816 # irrelevant.
816 for pubs_list in pubs_by_version.itervalues():817 for pubs_list in six.itervalues(pubs_by_version):
817 alter_creation_dates(pubs_list, ages)818 alter_creation_dates(pubs_list, ages)
818 pubs_list.sort(key=attrgetter('datecreated'))819 pubs_list.sort(key=attrgetter('datecreated'))
819820
820 live_versions = ["1.1", "1.2"]821 live_versions = ["1.1", "1.2"]
821 last_version_alive = sorted(live_versions)[-1]822 last_version_alive = sorted(live_versions)[-1]
822823
823 all_pubs = sum(pubs_by_version.itervalues(), [])824 all_pubs = sum(six.itervalues(pubs_by_version), [])
824 dominator = Dominator(DevNullLogger(), series.main_archive)825 dominator = Dominator(DevNullLogger(), series.main_archive)
825 supersede, _, delete = dominator.planPackageDomination(826 supersede, _, delete = dominator.planPackageDomination(
826 generalization.sortPublications(all_pubs), live_versions,827 generalization.sortPublications(all_pubs), live_versions,
diff --git a/lib/lp/archivepublisher/tests/test_publish_ftpmaster.py b/lib/lp/archivepublisher/tests/test_publish_ftpmaster.py
index 8c99b73..450da11 100644
--- a/lib/lp/archivepublisher/tests/test_publish_ftpmaster.py
+++ b/lib/lp/archivepublisher/tests/test_publish_ftpmaster.py
@@ -121,8 +121,7 @@ def get_a_suite(distroseries):
121121
122def get_marker_files(script, distroseries):122def get_marker_files(script, distroseries):
123 """Return filesystem paths for all indexes markers for `distroseries`."""123 """Return filesystem paths for all indexes markers for `distroseries`."""
124 suites = [124 suites = [distroseries.getSuite(pocket) for pocket in pocketsuffix]
125 distroseries.getSuite(pocket) for pocket in pocketsuffix.iterkeys()]
126 distro = distroseries.distribution125 distro = distroseries.distribution
127 return [script.locateIndexesMarker(distro, suite) for suite in suites]126 return [script.locateIndexesMarker(distro, suite) for suite in suites]
128127
@@ -998,7 +997,7 @@ class TestCreateDistroSeriesIndexes(TestCaseWithFactory, HelpersMixin):
998 script = self.makeScript(series.distribution)997 script = self.makeScript(series.distribution)
999 script.setUp()998 script.setUp()
1000 self.assertContentEqual(999 self.assertContentEqual(
1001 [series.getSuite(pocket) for pocket in pocketsuffix.iterkeys()],1000 [series.getSuite(pocket) for pocket in pocketsuffix],
1002 script.listSuitesNeedingIndexes(series))1001 script.listSuitesNeedingIndexes(series))
10031002
1004 def test_listSuitesNeedingIndexes_is_empty_for_nonfrozen_series(self):1003 def test_listSuitesNeedingIndexes_is_empty_for_nonfrozen_series(self):
@@ -1133,7 +1132,7 @@ class TestCreateDistroSeriesIndexes(TestCaseWithFactory, HelpersMixin):
1133 [((given_distro, given_suites), kwargs)] = script.createIndexes.calls1132 [((given_distro, given_suites), kwargs)] = script.createIndexes.calls
1134 self.assertEqual(distro, given_distro)1133 self.assertEqual(distro, given_distro)
1135 self.assertContentEqual(1134 self.assertContentEqual(
1136 [series.getSuite(pocket) for pocket in pocketsuffix.iterkeys()],1135 [series.getSuite(pocket) for pocket in pocketsuffix],
1137 given_suites)1136 given_suites)
11381137
1139 def test_createIndexes_ignores_other_series(self):1138 def test_createIndexes_ignores_other_series(self):
diff --git a/lib/lp/archiveuploader/dscfile.py b/lib/lp/archiveuploader/dscfile.py
index 604193c..fbe1e25 100644
--- a/lib/lp/archiveuploader/dscfile.py
+++ b/lib/lp/archiveuploader/dscfile.py
@@ -684,7 +684,7 @@ class DSCFile(SourceUploadFile, SignableTagFile):
684 ISourcePackageNameSet).getOrCreateByName(self.source)684 ISourcePackageNameSet).getOrCreateByName(self.source)
685685
686 user_defined_fields = self.extractUserDefinedFields([686 user_defined_fields = self.extractUserDefinedFields([
687 (field, encoded[field]) for field in self._dict.iterkeys()])687 (field, encoded[field]) for field in self._dict])
688688
689 if self.changes.buildinfo is not None:689 if self.changes.buildinfo is not None:
690 buildinfo_lfa = self.changes.buildinfo.storeInDatabase()690 buildinfo_lfa = self.changes.buildinfo.storeInDatabase()
diff --git a/lib/lp/archiveuploader/nascentuploadfile.py b/lib/lp/archiveuploader/nascentuploadfile.py
index f28e43e..0791141 100644
--- a/lib/lp/archiveuploader/nascentuploadfile.py
+++ b/lib/lp/archiveuploader/nascentuploadfile.py
@@ -26,6 +26,7 @@ import time
26import apt_inst26import apt_inst
27import apt_pkg27import apt_pkg
28from debian.deb822 import Deb822Dict28from debian.deb822 import Deb822Dict
29import six
29from zope.component import getUtility30from zope.component import getUtility
3031
31from lp.app.errors import NotFoundError32from lp.app.errors import NotFoundError
@@ -218,7 +219,7 @@ class NascentUploadFile:
218 ckfile = open(self.filepath, "r")219 ckfile = open(self.filepath, "r")
219 size = 0220 size = 0
220 for chunk in filechunks(ckfile):221 for chunk in filechunks(ckfile):
221 for digester in digesters.itervalues():222 for digester in six.itervalues(digesters):
222 digester.update(chunk)223 digester.update(chunk)
223 size += len(chunk)224 size += len(chunk)
224 ckfile.close()225 ckfile.close()
@@ -905,7 +906,7 @@ class BaseBinaryUploadFile(PackageUploadFile):
905 debug_package = None906 debug_package = None
906907
907 user_defined_fields = self.extractUserDefinedFields(908 user_defined_fields = self.extractUserDefinedFields(
908 [(field, encoded[field]) for field in self.control.iterkeys()])909 [(field, encoded[field]) for field in self.control])
909910
910 binary = build.createBinaryPackageRelease(911 binary = build.createBinaryPackageRelease(
911 binarypackagename=binary_name,912 binarypackagename=binary_name,
diff --git a/lib/lp/archiveuploader/utils.py b/lib/lp/archiveuploader/utils.py
index ac8057d..67a009f 100644
--- a/lib/lp/archiveuploader/utils.py
+++ b/lib/lp/archiveuploader/utils.py
@@ -39,6 +39,8 @@ import re
39import signal39import signal
40import subprocess40import subprocess
4141
42import six
43
42from lp.services.encoding import guess as guess_encoding44from lp.services.encoding import guess as guess_encoding
43from lp.soyuz.enums import BinaryPackageFileType45from lp.soyuz.enums import BinaryPackageFileType
4446
@@ -333,7 +335,7 @@ def merge_file_lists(files, checksums_sha1, checksums_sha256, changes=True):
333 (filename, file_hashes[filename], size))335 (filename, file_hashes[filename], size))
334336
335 # Ensure that each filename was only listed in Files once.337 # Ensure that each filename was only listed in Files once.
336 if set(file_counter.itervalues()) - set([1]):338 if set(six.itervalues(file_counter)) - set([1]):
337 raise UploadError("Duplicate filenames in Files field.")339 raise UploadError("Duplicate filenames in Files field.")
338340
339 # Ensure that the Checksums-Sha1 and Checksums-Sha256 fields, if341 # Ensure that the Checksums-Sha1 and Checksums-Sha256 fields, if
diff --git a/lib/lp/bugs/browser/bugalsoaffects.py b/lib/lp/bugs/browser/bugalsoaffects.py
index 4fa3421..b4f5ea5 100644
--- a/lib/lp/bugs/browser/bugalsoaffects.py
+++ b/lib/lp/bugs/browser/bugalsoaffects.py
@@ -16,6 +16,7 @@ from lazr.enum import (
16 Item,16 Item,
17 )17 )
18from lazr.lifecycle.event import ObjectCreatedEvent18from lazr.lifecycle.event import ObjectCreatedEvent
19import six
19from zope.browserpage import ViewPageTemplateFile20from zope.browserpage import ViewPageTemplateFile
20from zope.component import getUtility21from zope.component import getUtility
21from zope.event import notify22from zope.event import notify
@@ -605,7 +606,7 @@ class ProductBugTaskCreationStep(BugTaskCreationStep):
605606
606 # Don't request validation for text widgets that are not607 # Don't request validation for text widgets that are not
607 # related to the current radio selection.608 # related to the current radio selection.
608 for option, name in link_upstream_options.iteritems():609 for option, name in six.iteritems(link_upstream_options):
609 if link_upstream_how != option:610 if link_upstream_how != option:
610 names.discard(name)611 names.discard(name)
611 elif self.widgets[name].hasValidInput():612 elif self.widgets[name].hasValidInput():
@@ -619,7 +620,7 @@ class ProductBugTaskCreationStep(BugTaskCreationStep):
619 else:620 else:
620 # Don't validate these widgets when we don't yet know how621 # Don't validate these widgets when we don't yet know how
621 # we intend to link upstream.622 # we intend to link upstream.
622 names.difference_update(link_upstream_options.itervalues())623 names.difference_update(six.itervalues(link_upstream_options))
623624
624 return super(ProductBugTaskCreationStep,625 return super(ProductBugTaskCreationStep,
625 self).validate_widgets(data, names)626 self).validate_widgets(data, names)
diff --git a/lib/lp/bugs/browser/bugtarget.py b/lib/lp/bugs/browser/bugtarget.py
index 5755c1b..01b323d 100644
--- a/lib/lp/bugs/browser/bugtarget.py
+++ b/lib/lp/bugs/browser/bugtarget.py
@@ -28,6 +28,7 @@ from lazr.restful.interface import copy_field
28from lazr.restful.interfaces import IJSONRequestCache28from lazr.restful.interfaces import IJSONRequestCache
29from pytz import timezone29from pytz import timezone
30from simplejson import dumps30from simplejson import dumps
31import six
31from six.moves import http_client32from six.moves import http_client
32from six.moves.urllib.parse import (33from six.moves.urllib.parse import (
33 quote,34 quote,
@@ -1235,7 +1236,7 @@ class BugTargetBugTagsView(LaunchpadView):
1235 count=count,1236 count=count,
1236 url=self._getSearchURL(tag),1237 url=self._getSearchURL(tag),
1237 )1238 )
1238 for (tag, count) in tags.iteritems()],1239 for (tag, count) in six.iteritems(tags)],
1239 key=itemgetter('count'), reverse=True)1240 key=itemgetter('count'), reverse=True)
12401241
1241 @property1242 @property
diff --git a/lib/lp/bugs/interfaces/bugtaskfilter.py b/lib/lp/bugs/interfaces/bugtaskfilter.py
index e3407ed..898c955 100644
--- a/lib/lp/bugs/interfaces/bugtaskfilter.py
+++ b/lib/lp/bugs/interfaces/bugtaskfilter.py
@@ -17,6 +17,8 @@ from collections import (
17 )17 )
18from operator import attrgetter18from operator import attrgetter
1919
20import six
21
20from lp.bugs.interfaces.bugtarget import IHasBugs22from lp.bugs.interfaces.bugtarget import IHasBugs
2123
2224
@@ -67,5 +69,5 @@ def filter_bugtasks_by_context(context, bugtasks):
67 for task in bugtasks:69 for task in bugtasks:
68 bug_mapping[task.bugID].append(weight_calculator(task))70 bug_mapping[task.bugID].append(weight_calculator(task))
6971
70 filtered = [sorted(tasks)[0].task for tasks in bug_mapping.itervalues()]72 filtered = [sorted(tasks)[0].task for tasks in six.itervalues(bug_mapping)]
71 return sorted(filtered, key=attrgetter('bugID'))73 return sorted(filtered, key=attrgetter('bugID'))
diff --git a/lib/lp/bugs/model/bugtask.py b/lib/lp/bugs/model/bugtask.py
index 2c3b6ef..fe7d366 100644
--- a/lib/lp/bugs/model/bugtask.py
+++ b/lib/lp/bugs/model/bugtask.py
@@ -32,6 +32,7 @@ import re
3232
33from lazr.lifecycle.event import ObjectDeletedEvent33from lazr.lifecycle.event import ObjectDeletedEvent
34import pytz34import pytz
35import six
35from sqlobject import (36from sqlobject import (
36 ForeignKey,37 ForeignKey,
37 SQLObjectNotFound,38 SQLObjectNotFound,
@@ -1138,7 +1139,7 @@ class BugTask(SQLBase):
1138 new_key['sourcepackagename'] != self.sourcepackagename):1139 new_key['sourcepackagename'] != self.sourcepackagename):
1139 self._syncSourcePackages(new_key['sourcepackagename'], user)1140 self._syncSourcePackages(new_key['sourcepackagename'], user)
11401141
1141 for name, value in new_key.iteritems():1142 for name, value in six.iteritems(new_key):
1142 setattr(self, name, value)1143 setattr(self, name, value)
1143 self.updateTargetNameCache()1144 self.updateTargetNameCache()
1144 self.bug._reconcileAccess()1145 self.bug._reconcileAccess()
diff --git a/lib/lp/bugs/model/structuralsubscription.py b/lib/lp/bugs/model/structuralsubscription.py
index aec76a8..c2834e3 100644
--- a/lib/lp/bugs/model/structuralsubscription.py
+++ b/lib/lp/bugs/model/structuralsubscription.py
@@ -15,6 +15,7 @@ __all__ = [
15from collections import defaultdict15from collections import defaultdict
1616
17import pytz17import pytz
18import six
18from storm.base import Storm19from storm.base import Storm
19from storm.expr import (20from storm.expr import (
20 And,21 And,
@@ -137,7 +138,7 @@ class StructuralSubscription(Storm):
137 def __init__(self, subscriber, subscribed_by, **kwargs):138 def __init__(self, subscriber, subscribed_by, **kwargs):
138 self.subscriber = subscriber139 self.subscriber = subscriber
139 self.subscribed_by = subscribed_by140 self.subscribed_by = subscribed_by
140 for arg, value in kwargs.iteritems():141 for arg, value in six.iteritems(kwargs):
141 setattr(self, arg, value)142 setattr(self, arg, value)
142143
143 @property144 @property
@@ -463,7 +464,7 @@ class StructuralSubscriptionTargetMixin:
463 """See `IStructuralSubscriptionTarget`."""464 """See `IStructuralSubscriptionTarget`."""
464 from lp.registry.model.person import Person465 from lp.registry.model.person import Person
465 clauses = [StructuralSubscription.subscriberID == Person.id]466 clauses = [StructuralSubscription.subscriberID == Person.id]
466 for key, value in self._target_args.iteritems():467 for key, value in six.iteritems(self._target_args):
467 clauses.append(468 clauses.append(
468 getattr(StructuralSubscription, key) == value)469 getattr(StructuralSubscription, key) == value)
469470
diff --git a/lib/lp/bugs/model/tests/test_bugsubscriptioninfo.py b/lib/lp/bugs/model/tests/test_bugsubscriptioninfo.py
index 89c5c0f..f261fcb 100644
--- a/lib/lp/bugs/model/tests/test_bugsubscriptioninfo.py
+++ b/lib/lp/bugs/model/tests/test_bugsubscriptioninfo.py
@@ -7,6 +7,7 @@ __metaclass__ = type
77
8from contextlib import contextmanager8from contextlib import contextmanager
99
10import six
10from storm.store import Store11from storm.store import Store
11from testtools.matchers import Equals12from testtools.matchers import Equals
12from zope.component import queryAdapter13from zope.component import queryAdapter
@@ -64,7 +65,7 @@ class TestSubscriptionRelatedSets(TestCaseWithFactory):
64 subscribers = dict(65 subscribers = dict(
65 (name_pair, make_person(*name_pair))66 (name_pair, make_person(*name_pair))
66 for name_pair in self.name_pairs)67 for name_pair in self.name_pairs)
67 self.subscribers_set = frozenset(subscribers.itervalues())68 self.subscribers_set = frozenset(six.itervalues(subscribers))
68 self.subscribers_sorted = tuple(69 self.subscribers_sorted = tuple(
69 subscribers[name_pair] for name_pair in self.name_pairs_sorted)70 subscribers[name_pair] for name_pair in self.name_pairs_sorted)
7071
@@ -428,7 +429,7 @@ class TestBugSubscriptionInfoPermissions(TestCaseWithFactory):
428 self.assertEqual({}, checker.set_permissions)429 self.assertEqual({}, checker.set_permissions)
429430
430 # All attributes require launchpad.View.431 # All attributes require launchpad.View.
431 permissions = set(checker.get_permissions.itervalues())432 permissions = set(six.itervalues(checker.get_permissions))
432 self.assertContentEqual(["launchpad.View"], permissions)433 self.assertContentEqual(["launchpad.View"], permissions)
433434
434 # The security adapter for launchpad.View lets anyone reference the435 # The security adapter for launchpad.View lets anyone reference the
diff --git a/lib/lp/bugs/scripts/bugsummaryrebuild.py b/lib/lp/bugs/scripts/bugsummaryrebuild.py
index f41d8c2..f000905 100644
--- a/lib/lp/bugs/scripts/bugsummaryrebuild.py
+++ b/lib/lp/bugs/scripts/bugsummaryrebuild.py
@@ -3,6 +3,7 @@
33
4__metaclass__ = type4__metaclass__ = type
55
6import six
6from storm.expr import (7from storm.expr import (
7 Alias,8 Alias,
8 And,9 And,
@@ -116,7 +117,7 @@ def get_bugsummary_constraint(target, cls=RawBugSummary):
116 # Map to ID columns to work around Storm bug #682989.117 # Map to ID columns to work around Storm bug #682989.
117 return [118 return [
118 getattr(cls, k) == v119 getattr(cls, k) == v
119 for (k, v) in _get_bugsummary_constraint_bits(target).iteritems()]120 for (k, v) in six.iteritems(_get_bugsummary_constraint_bits(target))]
120121
121122
122def get_bugtaskflat_constraint(target):123def get_bugtaskflat_constraint(target):
@@ -161,8 +162,8 @@ def calculate_bugsummary_changes(old, new):
161 from the old one.162 from the old one.
162 """163 """
163 keys = set()164 keys = set()
164 keys.update(old.iterkeys())165 keys.update(six.iterkeys(old))
165 keys.update(new.iterkeys())166 keys.update(six.iterkeys(new))
166 added = {}167 added = {}
167 updated = {}168 updated = {}
168 removed = []169 removed = []
@@ -198,7 +199,7 @@ def apply_bugsummary_changes(target, added, updated, removed):
198 RawBugSummary.access_policy_id)199 RawBugSummary.access_policy_id)
199200
200 # Postgres doesn't do bulk updates, so do a delete+add.201 # Postgres doesn't do bulk updates, so do a delete+add.
201 for key, count in updated.iteritems():202 for key, count in six.iteritems(updated):
202 removed.append(key)203 removed.append(key)
203 added[key] = count204 added[key] = count
204205
@@ -219,7 +220,8 @@ def apply_bugsummary_changes(target, added, updated, removed):
219 if added:220 if added:
220 create(221 create(
221 target_cols + key_cols + (RawBugSummary.count,),222 target_cols + key_cols + (RawBugSummary.count,),
222 [target_key + key + (count,) for key, count in added.iteritems()])223 [target_key + key + (count,)
224 for key, count in six.iteritems(added)])
223225
224226
225def rebuild_bugsummary_for_target(target, log):227def rebuild_bugsummary_for_target(target, log):
diff --git a/lib/lp/bugs/scripts/bugtasktargetnamecaches.py b/lib/lp/bugs/scripts/bugtasktargetnamecaches.py
index 5d14052..429ff49 100644
--- a/lib/lp/bugs/scripts/bugtasktargetnamecaches.py
+++ b/lib/lp/bugs/scripts/bugtasktargetnamecaches.py
@@ -8,6 +8,7 @@ __all__ = ['BugTaskTargetNameCacheUpdater']
88
9from collections import defaultdict9from collections import defaultdict
1010
11import six
11from zope.interface import implementer12from zope.interface import implementer
1213
13from lp.bugs.model.bugtask import (14from lp.bugs.model.bugtask import (
@@ -65,7 +66,7 @@ class BugTaskTargetNameCachesTunableLoop(object):
65 candidates = defaultdict(set)66 candidates = defaultdict(set)
66 for candidate in candidate_set:67 for candidate in candidate_set:
67 candidates[candidate[:-1]].add(candidate[-1])68 candidates[candidate[:-1]].add(candidate[-1])
68 return list(candidates.iteritems())69 return list(six.iteritems(candidates))
6970
70 def isDone(self):71 def isDone(self):
71 """See `ITunableLoop`."""72 """See `ITunableLoop`."""
diff --git a/lib/lp/bugs/scripts/bzremotecomponentfinder.py b/lib/lp/bugs/scripts/bzremotecomponentfinder.py
index 4dcb6cb..cf4246e 100644
--- a/lib/lp/bugs/scripts/bzremotecomponentfinder.py
+++ b/lib/lp/bugs/scripts/bzremotecomponentfinder.py
@@ -12,6 +12,7 @@ __all__ = [
12import re12import re
1313
14import requests14import requests
15import six
15import transaction16import transaction
16from zope.component import getUtility17from zope.component import getUtility
1718
@@ -163,7 +164,7 @@ class BugzillaRemoteComponentFinder:
163 def storeRemoteProductsAndComponents(self, bz_bugtracker, lp_bugtracker):164 def storeRemoteProductsAndComponents(self, bz_bugtracker, lp_bugtracker):
164 """Stores parsed product/component data from bz_bugtracker"""165 """Stores parsed product/component data from bz_bugtracker"""
165 components_to_add = []166 components_to_add = []
166 for product in bz_bugtracker.products.itervalues():167 for product in six.itervalues(bz_bugtracker.products):
167 # Look up the component group id from Launchpad for the product168 # Look up the component group id from Launchpad for the product
168 # if it already exists. Otherwise, add it.169 # if it already exists. Otherwise, add it.
169 lp_component_group = lp_bugtracker.getRemoteComponentGroup(170 lp_component_group = lp_bugtracker.getRemoteComponentGroup(
diff --git a/lib/lp/bugs/tests/externalbugtracker.py b/lib/lp/bugs/tests/externalbugtracker.py
index b8a5b9d..afb1d81 100644
--- a/lib/lp/bugs/tests/externalbugtracker.py
+++ b/lib/lp/bugs/tests/externalbugtracker.py
@@ -17,6 +17,7 @@ import re
17import time17import time
1818
19import responses19import responses
20import six
20from six.moves import xmlrpc_client21from six.moves import xmlrpc_client
21from six.moves.urllib_parse import (22from six.moves.urllib_parse import (
22 parse_qs,23 parse_qs,
@@ -720,7 +721,7 @@ class TestBugzillaXMLRPCTransport(RequestsTransport):
720 def _copy_comment(self, comment, fields_to_return=None):721 def _copy_comment(self, comment, fields_to_return=None):
721 # Copy wanted fields.722 # Copy wanted fields.
722 return dict(723 return dict(
723 (key, value) for (key, value) in comment.iteritems()724 (key, value) for (key, value) in six.iteritems(comment)
724 if fields_to_return is None or key in fields_to_return)725 if fields_to_return is None or key in fields_to_return)
725726
726 def comments(self, arguments):727 def comments(self, arguments):
diff --git a/lib/lp/buildmaster/browser/builder.py b/lib/lp/buildmaster/browser/builder.py
index 0c5d05a..b378ea3 100644
--- a/lib/lp/buildmaster/browser/builder.py
+++ b/lib/lp/buildmaster/browser/builder.py
@@ -20,6 +20,7 @@ from itertools import groupby
20import operator20import operator
2121
22from lazr.restful.utils import smartquote22from lazr.restful.utils import smartquote
23import six
23from zope.component import getUtility24from zope.component import getUtility
24from zope.event import notify25from zope.event import notify
25from zope.formlib.widget import CustomWidgetFactory26from zope.formlib.widget import CustomWidgetFactory
@@ -273,7 +274,7 @@ class BuilderCategory:
273 else:274 else:
274 grouped_builders[processor] = [builder]275 grouped_builders[processor] = [builder]
275276
276 for processor, builders in grouped_builders.iteritems():277 for processor, builders in six.iteritems(grouped_builders):
277 virt_str = 'virt' if self.virtualized else 'nonvirt'278 virt_str = 'virt' if self.virtualized else 'nonvirt'
278 processor_name = processor.name if processor else None279 processor_name = processor.name if processor else None
279 queue_size, duration = build_queue_sizes[virt_str].get(280 queue_size, duration = build_queue_sizes[virt_str].get(
diff --git a/lib/lp/buildmaster/manager.py b/lib/lp/buildmaster/manager.py
index ea29ff2..3c80622 100644
--- a/lib/lp/buildmaster/manager.py
+++ b/lib/lp/buildmaster/manager.py
@@ -15,6 +15,7 @@ import datetime
15import functools15import functools
16import logging16import logging
1717
18import six
18from storm.expr import LeftJoin19from storm.expr import LeftJoin
19import transaction20import transaction
20from twisted.application import service21from twisted.application import service
@@ -139,7 +140,7 @@ class PrefetchedBuilderFactory:
139140
140 def iterVitals(self):141 def iterVitals(self):
141 """See `BuilderFactory`."""142 """See `BuilderFactory`."""
142 return (b for n, b in sorted(self.vitals_map.iteritems()))143 return (b for n, b in sorted(six.iteritems(self.vitals_map)))
143144
144145
145def judge_failure(builder_count, job_count, exc, retry=True):146def judge_failure(builder_count, job_count, exc, retry=True):
diff --git a/lib/lp/buildmaster/model/builder.py b/lib/lp/buildmaster/model/builder.py
index 4d32dcf..a44e7fc 100644
--- a/lib/lp/buildmaster/model/builder.py
+++ b/lib/lp/buildmaster/model/builder.py
@@ -11,6 +11,7 @@ __all__ = [
1111
12import logging12import logging
1313
14import six
14from sqlobject import (15from sqlobject import (
15 BoolCol,16 BoolCol,
16 ForeignKey,17 ForeignKey,
@@ -243,7 +244,7 @@ class Builder(SQLBase):
243244
244 job_type_conditions = []245 job_type_conditions = []
245 job_sources = specific_build_farm_job_sources()246 job_sources = specific_build_farm_job_sources()
246 for job_type, job_source in job_sources.iteritems():247 for job_type, job_source in six.iteritems(job_sources):
247 query = job_source.addCandidateSelectionCriteria(248 query = job_source.addCandidateSelectionCriteria(
248 self.processor, self.virtualized)249 self.processor, self.virtualized)
249 if query:250 if query:
diff --git a/lib/lp/buildmaster/queuedepth.py b/lib/lp/buildmaster/queuedepth.py
index 1fdb151..66f1986 100644
--- a/lib/lp/buildmaster/queuedepth.py
+++ b/lib/lp/buildmaster/queuedepth.py
@@ -14,6 +14,7 @@ from datetime import (
14 )14 )
1515
16from pytz import utc16from pytz import utc
17import six
17from storm.expr import Count18from storm.expr import Count
1819
19from lp.buildmaster.enums import BuildQueueStatus20from lp.buildmaster.enums import BuildQueueStatus
@@ -275,7 +276,7 @@ def estimate_job_delay(bq, builder_stats):
275276
276 sum_of_delays = 0277 sum_of_delays = 0
277 # Now devide the delays based on a jobs/builders comparison.278 # Now devide the delays based on a jobs/builders comparison.
278 for platform, duration in delays.iteritems():279 for platform, duration in six.iteritems(delays):
279 jobs = job_counts[platform]280 jobs = job_counts[platform]
280 builders = builder_stats[platform]281 builders = builder_stats[platform]
281 # If there are less jobs than builders that can take them on,282 # If there are less jobs than builders that can take them on,
diff --git a/lib/lp/buildmaster/tests/test_queuedepth.py b/lib/lp/buildmaster/tests/test_queuedepth.py
index 090fd11..b9198e1 100644
--- a/lib/lp/buildmaster/tests/test_queuedepth.py
+++ b/lib/lp/buildmaster/tests/test_queuedepth.py
@@ -10,6 +10,7 @@ from datetime import (
10 )10 )
1111
12from pytz import utc12from pytz import utc
13import six
13from zope.component import getUtility14from zope.component import getUtility
14from zope.security.proxy import removeSecurityProxy15from zope.security.proxy import removeSecurityProxy
1516
@@ -698,7 +699,7 @@ class TestMinTimeToNextBuilderMulti(MultiArchBuildsBase):
698 check_mintime_to_builder(self, job, 0)699 check_mintime_to_builder(self, job, 0)
699700
700 # Let's disable all builders.701 # Let's disable all builders.
701 for builders in self.builders.itervalues():702 for builders in six.itervalues(self.builders):
702 for builder in builders:703 for builder in builders:
703 builder.builderok = False704 builder.builderok = False
704705
diff --git a/lib/lp/code/browser/branch.py b/lib/lp/code/browser/branch.py
index 404c272..6ea17ac 100644
--- a/lib/lp/code/browser/branch.py
+++ b/lib/lp/code/browser/branch.py
@@ -36,6 +36,7 @@ from lazr.restful.interface import (
36from lazr.uri import URI36from lazr.uri import URI
37import pytz37import pytz
38import simplejson38import simplejson
39import six
39from zope.component import getUtility40from zope.component import getUtility
40from zope.event import notify41from zope.event import notify
41from zope.formlib import form42from zope.formlib import form
@@ -954,8 +955,8 @@ class BranchDeletionView(LaunchpadFormView):
954 :return: A list of tuples of (item, action, reason, allowed)955 :return: A list of tuples of (item, action, reason, allowed)
955 """956 """
956 reqs = []957 reqs = []
957 for item, (action, reason) in (958 for item, (action, reason) in six.iteritems(
958 self.context.deletionRequirements(eager_load=True).iteritems()):959 self.context.deletionRequirements(eager_load=True)):
959 allowed = check_permission('launchpad.Edit', item)960 allowed = check_permission('launchpad.Edit', item)
960 reqs.append((item, action, reason, allowed))961 reqs.append((item, action, reason, allowed))
961 return reqs962 return reqs
diff --git a/lib/lp/code/browser/branchlisting.py b/lib/lp/code/browser/branchlisting.py
index f472ef0..23a1e9c 100644
--- a/lib/lp/code/browser/branchlisting.py
+++ b/lib/lp/code/browser/branchlisting.py
@@ -33,6 +33,7 @@ from lazr.enum import (
33 EnumeratedType,33 EnumeratedType,
34 Item,34 Item,
35 )35 )
36import six
36from six.moves.urllib.parse import parse_qs37from six.moves.urllib.parse import parse_qs
37from storm.expr import Desc38from storm.expr import Desc
38from zope.browserpage import ViewPageTemplateFile39from zope.browserpage import ViewPageTemplateFile
@@ -1306,7 +1307,7 @@ class GroupedDistributionSourcePackageBranchesView(LaunchpadView,
1306 # For each distro series, we only want the "best" pocket if one branch1307 # For each distro series, we only want the "best" pocket if one branch
1307 # is linked to more than one pocket. Best here means smaller value.1308 # is linked to more than one pocket. Best here means smaller value.
1308 official_branches = {}1309 official_branches = {}
1309 for key, value in distro_links.iteritems():1310 for key, value in six.iteritems(distro_links):
1310 ordered = sorted(value, key=attrgetter('pocket'))1311 ordered = sorted(value, key=attrgetter('pocket'))
1311 seen_branches = set()1312 seen_branches = set()
1312 branches = []1313 branches = []
@@ -1363,7 +1364,7 @@ class GroupedDistributionSourcePackageBranchesView(LaunchpadView,
1363 and merge proposal links for badges.1364 and merge proposal links for badges.
1364 """1365 """
1365 visible_branches = []1366 visible_branches = []
1366 for branches, count in self.series_branches_map.itervalues():1367 for branches, count in six.itervalues(self.series_branches_map):
1367 visible_branches.extend(branches)1368 visible_branches.extend(branches)
1368 return visible_branches1369 return visible_branches
13691370
diff --git a/lib/lp/code/browser/branchmergeproposal.py b/lib/lp/code/browser/branchmergeproposal.py
index a1b41fb..6d33f97 100644
--- a/lib/lp/code/browser/branchmergeproposal.py
+++ b/lib/lp/code/browser/branchmergeproposal.py
@@ -35,6 +35,7 @@ from lazr.restful.interfaces import (
35 IWebServiceClientRequest,35 IWebServiceClientRequest,
36 )36 )
37import simplejson37import simplejson
38import six
38from zope.component import (39from zope.component import (
39 adapter,40 adapter,
40 getMultiAdapter,41 getMultiAdapter,
@@ -145,7 +146,7 @@ def latest_proposals_for_each_branch(proposals):
145 targets[target] = (proposal, date_created)146 targets[target] = (proposal, date_created)
146147
147 return sorted(148 return sorted(
148 [proposal for proposal, date_created in targets.itervalues()],149 [proposal for proposal, date_created in six.itervalues(targets)],
149 key=operator.attrgetter('date_created'), reverse=True)150 key=operator.attrgetter('date_created'), reverse=True)
150151
151152
diff --git a/lib/lp/code/browser/gitrepository.py b/lib/lp/code/browser/gitrepository.py
index c05dcc1..4f38702 100644
--- a/lib/lp/code/browser/gitrepository.py
+++ b/lib/lp/code/browser/gitrepository.py
@@ -31,6 +31,7 @@ from lazr.restful.interface import (
31 copy_field,31 copy_field,
32 use_template,32 use_template,
33 )33 )
34import six
34from six.moves.urllib_parse import (35from six.moves.urllib_parse import (
35 urlsplit,36 urlsplit,
36 urlunsplit,37 urlunsplit,
@@ -1273,9 +1274,8 @@ class GitRepositoryDeletionView(LaunchpadFormView):
1273 :return: A list of tuples of (item, action, reason, allowed)1274 :return: A list of tuples of (item, action, reason, allowed)
1274 """1275 """
1275 reqs = []1276 reqs = []
1276 for item, (action, reason) in (1277 for item, (action, reason) in six.iteritems(
1277 self.context.getDeletionRequirements(1278 self.context.getDeletionRequirements(eager_load=True)):
1278 eager_load=True).iteritems()):
1279 allowed = check_permission("launchpad.Edit", item)1279 allowed = check_permission("launchpad.Edit", item)
1280 reqs.append((item, action, reason, allowed))1280 reqs.append((item, action, reason, allowed))
1281 return reqs1281 return reqs
diff --git a/lib/lp/code/model/branchcollection.py b/lib/lp/code/model/branchcollection.py
index 79411cc..9c0b097 100644
--- a/lib/lp/code/model/branchcollection.py
+++ b/lib/lp/code/model/branchcollection.py
@@ -16,6 +16,7 @@ from lazr.uri import (
16 InvalidURIError,16 InvalidURIError,
17 URI,17 URI,
18 )18 )
19import six
19from storm.expr import (20from storm.expr import (
20 And,21 And,
21 Asc,22 Asc,
@@ -562,7 +563,7 @@ class GenericBranchCollection:
562 bugtasks_for_branch[bugbranch.branch].append(bugtask)563 bugtasks_for_branch[bugbranch.branch].append(bugtask)
563564
564 # Now filter those down to one bugtask per branch565 # Now filter those down to one bugtask per branch
565 for branch, tasks in bugtasks_for_branch.iteritems():566 for branch, tasks in six.iteritems(bugtasks_for_branch):
566 linked_bugtasks[branch.id].extend(567 linked_bugtasks[branch.id].extend(
567 filter_bugtasks_by_context(branch.target.context, tasks))568 filter_bugtasks_by_context(branch.target.context, tasks))
568569
diff --git a/lib/lp/code/model/branchjob.py b/lib/lp/code/model/branchjob.py
index a26c47b..7067f8a 100644
--- a/lib/lp/code/model/branchjob.py
+++ b/lib/lp/code/model/branchjob.py
@@ -684,7 +684,7 @@ class RevisionsAddedJob(BranchJobDerived):
684 proposals[source_id] = (proposal, date_created)684 proposals[source_id] = (proposal, date_created)
685685
686 return sorted(686 return sorted(
687 [proposal for proposal, date_created in proposals.itervalues()],687 [proposal for proposal, date_created in six.itervalues(proposals)],
688 key=operator.attrgetter('date_created'), reverse=True)688 key=operator.attrgetter('date_created'), reverse=True)
689689
690 def getRevisionMessage(self, revision_id, revno):690 def getRevisionMessage(self, revision_id, revno):
diff --git a/lib/lp/code/model/codereviewinlinecomment.py b/lib/lp/code/model/codereviewinlinecomment.py
index 580eb44..2ac74b0 100644
--- a/lib/lp/code/model/codereviewinlinecomment.py
+++ b/lib/lp/code/model/codereviewinlinecomment.py
@@ -10,6 +10,7 @@ __all__ = [
10 'CodeReviewInlineCommentSet',10 'CodeReviewInlineCommentSet',
11 ]11 ]
1212
13import six
13from storm.expr import LeftJoin14from storm.expr import LeftJoin
14from storm.locals import (15from storm.locals import (
15 Int,16 Int,
@@ -113,7 +114,7 @@ class CodeReviewInlineCommentSet:
113 list(crics), key=lambda c: c.comment.date_created)114 list(crics), key=lambda c: c.comment.date_created)
114 inline_comments = []115 inline_comments = []
115 for cric in sorted_crics:116 for cric in sorted_crics:
116 for line_number, text in cric.comments.iteritems():117 for line_number, text in six.iteritems(cric.comments):
117 comment = {118 comment = {
118 'line_number': line_number,119 'line_number': line_number,
119 'person': cric.person,120 'person': cric.person,
diff --git a/lib/lp/code/model/revision.py b/lib/lp/code/model/revision.py
index 4895ebb..a979c74 100644
--- a/lib/lp/code/model/revision.py
+++ b/lib/lp/code/model/revision.py
@@ -18,6 +18,7 @@ import email
1818
19from breezy.revision import NULL_REVISION19from breezy.revision import NULL_REVISION
20import pytz20import pytz
21import six
21from sqlobject import (22from sqlobject import (
22 BoolCol,23 BoolCol,
23 ForeignKey,24 ForeignKey,
@@ -287,7 +288,7 @@ class RevisionSet:
287 parent_id=parent_id)288 parent_id=parent_id)
288289
289 # Create revision properties.290 # Create revision properties.
290 for name, value in properties.iteritems():291 for name, value in six.iteritems(properties):
291 RevisionProperty(revision=revision, name=name, value=value)292 RevisionProperty(revision=revision, name=name, value=value)
292293
293 return revision294 return revision
@@ -378,7 +379,7 @@ class RevisionSet:
378 for bzr_revision in revisions:379 for bzr_revision in revisions:
379 db_id = revision_db_id[bzr_revision.revision_id]380 db_id = revision_db_id[bzr_revision.revision_id]
380 # Property data: revision DB id, name, value.381 # Property data: revision DB id, name, value.
381 for name, value in bzr_revision.properties.iteritems():382 for name, value in six.iteritems(bzr_revision.properties):
382 # pristine-tar properties can be huge, and storing them383 # pristine-tar properties can be huge, and storing them
383 # in the database provides no value. Exclude them.384 # in the database provides no value. Exclude them.
384 if name.startswith('deb-pristine-delta'):385 if name.startswith('deb-pristine-delta'):
diff --git a/lib/lp/codehosting/inmemory.py b/lib/lp/codehosting/inmemory.py
index a2a7103..2b704fd 100644
--- a/lib/lp/codehosting/inmemory.py
+++ b/lib/lp/codehosting/inmemory.py
@@ -131,7 +131,7 @@ class ObjectSet:
131 del self._objects[db_object.id]131 del self._objects[db_object.id]
132132
133 def __iter__(self):133 def __iter__(self):
134 return self._objects.itervalues()134 return six.itervalues(self._objects)
135135
136 def _find(self, **kwargs):136 def _find(self, **kwargs):
137 [(key, value)] = kwargs.items()137 [(key, value)] = kwargs.items()
diff --git a/lib/lp/codehosting/scanner/buglinks.py b/lib/lp/codehosting/scanner/buglinks.py
index f9609c3..116fb90 100644
--- a/lib/lp/codehosting/scanner/buglinks.py
+++ b/lib/lp/codehosting/scanner/buglinks.py
@@ -9,6 +9,7 @@ __all__ = [
9 ]9 ]
1010
11from breezy.bugtracker import InvalidBugStatus11from breezy.bugtracker import InvalidBugStatus
12import six
12from six.moves.urllib.parse import urlsplit13from six.moves.urllib.parse import urlsplit
13from zope.component import getUtility14from zope.component import getUtility
1415
@@ -77,7 +78,7 @@ class BugBranchLinker:
77 except InvalidBugStatus:78 except InvalidBugStatus:
78 return79 return
79 bug_set = getUtility(IBugSet)80 bug_set = getUtility(IBugSet)
80 for bug_id, status in bug_info.iteritems():81 for bug_id, status in six.iteritems(bug_info):
81 try:82 try:
82 bug = bug_set.get(bug_id)83 bug = bug_set.get(bug_id)
83 except NotFoundError:84 except NotFoundError:
diff --git a/lib/lp/codehosting/sshserver/session.py b/lib/lp/codehosting/sshserver/session.py
index 38bea68..a77855b 100644
--- a/lib/lp/codehosting/sshserver/session.py
+++ b/lib/lp/codehosting/sshserver/session.py
@@ -15,6 +15,7 @@ import sys
1515
16from lazr.sshserver.events import AvatarEvent16from lazr.sshserver.events import AvatarEvent
17from lazr.sshserver.session import DoNothingSession17from lazr.sshserver.session import DoNothingSession
18import six
18from six import reraise19from six import reraise
19from six.moves.urllib.parse import urlparse20from six.moves.urllib.parse import urlparse
20from twisted.internet import (21from twisted.internet import (
@@ -144,7 +145,7 @@ class ForkedProcessTransport(process.BaseProcess):
144 assert executable == 'brz', executable # Maybe .endswith()145 assert executable == 'brz', executable # Maybe .endswith()
145 assert args[0] == 'brz', args[0]146 assert args[0] == 'brz', args[0]
146 message = ['fork-env %s\n' % (' '.join(args[1:]),)]147 message = ['fork-env %s\n' % (' '.join(args[1:]),)]
147 for key, value in environment.iteritems():148 for key, value in six.iteritems(environment):
148 # XXX: Currently we only pass BRZ_EMAIL, should we be passing149 # XXX: Currently we only pass BRZ_EMAIL, should we be passing
149 # everything else? Note that many won't be handled properly,150 # everything else? Note that many won't be handled properly,
150 # since the process is already running.151 # since the process is already running.
diff --git a/lib/lp/codehosting/vfs/branchfsclient.py b/lib/lp/codehosting/vfs/branchfsclient.py
index b96d780..3307830 100644
--- a/lib/lp/codehosting/vfs/branchfsclient.py
+++ b/lib/lp/codehosting/vfs/branchfsclient.py
@@ -14,6 +14,7 @@ __all__ = [
1414
15import time15import time
1616
17import six
17from twisted.internet import defer18from twisted.internet import defer
1819
19from lp.code.interfaces.codehosting import BRANCH_TRANSPORT20from lp.code.interfaces.codehosting import BRANCH_TRANSPORT
@@ -84,7 +85,7 @@ class BranchFileSystemClient:
84 def _getFromCache(self, path):85 def _getFromCache(self, path):
85 """Get the cached 'transport_tuple' for 'path'."""86 """Get the cached 'transport_tuple' for 'path'."""
86 split_path = path.strip('/').split('/')87 split_path = path.strip('/').split('/')
87 for object_path, value in self._cache.iteritems():88 for object_path, value in six.iteritems(self._cache):
88 transport_type, data, inserted_time = value89 transport_type, data, inserted_time = value
89 split_object_path = object_path.strip('/').split('/')90 split_object_path = object_path.strip('/').split('/')
90 # Do a segment-by-segment comparison. Python sucks, lists should91 # Do a segment-by-segment comparison. Python sucks, lists should
diff --git a/lib/lp/registry/model/distroseriesdifference.py b/lib/lp/registry/model/distroseriesdifference.py
index e0ee875..0672584 100644
--- a/lib/lp/registry/model/distroseriesdifference.py
+++ b/lib/lp/registry/model/distroseriesdifference.py
@@ -19,6 +19,7 @@ from debian.changelog import (
19 Version,19 Version,
20 )20 )
21from lazr.enum import DBItem21from lazr.enum import DBItem
22import six
22from sqlobject import StringCol23from sqlobject import StringCol
23from storm.expr import (24from storm.expr import (
24 And,25 And,
@@ -279,10 +280,10 @@ def eager_load_dsds(dsds):
279 # referred to.280 # referred to.
280 sprs = bulk.load_related(281 sprs = bulk.load_related(
281 SourcePackageRelease, chain(282 SourcePackageRelease, chain(
282 source_pubs.itervalues(),283 six.itervalues(source_pubs),
283 parent_source_pubs.itervalues(),284 six.itervalues(parent_source_pubs),
284 source_pubs_for_release.itervalues(),285 six.itervalues(source_pubs_for_release),
285 parent_source_pubs_for_release.itervalues()),286 six.itervalues(parent_source_pubs_for_release)),
286 ("sourcepackagereleaseID",))287 ("sourcepackagereleaseID",))
287288
288 # Get packagesets and parent_packagesets for each DSD.289 # Get packagesets and parent_packagesets for each DSD.
diff --git a/lib/lp/registry/scripts/tests/test_populate_distroseriesdiff.py b/lib/lp/registry/scripts/tests/test_populate_distroseriesdiff.py
index a8acf8a..84f9f74 100644
--- a/lib/lp/registry/scripts/tests/test_populate_distroseriesdiff.py
+++ b/lib/lp/registry/scripts/tests/test_populate_distroseriesdiff.py
@@ -5,6 +5,7 @@
55
6__metaclass__ = type6__metaclass__ = type
77
8import six
8from storm.store import Store9from storm.store import Store
9import transaction10import transaction
10from zope.security.proxy import removeSecurityProxy11from zope.security.proxy import removeSecurityProxy
@@ -171,7 +172,8 @@ class TestFindLatestSourcePackageReleases(TestCaseWithFactory, FactoryHelper):
171 for status in active_publishing_status)172 for status in active_publishing_status)
172 query = compose_sql_find_latest_source_package_releases(distroseries)173 query = compose_sql_find_latest_source_package_releases(distroseries)
173 self.assertContentEqual(174 self.assertContentEqual(
174 [self.getExpectedResultFor(spph) for spph in spphs.itervalues()],175 [self.getExpectedResultFor(spph)
176 for spph in six.itervalues(spphs)],
175 Store.of(distroseries).execute(query))177 Store.of(distroseries).execute(query))
176178
177 def test_does_not_find_inactive_publication(self):179 def test_does_not_find_inactive_publication(self):
diff --git a/lib/lp/registry/services/sharingservice.py b/lib/lp/registry/services/sharingservice.py
index 68e33c3..09744ee 100644
--- a/lib/lp/registry/services/sharingservice.py
+++ b/lib/lp/registry/services/sharingservice.py
@@ -13,6 +13,7 @@ from operator import attrgetter
1313
14from lazr.restful.interfaces import IWebBrowserOriginatingRequest14from lazr.restful.interfaces import IWebBrowserOriginatingRequest
15from lazr.restful.utils import get_current_web_service_request15from lazr.restful.utils import get_current_web_service_request
16import six
16from storm.expr import (17from storm.expr import (
17 And,18 And,
18 Count,19 Count,
@@ -608,7 +609,7 @@ class SharingService:
608 for (grantee, permissions, shared_artifact_types) in grant_permissions:609 for (grantee, permissions, shared_artifact_types) in grant_permissions:
609 some_things_shared = len(shared_artifact_types) > 0610 some_things_shared = len(shared_artifact_types) > 0
610 grantee_permissions = {}611 grantee_permissions = {}
611 for (policy, permission) in permissions.iteritems():612 for (policy, permission) in six.iteritems(permissions):
612 grantee_permissions[policy.type.name] = permission.name613 grantee_permissions[policy.type.name] = permission.name
613 shared_artifact_type_names = [614 shared_artifact_type_names = [
614 info_type.name for info_type in shared_artifact_types]615 info_type.name for info_type in shared_artifact_types]
diff --git a/lib/lp/scripts/utilities/warninghandler.py b/lib/lp/scripts/utilities/warninghandler.py
index 46b8a73..cb0c4ff 100644
--- a/lib/lp/scripts/utilities/warninghandler.py
+++ b/lib/lp/scripts/utilities/warninghandler.py
@@ -12,6 +12,8 @@ import StringIO
12import sys12import sys
13import warnings13import warnings
1414
15import six
16
1517
16class WarningReport:18class WarningReport:
1719
@@ -211,7 +213,7 @@ def report_other_warnings():
211 if other_warnings:213 if other_warnings:
212 print(file=sys.stderr)214 print(file=sys.stderr)
213 print("General warnings.", file=sys.stderr)215 print("General warnings.", file=sys.stderr)
214 for warninginfo in other_warnings.itervalues():216 for warninginfo in six.itervalues(other_warnings):
215 print(file=sys.stderr)217 print(file=sys.stderr)
216 print(warninginfo, file=sys.stderr)218 print(warninginfo, file=sys.stderr)
217219
diff --git a/lib/lp/services/command_spawner.py b/lib/lp/services/command_spawner.py
index dcca28f..539a3fb 100644
--- a/lib/lp/services/command_spawner.py
+++ b/lib/lp/services/command_spawner.py
@@ -151,7 +151,7 @@ class CommandSpawner:
151 processes are cleaned up. Until then, they will stay around as151 processes are cleaned up. Until then, they will stay around as
152 zombies.152 zombies.
153 """153 """
154 for process in self.running_processes.iterkeys():154 for process in self.running_processes:
155 process.terminate()155 process.terminate()
156156
157 def _spawn(self, command):157 def _spawn(self, command):
diff --git a/lib/lp/services/config/__init__.py b/lib/lp/services/config/__init__.py
index 3c6ad51..ebe9ebf 100644
--- a/lib/lp/services/config/__init__.py
+++ b/lib/lp/services/config/__init__.py
@@ -22,6 +22,7 @@ import sys
2222
23from lazr.config import ImplicitTypeSchema23from lazr.config import ImplicitTypeSchema
24from lazr.config.interfaces import ConfigErrors24from lazr.config.interfaces import ConfigErrors
25import six
25from six.moves.urllib.parse import (26from six.moves.urllib.parse import (
26 urlparse,27 urlparse,
27 urlunparse,28 urlunparse,
@@ -459,7 +460,7 @@ class DatabaseConfig:
459460
460 Overriding a value to None removes the override.461 Overriding a value to None removes the override.
461 """462 """
462 for attr, value in kwargs.iteritems():463 for attr, value in six.iteritems(kwargs):
463 assert attr in self._db_config_attrs, (464 assert attr in self._db_config_attrs, (
464 "%s cannot be overridden" % attr)465 "%s cannot be overridden" % attr)
465 if value is None:466 if value is None:
diff --git a/lib/lp/services/database/bulk.py b/lib/lp/services/database/bulk.py
index f73bbf8..840e402 100644
--- a/lib/lp/services/database/bulk.py
+++ b/lib/lp/services/database/bulk.py
@@ -25,6 +25,7 @@ from operator import (
25 itemgetter,25 itemgetter,
26 )26 )
2727
28import six
28from storm.databases.postgres import Returning29from storm.databases.postgres import Returning
29from storm.expr import (30from storm.expr import (
30 And,31 And,
@@ -52,7 +53,7 @@ def collate(things, key):
52 collection = defaultdict(list)53 collection = defaultdict(list)
53 for thing in things:54 for thing in things:
54 collection[key(thing)].append(thing)55 collection[key(thing)].append(thing)
55 return collection.iteritems()56 return six.iteritems(collection)
5657
5758
58def get_type(thing):59def get_type(thing):
diff --git a/lib/lp/services/features/testing.py b/lib/lp/services/features/testing.py
index 998138d..3a2d69b 100644
--- a/lib/lp/services/features/testing.py
+++ b/lib/lp/services/features/testing.py
@@ -13,6 +13,7 @@ __all__ = [
13from fixtures import Fixture13from fixtures import Fixture
14from lazr.restful.utils import get_current_browser_request14from lazr.restful.utils import get_current_browser_request
15import psycopg215import psycopg2
16import six
1617
17from lp.services.features import (18from lp.services.features import (
18 get_relevant_feature_controller,19 get_relevant_feature_controller,
@@ -91,7 +92,7 @@ class FeatureFixtureMixin:
91 scope='default',92 scope='default',
92 priority=999,93 priority=999,
93 value=unicode(value))94 value=unicode(value))
94 for flag_name, value in self.desired_features.iteritems()95 for flag_name, value in six.iteritems(self.desired_features)
95 if value is not None]96 if value is not None]
9697
97 if self.full_feature_rules is not None:98 if self.full_feature_rules is not None:
diff --git a/lib/lp/services/librarianserver/testing/fake.py b/lib/lp/services/librarianserver/testing/fake.py
index 37d6bb6..e1e1f5e 100644
--- a/lib/lp/services/librarianserver/testing/fake.py
+++ b/lib/lp/services/librarianserver/testing/fake.py
@@ -19,6 +19,7 @@ import hashlib
19from StringIO import StringIO19from StringIO import StringIO
2020
21from fixtures import Fixture21from fixtures import Fixture
22import six
22from six.moves.urllib.parse import urljoin23from six.moves.urllib.parse import urljoin
23import transaction24import transaction
24from transaction.interfaces import ISynchronizer25from transaction.interfaces import ISynchronizer
@@ -138,7 +139,7 @@ class FakeLibrarian(Fixture):
138 database transaction.139 database transaction.
139 """140 """
140 # Note that all files have been committed to storage.141 # Note that all files have been committed to storage.
141 for alias in self.aliases.itervalues():142 for alias in six.itervalues(self.aliases):
142 alias.file_committed = True143 alias.file_committed = True
143144
144 def _makeAlias(self, file_id, name, content, content_type):145 def _makeAlias(self, file_id, name, content, content_type):
@@ -175,7 +176,7 @@ class FakeLibrarian(Fixture):
175176
176 def findBySHA256(self, sha256):177 def findBySHA256(self, sha256):
177 "See `ILibraryFileAliasSet`."""178 "See `ILibraryFileAliasSet`."""
178 for alias in self.aliases.itervalues():179 for alias in six.itervalues(self.aliases):
179 if alias.content.sha256 == sha256:180 if alias.content.sha256 == sha256:
180 return alias181 return alias
181182
diff --git a/lib/lp/services/mail/basemailer.py b/lib/lp/services/mail/basemailer.py
index a2f8a40..280ab78 100644
--- a/lib/lp/services/mail/basemailer.py
+++ b/lib/lp/services/mail/basemailer.py
@@ -12,6 +12,7 @@ import logging
12from smtplib import SMTPException12from smtplib import SMTPException
13import sys13import sys
1414
15import six
15from zope.component import getUtility16from zope.component import getUtility
16from zope.error.interfaces import IErrorReportingUtility17from zope.error.interfaces import IErrorReportingUtility
17from zope.security.management import getSecurityPolicy18from zope.security.management import getSecurityPolicy
@@ -79,7 +80,7 @@ class BaseMailer:
79 self._subject_template = subject80 self._subject_template = subject
80 self._template_name = template_name81 self._template_name = template_name
81 self._recipients = NotificationRecipientSet()82 self._recipients = NotificationRecipientSet()
82 for recipient, reason in recipients.iteritems():83 for recipient, reason in six.iteritems(recipients):
83 self._recipients.add(recipient, reason, reason.mail_header)84 self._recipients.add(recipient, reason, reason.mail_header)
84 self.from_address = from_address85 self.from_address = from_address
85 self.delta = delta86 self.delta = delta
diff --git a/lib/lp/services/messaging/tests/test_rabbit.py b/lib/lp/services/messaging/tests/test_rabbit.py
index 6cd9f99..dfd48af 100644
--- a/lib/lp/services/messaging/tests/test_rabbit.py
+++ b/lib/lp/services/messaging/tests/test_rabbit.py
@@ -9,6 +9,7 @@ from functools import partial
9from itertools import count9from itertools import count
10import socket10import socket
1111
12import six
12from testtools.testcase import ExpectedException13from testtools.testcase import ExpectedException
13import transaction14import transaction
14from transaction._transaction import Status as TransactionStatus15from transaction._transaction import Status as TransactionStatus
@@ -396,7 +397,7 @@ class TestRabbit(RabbitTestCase):
396 return set()397 return set()
397 else:398 else:
398 return set(399 return set(
399 sync.session for sync in syncs_set.data.itervalues()400 sync.session for sync in six.itervalues(syncs_set.data)
400 if isinstance(sync, RabbitSessionTransactionSync))401 if isinstance(sync, RabbitSessionTransactionSync))
401402
402 def test_global_session(self):403 def test_global_session(self):
diff --git a/lib/lp/services/osutils.py b/lib/lp/services/osutils.py
index b487165..7eafc40 100644
--- a/lib/lp/services/osutils.py
+++ b/lib/lp/services/osutils.py
@@ -28,6 +28,8 @@ from signal import (
28 )28 )
29import time29import time
3030
31import six
32
3133
32def remove_tree(path):34def remove_tree(path):
33 """Remove the tree at 'path' from disk."""35 """Remove the tree at 'path' from disk."""
@@ -41,7 +43,7 @@ def set_environ(new_values):
41 :return: a dict of the old values43 :return: a dict of the old values
42 """44 """
43 old_values = {}45 old_values = {}
44 for name, value in new_values.iteritems():46 for name, value in six.iteritems(new_values):
45 old_values[name] = os.environ.get(name)47 old_values[name] = os.environ.get(name)
46 if value is None:48 if value is None:
47 if old_values[name] is not None:49 if old_values[name] is not None:
diff --git a/lib/lp/services/testing/customresult.py b/lib/lp/services/testing/customresult.py
index 2164f3d..5862f84 100644
--- a/lib/lp/services/testing/customresult.py
+++ b/lib/lp/services/testing/customresult.py
@@ -11,6 +11,7 @@ __all__ = [
1111
12from unittest import TestSuite12from unittest import TestSuite
1313
14import six
14from zope.testrunner import find15from zope.testrunner import find
1516
1617
@@ -65,7 +66,7 @@ def filter_tests(list_name, reorder_tests=False):
65 test_lookup = {}66 test_lookup = {}
66 # Multiple unique testcases can be represented by a single id and they67 # Multiple unique testcases can be represented by a single id and they
67 # must be tracked separately.68 # must be tracked separately.
68 for layer_name, suite in tests_by_layer_name.iteritems():69 for layer_name, suite in six.iteritems(tests_by_layer_name):
69 for testcase in suite:70 for testcase in suite:
70 layer_to_tests = test_lookup.setdefault(71 layer_to_tests = test_lookup.setdefault(
71 testcase.id(), {})72 testcase.id(), {})
diff --git a/lib/lp/services/utils.py b/lib/lp/services/utils.py
index beda118..ea661c5 100644
--- a/lib/lp/services/utils.py
+++ b/lib/lp/services/utils.py
@@ -52,6 +52,7 @@ from fixtures import (
52 )52 )
53from lazr.enum import BaseItem53from lazr.enum import BaseItem
54import pytz54import pytz
55import six
55from six.moves import cPickle as pickle56from six.moves import cPickle as pickle
56from twisted.python.util import mergeFunctionMetadata57from twisted.python.util import mergeFunctionMetadata
57from zope.security.proxy import isinstance as zope_isinstance58from zope.security.proxy import isinstance as zope_isinstance
@@ -388,7 +389,7 @@ def obfuscate_structure(o):
388 elif isinstance(o, (dict)):389 elif isinstance(o, (dict)):
389 return dict(390 return dict(
390 (obfuscate_structure(key), obfuscate_structure(value))391 (obfuscate_structure(key), obfuscate_structure(value))
391 for key, value in o.iteritems())392 for key, value in six.iteritems(o))
392 else:393 else:
393 return o394 return o
394395
diff --git a/lib/lp/services/webapp/escaping.py b/lib/lp/services/webapp/escaping.py
index 8c4d965..bce499e 100644
--- a/lib/lp/services/webapp/escaping.py
+++ b/lib/lp/services/webapp/escaping.py
@@ -9,6 +9,7 @@ __all__ = [
9 ]9 ]
1010
11from lazr.restful.utils import get_current_browser_request11from lazr.restful.utils import get_current_browser_request
12import six
12from zope.i18n import (13from zope.i18n import (
13 Message,14 Message,
14 translate,15 translate,
@@ -95,7 +96,7 @@ class structured:
95 self.escapedtext = text % tuple(html_escape(rep) for rep in reps)96 self.escapedtext = text % tuple(html_escape(rep) for rep in reps)
96 elif kwreps:97 elif kwreps:
97 self.escapedtext = text % dict(98 self.escapedtext = text % dict(
98 (k, html_escape(v)) for k, v in kwreps.iteritems())99 (k, html_escape(v)) for k, v in six.iteritems(kwreps))
99 else:100 else:
100 self.escapedtext = text101 self.escapedtext = text
101102
diff --git a/lib/lp/services/webapp/login.py b/lib/lp/services/webapp/login.py
index 43eb478..fdbd079 100644
--- a/lib/lp/services/webapp/login.py
+++ b/lib/lp/services/webapp/login.py
@@ -290,7 +290,7 @@ class OpenIDCallbackView(OpenIDLogin):
290290
291 def _gather_params(self, request):291 def _gather_params(self, request):
292 params = dict(request.form)292 params = dict(request.form)
293 for key, value in request.query_string_params.iteritems():293 for key, value in six.iteritems(request.query_string_params):
294 if len(value) > 1:294 if len(value) > 1:
295 raise ValueError(295 raise ValueError(
296 'Did not expect multi-valued fields.')296 'Did not expect multi-valued fields.')
diff --git a/lib/lp/services/webapp/servers.py b/lib/lp/services/webapp/servers.py
index 8b85df8..1f77b76 100644
--- a/lib/lp/services/webapp/servers.py
+++ b/lib/lp/services/webapp/servers.py
@@ -529,7 +529,7 @@ def get_query_string_params(request):
529 parsed_qs = parse_qs(query_string, keep_blank_values=True)529 parsed_qs = parse_qs(query_string, keep_blank_values=True)
530 # Use BrowserRequest._decode() for decoding the received parameters.530 # Use BrowserRequest._decode() for decoding the received parameters.
531 decoded_qs = {}531 decoded_qs = {}
532 for key, values in parsed_qs.iteritems():532 for key, values in six.iteritems(parsed_qs):
533 decoded_qs[key] = [533 decoded_qs[key] = [
534 request._decode(value) for value in values]534 request._decode(value) for value in values]
535 return decoded_qs535 return decoded_qs
diff --git a/lib/lp/services/webhooks/interfaces.py b/lib/lp/services/webhooks/interfaces.py
index d4d20e3..ad01625 100644
--- a/lib/lp/services/webhooks/interfaces.py
+++ b/lib/lp/services/webhooks/interfaces.py
@@ -40,6 +40,7 @@ from lazr.restful.fields import (
40 Reference,40 Reference,
41 )41 )
42from lazr.restful.interface import copy_field42from lazr.restful.interface import copy_field
43import six
43from six.moves import http_client44from six.moves import http_client
44from zope.interface import (45from zope.interface import (
45 Attribute,46 Attribute,
@@ -105,7 +106,7 @@ class AnyWebhookEventTypeVocabulary(SimpleVocabulary):
105 def __init__(self, context):106 def __init__(self, context):
106 terms = [107 terms = [
107 self.createTerm(key, key, value)108 self.createTerm(key, key, value)
108 for key, value in WEBHOOK_EVENT_TYPES.iteritems()]109 for key, value in six.iteritems(WEBHOOK_EVENT_TYPES)]
109 super(AnyWebhookEventTypeVocabulary, self).__init__(terms)110 super(AnyWebhookEventTypeVocabulary, self).__init__(terms)
110111
111112
diff --git a/lib/lp/soyuz/browser/tests/archive-views.txt b/lib/lp/soyuz/browser/tests/archive-views.txt
index 8f440d7..72c1392 100644
--- a/lib/lp/soyuz/browser/tests/archive-views.txt
+++ b/lib/lp/soyuz/browser/tests/archive-views.txt
@@ -105,8 +105,10 @@ usage details in a dictionary containing:
105We will use a helper function for printing the returned dictionary105We will use a helper function for printing the returned dictionary
106contents.106contents.
107107
108 >>> import six
109
108 >>> def print_repository_usage(repository_usage):110 >>> def print_repository_usage(repository_usage):
109 ... for key, value in sorted(repository_usage.iteritems()):111 ... for key, value in sorted(six.iteritems(repository_usage)):
110 ... print('%s: %s' % (key, value))112 ... print('%s: %s' % (key, value))
111113
112Celso PPA has some packages, but still below the quota.114Celso PPA has some packages, but still below the quota.
diff --git a/lib/lp/soyuz/model/packagediff.py b/lib/lp/soyuz/model/packagediff.py
index 6933c31..12437cd 100644
--- a/lib/lp/soyuz/model/packagediff.py
+++ b/lib/lp/soyuz/model/packagediff.py
@@ -16,6 +16,7 @@ import shutil
16import subprocess16import subprocess
17import tempfile17import tempfile
1818
19import six
19from sqlobject import ForeignKey20from sqlobject import ForeignKey
20from storm.expr import Desc21from storm.expr import Desc
21from storm.store import EmptyResultSet22from storm.store import EmptyResultSet
@@ -215,7 +216,7 @@ class PackageDiff(SQLBase):
215 zip(directions, (self.from_source, self.to_source)))216 zip(directions, (self.from_source, self.to_source)))
216217
217 # Iterate over the packages to be diff'ed.218 # Iterate over the packages to be diff'ed.
218 for direction, package in packages.iteritems():219 for direction, package in six.iteritems(packages):
219 # Create distinct directory locations for220 # Create distinct directory locations for
220 # 'from' and 'to' files.221 # 'from' and 'to' files.
221 absolute_path = os.path.join(tmp_dir, direction)222 absolute_path = os.path.join(tmp_dir, direction)
diff --git a/lib/lp/soyuz/model/publishing.py b/lib/lp/soyuz/model/publishing.py
index fafd7f9..1c5d384 100644
--- a/lib/lp/soyuz/model/publishing.py
+++ b/lib/lp/soyuz/model/publishing.py
@@ -22,6 +22,7 @@ import os
22import sys22import sys
2323
24import pytz24import pytz
25import six
25from sqlobject import (26from sqlobject import (
26 ForeignKey,27 ForeignKey,
27 IntCol,28 IntCol,
@@ -1012,7 +1013,7 @@ def expand_binary_requests(distroseries, binaries):
1012 arch_map = dict((arch.architecturetag, arch) for arch in archs)1013 arch_map = dict((arch.architecturetag, arch) for arch in archs)
10131014
1014 expanded = []1015 expanded = []
1015 for bpr, overrides in binaries.iteritems():1016 for bpr, overrides in six.iteritems(binaries):
1016 if bpr.architecturespecific:1017 if bpr.architecturespecific:
1017 # Find the DAS in this series corresponding to the original1018 # Find the DAS in this series corresponding to the original
1018 # build arch tag. If it does not exist or is disabled, we should1019 # build arch tag. If it does not exist or is disabled, we should
diff --git a/lib/lp/soyuz/scripts/custom_uploads_copier.py b/lib/lp/soyuz/scripts/custom_uploads_copier.py
index e6f7e83..21cc1f2 100644
--- a/lib/lp/soyuz/scripts/custom_uploads_copier.py
+++ b/lib/lp/soyuz/scripts/custom_uploads_copier.py
@@ -14,6 +14,8 @@ __all__ = [
1414
15from operator import attrgetter15from operator import attrgetter
1616
17import six
18
17from lp.archivepublisher.ddtp_tarball import DdtpTarballUpload19from lp.archivepublisher.ddtp_tarball import DdtpTarballUpload
18from lp.archivepublisher.debian_installer import DebianInstallerUpload20from lp.archivepublisher.debian_installer import DebianInstallerUpload
19from lp.archivepublisher.dist_upgrader import DistUpgraderUpload21from lp.archivepublisher.dist_upgrader import DistUpgraderUpload
@@ -163,7 +165,7 @@ class CustomUploadsCopier:
163 self.target_series, source_pocket=self.target_pocket)165 self.target_series, source_pocket=self.target_pocket)
164 source_uploads = self.getLatestUploads(166 source_uploads = self.getLatestUploads(
165 source_series, source_pocket=source_pocket)167 source_series, source_pocket=source_pocket)
166 for upload in source_uploads.itervalues():168 for upload in six.itervalues(source_uploads):
167 if (not self.isObsolete(upload, target_uploads) and169 if (not self.isObsolete(upload, target_uploads) and
168 self.isForValidDAS(upload)):170 self.isForValidDAS(upload)):
169 self.copyUpload(upload)171 self.copyUpload(upload)
diff --git a/lib/lp/soyuz/scripts/gina/handlers.py b/lib/lp/soyuz/scripts/gina/handlers.py
index 54539a4..597e5aa 100644
--- a/lib/lp/soyuz/scripts/gina/handlers.py
+++ b/lib/lp/soyuz/scripts/gina/handlers.py
@@ -24,6 +24,7 @@ from cStringIO import StringIO
24import os24import os
25import re25import re
2626
27import six
27from sqlobject import (28from sqlobject import (
28 SQLObjectMoreThanOneResultError,29 SQLObjectMoreThanOneResultError,
29 SQLObjectNotFound,30 SQLObjectNotFound,
@@ -504,7 +505,7 @@ class SourcePackageHandler:
504 dsc_contents = parse_tagfile(dsc_path)505 dsc_contents = parse_tagfile(dsc_path)
505 dsc_contents = dict([506 dsc_contents = dict([
506 (name.lower(), value) for507 (name.lower(), value) for
507 (name, value) in dsc_contents.iteritems()])508 (name, value) in six.iteritems(dsc_contents)])
508509
509 # Since the dsc doesn't know, we add in the directory, package510 # Since the dsc doesn't know, we add in the directory, package
510 # component and section511 # component and section
diff --git a/lib/lp/soyuz/scripts/gina/runner.py b/lib/lp/soyuz/scripts/gina/runner.py
index d9edd1f..631323f 100644
--- a/lib/lp/soyuz/scripts/gina/runner.py
+++ b/lib/lp/soyuz/scripts/gina/runner.py
@@ -157,7 +157,7 @@ def import_sourcepackages(distro, packages_map, package_root,
157 npacks = len(packages_map.src_map)157 npacks = len(packages_map.src_map)
158 log.info('%i Source Packages to be imported', npacks)158 log.info('%i Source Packages to be imported', npacks)
159159
160 for package in sorted(packages_map.src_map.iterkeys()):160 for package in sorted(packages_map.src_map):
161 for source in packages_map.src_map[package]:161 for source in packages_map.src_map[package]:
162 attempt_source_package_import(162 attempt_source_package_import(
163 distro, source, package_root, importer_handler)163 distro, source, package_root, importer_handler)
@@ -193,7 +193,7 @@ def import_binarypackages(distro, packages_map, package_root,
193 log.info(193 log.info(
194 '%i Binary Packages to be imported for %s', npacks, archtag)194 '%i Binary Packages to be imported for %s', npacks, archtag)
195 # Go over binarypackages importing them for this architecture195 # Go over binarypackages importing them for this architecture
196 for package_name in sorted(packages_map.bin_map[archtag].iterkeys()):196 for package_name in sorted(packages_map.bin_map[archtag]):
197 binary = packages_map.bin_map[archtag][package_name]197 binary = packages_map.bin_map[archtag][package_name]
198 try:198 try:
199 try:199 try:
diff --git a/lib/lp/testing/__init__.py b/lib/lp/testing/__init__.py
index 20a50d9..81e86f1 100644
--- a/lib/lp/testing/__init__.py
+++ b/lib/lp/testing/__init__.py
@@ -96,6 +96,7 @@ import oops_datedir_repo.serializer_rfc822
96import pytz96import pytz
97import scandir97import scandir
98import simplejson98import simplejson
99import six
99from storm.store import Store100from storm.store import Store
100import subunit101import subunit
101import testtools102import testtools
@@ -697,7 +698,7 @@ class TestCase(testtools.TestCase, fixtures.TestWithFixtures):
697 The config values will be restored during test tearDown.698 The config values will be restored during test tearDown.
698 """699 """
699 name = self.factory.getUniqueString()700 name = self.factory.getUniqueString()
700 body = '\n'.join("%s: %s" % (k, v) for k, v in kwargs.iteritems())701 body = '\n'.join("%s: %s" % (k, v) for k, v in six.iteritems(kwargs))
701 config.push(name, "\n[%s]\n%s\n" % (section, body))702 config.push(name, "\n[%s]\n%s\n" % (section, body))
702 self.addCleanup(config.pop, name)703 self.addCleanup(config.pop, name)
703704
@@ -1527,13 +1528,13 @@ def monkey_patch(context, **kwargs):
1527 """1528 """
1528 old_values = {}1529 old_values = {}
1529 not_set = object()1530 not_set = object()
1530 for name, value in kwargs.iteritems():1531 for name, value in six.iteritems(kwargs):
1531 old_values[name] = getattr(context, name, not_set)1532 old_values[name] = getattr(context, name, not_set)
1532 setattr(context, name, value)1533 setattr(context, name, value)
1533 try:1534 try:
1534 yield1535 yield
1535 finally:1536 finally:
1536 for name, value in old_values.iteritems():1537 for name, value in six.iteritems(old_values):
1537 if value is not_set:1538 if value is not_set:
1538 delattr(context, name)1539 delattr(context, name)
1539 else:1540 else:
diff --git a/lib/lp/testing/swift/fakeswift.py b/lib/lp/testing/swift/fakeswift.py
index 0712e7a..c90dc0d 100644
--- a/lib/lp/testing/swift/fakeswift.py
+++ b/lib/lp/testing/swift/fakeswift.py
@@ -22,6 +22,7 @@ import sys
22import time22import time
23import uuid23import uuid
2424
25import six
25from twisted.web import (26from twisted.web import (
26 http,27 http,
27 resource,28 resource,
@@ -77,7 +78,7 @@ class FakeKeystone(resource.Resource):
77 if self._isValidToken(token, tenant_name):78 if self._isValidToken(token, tenant_name):
78 return token79 return token
79 else:80 else:
80 for id, token in self.tokens.iteritems():81 for id, token in six.iteritems(self.tokens):
81 if self._isValidToken(token, tenant_name):82 if self._isValidToken(token, tenant_name):
82 return token83 return token
8384
diff --git a/lib/lp/translations/browser/translationlinksaggregator.py b/lib/lp/translations/browser/translationlinksaggregator.py
index 3f196bc..4b06509 100644
--- a/lib/lp/translations/browser/translationlinksaggregator.py
+++ b/lib/lp/translations/browser/translationlinksaggregator.py
@@ -7,6 +7,8 @@ __all__ = [
7 'TranslationLinksAggregator',7 'TranslationLinksAggregator',
8 ]8 ]
99
10import six
11
10from lp.services.webapp import canonical_url12from lp.services.webapp import canonical_url
11from lp.translations.interfaces.pofile import IPOFile13from lp.translations.interfaces.pofile import IPOFile
12from lp.translations.model.productserieslanguage import ProductSeriesLanguage14from lp.translations.model.productserieslanguage import ProductSeriesLanguage
@@ -177,10 +179,10 @@ class TranslationLinksAggregator:
177 returns for the sensible chunks.179 returns for the sensible chunks.
178 """180 """
179 links = []181 links = []
180 for target, sheets in self._bundle(sheets).iteritems():182 for target, sheets in six.iteritems(self._bundle(sheets)):
181 assert sheets, "Translation target has no POFiles or templates."183 assert sheets, "Translation target has no POFiles or templates."
182 links_and_sheets = self._circumscribe(sheets)184 links_and_sheets = self._circumscribe(sheets)
183 for link, covered_sheets in links_and_sheets.iteritems():185 for link, covered_sheets in six.iteritems(links_and_sheets):
184 links.append(self.describe(target, link, covered_sheets))186 links.append(self.describe(target, link, covered_sheets))
185187
186 return links188 return links
diff --git a/lib/lp/translations/browser/translationmessage.py b/lib/lp/translations/browser/translationmessage.py
index ef75f6c..dbdf1d1 100644
--- a/lib/lp/translations/browser/translationmessage.py
+++ b/lib/lp/translations/browser/translationmessage.py
@@ -23,6 +23,7 @@ import operator
23import re23import re
2424
25import pytz25import pytz
26import six
26from six.moves.urllib.parse import (27from six.moves.urllib.parse import (
27 parse_qsl,28 parse_qsl,
28 urlencode,29 urlencode,
@@ -96,7 +97,7 @@ def revert_unselected_translations(translations, current_message,
96 original_translations = dict(enumerate(current_message.translations))97 original_translations = dict(enumerate(current_message.translations))
9798
98 output = {}99 output = {}
99 for plural_form, translation in translations.iteritems():100 for plural_form, translation in six.iteritems(translations):
100 if plural_form in plural_indices_to_store:101 if plural_form in plural_indices_to_store:
101 output[plural_form] = translation102 output[plural_form] = translation
102 elif original_translations.get(plural_form) is None:103 elif original_translations.get(plural_form) is None:
@@ -113,7 +114,7 @@ def contains_translations(translations):
113 :param translations: a dict mapping plural forms to their respective114 :param translations: a dict mapping plural forms to their respective
114 translation strings.115 translation strings.
115 """116 """
116 for text in translations.itervalues():117 for text in six.itervalues(translations):
117 if text is not None and len(text) != 0:118 if text is not None and len(text) != 0:
118 return True119 return True
119 return False120 return False
diff --git a/lib/lp/translations/doc/translationimportqueue.txt b/lib/lp/translations/doc/translationimportqueue.txt
index 9f7d8c9..c62423b 100644
--- a/lib/lp/translations/doc/translationimportqueue.txt
+++ b/lib/lp/translations/doc/translationimportqueue.txt
@@ -1223,9 +1223,11 @@ bug 138650 for an example).
1223If such bad requests do end up on the import queue, the import queue code will1223If such bad requests do end up on the import queue, the import queue code will
1224raise errors about them.1224raise errors about them.
12251225
1226 >>> import six
1227
1226 >>> def print_import_failures(import_script):1228 >>> def print_import_failures(import_script):
1227 ... """List failures recorded in an import script instance."""1229 ... """List failures recorded in an import script instance."""
1228 ... for reason, entries in script.failures.iteritems():1230 ... for reason, entries in six.iteritems(script.failures):
1229 ... print(reason)1231 ... print(reason)
1230 ... for entry in entries:1232 ... for entry in entries:
1231 ... print("-> " + entry)1233 ... print("-> " + entry)
diff --git a/lib/lp/translations/model/potemplate.py b/lib/lp/translations/model/potemplate.py
index ba0a632..70dedd2 100644
--- a/lib/lp/translations/model/potemplate.py
+++ b/lib/lp/translations/model/potemplate.py
@@ -19,6 +19,7 @@ import operator
19import os19import os
2020
21from psycopg2.extensions import TransactionRollbackError21from psycopg2.extensions import TransactionRollbackError
22import six
22from sqlobject import (23from sqlobject import (
23 BoolCol,24 BoolCol,
24 ForeignKey,25 ForeignKey,
@@ -1560,7 +1561,7 @@ class POTemplateSharingSubset(object):
1560 equivalents[key] = []1561 equivalents[key] = []
1561 equivalents[key].append(template)1562 equivalents[key].append(template)
15621563
1563 for equivalence_list in equivalents.itervalues():1564 for equivalence_list in six.itervalues(equivalents):
1564 # Sort potemplates from "most representative" to "least1565 # Sort potemplates from "most representative" to "least
1565 # representative."1566 # representative."
1566 equivalence_list.sort(key=POTemplate.sharingKey, reverse=True)1567 equivalence_list.sort(key=POTemplate.sharingKey, reverse=True)
diff --git a/lib/lp/translations/model/potmsgset.py b/lib/lp/translations/model/potmsgset.py
index 12f9f05..f256384 100644
--- a/lib/lp/translations/model/potmsgset.py
+++ b/lib/lp/translations/model/potmsgset.py
@@ -14,6 +14,7 @@ from collections import (
14import logging14import logging
15import re15import re
1616
17import six
17from sqlobject import (18from sqlobject import (
18 ForeignKey,19 ForeignKey,
19 SQLObjectNotFound,20 SQLObjectNotFound,
@@ -122,7 +123,7 @@ def dictify_translations(translations):
122 # Filter out None values.123 # Filter out None values.
123 return dict(124 return dict(
124 (form, translation)125 (form, translation)
125 for form, translation in translations.iteritems()126 for form, translation in six.iteritems(translations)
126 if translation is not None)127 if translation is not None)
127128
128129
@@ -611,7 +612,7 @@ class POTMsgSet(SQLBase):
611612
612 forms = dict(613 forms = dict(
613 ('msgstr%d' % form, potranslation)614 ('msgstr%d' % form, potranslation)
614 for form, potranslation in potranslations.iteritems())615 for form, potranslation in six.iteritems(potranslations))
615616
616 if from_import:617 if from_import:
617 origin = RosettaTranslationOrigin.SCM618 origin = RosettaTranslationOrigin.SCM
@@ -748,7 +749,7 @@ class POTMsgSet(SQLBase):
748749
749 translation_args = dict(750 translation_args = dict(
750 ('msgstr%d' % form, translation)751 ('msgstr%d' % form, translation)
751 for form, translation in translations.iteritems())752 for form, translation in six.iteritems(translations))
752753
753 return TranslationMessage(754 return TranslationMessage(
754 potmsgset=self,755 potmsgset=self,
diff --git a/lib/lp/translations/model/translationimportqueue.py b/lib/lp/translations/model/translationimportqueue.py
index 3ded490..483a4c3 100644
--- a/lib/lp/translations/model/translationimportqueue.py
+++ b/lib/lp/translations/model/translationimportqueue.py
@@ -19,6 +19,7 @@ from textwrap import dedent
1919
20import posixpath20import posixpath
21import pytz21import pytz
22import six
22from sqlobject import (23from sqlobject import (
23 BoolCol,24 BoolCol,
24 ForeignKey,25 ForeignKey,
@@ -1457,7 +1458,8 @@ class TranslationImportQueue:
1457 """1458 """
1458 now = datetime.datetime.now(pytz.UTC)1459 now = datetime.datetime.now(pytz.UTC)
1459 deletion_clauses = []1460 deletion_clauses = []
1460 for status, max_age in translation_import_queue_entry_age.iteritems():1461 for status, max_age in six.iteritems(
1462 translation_import_queue_entry_age):
1461 cutoff = now - max_age1463 cutoff = now - max_age
1462 deletion_clauses.append(And(1464 deletion_clauses.append(And(
1463 TranslationImportQueueEntry.status == status,1465 TranslationImportQueueEntry.status == status,
diff --git a/lib/lp/translations/model/translationsharingjob.py b/lib/lp/translations/model/translationsharingjob.py
index 8a60008..313e8db 100644
--- a/lib/lp/translations/model/translationsharingjob.py
+++ b/lib/lp/translations/model/translationsharingjob.py
@@ -170,7 +170,7 @@ class TranslationSharingJobDerived(
170 for.170 for.
171 :param event: The event itself.171 :param event: The event itself.
172 """172 """
173 for event_type, job_classes in cls._event_types.iteritems():173 for event_type, job_classes in six.iteritems(cls._event_types):
174 if not event_type.providedBy(event):174 if not event_type.providedBy(event):
175 continue175 continue
176 for job_class in job_classes:176 for job_class in job_classes:
@@ -191,7 +191,7 @@ class TranslationSharingJobDerived(
191 # Ignore changes to POTemplates that are neither renames,191 # Ignore changes to POTemplates that are neither renames,
192 # nor moves to a different package/project.192 # nor moves to a different package/project.
193 return193 return
194 for event_type, job_classes in cls._event_types.iteritems():194 for event_type, job_classes in six.iteritems(cls._event_types):
195 if not event_type.providedBy(event):195 if not event_type.providedBy(event):
196 continue196 continue
197 for job_class in job_classes:197 for job_class in job_classes:
diff --git a/lib/lp/translations/scripts/po_import.py b/lib/lp/translations/scripts/po_import.py
index 3e97f8c..9c9779e 100644
--- a/lib/lp/translations/scripts/po_import.py
+++ b/lib/lp/translations/scripts/po_import.py
@@ -17,6 +17,7 @@ from datetime import (
17import sys17import sys
1818
19import pytz19import pytz
20import six
20from zope.component import getUtility21from zope.component import getUtility
2122
22from lp.app.interfaces.launchpad import ILaunchpadCelebrities23from lp.app.interfaces.launchpad import ILaunchpadCelebrities
@@ -212,5 +213,5 @@ class TranslationsImport(LaunchpadCronScript):
212213
213 def _reportFailures(self):214 def _reportFailures(self):
214 """Bulk-report deferred failures as oopses."""215 """Bulk-report deferred failures as oopses."""
215 for reason, entries in self.failures.iteritems():216 for reason, entries in six.iteritems(self.failures):
216 self._reportOops(reason, entries)217 self._reportOops(reason, entries)
diff --git a/lib/lp/translations/scripts/tests/test_reupload_translations.py b/lib/lp/translations/scripts/tests/test_reupload_translations.py
index f2a449f..2ec0cee 100644
--- a/lib/lp/translations/scripts/tests/test_reupload_translations.py
+++ b/lib/lp/translations/scripts/tests/test_reupload_translations.py
@@ -11,6 +11,7 @@ import re
11from StringIO import StringIO11from StringIO import StringIO
12import tarfile12import tarfile
1313
14import six
14import transaction15import transaction
15from zope.security.proxy import removeSecurityProxy16from zope.security.proxy import removeSecurityProxy
1617
@@ -61,7 +62,7 @@ def upload_tarball(translation_files):
61 """62 """
62 buf = StringIO()63 buf = StringIO()
63 tarball = tarfile.open('', 'w:gz', buf)64 tarball = tarfile.open('', 'w:gz', buf)
64 for name, contents in translation_files.iteritems():65 for name, contents in six.iteritems(translation_files):
65 pseudofile = StringIO(contents)66 pseudofile = StringIO(contents)
66 tarinfo = tarfile.TarInfo()67 tarinfo = tarfile.TarInfo()
67 tarinfo.name = name68 tarinfo.name = name
@@ -93,7 +94,7 @@ def filter_paths(files_dict):
93 applied to each file's path, and non-Ubuntu files left out.94 applied to each file's path, and non-Ubuntu files left out.
94 """95 """
95 filtered_dict = {}96 filtered_dict = {}
96 for original_path, content in files_dict.iteritems():97 for original_path, content in six.iteritems(files_dict):
97 new_path = _filter_ubuntu_translation_file(original_path)98 new_path = _filter_ubuntu_translation_file(original_path)
98 if new_path:99 if new_path:
99 filtered_dict[new_path] = content100 filtered_dict[new_path] = content
diff --git a/lib/lp/translations/scripts/tests/test_translations_to_branch.py b/lib/lp/translations/scripts/tests/test_translations_to_branch.py
index 248b2e0..0cd058a 100644
--- a/lib/lp/translations/scripts/tests/test_translations_to_branch.py
+++ b/lib/lp/translations/scripts/tests/test_translations_to_branch.py
@@ -9,6 +9,7 @@ from textwrap import dedent
99
10from breezy.errors import NotBranchError10from breezy.errors import NotBranchError
11import pytz11import pytz
12import six
12from testtools.matchers import MatchesRegex13from testtools.matchers import MatchesRegex
13import transaction14import transaction
14from zope.component import getUtility15from zope.component import getUtility
@@ -116,8 +117,8 @@ class TestExportTranslationsToBranch(TestCaseWithFactory):
116 msgstr "Hallo Wereld"\n""",117 msgstr "Hallo Wereld"\n""",
117 }118 }
118119
119 branch_filenames = set(branch_contents.iterkeys())120 branch_filenames = set(branch_contents)
120 expected_filenames = set(expected_contents.iterkeys())121 expected_filenames = set(expected_contents)
121122
122 unexpected_filenames = branch_filenames - expected_filenames123 unexpected_filenames = branch_filenames - expected_filenames
123 self.assertEqual(set(), unexpected_filenames)124 self.assertEqual(set(), unexpected_filenames)
@@ -125,7 +126,7 @@ class TestExportTranslationsToBranch(TestCaseWithFactory):
125 missing_filenames = expected_filenames - branch_filenames126 missing_filenames = expected_filenames - branch_filenames
126 self.assertEqual(set(), missing_filenames)127 self.assertEqual(set(), missing_filenames)
127128
128 for filename, expected in expected_contents.iteritems():129 for filename, expected in six.iteritems(expected_contents):
129 contents = branch_contents[filename].lstrip('\n')130 contents = branch_contents[filename].lstrip('\n')
130 pattern = dedent(expected.lstrip('\n'))131 pattern = dedent(expected.lstrip('\n'))
131 if not re.match(pattern, contents, re.MULTILINE):132 if not re.match(pattern, contents, re.MULTILINE):
diff --git a/lib/lp/translations/stories/webservice/xx-translationimportqueue.txt b/lib/lp/translations/stories/webservice/xx-translationimportqueue.txt
index ca3f633..4b668ed 100644
--- a/lib/lp/translations/stories/webservice/xx-translationimportqueue.txt
+++ b/lib/lp/translations/stories/webservice/xx-translationimportqueue.txt
@@ -29,7 +29,7 @@ to be cleaned up.
29 ... shown. If omitted, all keys are shown.29 ... shown. If omitted, all keys are shown.
30 ... """30 ... """
31 ... print('Entry:')31 ... print('Entry:')
32 ... for key in sorted(a_dict.iterkeys()):32 ... for key in sorted(a_dict):
33 ... if shown_keys is None or key in shown_keys:33 ... if shown_keys is None or key in shown_keys:
34 ... print('', key, a_dict[key])34 ... print('', key, a_dict[key])
3535
diff --git a/lib/lp/translations/tests/test_potemplate.py b/lib/lp/translations/tests/test_potemplate.py
index 4ebb735..d08826e 100644
--- a/lib/lp/translations/tests/test_potemplate.py
+++ b/lib/lp/translations/tests/test_potemplate.py
@@ -5,6 +5,7 @@ __metaclass__ = type
55
6from operator import methodcaller6from operator import methodcaller
77
8import six
8from zope.component import getUtility9from zope.component import getUtility
9from zope.security.proxy import removeSecurityProxy10from zope.security.proxy import removeSecurityProxy
1011
@@ -193,8 +194,8 @@ class EquivalenceClassTestMixin:
193 This ignores the ordering of templates in an equivalence class.194 This ignores the ordering of templates in an equivalence class.
194 A separate test looks at ordering.195 A separate test looks at ordering.
195 """196 """
196 self.assertEqual(set(actual.iterkeys()), set(expected.iterkeys()))197 self.assertEqual(set(actual), set(expected))
197 for key, value in actual.iteritems():198 for key, value in six.iteritems(actual):
198 self.assertEqual(set(value), set(expected[key]))199 self.assertEqual(set(value), set(expected[key]))
199200
200201
diff --git a/lib/lp/translations/tests/test_side.py b/lib/lp/translations/tests/test_side.py
index f5807d0..c7ab892 100644
--- a/lib/lp/translations/tests/test_side.py
+++ b/lib/lp/translations/tests/test_side.py
@@ -5,6 +5,7 @@
55
6__metaclass__ = type6__metaclass__ = type
77
8import six
8from zope.component import getUtility9from zope.component import getUtility
9from zope.interface.verify import verifyObject10from zope.interface.verify import verifyObject
1011
@@ -23,7 +24,7 @@ class TestTranslationSideTraitsSet(TestCaseWithFactory):
23 def test_baseline(self):24 def test_baseline(self):
24 utility = getUtility(ITranslationSideTraitsSet)25 utility = getUtility(ITranslationSideTraitsSet)
25 self.assertTrue(verifyObject(ITranslationSideTraitsSet, utility))26 self.assertTrue(verifyObject(ITranslationSideTraitsSet, utility))
26 for traits in utility.getAllTraits().itervalues():27 for traits in six.itervalues(utility.getAllTraits()):
27 self.assertTrue(verifyObject(ITranslationSideTraits, traits))28 self.assertTrue(verifyObject(ITranslationSideTraits, traits))
2829
29 def test_other_sides(self):30 def test_other_sides(self):
@@ -64,7 +65,7 @@ class TestTranslationSideTraitsSet(TestCaseWithFactory):
64 [TranslationSide.UPSTREAM, TranslationSide.UBUNTU],65 [TranslationSide.UPSTREAM, TranslationSide.UBUNTU],
65 traits_dict.keys())66 traits_dict.keys())
6667
67 for side, traits in traits_dict.iteritems():68 for side, traits in six.iteritems(traits_dict):
68 self.assertEqual(side, traits.side)69 self.assertEqual(side, traits.side)
69 self.assertEqual(traits, utility.getTraits(side))70 self.assertEqual(traits, utility.getTraits(side))
7071
diff --git a/lib/lp/translations/utilities/gettext_po_parser.py b/lib/lp/translations/utilities/gettext_po_parser.py
index c087ef9..78de456 100644
--- a/lib/lp/translations/utilities/gettext_po_parser.py
+++ b/lib/lp/translations/utilities/gettext_po_parser.py
@@ -20,6 +20,7 @@ import logging
20import re20import re
2121
22import pytz22import pytz
23import six
23from zope import datetime as zope_datetime24from zope import datetime as zope_datetime
24from zope.interface import implementer25from zope.interface import implementer
2526
@@ -230,7 +231,7 @@ class POHeader:
230231
231 def _parseHeaderFields(self):232 def _parseHeaderFields(self):
232 """Return plural form values based on the parsed header."""233 """Return plural form values based on the parsed header."""
233 for key, value in self._header_dictionary.iteritems():234 for key, value in six.iteritems(self._header_dictionary):
234 if key == 'plural-forms':235 if key == 'plural-forms':
235 parts = self._parseAssignments(value)236 parts = self._parseAssignments(value)
236 nplurals = parts.get('nplurals')237 nplurals = parts.get('nplurals')
@@ -362,7 +363,7 @@ class POHeader:
362 raise AssertionError('key %s is not being handled!' % value)363 raise AssertionError('key %s is not being handled!' % value)
363364
364 # Now, we copy any other header information in the original .po file.365 # Now, we copy any other header information in the original .po file.
365 for key, value in self._header_dictionary.iteritems():366 for key, value in six.iteritems(self._header_dictionary):
366 if key in self._handled_keys_mapping:367 if key in self._handled_keys_mapping:
367 # It's already handled, skip it.368 # It's already handled, skip it.
368 continue369 continue
diff --git a/lib/lp/translations/utilities/pluralforms.py b/lib/lp/translations/utilities/pluralforms.py
index 680ba14..8a82685 100644
--- a/lib/lp/translations/utilities/pluralforms.py
+++ b/lib/lp/translations/utilities/pluralforms.py
@@ -12,6 +12,8 @@ __all__ = [
12import gettext12import gettext
13import re13import re
1414
15import six
16
15from lp.translations.interfaces.translations import TranslationConstants17from lp.translations.interfaces.translations import TranslationConstants
1618
1719
@@ -47,7 +49,7 @@ def make_friendly_plural_forms(expression, expected_forms):
4749
48 return [50 return [
49 {'form': form, 'examples': examples}51 {'form': form, 'examples': examples}
50 for (form, examples) in forms.iteritems()52 for (form, examples) in six.iteritems(forms)
51 ]53 ]
5254
5355
diff --git a/lib/lp/translations/utilities/tests/test_translation_importer.py b/lib/lp/translations/utilities/tests/test_translation_importer.py
index dcf203b..2d47d01 100644
--- a/lib/lp/translations/utilities/tests/test_translation_importer.py
+++ b/lib/lp/translations/utilities/tests/test_translation_importer.py
@@ -7,6 +7,7 @@ __metaclass__ = type
77
8from io import BytesIO8from io import BytesIO
99
10import six
10import transaction11import transaction
1112
12from lp.services.log.logger import DevNullLogger13from lp.services.log.logger import DevNullLogger
@@ -96,7 +97,7 @@ class TranslationImporterTestCase(TestCaseWithFactory):
96 exactly the same priority."""97 exactly the same priority."""
97 for file_extension in TranslationImporter().supported_file_extensions:98 for file_extension in TranslationImporter().supported_file_extensions:
98 priorities = []99 priorities = []
99 for format, importer in importers.iteritems():100 for format, importer in six.iteritems(importers):
100 if file_extension in importer.file_extensions:101 if file_extension in importer.file_extensions:
101 self.assertNotIn(importer.priority, priorities)102 self.assertNotIn(importer.priority, priorities)
102 priorities.append(importer.priority)103 priorities.append(importer.priority)
diff --git a/lib/lp/translations/utilities/translation_import.py b/lib/lp/translations/utilities/translation_import.py
index 197153d..f9af932 100644
--- a/lib/lp/translations/utilities/translation_import.py
+++ b/lib/lp/translations/utilities/translation_import.py
@@ -14,6 +14,7 @@ from operator import attrgetter
1414
15import posixpath15import posixpath
16import pytz16import pytz
17import six
17from storm.exceptions import TimeoutError18from storm.exceptions import TimeoutError
18import transaction19import transaction
19from zope.component import getUtility20from zope.component import getUtility
@@ -274,7 +275,7 @@ class TranslationImporter:
274 """See `ITranslationImporter`."""275 """See `ITranslationImporter`."""
275 file_extensions = []276 file_extensions = []
276277
277 for importer in importers.itervalues():278 for importer in six.itervalues(importers):
278 file_extensions.extend(importer.file_extensions)279 file_extensions.extend(importer.file_extensions)
279280
280 return sorted(set(file_extensions))281 return sorted(set(file_extensions))
@@ -290,7 +291,7 @@ class TranslationImporter:
290291
291 def isTemplateName(self, path):292 def isTemplateName(self, path):
292 """See `ITranslationImporter`."""293 """See `ITranslationImporter`."""
293 for importer in importers.itervalues():294 for importer in six.itervalues(importers):
294 if path.endswith(importer.template_suffix):295 if path.endswith(importer.template_suffix):
295 return True296 return True
296 return False297 return False
diff --git a/lib/lp/translations/utilities/translationmerger.py b/lib/lp/translations/utilities/translationmerger.py
index 044d058..b507fb6 100644
--- a/lib/lp/translations/utilities/translationmerger.py
+++ b/lib/lp/translations/utilities/translationmerger.py
@@ -283,7 +283,7 @@ class MessageSharingMerge(LaunchpadScript):
283 log.info("Merging %d template equivalence classes." % class_count)283 log.info("Merging %d template equivalence classes." % class_count)
284284
285 tm = TransactionManager(self.txn, self.options.dry_run)285 tm = TransactionManager(self.txn, self.options.dry_run)
286 for number, name in enumerate(sorted(equivalence_classes.iterkeys())):286 for number, name in enumerate(sorted(equivalence_classes)):
287 templates = equivalence_classes[name]287 templates = equivalence_classes[name]
288 log.info(288 log.info(
289 "Merging equivalence class '%s': %d template(s) (%d / %d)" % (289 "Merging equivalence class '%s': %d template(s) (%d / %d)" % (
@@ -429,7 +429,7 @@ class TranslationMerger:
429429
430 self.tm.endTransaction(intermediate=True)430 self.tm.endTransaction(intermediate=True)
431431
432 for representative_id in representatives.itervalues():432 for representative_id in six.itervalues(representatives):
433 representative = POTMsgSet.get(representative_id)433 representative = POTMsgSet.get(representative_id)
434 self._scrubPOTMsgSetTranslations(representative)434 self._scrubPOTMsgSetTranslations(representative)
435 self.tm.endTransaction(intermediate=True)435 self.tm.endTransaction(intermediate=True)
@@ -484,7 +484,7 @@ class TranslationMerger:
484 num_representatives = len(subordinates)484 num_representatives = len(subordinates)
485 representative_num = 0485 representative_num = 0
486486
487 for representative, potmsgsets in subordinates.iteritems():487 for representative, potmsgsets in six.iteritems(subordinates):
488 representative_num += 1488 representative_num += 1
489 log.debug("Message %d/%d: %d subordinate(s)." % (489 log.debug("Message %d/%d: %d subordinate(s)." % (
490 representative_num, num_representatives, len(potmsgsets)))490 representative_num, num_representatives, len(potmsgsets)))
diff --git a/lib/lp/translations/utilities/validate.py b/lib/lp/translations/utilities/validate.py
index 0b9e8df..371a060 100644
--- a/lib/lp/translations/utilities/validate.py
+++ b/lib/lp/translations/utilities/validate.py
@@ -9,6 +9,7 @@ __all__ = [
9 ]9 ]
1010
11import gettextpo11import gettextpo
12import six
1213
1314
14class GettextValidationError(ValueError):15class GettextValidationError(ValueError):
@@ -37,7 +38,7 @@ def validate_translation(original_singular, original_plural,
37 else:38 else:
38 # Message with plural forms.39 # Message with plural forms.
39 msg.set_msgid_plural(original_plural)40 msg.set_msgid_plural(original_plural)
40 for form, translation in translations.iteritems():41 for form, translation in six.iteritems(translations):
41 msg.set_msgstr_plural(form, translation)42 msg.set_msgstr_plural(form, translation)
4243
43 for flag in flags:44 for flag in flags:
diff --git a/utilities/findimports.py b/utilities/findimports.py
index b5615a8..09e0cf1 100755
--- a/utilities/findimports.py
+++ b/utilities/findimports.py
@@ -46,6 +46,8 @@ import linecache
46import os46import os
47import sys47import sys
4848
49import six
50
4951
50class ImportFinder(ASTVisitor):52class ImportFinder(ASTVisitor):
51 """AST visitor that collects all imported names in its imports attribute.53 """AST visitor that collects all imported names in its imports attribute.
@@ -285,7 +287,7 @@ class ModuleGraph(object):
285 def printUnusedImports(self):287 def printUnusedImports(self):
286 for module in self.listModules():288 for module in self.listModules():
287 names = [(unused.lineno, unused.name)289 names = [(unused.lineno, unused.name)
288 for unused in module.unused_names.itervalues()]290 for unused in six.itervalues(module.unused_names)]
289 names.sort()291 names.sort()
290 for lineno, name in names:292 for lineno, name in names:
291 if not self.all_unused:293 if not self.all_unused:
diff --git a/utilities/generate-external-bug-status-docs b/utilities/generate-external-bug-status-docs
index a2d28e8..43e0263 100755
--- a/utilities/generate-external-bug-status-docs
+++ b/utilities/generate-external-bug-status-docs
@@ -26,6 +26,8 @@ from itertools import chain
26from optparse import OptionParser26from optparse import OptionParser
27import sys27import sys
2828
29import six
30
29from lp.bugs.externalbugtracker import BUG_TRACKER_CLASSES31from lp.bugs.externalbugtracker import BUG_TRACKER_CLASSES
3032
3133
@@ -85,7 +87,7 @@ def generate_table(typ, cls):
8587
86def generate_documentable_classes():88def generate_documentable_classes():
87 """Yield each class that has a mapping table defined."""89 """Yield each class that has a mapping table defined."""
88 for typ, cls in BUG_TRACKER_CLASSES.iteritems():90 for typ, cls in six.iteritems(BUG_TRACKER_CLASSES):
89 if getattr(cls, '_status_lookup', None) is not None:91 if getattr(cls, '_status_lookup', None) is not None:
90 yield typ, cls92 yield typ, cls
9193
diff --git a/utilities/list-pages b/utilities/list-pages
index 9989cf6..bf08d0a 100755
--- a/utilities/list-pages
+++ b/utilities/list-pages
@@ -49,6 +49,7 @@ import _pythonpath
49from inspect import getmro49from inspect import getmro
50import os50import os
5151
52import six
52from zope.app.wsgi.testlayer import BrowserLayer53from zope.app.wsgi.testlayer import BrowserLayer
53from zope.browserpage.simpleviewclass import simple54from zope.browserpage.simpleviewclass import simple
54from zope.component import adapter, getGlobalSiteManager55from zope.component import adapter, getGlobalSiteManager
@@ -191,7 +192,7 @@ class Whatever(object):
191192
192 def __call__(self, *args, **kwargs):193 def __call__(self, *args, **kwargs):
193 args = map(repr, args)194 args = map(repr, args)
194 args.extend('%s=%r' % (k, v) for k, v in kwargs.iteritems())195 args.extend('%s=%r' % (k, v) for k, v in six.iteritems(kwargs))
195 # If we're being called with no args, assume this is part of crazy196 # If we're being called with no args, assume this is part of crazy
196 # TALES stuff:197 # TALES stuff:
197 # webapp/metazcml.py(365)path()198 # webapp/metazcml.py(365)path()

Subscribers

People subscribed via source and target branches

to status/vote changes: