Merge ~cjwatson/launchpad:pyupgrade into launchpad:master

Proposed by Colin Watson
Status: Merged
Approved by: Colin Watson
Approved revision: 8e0ebdd3dd6ce056d8d4595b331b7f4cc8a400dc
Merge reported by: Otto Co-Pilot
Merged at revision: not available
Proposed branch: ~cjwatson/launchpad:pyupgrade
Merge into: launchpad:master
Diff against target: 8088 lines (+1177/-1171)
273 files modified
.git-blame-ignore-revs (+2/-0)
.pre-commit-config.yaml (+6/-0)
database/replication/helpers.py (+10/-10)
database/replication/walblock.py (+1/-1)
database/schema/preflight.py (+7/-7)
database/schema/security.py (+9/-9)
lib/devscripts/sourcecode.py (+1/-1)
lib/devscripts/tests/test_sourcecode.py (+1/-1)
lib/lp/answers/model/question.py (+4/-4)
lib/lp/answers/model/tests/test_question.py (+1/-1)
lib/lp/answers/model/tests/test_questionsubscription.py (+1/-1)
lib/lp/app/browser/launchpad.py (+4/-4)
lib/lp/app/browser/linkchecker.py (+1/-1)
lib/lp/app/browser/root.py (+4/-4)
lib/lp/app/browser/stringformatter.py (+1/-1)
lib/lp/app/browser/tales.py (+11/-11)
lib/lp/app/browser/tests/test_launchpad.py (+2/-2)
lib/lp/app/tests/test_tales.py (+2/-2)
lib/lp/app/widgets/suggestion.py (+1/-1)
lib/lp/archivepublisher/model/ftparchive.py (+2/-2)
lib/lp/archivepublisher/publishing.py (+1/-1)
lib/lp/archivepublisher/scripts/publish_ftpmaster.py (+9/-9)
lib/lp/archivepublisher/tests/test_dominator.py (+17/-17)
lib/lp/archivepublisher/tests/test_publish_ftpmaster.py (+1/-1)
lib/lp/archivepublisher/tests/test_publisher.py (+4/-4)
lib/lp/archiveuploader/changesfile.py (+2/-2)
lib/lp/archiveuploader/dscfile.py (+4/-4)
lib/lp/archiveuploader/nascentupload.py (+1/-1)
lib/lp/archiveuploader/nascentuploadfile.py (+4/-4)
lib/lp/archiveuploader/tests/__init__.py (+1/-1)
lib/lp/archiveuploader/tests/test_changesfile.py (+2/-2)
lib/lp/archiveuploader/utils.py (+1/-1)
lib/lp/blueprints/browser/person_upcomingwork.py (+2/-2)
lib/lp/blueprints/browser/specification.py (+2/-2)
lib/lp/blueprints/browser/sprint.py (+7/-7)
lib/lp/blueprints/browser/tests/test_specification.py (+3/-3)
lib/lp/blueprints/browser/tests/test_specificationsubscription.py (+3/-3)
lib/lp/blueprints/model/specificationsearch.py (+10/-10)
lib/lp/blueprints/model/sprint.py (+1/-1)
lib/lp/blueprints/tests/test_specification.py (+13/-13)
lib/lp/bugs/browser/bug.py (+3/-3)
lib/lp/bugs/browser/bugalsoaffects.py (+2/-2)
lib/lp/bugs/browser/buglisting.py (+3/-3)
lib/lp/bugs/browser/bugtarget.py (+2/-2)
lib/lp/bugs/browser/bugtask.py (+10/-10)
lib/lp/bugs/browser/bugtracker.py (+2/-2)
lib/lp/bugs/browser/structuralsubscription.py (+6/-6)
lib/lp/bugs/browser/tests/test_bugcomment.py (+1/-1)
lib/lp/bugs/browser/tests/test_bugsubscriptionfilter.py (+3/-3)
lib/lp/bugs/browser/tests/test_bugtask.py (+1/-1)
lib/lp/bugs/externalbugtracker/bugzilla.py (+4/-4)
lib/lp/bugs/interfaces/bugtasksearch.py (+3/-3)
lib/lp/bugs/interfaces/tests/test_bugtask.py (+15/-15)
lib/lp/bugs/mail/bugnotificationbuilder.py (+1/-1)
lib/lp/bugs/mail/handler.py (+2/-2)
lib/lp/bugs/model/bug.py (+7/-7)
lib/lp/bugs/model/bugsubscriptionfilter.py (+3/-3)
lib/lp/bugs/model/bugtarget.py (+1/-1)
lib/lp/bugs/model/bugtask.py (+17/-17)
lib/lp/bugs/model/bugtasksearch.py (+6/-6)
lib/lp/bugs/model/bugtracker.py (+3/-3)
lib/lp/bugs/model/cve.py (+3/-3)
lib/lp/bugs/model/personsubscriptioninfo.py (+2/-2)
lib/lp/bugs/model/structuralsubscription.py (+1/-1)
lib/lp/bugs/model/tests/test_bug.py (+11/-11)
lib/lp/bugs/model/tests/test_bugsubscriptioninfo.py (+3/-3)
lib/lp/bugs/model/tests/test_bugtask.py (+4/-4)
lib/lp/bugs/model/tests/test_bugtasksearch.py (+1/-1)
lib/lp/bugs/scripts/bugsummaryrebuild.py (+8/-8)
lib/lp/bugs/scripts/checkwatches/core.py (+5/-5)
lib/lp/bugs/scripts/tests/test_bugnotification.py (+3/-3)
lib/lp/bugs/tests/externalbugtracker.py (+9/-9)
lib/lp/bugs/tests/test_bug_messages_webservice.py (+6/-6)
lib/lp/bugs/tests/test_bugchanges.py (+9/-9)
lib/lp/bugs/tests/test_bugnotification.py (+6/-6)
lib/lp/bugs/tests/test_bugwatch.py (+1/-1)
lib/lp/bugs/tests/test_structuralsubscription.py (+14/-14)
lib/lp/bugs/tests/test_structuralsubscriptiontarget.py (+2/-2)
lib/lp/bugs/vocabularies.py (+4/-4)
lib/lp/buildmaster/manager.py (+7/-7)
lib/lp/buildmaster/model/buildqueue.py (+6/-6)
lib/lp/buildmaster/tests/test_manager.py (+3/-3)
lib/lp/buildmaster/tests/test_webservice.py (+2/-2)
lib/lp/charms/model/charmrecipe.py (+1/-1)
lib/lp/code/browser/branch.py (+1/-1)
lib/lp/code/browser/branchlisting.py (+9/-9)
lib/lp/code/browser/branchmergeproposal.py (+1/-1)
lib/lp/code/browser/tests/test_branchlisting.py (+5/-5)
lib/lp/code/browser/tests/test_branchmergeproposal.py (+3/-3)
lib/lp/code/browser/tests/test_gitrepository.py (+1/-1)
lib/lp/code/browser/tests/test_sourcepackagerecipe.py (+6/-6)
lib/lp/code/browser/tests/test_tales.py (+4/-4)
lib/lp/code/interfaces/tests/test_branch.py (+2/-2)
lib/lp/code/mail/tests/test_branchmergeproposal.py (+3/-3)
lib/lp/code/model/branch.py (+5/-5)
lib/lp/code/model/branchcollection.py (+7/-7)
lib/lp/code/model/branchjob.py (+1/-1)
lib/lp/code/model/branchlookup.py (+1/-1)
lib/lp/code/model/branchmergeproposal.py (+10/-10)
lib/lp/code/model/codereviewcomment.py (+1/-1)
lib/lp/code/model/diff.py (+5/-5)
lib/lp/code/model/gitcollection.py (+3/-3)
lib/lp/code/model/gitref.py (+1/-1)
lib/lp/code/model/gitrepository.py (+4/-4)
lib/lp/code/model/revision.py (+6/-6)
lib/lp/code/model/seriessourcepackagebranch.py (+1/-1)
lib/lp/code/model/sourcepackagerecipebuild.py (+2/-2)
lib/lp/code/model/tests/test_branch.py (+9/-9)
lib/lp/code/model/tests/test_branchjob.py (+3/-3)
lib/lp/code/model/tests/test_branchmergeproposal.py (+17/-17)
lib/lp/code/model/tests/test_codeimportjob.py (+1/-1)
lib/lp/code/model/tests/test_diff.py (+44/-44)
lib/lp/code/model/tests/test_gitrepository.py (+11/-11)
lib/lp/code/model/tests/test_revision.py (+2/-2)
lib/lp/code/model/tests/test_sourcepackagerecipe.py (+2/-2)
lib/lp/code/tests/test_bzr.py (+6/-6)
lib/lp/code/vocabularies/tests/test_branch_vocabularies.py (+3/-3)
lib/lp/code/vocabularies/tests/test_gitrepository_vocabularies.py (+2/-2)
lib/lp/codehosting/inmemory.py (+4/-4)
lib/lp/codehosting/scanner/bzrsync.py (+4/-4)
lib/lp/codehosting/scanner/tests/test_bzrsync.py (+11/-11)
lib/lp/codehosting/scanner/tests/test_mergedetection.py (+4/-4)
lib/lp/codehosting/scripts/tests/test_modifiedbranches.py (+4/-4)
lib/lp/codehosting/tests/test_sftp.py (+1/-1)
lib/lp/oci/browser/tests/test_ocirecipe.py (+1/-1)
lib/lp/registry/browser/distributionsourcepackage.py (+3/-3)
lib/lp/registry/browser/distroseries.py (+6/-6)
lib/lp/registry/browser/milestone.py (+1/-1)
lib/lp/registry/browser/pillar.py (+5/-5)
lib/lp/registry/browser/product.py (+2/-2)
lib/lp/registry/browser/sourcepackage.py (+2/-2)
lib/lp/registry/browser/tests/test_mailinglists.py (+0/-1)
lib/lp/registry/interfaces/pocket.py (+1/-1)
lib/lp/registry/model/accesspolicy.py (+7/-7)
lib/lp/registry/model/distributionsourcepackage.py (+3/-3)
lib/lp/registry/model/distroseriesdifference.py (+3/-3)
lib/lp/registry/model/person.py (+9/-9)
lib/lp/registry/model/product.py (+12/-12)
lib/lp/registry/model/sourcepackage.py (+2/-2)
lib/lp/registry/scripts/teamparticipation.py (+1/-1)
lib/lp/registry/scripts/tests/test_populate_distroseriesdiff.py (+10/-10)
lib/lp/registry/services/tests/test_sharingservice.py (+4/-4)
lib/lp/registry/tests/test_distributionmirror_prober.py (+2/-2)
lib/lp/registry/tests/test_distroseries.py (+1/-1)
lib/lp/registry/tests/test_distroseries_vocabularies.py (+7/-7)
lib/lp/registry/tests/test_distroseriesdifference.py (+16/-16)
lib/lp/registry/tests/test_initderiveddistroseries.py (+2/-2)
lib/lp/registry/tests/test_mailinglistapi.py (+2/-2)
lib/lp/registry/tests/test_milestone.py (+17/-17)
lib/lp/registry/tests/test_mlists.py (+4/-4)
lib/lp/registry/tests/test_ociproject.py (+2/-2)
lib/lp/registry/tests/test_oopsreferences.py (+14/-14)
lib/lp/registry/tests/test_person.py (+5/-5)
lib/lp/registry/tests/test_person_vocabularies.py (+4/-4)
lib/lp/registry/tests/test_prf_finder.py (+1/-1)
lib/lp/registry/tests/test_product.py (+26/-26)
lib/lp/registry/tests/test_productseries.py (+13/-13)
lib/lp/registry/tests/test_teammembership.py (+1/-1)
lib/lp/registry/vocabularies.py (+8/-8)
lib/lp/registry/xmlrpc/canonicalsso.py (+3/-3)
lib/lp/scripts/garbo.py (+1/-1)
lib/lp/scripts/tests/test_garbo.py (+6/-6)
lib/lp/scripts/utilities/importpedant.py (+15/-15)
lib/lp/scripts/utilities/warninghandler.py (+2/-2)
lib/lp/security.py (+4/-4)
lib/lp/services/config/tests/test_config.py (+1/-1)
lib/lp/services/database/bulk.py (+1/-1)
lib/lp/services/database/postgresql.py (+4/-4)
lib/lp/services/database/sqlbase.py (+1/-1)
lib/lp/services/database/tests/test_bulk.py (+5/-5)
lib/lp/services/database/tests/test_connectionstring.py (+1/-1)
lib/lp/services/features/flags.py (+2/-2)
lib/lp/services/features/scopes.py (+1/-1)
lib/lp/services/gpg/tests/test_gpghandler.py (+3/-3)
lib/lp/services/job/celeryjob.py (+2/-2)
lib/lp/services/librarianserver/librariangc.py (+2/-2)
lib/lp/services/librarianserver/swift.py (+18/-18)
lib/lp/services/librarianserver/tests/test_gc.py (+1/-1)
lib/lp/services/librarianserver/tests/test_swift.py (+5/-5)
lib/lp/services/log/logger.py (+3/-3)
lib/lp/services/mail/commands.py (+3/-3)
lib/lp/services/mail/helpers.py (+2/-2)
lib/lp/services/mail/tests/test_helpers.py (+3/-3)
lib/lp/services/messages/tests/test_message.py (+1/-1)
lib/lp/services/messaging/tests/test_rabbit.py (+2/-2)
lib/lp/services/oauth/browser/__init__.py (+2/-2)
lib/lp/services/profile/mem.py (+2/-2)
lib/lp/services/profile/profile.py (+2/-2)
lib/lp/services/profile/tests.py (+15/-15)
lib/lp/services/twistedsupport/features.py (+2/-2)
lib/lp/services/utils.py (+3/-3)
lib/lp/services/webapp/batching.py (+2/-2)
lib/lp/services/webapp/errorlog.py (+4/-4)
lib/lp/services/webapp/escaping.py (+2/-2)
lib/lp/services/webapp/menu.py (+3/-3)
lib/lp/services/webapp/tests/test_error.py (+1/-1)
lib/lp/services/webapp/tests/test_errorlog.py (+2/-2)
lib/lp/services/webhooks/model.py (+1/-1)
lib/lp/services/webhooks/tests/test_model.py (+4/-4)
lib/lp/services/worlddata/model/language.py (+2/-2)
lib/lp/snappy/tests/test_snapstoreclient.py (+1/-1)
lib/lp/snappy/vocabularies.py (+1/-1)
lib/lp/soyuz/adapters/archivedependencies.py (+2/-2)
lib/lp/soyuz/adapters/buildarch.py (+1/-1)
lib/lp/soyuz/adapters/copypolicy.py (+1/-1)
lib/lp/soyuz/adapters/overrides.py (+24/-24)
lib/lp/soyuz/adapters/tests/test_overrides.py (+13/-13)
lib/lp/soyuz/browser/distributionsourcepackagerelease.py (+1/-1)
lib/lp/soyuz/browser/queue.py (+5/-5)
lib/lp/soyuz/model/archive.py (+4/-4)
lib/lp/soyuz/model/archivefile.py (+2/-2)
lib/lp/soyuz/model/binarypackagebuild.py (+4/-4)
lib/lp/soyuz/model/distroseriesdifferencejob.py (+5/-5)
lib/lp/soyuz/model/publishing.py (+13/-13)
lib/lp/soyuz/model/queue.py (+4/-4)
lib/lp/soyuz/model/sourcepackagerelease.py (+2/-2)
lib/lp/soyuz/scripts/custom_uploads_copier.py (+1/-1)
lib/lp/soyuz/scripts/gina/handlers.py (+3/-3)
lib/lp/soyuz/scripts/gina/packages.py (+2/-2)
lib/lp/soyuz/scripts/initialize_distroseries.py (+2/-2)
lib/lp/soyuz/scripts/packagecopier.py (+7/-7)
lib/lp/soyuz/scripts/retrydepwait.py (+1/-1)
lib/lp/soyuz/scripts/tests/test_custom_uploads_copier.py (+2/-2)
lib/lp/soyuz/scripts/tests/test_initialize_distroseries.py (+6/-6)
lib/lp/soyuz/scripts/tests/test_populatearchive.py (+7/-7)
lib/lp/soyuz/scripts/tests/test_ppa_apache_log_parser.py (+2/-2)
lib/lp/soyuz/tests/test_archive.py (+5/-5)
lib/lp/soyuz/tests/test_distroseriesdifferencejob.py (+8/-8)
lib/lp/soyuz/tests/test_packagecloner.py (+2/-2)
lib/lp/soyuz/tests/test_packagecopyjob.py (+2/-2)
lib/lp/soyuz/tests/test_packageupload.py (+6/-6)
lib/lp/soyuz/tests/test_publishing.py (+4/-4)
lib/lp/testing/__init__.py (+2/-2)
lib/lp/testing/mail_helpers.py (+3/-3)
lib/lp/testing/pages.py (+2/-2)
lib/lp/testing/swift/fakeswift.py (+4/-4)
lib/lp/testing/swift/tests/test_fixture.py (+3/-3)
lib/lp/testing/tests/test_factory.py (+2/-2)
lib/lp/testing/tests/test_pages.py (+1/-1)
lib/lp/testing/tests/test_testcase.py (+1/-1)
lib/lp/translations/browser/distroseries.py (+1/-1)
lib/lp/translations/browser/person.py (+4/-4)
lib/lp/translations/browser/productseries.py (+1/-1)
lib/lp/translations/browser/tests/test_persontranslationview.py (+3/-3)
lib/lp/translations/browser/tests/test_potemplate_views.py (+2/-2)
lib/lp/translations/browser/tests/test_translationmessage_view.py (+2/-2)
lib/lp/translations/browser/translationlinksaggregator.py (+11/-11)
lib/lp/translations/browser/translationmessage.py (+4/-4)
lib/lp/translations/model/pofile.py (+2/-2)
lib/lp/translations/model/pofiletranslator.py (+1/-1)
lib/lp/translations/model/potemplate.py (+3/-3)
lib/lp/translations/model/potmsgset.py (+11/-11)
lib/lp/translations/model/side.py (+3/-3)
lib/lp/translations/model/translationimportqueue.py (+2/-2)
lib/lp/translations/model/translationmessage.py (+3/-3)
lib/lp/translations/scripts/scrub_pofiletranslator.py (+2/-2)
lib/lp/translations/scripts/tests/test_reupload_translations.py (+1/-1)
lib/lp/translations/scripts/tests/test_scrub_pofiletranslator.py (+3/-3)
lib/lp/translations/scripts/tests/test_translations_import.py (+2/-2)
lib/lp/translations/tests/test_hastranslationtemplates.py (+4/-4)
lib/lp/translations/tests/test_potemplate.py (+9/-10)
lib/lp/translations/tests/test_potmsgset.py (+3/-3)
lib/lp/translations/tests/test_translationmerger.py (+2/-2)
lib/lp/translations/tests/test_translationpermission.py (+3/-3)
lib/lp/translations/tests/test_translationtemplatesbuildbehaviour.py (+1/-1)
lib/lp/translations/utilities/translation_import.py (+2/-2)
lib/lp/translations/utilities/translationmerger.py (+5/-5)
scripts/librarian-report.py (+2/-2)
scripts/memcached-stats.py (+1/-1)
test_on_merge.py (+1/-1)
utilities/community-contributions.py (+2/-2)
utilities/massage-bug-import-xml (+8/-8)
utilities/roundup-sniffer.py (+1/-1)
Reviewer Review Type Date Requested Status
Jürgen Gmach Approve
Review via email: mp+412005@code.launchpad.net

Commit message

Apply pyupgrade

Description of the change

I've started out with some conservative options that make minimal changes, so at the moment most of the changes are for things like using more modern set literal and dictionary comprehension syntax. We can apply further options to upgrade to Python 3 syntax as a separate step.

`contrib` is excluded (as with `flake8`) because it consists of code mainly copied from elsewhere.

Except for the change to `.pre-commit-config.yaml`, all the changes here were automatic. I've done a full test run with no errors.

To post a comment you must log in.
Revision history for this message
Jürgen Gmach (jugmac00) wrote :

LGTM

The changes mostly consist of using literal set notation, dict comprehensions, removing redundant parenthesis, converting list to set comprehensions, when they were consumed immediately afterwards, and some long strings, which were initially encoded and are now written as byte literals, and some updates to the str format syntax, ie {0} -> {}.

The commit id could be included in a git-blame-ignore-revs file.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs
0new file mode 1006440new file mode 100644
index 0000000..2cb1da8
--- /dev/null
+++ b/.git-blame-ignore-revs
@@ -0,0 +1,2 @@
1# apply pyupgrade
267e3b53a4375288983a72a7beb9a5a67ba739527
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 7c8290a..4042766 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -28,6 +28,12 @@ repos:
28 hooks:28 hooks:
29 - id: flake829 - id: flake8
30 exclude: ^lib/contrib/30 exclude: ^lib/contrib/
31- repo: https://github.com/asottile/pyupgrade
32 rev: v2.29.1
33 hooks:
34 - id: pyupgrade
35 args: [--keep-percent-format]
36 exclude: ^lib/contrib/
31- repo: https://github.com/PyCQA/isort37- repo: https://github.com/PyCQA/isort
32 rev: 5.9.238 rev: 5.9.2
33 hooks:39 hooks:
diff --git a/database/replication/helpers.py b/database/replication/helpers.py
index 726f1e6..b7e6bd4 100644
--- a/database/replication/helpers.py
+++ b/database/replication/helpers.py
@@ -78,7 +78,7 @@ LPMAIN_SEED = frozenset([
78# Explicitly list tables that should not be replicated. This includes the78# Explicitly list tables that should not be replicated. This includes the
79# session tables, as these might exist in developer databases but will not79# session tables, as these might exist in developer databases but will not
80# exist in the production launchpad database.80# exist in the production launchpad database.
81IGNORED_TABLES = set([81IGNORED_TABLES = {
82 # Session tables that in some situations will exist in the main lp82 # Session tables that in some situations will exist in the main lp
83 # database.83 # database.
84 'public.secret', 'public.sessiondata', 'public.sessionpkgdata',84 'public.secret', 'public.sessiondata', 'public.sessionpkgdata',
@@ -118,10 +118,10 @@ IGNORED_TABLES = set([
118 'public.oauth_consumer_id_seq',118 'public.oauth_consumer_id_seq',
119 'public.api_user_id_seq',119 'public.api_user_id_seq',
120 'public.oauth_nonce_id_seq',120 'public.oauth_nonce_id_seq',
121 ])121 }
122122
123# Calculate IGNORED_SEQUENCES123# Calculate IGNORED_SEQUENCES
124IGNORED_SEQUENCES = set('%s_id_seq' % table for table in IGNORED_TABLES)124IGNORED_SEQUENCES = {'%s_id_seq' % table for table in IGNORED_TABLES}
125125
126126
127def slony_installed(con):127def slony_installed(con):
@@ -487,7 +487,7 @@ def calculate_replication_set(cur, seeds):
487487
488 # We can't easily convert the sequence name to (namespace, name) tuples,488 # We can't easily convert the sequence name to (namespace, name) tuples,
489 # so we might as well convert the tables to dot notation for consistancy.489 # so we might as well convert the tables to dot notation for consistancy.
490 tables = set(fqn(namespace, tablename) for namespace, tablename in tables)490 tables = {fqn(namespace, tablename) for namespace, tablename in tables}
491491
492 return tables, sequences492 return tables, sequences
493493
@@ -503,24 +503,24 @@ def discover_unreplicated(cur):
503503
504 # Ignore any tables and sequences starting with temp_. These are504 # Ignore any tables and sequences starting with temp_. These are
505 # transient and not to be replicated per Bug #778338.505 # transient and not to be replicated per Bug #778338.
506 all_tables = set(506 all_tables = {
507 table for table in all_tables507 table for table in all_tables
508 if not table.startswith('public.temp_'))508 if not table.startswith('public.temp_')}
509 all_sequences = set(509 all_sequences = {
510 sequence for sequence in all_sequences510 sequence for sequence in all_sequences
511 if not sequence.startswith('public.temp_'))511 if not sequence.startswith('public.temp_')}
512512
513 cur.execute("""513 cur.execute("""
514 SELECT tab_nspname, tab_relname FROM %s514 SELECT tab_nspname, tab_relname FROM %s
515 WHERE tab_nspname = 'public'515 WHERE tab_nspname = 'public'
516 """ % fqn(CLUSTER_NAMESPACE, "sl_table"))516 """ % fqn(CLUSTER_NAMESPACE, "sl_table"))
517 replicated_tables = set(fqn(*row) for row in cur.fetchall())517 replicated_tables = {fqn(*row) for row in cur.fetchall()}
518518
519 cur.execute("""519 cur.execute("""
520 SELECT seq_nspname, seq_relname FROM %s520 SELECT seq_nspname, seq_relname FROM %s
521 WHERE seq_nspname = 'public'521 WHERE seq_nspname = 'public'
522 """ % fqn(CLUSTER_NAMESPACE, "sl_sequence"))522 """ % fqn(CLUSTER_NAMESPACE, "sl_sequence"))
523 replicated_sequences = set(fqn(*row) for row in cur.fetchall())523 replicated_sequences = {fqn(*row) for row in cur.fetchall()}
524524
525 return (525 return (
526 all_tables - replicated_tables - IGNORED_TABLES,526 all_tables - replicated_tables - IGNORED_TABLES,
diff --git a/database/replication/walblock.py b/database/replication/walblock.py
index bcf48c4..49f1b61 100755
--- a/database/replication/walblock.py
+++ b/database/replication/walblock.py
@@ -39,7 +39,7 @@ def main():
39 if options.verbose and not notified:39 if options.verbose and not notified:
40 notified = True40 notified = True
41 print(41 print(
42 'Blocking on {0} unshipped WAL'.format(42 'Blocking on {} unshipped WAL'.format(
43 len(glob(ready_wal_glob))),43 len(glob(ready_wal_glob))),
44 end='', file=sys.stderr)44 end='', file=sys.stderr)
45 time.sleep(5)45 time.sleep(5)
diff --git a/database/schema/preflight.py b/database/schema/preflight.py
index 9a8d8e5..24c5dfb 100755
--- a/database/schema/preflight.py
+++ b/database/schema/preflight.py
@@ -38,32 +38,32 @@ import upgrade
3838
3939
40# Ignore connections by these users.40# Ignore connections by these users.
41SYSTEM_USERS = set(['postgres', 'slony', 'nagios', 'lagmon'])41SYSTEM_USERS = {'postgres', 'slony', 'nagios', 'lagmon'}
4242
43# Fail checks if these users are connected. If a process should not be43# Fail checks if these users are connected. If a process should not be
44# interrupted by a rollout, the database user it connects as should be44# interrupted by a rollout, the database user it connects as should be
45# added here. The preflight check will fail if any of these users are45# added here. The preflight check will fail if any of these users are
46# connected, so these systems will need to be shut down manually before46# connected, so these systems will need to be shut down manually before
47# a database update.47# a database update.
48FRAGILE_USERS = set([48FRAGILE_USERS = {
49 # process_accepted is fragile, but also fast so we likely shouldn't49 # process_accepted is fragile, but also fast so we likely shouldn't
50 # need to ever manually shut it down.50 # need to ever manually shut it down.
51 'process_accepted',51 'process_accepted',
52 'process_upload',52 'process_upload',
53 'publish_distro',53 'publish_distro',
54 'publish_ftpmaster',54 'publish_ftpmaster',
55 ])55 }
5656
57# If these users have long running transactions, just kill 'em. Entries57# If these users have long running transactions, just kill 'em. Entries
58# added here must come with a bug number, a if part of Launchpad holds58# added here must come with a bug number, a if part of Launchpad holds
59# open a long running transaction it is a bug we need to fix.59# open a long running transaction it is a bug we need to fix.
60BAD_USERS = set([60BAD_USERS = {
61 'karma', # Bug #86310961 'karma', # Bug #863109
62 'rosettaadmin', # Bug #86312262 'rosettaadmin', # Bug #863122
63 'update-pkg-cache', # Bug #91214463 'update-pkg-cache', # Bug #912144
64 'process_death_row', # Bug #91214664 'process_death_row', # Bug #912146
65 'langpack', # Bug #91214765 'langpack', # Bug #912147
66 ])66 }
6767
68# How lagged the cluster can be before failing the preflight check.68# How lagged the cluster can be before failing the preflight check.
69# If this is set too low, perfectly normal state will abort rollouts. If69# If this is set too low, perfectly normal state will abort rollouts. If
@@ -82,7 +82,7 @@ class DatabasePreflight:
8282
83 node = Node(None, None, None, True)83 node = Node(None, None, None, True)
84 node.con = master_con84 node.con = master_con
85 self.nodes = set([node])85 self.nodes = {node}
86 self.lpmain_nodes = self.nodes86 self.lpmain_nodes = self.nodes
87 self.lpmain_master_node = node87 self.lpmain_master_node = node
8888
@@ -343,7 +343,7 @@ class KillConnectionsPreflight(DatabasePreflight):
343 num_tries = 100343 num_tries = 100
344 seconds_to_pause = 0.1344 seconds_to_pause = 0.1
345 if self.replication_paused:345 if self.replication_paused:
346 nodes = set([self.lpmain_master_node])346 nodes = {self.lpmain_master_node}
347 else:347 else:
348 nodes = self.lpmain_nodes348 nodes = self.lpmain_nodes
349349
diff --git a/database/schema/security.py b/database/schema/security.py
index 573486a..653a126 100755
--- a/database/schema/security.py
+++ b/database/schema/security.py
@@ -26,14 +26,14 @@ from lp.services.scripts import (
26# The 'read' group does not get given select permission on the following26# The 'read' group does not get given select permission on the following
27# tables. This is to stop the ro user being given access to security27# tables. This is to stop the ro user being given access to security
28# sensitive information that interactive sessions don't need.28# sensitive information that interactive sessions don't need.
29SECURE_TABLES = set((29SECURE_TABLES = {
30 'public.oauthnonce',30 'public.oauthnonce',
31 'public.oauthnonce_id_seq',31 'public.oauthnonce_id_seq',
32 'public.openidnonce',32 'public.openidnonce',
33 'public.openidnonce_id_seq',33 'public.openidnonce_id_seq',
34 'public.openidconsumernonce',34 'public.openidconsumernonce',
35 'public.openidconsumernonce_id_seq',35 'public.openidconsumernonce_id_seq',
36 ))36 }
3737
38POSTGRES_ACL_MAP = {38POSTGRES_ACL_MAP = {
39 'r': 'SELECT',39 'r': 'SELECT',
@@ -218,9 +218,9 @@ class DbSchema(dict):
218 options = (218 options = (
219 'SUPERUSER', 'INHERIT', 'CREATEROLE', 'CREATEDB', 'LOGIN',219 'SUPERUSER', 'INHERIT', 'CREATEROLE', 'CREATEDB', 'LOGIN',
220 'REPLICATION')220 'REPLICATION')
221 self.roles = dict(221 self.roles = {
222 (r[0], set(opt for (opt, val) in zip(options, r[1:]) if val))222 r[0]: {opt for (opt, val) in zip(options, r[1:]) if val}
223 for r in cur.fetchall())223 for r in cur.fetchall()}
224224
225225
226class CursorWrapper(object):226class CursorWrapper(object):
@@ -326,9 +326,9 @@ class PermissionGatherer:
326326
327 def countPrincipals(self):327 def countPrincipals(self):
328 """Count the number of different principals."""328 """Count the number of different principals."""
329 return len(set(sum([329 return len(set(sum((
330 list(principals)330 list(principals)
331 for principals in six.itervalues(self.permissions)], [])))331 for principals in six.itervalues(self.permissions)), [])))
332332
333 def grant(self, cur):333 def grant(self, cur):
334 """Grant all gathered permissions.334 """Grant all gathered permissions.
@@ -422,7 +422,7 @@ def reset_permissions(con, config, options):
422 type_ = config.get(section_name, 'type')422 type_ = config.get(section_name, 'type')
423 assert type_ in ['user', 'group'], 'Unknown type %s' % type_423 assert type_ in ['user', 'group'], 'Unknown type %s' % type_
424424
425 desired_opts = set(('INHERIT',))425 desired_opts = {'INHERIT'}
426 if type_ == 'user':426 if type_ == 'user':
427 desired_opts.add('LOGIN')427 desired_opts.add('LOGIN')
428428
@@ -476,7 +476,7 @@ def reset_permissions(con, config, options):
476 else:476 else:
477 log.debug2("%s not in any roles", user)477 log.debug2("%s not in any roles", user)
478478
479 managed_roles = set(['read', 'admin'])479 managed_roles = {'read', 'admin'}
480 for section_name in config.sections():480 for section_name in config.sections():
481 managed_roles.add(section_name)481 managed_roles.add(section_name)
482 if section_name != 'public':482 if section_name != 'public':
diff --git a/lib/devscripts/sourcecode.py b/lib/devscripts/sourcecode.py
index 2fa821e..2dd528a 100644
--- a/lib/devscripts/sourcecode.py
+++ b/lib/devscripts/sourcecode.py
@@ -128,7 +128,7 @@ def interpret_config(config_entries, public_only, use_http=False):
128128
129def _subset_dict(d, keys):129def _subset_dict(d, keys):
130 """Return a dict that's a subset of 'd', based on the keys in 'keys'."""130 """Return a dict that's a subset of 'd', based on the keys in 'keys'."""
131 return dict((key, d[key]) for key in keys)131 return {key: d[key] for key in keys}
132132
133133
134def plan_update(existing_branches, configuration):134def plan_update(existing_branches, configuration):
diff --git a/lib/devscripts/tests/test_sourcecode.py b/lib/devscripts/tests/test_sourcecode.py
index e3abbf2..5d5f429 100644
--- a/lib/devscripts/tests/test_sourcecode.py
+++ b/lib/devscripts/tests/test_sourcecode.py
@@ -171,7 +171,7 @@ class TestPlanUpdate(unittest.TestCase):
171 new, existing, removed = plan_update(['a', 'b', 'c'], {})171 new, existing, removed = plan_update(['a', 'b', 'c'], {})
172 self.assertEqual({}, new)172 self.assertEqual({}, new)
173 self.assertEqual({}, existing)173 self.assertEqual({}, existing)
174 self.assertEqual(set(['a', 'b', 'c']), removed)174 self.assertEqual({'a', 'b', 'c'}, removed)
175175
176 def test_all_same(self):176 def test_all_same(self):
177 # If the set of existing branches is the same as the set of177 # If the set of existing branches is the same as the set of
diff --git a/lib/lp/answers/model/question.py b/lib/lp/answers/model/question.py
index 0441a70..61a534c 100644
--- a/lib/lp/answers/model/question.py
+++ b/lib/lp/answers/model/question.py
@@ -850,7 +850,7 @@ class QuestionSet:
850 def getOpenQuestionCountByPackages(self, packages):850 def getOpenQuestionCountByPackages(self, packages):
851 """See `IQuestionSet`."""851 """See `IQuestionSet`."""
852 distributions = list(852 distributions = list(
853 set(package.distribution for package in packages))853 {package.distribution for package in packages})
854 # We can't get counts for all packages in one query, since we'd854 # We can't get counts for all packages in one query, since we'd
855 # need to match on (distribution, sourcepackagename). Issue one855 # need to match on (distribution, sourcepackagename). Issue one
856 # query per distribution instead.856 # query per distribution instead.
@@ -882,7 +882,7 @@ class QuestionSet:
882 sourcepackagename_set = getUtility(ISourcePackageNameSet)882 sourcepackagename_set = getUtility(ISourcePackageNameSet)
883 # Only packages with open questions are included in the query883 # Only packages with open questions are included in the query
884 # result, so initialize each package to 0.884 # result, so initialize each package to 0.
885 counts = dict((package, 0) for package in packages)885 counts = {package: 0 for package in packages}
886 for distro_id, spn_id, open_questions in results:886 for distro_id, spn_id, open_questions in results:
887 # The SourcePackageNames here should already be pre-fetched,887 # The SourcePackageNames here should already be pre-fetched,
888 # so that .get(spn_id) won't issue a DB query.888 # so that .get(spn_id) won't issue a DB query.
@@ -1525,6 +1525,6 @@ class QuestionTargetMixin:
1525 for contact in self.answer_contacts_with_languages:1525 for contact in self.answer_contacts_with_languages:
1526 languages |= set(contact.languages)1526 languages |= set(contact.languages)
1527 languages.add(getUtility(ILaunchpadCelebrities).english)1527 languages.add(getUtility(ILaunchpadCelebrities).english)
1528 languages = set(1528 languages = {
1529 lang for lang in languages if not is_english_variant(lang))1529 lang for lang in languages if not is_english_variant(lang)}
1530 return list(languages)1530 return list(languages)
diff --git a/lib/lp/answers/model/tests/test_question.py b/lib/lp/answers/model/tests/test_question.py
index 0735fe3..979e2ce 100644
--- a/lib/lp/answers/model/tests/test_question.py
+++ b/lib/lp/answers/model/tests/test_question.py
@@ -99,7 +99,7 @@ class TestQuestionInDirectSubscribers(TestCaseWithFactory):
99 english_person.addLanguage(getUtility(ILanguageSet)['en'])99 english_person.addLanguage(getUtility(ILanguageSet)['en'])
100 spanish = getUtility(ILanguageSet)['es']100 spanish = getUtility(ILanguageSet)['es']
101 spanish_person = self.factory.makePerson()101 spanish_person = self.factory.makePerson()
102 with person_logged_in((spanish_person)):102 with person_logged_in(spanish_person):
103 spanish_person.addLanguage(spanish)103 spanish_person.addLanguage(spanish)
104 question = self.factory.makeQuestion(language=spanish)104 question = self.factory.makeQuestion(language=spanish)
105 with person_logged_in(question.owner):105 with person_logged_in(question.owner):
diff --git a/lib/lp/answers/model/tests/test_questionsubscription.py b/lib/lp/answers/model/tests/test_questionsubscription.py
index 513914c..c20257b 100644
--- a/lib/lp/answers/model/tests/test_questionsubscription.py
+++ b/lib/lp/answers/model/tests/test_questionsubscription.py
@@ -126,7 +126,7 @@ class TestQuestionSubscriptionCanBeUnsubscribedbyUser(TestCaseWithFactory):
126 """Question target answer contact can unsubscribe someone."""126 """Question target answer contact can unsubscribe someone."""
127 answer_contact = self.factory.makePerson()127 answer_contact = self.factory.makePerson()
128 english = getUtility(ILanguageSet)['en']128 english = getUtility(ILanguageSet)['en']
129 with person_logged_in((answer_contact)):129 with person_logged_in(answer_contact):
130 answer_contact.addLanguage(english)130 answer_contact.addLanguage(english)
131 distro_owner = self.factory.makePerson()131 distro_owner = self.factory.makePerson()
132 distro = self.factory.makeDistribution(owner=distro_owner)132 distro = self.factory.makeDistribution(owner=distro_owner)
diff --git a/lib/lp/app/browser/launchpad.py b/lib/lp/app/browser/launchpad.py
index c9bb53e..6c5045f 100644
--- a/lib/lp/app/browser/launchpad.py
+++ b/lib/lp/app/browser/launchpad.py
@@ -188,9 +188,9 @@ class NavigationMenuTabs(LaunchpadView):
188188
189 def initialize(self):189 def initialize(self):
190 menuapi = MenuAPI(self.context)190 menuapi = MenuAPI(self.context)
191 self.links = sorted([191 self.links = sorted((
192 link for link in menuapi.navigation.values()192 link for link in menuapi.navigation.values()
193 if (link.enabled or config.launchpad.devmode)],193 if (link.enabled or config.launchpad.devmode)),
194 key=operator.attrgetter('sort_key'))194 key=operator.attrgetter('sort_key'))
195 self.title = None195 self.title = None
196 if len(self.links) > 0:196 if len(self.links) > 0:
@@ -273,9 +273,9 @@ class Hierarchy(LaunchpadView):
273 """The objects for which we want breadcrumbs."""273 """The objects for which we want breadcrumbs."""
274 # Start the chain with the deepest object that has a breadcrumb.274 # Start the chain with the deepest object that has a breadcrumb.
275 try:275 try:
276 objects = [next((276 objects = [next(
277 obj for obj in reversed(self.request.traversed_objects)277 obj for obj in reversed(self.request.traversed_objects)
278 if IBreadcrumb(obj, None)))]278 if IBreadcrumb(obj, None))]
279 except StopIteration:279 except StopIteration:
280 return []280 return []
281 # Now iterate. If an object has a breadcrumb, it can override281 # Now iterate. If an object has a breadcrumb, it can override
diff --git a/lib/lp/app/browser/linkchecker.py b/lib/lp/app/browser/linkchecker.py
index b541907..fbdacc1 100644
--- a/lib/lp/app/browser/linkchecker.py
+++ b/lib/lp/app/browser/linkchecker.py
@@ -89,7 +89,7 @@ class LinkCheckerAPI(LaunchpadView):
89 valid_links = {}89 valid_links = {}
90 user = self.user90 user = self.user
91 # List of all the bugs we are checking.91 # List of all the bugs we are checking.
92 bugs_ids = set([int(link[len('/bugs/'):]) for link in links])92 bugs_ids = {int(link[len('/bugs/'):]) for link in links}
93 if bugs_ids:93 if bugs_ids:
94 params = BugTaskSearchParams(94 params = BugTaskSearchParams(
95 user=user, status=None,95 user=user, status=None,
diff --git a/lib/lp/app/browser/root.py b/lib/lp/app/browser/root.py
index fa6becd..f0e85f7 100644
--- a/lib/lp/app/browser/root.py
+++ b/lib/lp/app/browser/root.py
@@ -262,13 +262,13 @@ class LaunchpadSearchView(LaunchpadFormView):
262 schema = ILaunchpadSearch262 schema = ILaunchpadSearch
263 field_names = ['text']263 field_names = ['text']
264264
265 shipit_keywords = set([265 shipit_keywords = {
266 'ubuntu', 'kubuntu', 'edubuntu',266 'ubuntu', 'kubuntu', 'edubuntu',
267 'ship', 'shipit', 'send', 'get', 'mail', 'free',267 'ship', 'shipit', 'send', 'get', 'mail', 'free',
268 'cd', 'cds', 'dvd', 'dvds', 'disc'])268 'cd', 'cds', 'dvd', 'dvds', 'disc'}
269 shipit_anti_keywords = set([269 shipit_anti_keywords = {
270 'burn', 'burning', 'enable', 'error', 'errors', 'image', 'iso',270 'burn', 'burning', 'enable', 'error', 'errors', 'image', 'iso',
271 'read', 'rip', 'write'])271 'read', 'rip', 'write'}
272272
273 def __init__(self, context, request):273 def __init__(self, context, request):
274 """Initialize the view.274 """Initialize the view.
diff --git a/lib/lp/app/browser/stringformatter.py b/lib/lp/app/browser/stringformatter.py
index bc40322..500ae96 100644
--- a/lib/lp/app/browser/stringformatter.py
+++ b/lib/lp/app/browser/stringformatter.py
@@ -243,7 +243,7 @@ def linkify_bug_numbers(text):
243def extract_email_addresses(text):243def extract_email_addresses(text):
244 '''Unique email addresses in the text.'''244 '''Unique email addresses in the text.'''
245 matches = re.finditer(re_email_address, text)245 matches = re.finditer(re_email_address, text)
246 return list(set([match.group() for match in matches]))246 return list({match.group() for match in matches})
247247
248248
249def parse_diff(text):249def parse_diff(text):
diff --git a/lib/lp/app/browser/tales.py b/lib/lp/app/browser/tales.py
index 51239bb..08d2a71 100644
--- a/lib/lp/app/browser/tales.py
+++ b/lib/lp/app/browser/tales.py
@@ -499,7 +499,7 @@ class NoneFormatter:
499 attributes in content classes.499 attributes in content classes.
500 """500 """
501501
502 allowed_names = set([502 allowed_names = {
503 'approximatedate',503 'approximatedate',
504 'approximatedatetitle',504 'approximatedatetitle',
505 'approximateduration',505 'approximateduration',
@@ -520,7 +520,7 @@ class NoneFormatter:
520 'time',520 'time',
521 'url',521 'url',
522 'link',522 'link',
523 ])523 }
524524
525 def __init__(self, context):525 def __init__(self, context):
526 self.context = context526 self.context = context
@@ -670,7 +670,7 @@ class ObjectFormatterAPI:
670 "for %r." % (self, self._context))670 "for %r." % (self, self._context))
671671
672 def global_css(self):672 def global_css(self):
673 css_classes = set([])673 css_classes = set()
674 view = self._context674 view = self._context
675675
676 # XXX: Bug #1076074676 # XXX: Bug #1076074
@@ -915,13 +915,13 @@ class BugTaskImageDisplayAPI(ObjectImageDisplayAPI):
915 Used for image:icon.915 Used for image:icon.
916 """916 """
917917
918 allowed_names = set([918 allowed_names = {
919 'icon',919 'icon',
920 'logo',920 'logo',
921 'mugshot',921 'mugshot',
922 'badges',922 'badges',
923 'sprite_css',923 'sprite_css',
924 ])924 }
925925
926 icon_template = (926 icon_template = (
927 '<span alt="%s" title="%s" class="%s"></span>')927 '<span alt="%s" title="%s" class="%s"></span>')
@@ -1424,9 +1424,9 @@ class CustomizableFormatter(ObjectFormatterAPI):
1424 This summary is for use in fmt:link, which is meant to be used in1424 This summary is for use in fmt:link, which is meant to be used in
1425 contexts like lists of items.1425 contexts like lists of items.
1426 """1426 """
1427 values = dict(1427 values = {
1428 (k, v if v is not None else '')1428 k: v if v is not None else ''
1429 for k, v in six.iteritems(self._link_summary_values()))1429 for k, v in six.iteritems(self._link_summary_values())}
1430 return structured(self._link_summary_template, **values).escapedtext1430 return structured(self._link_summary_template, **values).escapedtext
14311431
1432 def _title_values(self):1432 def _title_values(self):
@@ -1446,9 +1446,9 @@ class CustomizableFormatter(ObjectFormatterAPI):
1446 title_template = getattr(self, '_title_template', None)1446 title_template = getattr(self, '_title_template', None)
1447 if title_template is None:1447 if title_template is None:
1448 return None1448 return None
1449 values = dict(1449 values = {
1450 (k, v if v is not None else '')1450 k: v if v is not None else ''
1451 for k, v in six.iteritems(self._title_values()))1451 for k, v in six.iteritems(self._title_values())}
1452 return structured(title_template, **values).escapedtext1452 return structured(title_template, **values).escapedtext
14531453
1454 def sprite_css(self):1454 def sprite_css(self):
diff --git a/lib/lp/app/browser/tests/test_launchpad.py b/lib/lp/app/browser/tests/test_launchpad.py
index a25c46c..dc697fd 100644
--- a/lib/lp/app/browser/tests/test_launchpad.py
+++ b/lib/lp/app/browser/tests/test_launchpad.py
@@ -754,8 +754,8 @@ class TestIterViewRegistrations(TestCaseWithFactory):
754 """iter_view_registrations provides only registrations of class."""754 """iter_view_registrations provides only registrations of class."""
755 macros = getMultiAdapter(755 macros = getMultiAdapter(
756 (object(), LaunchpadTestRequest()), name='+base-layout-macros')756 (object(), LaunchpadTestRequest()), name='+base-layout-macros')
757 names = set(757 names = {
758 reg.name for reg in iter_view_registrations(macros.__class__))758 reg.name for reg in iter_view_registrations(macros.__class__)}
759 self.assertIn('+base-layout-macros', names)759 self.assertIn('+base-layout-macros', names)
760 self.assertNotIn('+related-pages', names)760 self.assertNotIn('+related-pages', names)
761761
diff --git a/lib/lp/app/tests/test_tales.py b/lib/lp/app/tests/test_tales.py
index 73a8464..ffd5f91 100644
--- a/lib/lp/app/tests/test_tales.py
+++ b/lib/lp/app/tests/test_tales.py
@@ -326,7 +326,7 @@ class TestNoneFormatterAPI(TestCaseWithFactory):
326 def test_valid_traversal(self):326 def test_valid_traversal(self):
327 # Traversal of allowed names works as expected.327 # Traversal of allowed names works as expected.
328328
329 allowed_names = set([329 allowed_names = {
330 'approximatedate',330 'approximatedate',
331 'approximateduration',331 'approximateduration',
332 'break-long-words',332 'break-long-words',
@@ -345,7 +345,7 @@ class TestNoneFormatterAPI(TestCaseWithFactory):
345 'time',345 'time',
346 'url',346 'url',
347 'link',347 'link',
348 ])348 }
349349
350 for name in allowed_names:350 for name in allowed_names:
351 self.assertEqual('', test_tales('foo/fmt:%s' % name, foo=None))351 self.assertEqual('', test_tales('foo/fmt:%s' % name, foo=None))
diff --git a/lib/lp/app/widgets/suggestion.py b/lib/lp/app/widgets/suggestion.py
index dc2a13e..6ce8e46 100644
--- a/lib/lp/app/widgets/suggestion.py
+++ b/lib/lp/app/widgets/suggestion.py
@@ -376,7 +376,7 @@ class RecipeOwnerWidget(SuggestionWidget):
376 def _getSuggestions(branch):376 def _getSuggestions(branch):
377 """Suggest the branch owner and current user."""377 """Suggest the branch owner and current user."""
378 logged_in_user = getUtility(ILaunchBag).user378 logged_in_user = getUtility(ILaunchBag).user
379 return set([branch.owner, logged_in_user])379 return {branch.owner, logged_in_user}
380380
381 @staticmethod381 @staticmethod
382 def _valueDisplayname(value):382 def _valueDisplayname(value):
diff --git a/lib/lp/archivepublisher/model/ftparchive.py b/lib/lp/archivepublisher/model/ftparchive.py
index 2dcc94d..da2ecf6 100644
--- a/lib/lp/archivepublisher/model/ftparchive.py
+++ b/lib/lp/archivepublisher/model/ftparchive.py
@@ -198,10 +198,10 @@ class FTPArchiveHandler:
198 spawner.complete()198 spawner.complete()
199 stdout_handler.finalize()199 stdout_handler.finalize()
200 stderr_handler.finalize()200 stderr_handler.finalize()
201 failures = sorted([201 failures = sorted(
202 (tag, receiver.returncode)202 (tag, receiver.returncode)
203 for tag, receiver in six.iteritems(returncodes)203 for tag, receiver in six.iteritems(returncodes)
204 if receiver.returncode != 0])204 if receiver.returncode != 0)
205 if len(failures) > 0:205 if len(failures) > 0:
206 by_arch = ["%s (returned %d)" % failure for failure in failures]206 by_arch = ["%s (returned %d)" % failure for failure in failures]
207 raise AptFTPArchiveFailure(207 raise AptFTPArchiveFailure(
diff --git a/lib/lp/archivepublisher/publishing.py b/lib/lp/archivepublisher/publishing.py
index dec1312..a1f4ec0 100644
--- a/lib/lp/archivepublisher/publishing.py
+++ b/lib/lp/archivepublisher/publishing.py
@@ -143,7 +143,7 @@ def remove_suffix(path):
143143
144def get_suffixed_indices(path):144def get_suffixed_indices(path):
145 """Return a set of paths to compressed copies of the given index."""145 """Return a set of paths to compressed copies of the given index."""
146 return set([path + suffix for suffix in ('', '.gz', '.bz2', '.xz')])146 return {path + suffix for suffix in ('', '.gz', '.bz2', '.xz')}
147147
148148
149def _getDiskPool(pubconf, log):149def _getDiskPool(pubconf, log):
diff --git a/lib/lp/archivepublisher/scripts/publish_ftpmaster.py b/lib/lp/archivepublisher/scripts/publish_ftpmaster.py
index e691dfc..03bfe43 100644
--- a/lib/lp/archivepublisher/scripts/publish_ftpmaster.py
+++ b/lib/lp/archivepublisher/scripts/publish_ftpmaster.py
@@ -95,9 +95,9 @@ def map_distro_pubconfigs(distro):
95 candidates = [95 candidates = [
96 (archive.purpose, getPubConfig(archive))96 (archive.purpose, getPubConfig(archive))
97 for archive in get_publishable_archives(distro)]97 for archive in get_publishable_archives(distro)]
98 return dict(98 return {
99 (purpose, config)99 purpose: config
100 for purpose, config in candidates if config is not None)100 for purpose, config in candidates if config is not None}
101101
102102
103def newer_mtime(one_file, other_file):103def newer_mtime(one_file, other_file):
@@ -185,9 +185,9 @@ class PublishFTPMaster(LaunchpadCronScript):
185185
186 So: getConfigs[distro][purpose] gives you a config.186 So: getConfigs[distro][purpose] gives you a config.
187 """187 """
188 return dict(188 return {
189 (distro, map_distro_pubconfigs(distro))189 distro: map_distro_pubconfigs(distro)
190 for distro in self.distributions)190 for distro in self.distributions}
191191
192 def locateIndexesMarker(self, distribution, suite):192 def locateIndexesMarker(self, distribution, suite):
193 """Give path for marker file whose presence marks index creation.193 """Give path for marker file whose presence marks index creation.
@@ -266,9 +266,9 @@ class PublishFTPMaster(LaunchpadCronScript):
266 only_unpublished=True))266 only_unpublished=True))
267 load_related(267 load_related(
268 DistroArchSeries, pending_binaries, ['distroarchseriesID'])268 DistroArchSeries, pending_binaries, ['distroarchseriesID'])
269 return set(269 return {
270 pub.distroseries.name + pocketsuffix[pub.pocket]270 pub.distroseries.name + pocketsuffix[pub.pocket]
271 for pub in pending_sources + pending_binaries)271 for pub in pending_sources + pending_binaries}
272272
273 def getDirtySecuritySuites(self, distribution):273 def getDirtySecuritySuites(self, distribution):
274 """List security suites with pending publications."""274 """List security suites with pending publications."""
@@ -345,7 +345,7 @@ class PublishFTPMaster(LaunchpadCronScript):
345 arguments = (345 arguments = (
346 ['-d', distribution.name] +346 ['-d', distribution.name] +
347 args +347 args +
348 sum([['-s', suite] for suite in suites], []))348 sum((['-s', suite] for suite in suites), []))
349349
350 publish_distro = PublishDistro(350 publish_distro = PublishDistro(
351 test_args=arguments, logger=self.logger, ignore_cron_control=True)351 test_args=arguments, logger=self.logger, ignore_cron_control=True)
diff --git a/lib/lp/archivepublisher/tests/test_dominator.py b/lib/lp/archivepublisher/tests/test_dominator.py
index c079559..2b608fe 100755
--- a/lib/lp/archivepublisher/tests/test_dominator.py
+++ b/lib/lp/archivepublisher/tests/test_dominator.py
@@ -784,10 +784,10 @@ class TestDominatorMethods(TestCaseWithFactory):
784 versions = ["1.%d" % number for number in range(4)]784 versions = ["1.%d" % number for number in range(4)]
785785
786 # We have one package releases for each version.786 # We have one package releases for each version.
787 relevant_releases = dict(787 relevant_releases = {
788 (version, self.factory.makeSourcePackageRelease(788 version: self.factory.makeSourcePackageRelease(
789 sourcepackagename=package, version=version))789 sourcepackagename=package, version=version)
790 for version in jumble(versions))790 for version in jumble(versions)}
791791
792 # Each of those releases is subsequently published in792 # Each of those releases is subsequently published in
793 # different components.793 # different components.
@@ -798,15 +798,15 @@ class TestDominatorMethods(TestCaseWithFactory):
798 # oldest to newest. Each re-publishing into a different798 # oldest to newest. Each re-publishing into a different
799 # component is meant to supersede publication into the previous799 # component is meant to supersede publication into the previous
800 # component.800 # component.
801 pubs_by_version = dict(801 pubs_by_version = {
802 (version, [802 version: [
803 self.factory.makeSourcePackagePublishingHistory(803 self.factory.makeSourcePackagePublishingHistory(
804 archive=series.main_archive, distroseries=series,804 archive=series.main_archive, distroseries=series,
805 pocket=pocket, status=PackagePublishingStatus.PUBLISHED,805 pocket=pocket, status=PackagePublishingStatus.PUBLISHED,
806 sourcepackagerelease=relevant_releases[version],806 sourcepackagerelease=relevant_releases[version],
807 component=component)807 component=component)
808 for component in components])808 for component in components]
809 for version in jumble(versions))809 for version in jumble(versions)}
810810
811 ages = jumble(811 ages = jumble(
812 [datetime.timedelta(age) for age in range(len(versions))])812 [datetime.timedelta(age) for age in range(len(versions))])
@@ -904,11 +904,11 @@ class TestDominatorMethods(TestCaseWithFactory):
904 def test_findPublishedSourcePackageNames_ignores_other_states(self):904 def test_findPublishedSourcePackageNames_ignores_other_states(self):
905 series = self.factory.makeDistroSeries()905 series = self.factory.makeDistroSeries()
906 pocket = PackagePublishingPocket.RELEASE906 pocket = PackagePublishingPocket.RELEASE
907 spphs = dict(907 spphs = {
908 (status, self.factory.makeSourcePackagePublishingHistory(908 status: self.factory.makeSourcePackagePublishingHistory(
909 distroseries=series, archive=series.main_archive,909 distroseries=series, archive=series.main_archive,
910 pocket=pocket, status=status))910 pocket=pocket, status=status)
911 for status in PackagePublishingStatus.items)911 for status in PackagePublishingStatus.items}
912 published_spph = spphs[PackagePublishingStatus.PUBLISHED]912 published_spph = spphs[PackagePublishingStatus.PUBLISHED]
913 dominator = self.makeDominator(list(spphs.values()))913 dominator = self.makeDominator(list(spphs.values()))
914 self.assertContentEqual(914 self.assertContentEqual(
@@ -988,13 +988,13 @@ class TestDominatorMethods(TestCaseWithFactory):
988 series = self.factory.makeDistroSeries()988 series = self.factory.makeDistroSeries()
989 package = self.factory.makeSourcePackageName()989 package = self.factory.makeSourcePackageName()
990 pocket = PackagePublishingPocket.RELEASE990 pocket = PackagePublishingPocket.RELEASE
991 spphs = dict(991 spphs = {
992 (status, self.factory.makeSourcePackagePublishingHistory(992 status: self.factory.makeSourcePackagePublishingHistory(
993 distroseries=series, archive=series.main_archive,993 distroseries=series, archive=series.main_archive,
994 pocket=pocket, status=status,994 pocket=pocket, status=status,
995 sourcepackagerelease=self.factory.makeSourcePackageRelease(995 sourcepackagerelease=self.factory.makeSourcePackageRelease(
996 sourcepackagename=package)))996 sourcepackagename=package))
997 for status in PackagePublishingStatus.items)997 for status in PackagePublishingStatus.items}
998 dominator = self.makeDominator(list(spphs.values()))998 dominator = self.makeDominator(list(spphs.values()))
999 self.assertContentEqual(999 self.assertContentEqual(
1000 [spphs[PackagePublishingStatus.PUBLISHED]],1000 [spphs[PackagePublishingStatus.PUBLISHED]],
@@ -1336,7 +1336,7 @@ class TestArchSpecificPublicationsCache(TestCaseWithFactory):
1336 cache = self.makeCache()1336 cache = self.makeCache()
1337 self.assertContentEqual(1337 self.assertContentEqual(
1338 [cache.getKey(bpph) for bpph in bpphs],1338 [cache.getKey(bpph) for bpph in bpphs],
1339 set(cache.getKey(bpph) for bpph in bpphs * 2))1339 {cache.getKey(bpph) for bpph in bpphs * 2})
13401340
1341 def test_hasArchSpecificPublications_is_consistent_and_correct(self):1341 def test_hasArchSpecificPublications_is_consistent_and_correct(self):
1342 # hasArchSpecificPublications consistently, repeatably returns1342 # hasArchSpecificPublications consistently, repeatably returns
diff --git a/lib/lp/archivepublisher/tests/test_publish_ftpmaster.py b/lib/lp/archivepublisher/tests/test_publish_ftpmaster.py
index 8e01387..1847248 100644
--- a/lib/lp/archivepublisher/tests/test_publish_ftpmaster.py
+++ b/lib/lp/archivepublisher/tests/test_publish_ftpmaster.py
@@ -552,7 +552,7 @@ class TestPublishFTPMasterScript(
552 script.runFinalizeParts(distro)552 script.runFinalizeParts(distro)
553 _, kwargs = run_parts_fixture.new_value.calls[0]553 _, kwargs = run_parts_fixture.new_value.calls[0]
554 env = kwargs["env"]554 env = kwargs["env"]
555 required_parameters = set(["ARCHIVEROOTS", "SECURITY_UPLOAD_ONLY"])555 required_parameters = {"ARCHIVEROOTS", "SECURITY_UPLOAD_ONLY"}
556 missing_parameters = required_parameters.difference(set(env.keys()))556 missing_parameters = required_parameters.difference(set(env.keys()))
557 self.assertEqual(set(), missing_parameters)557 self.assertEqual(set(), missing_parameters)
558558
diff --git a/lib/lp/archivepublisher/tests/test_publisher.py b/lib/lp/archivepublisher/tests/test_publisher.py
index 977b626..176044a 100644
--- a/lib/lp/archivepublisher/tests/test_publisher.py
+++ b/lib/lp/archivepublisher/tests/test_publisher.py
@@ -2217,9 +2217,9 @@ class TestPublisher(TestPublisherBase):
22172217
2218 release = self.parseRelease(suite_path('Release'))2218 release = self.parseRelease(suite_path('Release'))
2219 paths = ['Release'] + [entry['name'] for entry in release['md5sum']]2219 paths = ['Release'] + [entry['name'] for entry in release['md5sum']]
2220 timestamps = set(2220 timestamps = {
2221 os.stat(suite_path(path)).st_mtime for path in paths2221 os.stat(suite_path(path)).st_mtime for path in paths
2222 if '/dep11/' not in path and os.path.exists(suite_path(path)))2222 if '/dep11/' not in path and os.path.exists(suite_path(path))}
2223 self.assertEqual(1, len(timestamps))2223 self.assertEqual(1, len(timestamps))
22242224
2225 # Non-core files preserve their original timestamps.2225 # Non-core files preserve their original timestamps.
@@ -3380,8 +3380,8 @@ class TestPublisherLite(TestCaseWithFactory):
3380 paths = [path for path, _ in path_times]3380 paths = [path for path, _ in path_times]
3381 self.makePublisher(series)._syncTimestamps(series.name, set(paths))3381 self.makePublisher(series)._syncTimestamps(series.name, set(paths))
33823382
3383 timestamps = set(3383 timestamps = {
3384 os.stat(os.path.join(location, path)).st_mtime for path in paths)3384 os.stat(os.path.join(location, path)).st_mtime for path in paths}
3385 self.assertEqual(1, len(timestamps))3385 self.assertEqual(1, len(timestamps))
3386 # The filesystem may round off subsecond parts of timestamps.3386 # The filesystem may round off subsecond parts of timestamps.
3387 self.assertEqual(int(now), int(list(timestamps)[0]))3387 self.assertEqual(int(now), int(list(timestamps)[0]))
diff --git a/lib/lp/archiveuploader/changesfile.py b/lib/lp/archiveuploader/changesfile.py
index 1a28b35..1a97999 100644
--- a/lib/lp/archiveuploader/changesfile.py
+++ b/lib/lp/archiveuploader/changesfile.py
@@ -58,13 +58,13 @@ class CannotDetermineFileTypeError(Exception):
58class ChangesFile(SignableTagFile):58class ChangesFile(SignableTagFile):
59 """Changesfile model."""59 """Changesfile model."""
6060
61 mandatory_fields = set([61 mandatory_fields = {
62 "Source", "Architecture", "Version", "Distribution",62 "Source", "Architecture", "Version", "Distribution",
63 "Maintainer", "Files", "Changes", "Date",63 "Maintainer", "Files", "Changes", "Date",
64 # Changed-By is not technically mandatory according to64 # Changed-By is not technically mandatory according to
65 # Debian policy but Soyuz relies on it being set in65 # Debian policy but Soyuz relies on it being set in
66 # various places.66 # various places.
67 "Changed-By"])67 "Changed-By"}
6868
69 # Map urgencies to their dbschema values.69 # Map urgencies to their dbschema values.
70 # Debian policy only permits low, medium, high, emergency.70 # Debian policy only permits low, medium, high, emergency.
diff --git a/lib/lp/archiveuploader/dscfile.py b/lib/lp/archiveuploader/dscfile.py
index 0ca6d03..50e6d70 100644
--- a/lib/lp/archiveuploader/dscfile.py
+++ b/lib/lp/archiveuploader/dscfile.py
@@ -250,15 +250,15 @@ class SignableTagFile:
250class DSCFile(SourceUploadFile, SignableTagFile):250class DSCFile(SourceUploadFile, SignableTagFile):
251 """Models a given DSC file and its content."""251 """Models a given DSC file and its content."""
252252
253 mandatory_fields = set([253 mandatory_fields = {
254 "Source",254 "Source",
255 "Version",255 "Version",
256 "Binary",256 "Binary",
257 "Maintainer",257 "Maintainer",
258 "Architecture",258 "Architecture",
259 "Files"])259 "Files"}
260260
261 known_fields = mandatory_fields.union(set([261 known_fields = mandatory_fields.union({
262 "Build-Depends",262 "Build-Depends",
263 "Build-Depends-Indep",263 "Build-Depends-Indep",
264 "Build-Conflicts",264 "Build-Conflicts",
@@ -269,7 +269,7 @@ class DSCFile(SourceUploadFile, SignableTagFile):
269 "Format",269 "Format",
270 "Homepage",270 "Homepage",
271 "Standards-Version",271 "Standards-Version",
272 ]))272 })
273273
274 # Note that files is actually only set inside verify().274 # Note that files is actually only set inside verify().
275 files = None275 files = None
diff --git a/lib/lp/archiveuploader/nascentupload.py b/lib/lp/archiveuploader/nascentupload.py
index eba9a06..cb6e144 100644
--- a/lib/lp/archiveuploader/nascentupload.py
+++ b/lib/lp/archiveuploader/nascentupload.py
@@ -458,7 +458,7 @@ class NascentUpload:
458458
459 def getComponents(self):459 def getComponents(self):
460 """Return a set of components present in the uploaded files."""460 """Return a set of components present in the uploaded files."""
461 return set(file.component_name for file in self.changes.files)461 return {file.component_name for file in self.changes.files}
462462
463 def reject(self, msg):463 def reject(self, msg):
464 """Add the provided message to the rejection message."""464 """Add the provided message to the rejection message."""
diff --git a/lib/lp/archiveuploader/nascentuploadfile.py b/lib/lp/archiveuploader/nascentuploadfile.py
index b3d68cc..e996fc4 100644
--- a/lib/lp/archiveuploader/nascentuploadfile.py
+++ b/lib/lp/archiveuploader/nascentuploadfile.py
@@ -215,7 +215,7 @@ class NascentUploadFile:
215215
216 # Read in the file and compute its md5 and sha1 checksums and remember216 # Read in the file and compute its md5 and sha1 checksums and remember
217 # the size of the file as read-in.217 # the size of the file as read-in.
218 digesters = dict((n, hashlib.new(n)) for n in self.checksums.keys())218 digesters = {n: hashlib.new(n) for n in self.checksums.keys()}
219 with open(self.filepath, "rb") as ckfile:219 with open(self.filepath, "rb") as ckfile:
220 size = 0220 size = 0
221 for chunk in filechunks(ckfile):221 for chunk in filechunks(ckfile):
@@ -432,9 +432,9 @@ class BaseBinaryUploadFile(PackageUploadFile):
432 ddeb_file = None432 ddeb_file = None
433433
434 # Capitalised because we extract these directly from the control file.434 # Capitalised because we extract these directly from the control file.
435 mandatory_fields = set(["Package", "Architecture", "Version"])435 mandatory_fields = {"Package", "Architecture", "Version"}
436436
437 known_fields = mandatory_fields.union(set([437 known_fields = mandatory_fields.union({
438 "Depends",438 "Depends",
439 "Conflicts",439 "Conflicts",
440 "Breaks",440 "Breaks",
@@ -458,7 +458,7 @@ class BaseBinaryUploadFile(PackageUploadFile):
458 "Maintainer",458 "Maintainer",
459 "Source",459 "Source",
460 "Homepage",460 "Homepage",
461 ]))461 })
462462
463 # Map priorities to their dbschema valuesa463 # Map priorities to their dbschema valuesa
464 # We treat a priority of '-' as EXTRA since some packages in some distros464 # We treat a priority of '-' as EXTRA since some packages in some distros
diff --git a/lib/lp/archiveuploader/tests/__init__.py b/lib/lp/archiveuploader/tests/__init__.py
index 6fe2757..2133cd0 100644
--- a/lib/lp/archiveuploader/tests/__init__.py
+++ b/lib/lp/archiveuploader/tests/__init__.py
@@ -49,7 +49,7 @@ def insertFakeChangesFile(fileID, path=None):
4949
50def insertFakeChangesFileForAllPackageUploads():50def insertFakeChangesFileForAllPackageUploads():
51 """Ensure all the PackageUpload records point to a valid changes file."""51 """Ensure all the PackageUpload records point to a valid changes file."""
52 for id in set(pu.changesfile.content.id for pu in PackageUploadSet()):52 for id in {pu.changesfile.content.id for pu in PackageUploadSet()}:
53 insertFakeChangesFile(id)53 insertFakeChangesFile(id)
5454
5555
diff --git a/lib/lp/archiveuploader/tests/test_changesfile.py b/lib/lp/archiveuploader/tests/test_changesfile.py
index 6ce64e8..427b43b 100644
--- a/lib/lp/archiveuploader/tests/test_changesfile.py
+++ b/lib/lp/archiveuploader/tests/test_changesfile.py
@@ -209,7 +209,7 @@ class ChangesFileTests(TestCase):
209 contents["Binary"] = "binary1\n binary2 \n binary3"209 contents["Binary"] = "binary1\n binary2 \n binary3"
210 changes = self.createChangesFile("mypkg_0.1_i386.changes", contents)210 changes = self.createChangesFile("mypkg_0.1_i386.changes", contents)
211 self.assertEqual(211 self.assertEqual(
212 set(["binary1", "binary2", "binary3"]), changes.binaries)212 {"binary1", "binary2", "binary3"}, changes.binaries)
213213
214 def test_checkFileName(self):214 def test_checkFileName(self):
215 # checkFileName() yields an UploadError if the filename is invalid.215 # checkFileName() yields an UploadError if the filename is invalid.
@@ -245,7 +245,7 @@ class ChangesFileTests(TestCase):
245 changes = self.createChangesFile(245 changes = self.createChangesFile(
246 "mypkg_0.1_i386.changes", self.getBaseChanges())246 "mypkg_0.1_i386.changes", self.getBaseChanges())
247 self.assertEqual("i386", changes.architecture_line)247 self.assertEqual("i386", changes.architecture_line)
248 self.assertEqual(set(["i386"]), changes.architectures)248 self.assertEqual({"i386"}, changes.architectures)
249249
250 def test_source(self):250 def test_source(self):
251 # The source package name gets extracted from the changes file.251 # The source package name gets extracted from the changes file.
diff --git a/lib/lp/archiveuploader/utils.py b/lib/lp/archiveuploader/utils.py
index 949b37a..5ff24d2 100644
--- a/lib/lp/archiveuploader/utils.py
+++ b/lib/lp/archiveuploader/utils.py
@@ -324,7 +324,7 @@ def merge_file_lists(files, checksums_sha1, checksums_sha256, changes=True):
324 (filename, file_hashes[filename], size))324 (filename, file_hashes[filename], size))
325325
326 # Ensure that each filename was only listed in Files once.326 # Ensure that each filename was only listed in Files once.
327 if set(six.itervalues(file_counter)) - set([1]):327 if set(six.itervalues(file_counter)) - {1}:
328 raise UploadError("Duplicate filenames in Files field.")328 raise UploadError("Duplicate filenames in Files field.")
329329
330 # Ensure that the Checksums-Sha1 and Checksums-Sha256 fields, if330 # Ensure that the Checksums-Sha1 and Checksums-Sha256 fields, if
diff --git a/lib/lp/blueprints/browser/person_upcomingwork.py b/lib/lp/blueprints/browser/person_upcomingwork.py
index 5646a25..37b0030 100644
--- a/lib/lp/blueprints/browser/person_upcomingwork.py
+++ b/lib/lp/blueprints/browser/person_upcomingwork.py
@@ -62,7 +62,7 @@ class PersonUpcomingWorkView(LaunchpadView):
62 if total_items > 0:62 if total_items > 0:
63 done_or_postponed = total_done + total_postponed63 done_or_postponed = total_done + total_postponed
64 percent_done = 100.0 * done_or_postponed / total_items64 percent_done = 100.0 * done_or_postponed / total_items
65 self.progress_per_date[date] = '{0:.0f}'.format(percent_done)65 self.progress_per_date[date] = '{:.0f}'.format(percent_done)
6666
67 @property67 @property
68 def label(self):68 def label(self):
@@ -124,7 +124,7 @@ class WorkItemContainer(object):
124 done_or_postponed = (len(self.done_items) +124 done_or_postponed = (len(self.done_items) +
125 len(self.postponed_items))125 len(self.postponed_items))
126 percent_done = 100.0 * done_or_postponed / len(self._items)126 percent_done = 100.0 * done_or_postponed / len(self._items)
127 return '{0:.0f}'.format(percent_done)127 return '{:.0f}'.format(percent_done)
128128
129 @property129 @property
130 def has_incomplete_work(self):130 def has_incomplete_work(self):
diff --git a/lib/lp/blueprints/browser/specification.py b/lib/lp/blueprints/browser/specification.py
index cc2d3b0..2f89e1e 100644
--- a/lib/lp/blueprints/browser/specification.py
+++ b/lib/lp/blueprints/browser/specification.py
@@ -1180,7 +1180,7 @@ class SpecGraph:
1180 graph.link(node, related)1180 graph.link(node, related)
1181 """1181 """
1182 # This is a standard pattern for "flattening" a recursive algorithm.1182 # This is a standard pattern for "flattening" a recursive algorithm.
1183 to_search = set([spec])1183 to_search = {spec}
1184 visited = set()1184 visited = set()
1185 while to_search:1185 while to_search:
1186 current_spec = to_search.pop()1186 current_spec = to_search.pop()
@@ -1341,7 +1341,7 @@ class SpecGraphNode:
1341 # We want to have links in the image map for all nodes1341 # We want to have links in the image map for all nodes
1342 # except the one that were currently on the page of.1342 # except the one that were currently on the page of.
1343 attrnames.append('URL')1343 attrnames.append('URL')
1344 attrdict = dict((name, getattr(self, name)) for name in attrnames)1344 attrdict = {name: getattr(self, name) for name in attrnames}
1345 return u'%s\n%s' % (to_DOT_ID(self.name), dict_to_DOT_attrs(attrdict))1345 return u'%s\n%s' % (to_DOT_ID(self.name), dict_to_DOT_attrs(attrdict))
13461346
13471347
diff --git a/lib/lp/blueprints/browser/sprint.py b/lib/lp/blueprints/browser/sprint.py
index a7f1fdb..3945820 100644
--- a/lib/lp/blueprints/browser/sprint.py
+++ b/lib/lp/blueprints/browser/sprint.py
@@ -410,8 +410,8 @@ class SprintTopicSetView(HasSpecificationsView, LaunchpadView):
410 def initialize(self):410 def initialize(self):
411 self.status_message = None411 self.status_message = None
412 self.process_form()412 self.process_form()
413 self.attendee_ids = set(413 self.attendee_ids = {
414 attendance.attendeeID for attendance in self.context.attendances)414 attendance.attendeeID for attendance in self.context.attendances}
415415
416 @cachedproperty416 @cachedproperty
417 def spec_filter(self):417 def spec_filter(self):
@@ -523,8 +523,8 @@ class SprintMeetingExportView(LaunchpadView):
523 if spec.drafter is not None:523 if spec.drafter is not None:
524 spec_people[spec.drafter.id] = True524 spec_people[spec.drafter.id] = True
525 attendee_set.add(spec.drafter.id)525 attendee_set.add(spec.drafter.id)
526 people_by_id = dict((person.id, person) for person in526 people_by_id = {person.id: person for person in
527 getUtility(IPersonSet).getPrecachedPersonsFromIDs(attendee_set))527 getUtility(IPersonSet).getPrecachedPersonsFromIDs(attendee_set)}
528 self.specifications = [528 self.specifications = [
529 dict(spec=spec, interested=[529 dict(spec=spec, interested=[
530 dict(name=people_by_id[person_id].name, required=required)530 dict(name=people_by_id[person_id].name, required=required)
@@ -593,9 +593,9 @@ class SprintAttendeesCsvExportView(LaunchpadView):
593 location = attendance.attendee.location593 location = attendance.attendee.location
594 if location is not None and location.visible:594 if location is not None and location.visible:
595 time_zone = attendance.attendee.time_zone595 time_zone = attendance.attendee.time_zone
596 irc_nicknames = ', '.join(sorted(set(596 irc_nicknames = ', '.join(sorted({
597 [ircid.nickname for ircid597 ircid.nickname for ircid
598 in attendance.attendee.ircnicknames])))598 in attendance.attendee.ircnicknames}))
599 rows.append(599 rows.append(
600 (attendance.attendee.name,600 (attendance.attendee.name,
601 attendance.attendee.displayname,601 attendance.attendee.displayname,
diff --git a/lib/lp/blueprints/browser/tests/test_specification.py b/lib/lp/blueprints/browser/tests/test_specification.py
index 19596ff..192f0c2 100644
--- a/lib/lp/blueprints/browser/tests/test_specification.py
+++ b/lib/lp/blueprints/browser/tests/test_specification.py
@@ -370,7 +370,7 @@ NEW_SPEC_FROM_ROOT_URL = 'http://blueprints.launchpad.test/specs/+new'
370370
371class NewSpecificationTests:371class NewSpecificationTests:
372372
373 expected_keys = set(['PROPRIETARY', 'PUBLIC', 'EMBARGOED'])373 expected_keys = {'PROPRIETARY', 'PUBLIC', 'EMBARGOED'}
374374
375 def _create_form_data(self, context):375 def _create_form_data(self, context):
376 return {376 return {
@@ -474,7 +474,7 @@ class TestNewSpecificationFromProductView(TestCaseWithFactory,
474474
475 layer = DatabaseFunctionalLayer475 layer = DatabaseFunctionalLayer
476476
477 expected_keys = set(['PROPRIETARY', 'EMBARGOED'])477 expected_keys = {'PROPRIETARY', 'EMBARGOED'}
478478
479 def createInitializedView(self):479 def createInitializedView(self):
480 policy = SpecificationSharingPolicy.EMBARGOED_OR_PROPRIETARY480 policy = SpecificationSharingPolicy.EMBARGOED_OR_PROPRIETARY
@@ -495,7 +495,7 @@ class TestNewSpecificationFromDistributionView(TestCaseWithFactory,
495495
496 layer = DatabaseFunctionalLayer496 layer = DatabaseFunctionalLayer
497497
498 expected_keys = set(['PUBLIC'])498 expected_keys = {'PUBLIC'}
499499
500 def createInitializedView(self):500 def createInitializedView(self):
501 distro = self.factory.makeDistribution()501 distro = self.factory.makeDistribution()
diff --git a/lib/lp/blueprints/browser/tests/test_specificationsubscription.py b/lib/lp/blueprints/browser/tests/test_specificationsubscription.py
index ab7ff1d..6f0d148 100644
--- a/lib/lp/blueprints/browser/tests/test_specificationsubscription.py
+++ b/lib/lp/blueprints/browser/tests/test_specificationsubscription.py
@@ -41,7 +41,7 @@ class TestSpecificationPortletSubcribersIds(TestCaseWithFactory):
41 spec.subscribe(subscriber, subscriber)41 spec.subscribe(subscriber, subscriber)
42 view = create_initialized_view(42 view = create_initialized_view(
43 spec, name="+blueprint-portlet-subscribers-ids")43 spec, name="+blueprint-portlet-subscribers-ids")
44 subscriber_ids = dict(44 subscriber_ids = {
45 (subscriber.name, 'subscriber-%s' % subscriber.id)45 subscriber.name: 'subscriber-%s' % subscriber.id
46 for subscriber in [person, subscriber])46 for subscriber in [person, subscriber]}
47 self.assertEqual(subscriber_ids, view.subscriber_ids)47 self.assertEqual(subscriber_ids, view.subscriber_ids)
diff --git a/lib/lp/blueprints/model/specificationsearch.py b/lib/lp/blueprints/model/specificationsearch.py
index 0e77bc2..a8404ff 100644
--- a/lib/lp/blueprints/model/specificationsearch.py
+++ b/lib/lp/blueprints/model/specificationsearch.py
@@ -69,13 +69,13 @@ def search_specifications(context, base_clauses, user, sort=None,
69 store = IStore(Specification)69 store = IStore(Specification)
70 if not default_acceptance:70 if not default_acceptance:
71 default = SpecificationFilter.INCOMPLETE71 default = SpecificationFilter.INCOMPLETE
72 options = set([72 options = {
73 SpecificationFilter.COMPLETE, SpecificationFilter.INCOMPLETE])73 SpecificationFilter.COMPLETE, SpecificationFilter.INCOMPLETE}
74 else:74 else:
75 default = SpecificationFilter.ACCEPTED75 default = SpecificationFilter.ACCEPTED
76 options = set([76 options = {
77 SpecificationFilter.ACCEPTED, SpecificationFilter.DECLINED,77 SpecificationFilter.ACCEPTED, SpecificationFilter.DECLINED,
78 SpecificationFilter.PROPOSED])78 SpecificationFilter.PROPOSED}
79 if not spec_filter:79 if not spec_filter:
80 spec_filter = [default]80 spec_filter = [default]
8181
@@ -120,8 +120,8 @@ def search_specifications(context, base_clauses, user, sort=None,
120 # If not specially looking for complete, we care about date120 # If not specially looking for complete, we care about date
121 # registered.121 # registered.
122 order = []122 order = []
123 show_proposed = set(123 show_proposed = {
124 [SpecificationFilter.ALL, SpecificationFilter.PROPOSED])124 SpecificationFilter.ALL, SpecificationFilter.PROPOSED}
125 if default_acceptance and not (set(spec_filter) & show_proposed):125 if default_acceptance and not (set(spec_filter) & show_proposed):
126 order.append(Desc(Specification.date_goal_decided))126 order.append(Desc(Specification.date_goal_decided))
127 order.extend([Desc(Specification.datecreated), Specification.id])127 order.extend([Desc(Specification.datecreated), Specification.id])
@@ -135,8 +135,8 @@ def search_specifications(context, base_clauses, user, sort=None,
135 work_items_by_spec = defaultdict(list)135 work_items_by_spec = defaultdict(list)
136 for spec in rows:136 for spec in rows:
137 if need_people:137 if need_people:
138 person_ids |= set(138 person_ids |= {
139 [spec._assigneeID, spec._approverID, spec._drafterID])139 spec._assigneeID, spec._approverID, spec._drafterID}
140 if need_branches:140 if need_branches:
141 get_property_cache(spec).linked_branches = []141 get_property_cache(spec).linked_branches = []
142 if need_workitems:142 if need_workitems:
@@ -146,7 +146,7 @@ def search_specifications(context, base_clauses, user, sort=None,
146 for workitem in work_items:146 for workitem in work_items:
147 person_ids.add(workitem.assignee_id)147 person_ids.add(workitem.assignee_id)
148 work_items_by_spec[workitem.specification_id].append(workitem)148 work_items_by_spec[workitem.specification_id].append(workitem)
149 person_ids -= set([None])149 person_ids -= {None}
150 if need_people:150 if need_people:
151 list(getUtility(IPersonSet).getPrecachedPersonsFromIDs(151 list(getUtility(IPersonSet).getPrecachedPersonsFromIDs(
152 person_ids, need_validity=True))152 person_ids, need_validity=True))
@@ -274,7 +274,7 @@ def _make_cache_user_can_view_spec(user):
274 userid = user.id274 userid = user.id
275275
276 def cache_user_can_view_spec(spec):276 def cache_user_can_view_spec(spec):
277 get_property_cache(spec)._known_viewers = set([userid])277 get_property_cache(spec)._known_viewers = {userid}
278 return spec278 return spec
279 return cache_user_can_view_spec279 return cache_user_can_view_spec
280280
diff --git a/lib/lp/blueprints/model/sprint.py b/lib/lp/blueprints/model/sprint.py
index 65c04b8..32607bb 100644
--- a/lib/lp/blueprints/model/sprint.py
+++ b/lib/lp/blueprints/model/sprint.py
@@ -192,7 +192,7 @@ class Sprint(StormBase, HasDriversMixin, HasSpecificationsMixin):
192 # need_* is provided only for interface compatibility and192 # need_* is provided only for interface compatibility and
193 # need_*=True is not implemented.193 # need_*=True is not implemented.
194 if filter is None:194 if filter is None:
195 filter = set([SpecificationFilter.ACCEPTED])195 filter = {SpecificationFilter.ACCEPTED}
196 tables, query = self.spec_filter_clause(user, filter)196 tables, query = self.spec_filter_clause(user, filter)
197 # import here to avoid circular deps197 # import here to avoid circular deps
198 from lp.blueprints.model.specification import Specification198 from lp.blueprints.model.specification import Specification
diff --git a/lib/lp/blueprints/tests/test_specification.py b/lib/lp/blueprints/tests/test_specification.py
index 3ce41fe..68198a6 100644
--- a/lib/lp/blueprints/tests/test_specification.py
+++ b/lib/lp/blueprints/tests/test_specification.py
@@ -158,9 +158,9 @@ class SpecificationTests(TestCaseWithFactory):
158158
159 def test_get_permissions(self):159 def test_get_permissions(self):
160 expected_get_permissions = {160 expected_get_permissions = {
161 CheckerPublic: set((161 CheckerPublic: {
162 'id', 'information_type', 'private', 'userCanView')),162 'id', 'information_type', 'private', 'userCanView'},
163 'launchpad.LimitedView': set((163 'launchpad.LimitedView': {
164 'all_blocked', 'all_deps', 'approver', 'approverID',164 'all_blocked', 'all_deps', 'approver', 'approverID',
165 'assignee', 'assigneeID', 'bugs', 'completer',165 'assignee', 'assigneeID', 'bugs', 'completer',
166 'createDependency', 'date_completed', 'date_goal_decided',166 'createDependency', 'date_completed', 'date_goal_decided',
@@ -182,14 +182,14 @@ class SpecificationTests(TestCaseWithFactory):
182 'superseded_by', 'target', 'title', 'unlinkBranch',182 'superseded_by', 'target', 'title', 'unlinkBranch',
183 'unlinkSprint', 'unsubscribe', 'updateLifecycleStatus',183 'unlinkSprint', 'unsubscribe', 'updateLifecycleStatus',
184 'validateMove', 'whiteboard', 'work_items',184 'validateMove', 'whiteboard', 'work_items',
185 'workitems_text')),185 'workitems_text'},
186 'launchpad.Edit': set((186 'launchpad.Edit': {
187 'newWorkItem', 'proposeGoal', 'retarget',187 'newWorkItem', 'proposeGoal', 'retarget',
188 'setDefinitionStatus', 'setImplementationStatus', 'setTarget',188 'setDefinitionStatus', 'setImplementationStatus', 'setTarget',
189 'transitionToInformationType', 'updateWorkItems')),189 'transitionToInformationType', 'updateWorkItems'},
190 'launchpad.Driver': set(('acceptBy', 'declineBy')),190 'launchpad.Driver': {'acceptBy', 'declineBy'},
191 'launchpad.AnyLegitimatePerson': set((191 'launchpad.AnyLegitimatePerson': {
192 'unlinkBug', 'linkBug', 'setWorkItems')),192 'unlinkBug', 'linkBug', 'setWorkItems'},
193 }193 }
194 specification = self.factory.makeSpecification()194 specification = self.factory.makeSpecification()
195 checker = getChecker(specification)195 checker = getChecker(specification)
@@ -198,13 +198,13 @@ class SpecificationTests(TestCaseWithFactory):
198198
199 def test_set_permissions(self):199 def test_set_permissions(self):
200 expected_get_permissions = {200 expected_get_permissions = {
201 'launchpad.Admin': set(('direction_approved', 'priority')),201 'launchpad.Admin': {'direction_approved', 'priority'},
202 'launchpad.AnyLegitimatePerson': set(('whiteboard', )),202 'launchpad.AnyLegitimatePerson': {'whiteboard'},
203 'launchpad.Edit': set((203 'launchpad.Edit': {
204 'approver', 'assignee', 'definition_status', 'distribution',204 'approver', 'assignee', 'definition_status', 'distribution',
205 'drafter', 'implementation_status', 'man_days', 'milestone',205 'drafter', 'implementation_status', 'man_days', 'milestone',
206 'name', 'product', 'specurl', 'summary', 'superseded_by',206 'name', 'product', 'specurl', 'summary', 'superseded_by',
207 'title')),207 'title'},
208 }208 }
209 specification = self.factory.makeSpecification()209 specification = self.factory.makeSpecification()
210 checker = getChecker(specification)210 checker = getChecker(specification)
diff --git a/lib/lp/bugs/browser/bug.py b/lib/lp/bugs/browser/bug.py
index 04c4f69..f4e5eea 100644
--- a/lib/lp/bugs/browser/bug.py
+++ b/lib/lp/bugs/browser/bug.py
@@ -570,10 +570,10 @@ class BugView(LaunchpadView, BugViewMixin):
570 """570 """
571 duplicate_bugs = list(self.context.duplicates)571 duplicate_bugs = list(self.context.duplicates)
572 current_task = self.current_bugtask572 current_task = self.current_bugtask
573 dupes_in_current_context = dict(573 dupes_in_current_context = {
574 (bugtask.bug, bugtask)574 bugtask.bug: bugtask
575 for bugtask in current_task.target.searchTasks(575 for bugtask in current_task.target.searchTasks(
576 BugTaskSearchParams(self.user, bug=any(*duplicate_bugs))))576 BugTaskSearchParams(self.user, bug=any(*duplicate_bugs)))}
577 dupes = []577 dupes = []
578 for bug in duplicate_bugs:578 for bug in duplicate_bugs:
579 # Don't disclose even the ID of a private bug. The link will579 # Don't disclose even the ID of a private bug. The link will
diff --git a/lib/lp/bugs/browser/bugalsoaffects.py b/lib/lp/bugs/browser/bugalsoaffects.py
index d1bfe3e..40f30f4 100644
--- a/lib/lp/bugs/browser/bugalsoaffects.py
+++ b/lib/lp/bugs/browser/bugalsoaffects.py
@@ -650,8 +650,8 @@ class ProductBugTaskCreationStep(BugTaskCreationStep):
650 # link_upstream_how has _displayItemForMissingValue=False650 # link_upstream_how has _displayItemForMissingValue=False
651 # so that renderItems() doesn't return an extra radio button which651 # so that renderItems() doesn't return an extra radio button which
652 # prevents it from matching widget.vocabulary's ordering.652 # prevents it from matching widget.vocabulary's ordering.
653 return dict((entry.token, items[i])653 return {entry.token: items[i]
654 for i, entry in enumerate(widget.vocabulary))654 for i, entry in enumerate(widget.vocabulary)}
655655
656 def main_action(self, data):656 def main_action(self, data):
657 link_upstream_how = data.get('link_upstream_how')657 link_upstream_how = data.get('link_upstream_how')
diff --git a/lib/lp/bugs/browser/buglisting.py b/lib/lp/bugs/browser/buglisting.py
index 8e8e49e..3a4a6c3 100644
--- a/lib/lp/bugs/browser/buglisting.py
+++ b/lib/lp/bugs/browser/buglisting.py
@@ -1070,8 +1070,8 @@ class BugTaskSearchListingView(LaunchpadFormView, FeedsMixin, BugsInfoMixin):
1070 not FeedsLayer.providedBy(self.request) and1070 not FeedsLayer.providedBy(self.request) and
1071 not self.request.form.get('advanced')):1071 not self.request.form.get('advanced')):
1072 cache = IJSONRequestCache(self.request)1072 cache = IJSONRequestCache(self.request)
1073 view_names = set(reg.name for reg1073 view_names = {reg.name for reg
1074 in iter_view_registrations(self.__class__))1074 in iter_view_registrations(self.__class__)}
1075 if len(view_names) != 1:1075 if len(view_names) != 1:
1076 raise AssertionError("Ambiguous view name.")1076 raise AssertionError("Ambiguous view name.")
1077 cache.objects['view_name'] = view_names.pop()1077 cache.objects['view_name'] = view_names.pop()
@@ -1157,7 +1157,7 @@ class BugTaskSearchListingView(LaunchpadFormView, FeedsMixin, BugsInfoMixin):
1157 "are out of date or you changed the URL by hand?" %1157 "are out of date or you changed the URL by hand?" %
1158 field_name)1158 field_name)
11591159
1160 sort_column_names = set(sort_key[0] for sort_key in SORT_KEYS)1160 sort_column_names = {sort_key[0] for sort_key in SORT_KEYS}
1161 orderby = get_sortorder_from_request(self.request)1161 orderby = get_sortorder_from_request(self.request)
1162 for orderby_col in orderby:1162 for orderby_col in orderby:
1163 if orderby_col.startswith("-"):1163 if orderby_col.startswith("-"):
diff --git a/lib/lp/bugs/browser/bugtarget.py b/lib/lp/bugs/browser/bugtarget.py
index a8bfe2e..d140bca 100644
--- a/lib/lp/bugs/browser/bugtarget.py
+++ b/lib/lp/bugs/browser/bugtarget.py
@@ -1222,12 +1222,12 @@ class BugTargetBugTagsView(LaunchpadView):
1222 self.user, 10, official_tags)1222 self.user, 10, official_tags)
12231223
1224 return sorted(1224 return sorted(
1225 [dict(1225 (dict(
1226 tag=tag,1226 tag=tag,
1227 count=count,1227 count=count,
1228 url=self._getSearchURL(tag),1228 url=self._getSearchURL(tag),
1229 )1229 )
1230 for (tag, count) in six.iteritems(tags)],1230 for (tag, count) in six.iteritems(tags)),
1231 key=lambda item: (-item['count'], item['tag']))1231 key=lambda item: (-item['count'], item['tag']))
12321232
1233 @property1233 @property
diff --git a/lib/lp/bugs/browser/bugtask.py b/lib/lp/bugs/browser/bugtask.py
index 5852a49..a4b0fc0 100644
--- a/lib/lp/bugs/browser/bugtask.py
+++ b/lib/lp/bugs/browser/bugtask.py
@@ -284,7 +284,7 @@ def get_visible_comments(comments, user=None):
284 # so that checking owner.is_valid_person, when rendering the link,284 # so that checking owner.is_valid_person, when rendering the link,
285 # won't issue a DB query. Note that this should be obsolete now with285 # won't issue a DB query. Note that this should be obsolete now with
286 # getMessagesForView improvements.286 # getMessagesForView improvements.
287 commenters = set(comment.owner for comment in visible_comments)287 commenters = {comment.owner for comment in visible_comments}
288 getUtility(IPersonSet).getValidPersons(commenters)288 getUtility(IPersonSet).getValidPersons(commenters)
289289
290 # If a user is supplied, we can also strip out comments that the user290 # If a user is supplied, we can also strip out comments that the user
@@ -602,8 +602,8 @@ class BugTaskView(LaunchpadView, BugViewMixin, FeedsMixin):
602 activity_item for activity_item in activity602 activity_item for activity_item in activity
603 if interesting_match(activity_item.whatchanged) is not None]603 if interesting_match(activity_item.whatchanged) is not None]
604 # Pre-load the doers of the activities in one query.604 # Pre-load the doers of the activities in one query.
605 person_ids = set(605 person_ids = {
606 activity_item.personID for activity_item in activity_items)606 activity_item.personID for activity_item in activity_items}
607 list(getUtility(IPersonSet).getPrecachedPersonsFromIDs(607 list(getUtility(IPersonSet).getPrecachedPersonsFromIDs(
608 person_ids, need_validity=True))608 person_ids, need_validity=True))
609609
@@ -703,10 +703,10 @@ class BugTaskView(LaunchpadView, BugViewMixin, FeedsMixin):
703 activities, attrgetter("target"))]703 activities, attrgetter("target"))]
704704
705 def comment_event_dict(comment):705 def comment_event_dict(comment):
706 actors = set(activity.person for activity in comment.activity)706 actors = {activity.person for activity in comment.activity}
707 actors.add(comment.owner)707 actors.add(comment.owner)
708 assert len(actors) == 1, actors708 assert len(actors) == 1, actors
709 dates = set(activity.datechanged for activity in comment.activity)709 dates = {activity.datechanged for activity in comment.activity}
710 dates.add(comment.datecreated)710 dates.add(comment.datecreated)
711 comment.activity = group_activities_by_target(comment.activity)711 comment.activity = group_activities_by_target(comment.activity)
712 return {712 return {
@@ -716,9 +716,9 @@ class BugTaskView(LaunchpadView, BugViewMixin, FeedsMixin):
716 }716 }
717717
718 def activity_event_dict(activities):718 def activity_event_dict(activities):
719 actors = set(activity.person for activity in activities)719 actors = {activity.person for activity in activities}
720 assert len(actors) == 1, actors720 assert len(actors) == 1, actors
721 dates = set(activity.datechanged for activity in activities)721 dates = {activity.datechanged for activity in activities}
722 return {722 return {
723 "activity": group_activities_by_target(activities),723 "activity": group_activities_by_target(activities),
724 "date": min(dates),724 "date": min(dates),
@@ -1173,7 +1173,7 @@ class BugTaskEditView(LaunchpadEditFormView, BugTaskBugWatchMixin,
1173 if 'importance' in editable_field_names:1173 if 'importance' in editable_field_names:
1174 editable_field_names.remove("importance")1174 editable_field_names.remove("importance")
1175 else:1175 else:
1176 editable_field_names = set(('bugwatch', ))1176 editable_field_names = {'bugwatch'}
1177 if self.context.bugwatch is None:1177 if self.context.bugwatch is None:
1178 editable_field_names.update(('status', 'assignee'))1178 editable_field_names.update(('status', 'assignee'))
1179 if ('importance' in self.default_field_names1179 if ('importance' in self.default_field_names
@@ -1250,8 +1250,8 @@ class BugTaskEditView(LaunchpadEditFormView, BugTaskBugWatchMixin,
1250 if self.user is None:1250 if self.user is None:
1251 status_noshow = set(BugTaskStatus.items)1251 status_noshow = set(BugTaskStatus.items)
1252 else:1252 else:
1253 status_noshow = set((1253 status_noshow = {
1254 BugTaskStatus.UNKNOWN, BugTaskStatus.EXPIRED))1254 BugTaskStatus.UNKNOWN, BugTaskStatus.EXPIRED}
1255 status_noshow.update(1255 status_noshow.update(
1256 status for status in BugTaskStatus.items1256 status for status in BugTaskStatus.items
1257 if not self.context.canTransitionToStatus(1257 if not self.context.canTransitionToStatus(
diff --git a/lib/lp/bugs/browser/bugtracker.py b/lib/lp/bugs/browser/bugtracker.py
index 95c1479..dee3683 100644
--- a/lib/lp/bugs/browser/bugtracker.py
+++ b/lib/lp/bugs/browser/bugtracker.py
@@ -375,9 +375,9 @@ class BugTrackerEditView(LaunchpadEditFormView):
375375
376 # If the bugtracker is a celebrity then we protect it from376 # If the bugtracker is a celebrity then we protect it from
377 # deletion.377 # deletion.
378 celebrities_set = set(378 celebrities_set = {
379 getattr(celebrities, name)379 getattr(celebrities, name)
380 for name in ILaunchpadCelebrities.names())380 for name in ILaunchpadCelebrities.names()}
381 if self.context in celebrities_set:381 if self.context in celebrities_set:
382 reasons.append(382 reasons.append(
383 'This bug tracker is protected from deletion.')383 'This bug tracker is protected from deletion.')
diff --git a/lib/lp/bugs/browser/structuralsubscription.py b/lib/lp/bugs/browser/structuralsubscription.py
index 66415f3..5506bee 100644
--- a/lib/lp/bugs/browser/structuralsubscription.py
+++ b/lib/lp/bugs/browser/structuralsubscription.py
@@ -155,10 +155,10 @@ class StructuralSubscriptionView(LaunchpadFormView):
155 be removed, else return None.155 be removed, else return None.
156 """156 """
157 teams = set(self.user_teams)157 teams = set(self.user_teams)
158 other_subscriptions = set(158 other_subscriptions = {
159 subscription.subscriber159 subscription.subscriber
160 for subscription160 for subscription
161 in self.context.bug_subscriptions)161 in self.context.bug_subscriptions}
162162
163 # Teams and the current user have their own UI elements. Remove163 # Teams and the current user have their own UI elements. Remove
164 # them to avoid duplicates.164 # them to avoid duplicates.
@@ -196,9 +196,9 @@ class StructuralSubscriptionView(LaunchpadFormView):
196 def initial_values(self):196 def initial_values(self):
197 """See `LaunchpadFormView`."""197 """See `LaunchpadFormView`."""
198 teams = set(self.user_teams)198 teams = set(self.user_teams)
199 subscribed_teams = set(team199 subscribed_teams = {team
200 for team in teams200 for team in teams
201 if self.isSubscribed(team))201 if self.isSubscribed(team)}
202 return {202 return {
203 'subscribe_me': self.currentUserIsSubscribed(),203 'subscribe_me': self.currentUserIsSubscribed(),
204 'subscriptions_team': subscribed_teams,204 'subscriptions_team': subscribed_teams,
@@ -261,8 +261,8 @@ class StructuralSubscriptionView(LaunchpadFormView):
261 target = self.context261 target = self.context
262 teams = set(self.user_teams)262 teams = set(self.user_teams)
263 form_selected_teams = teams & set(form_selected_teams)263 form_selected_teams = teams & set(form_selected_teams)
264 subscriptions = set(264 subscriptions = {
265 team for team in teams if self.isSubscribed(team))265 team for team in teams if self.isSubscribed(team)}
266266
267 for team in form_selected_teams - subscriptions:267 for team in form_selected_teams - subscriptions:
268 target.addBugSubscription(team, self.user)268 target.addBugSubscription(team, self.user)
diff --git a/lib/lp/bugs/browser/tests/test_bugcomment.py b/lib/lp/bugs/browser/tests/test_bugcomment.py
index c23f3b0..f93a5c9 100644
--- a/lib/lp/bugs/browser/tests/test_bugcomment.py
+++ b/lib/lp/bugs/browser/tests/test_bugcomment.py
@@ -129,7 +129,7 @@ class TestGroupCommentsWithActivities(TestCase):
129 activity2 = BugActivityStub(next(self.time_index)[0])129 activity2 = BugActivityStub(next(self.time_index)[0])
130 comment2 = BugCommentStub(*next(self.time_index))130 comment2 = BugCommentStub(*next(self.time_index))
131131
132 activities = set([activity1, activity2])132 activities = {activity1, activity2}
133 comments = list([comment1, comment2])133 comments = list([comment1, comment2])
134134
135 self.assertEqual(135 self.assertEqual(
diff --git a/lib/lp/bugs/browser/tests/test_bugsubscriptionfilter.py b/lib/lp/bugs/browser/tests/test_bugsubscriptionfilter.py
index c0db2c2..342e984 100644
--- a/lib/lp/bugs/browser/tests/test_bugsubscriptionfilter.py
+++ b/lib/lp/bugs/browser/tests/test_bugsubscriptionfilter.py
@@ -160,7 +160,7 @@ class TestBugSubscriptionFilterAPIModifications(
160 self.assertTrue(self.subscription_filter.include_any_tags)160 self.assertTrue(self.subscription_filter.include_any_tags)
161 self.assertTrue(self.subscription_filter.exclude_any_tags)161 self.assertTrue(self.subscription_filter.exclude_any_tags)
162 self.assertEqual(162 self.assertEqual(
163 set(["*", "-*", "foo", "-bar"]),163 {"*", "-*", "foo", "-bar"},
164 self.subscription_filter.tags)164 self.subscription_filter.tags)
165165
166 def test_modify_description(self):166 def test_modify_description(self):
@@ -189,7 +189,7 @@ class TestBugSubscriptionFilterAPIModifications(
189189
190 # Updated state.190 # Updated state.
191 self.assertEqual(191 self.assertEqual(
192 set([BugTaskStatus.NEW, BugTaskStatus.TRIAGED]),192 {BugTaskStatus.NEW, BugTaskStatus.TRIAGED},
193 self.subscription_filter.statuses)193 self.subscription_filter.statuses)
194194
195 def test_modify_importances(self):195 def test_modify_importances(self):
@@ -204,7 +204,7 @@ class TestBugSubscriptionFilterAPIModifications(
204204
205 # Updated state.205 # Updated state.
206 self.assertEqual(206 self.assertEqual(
207 set([BugTaskImportance.LOW, BugTaskImportance.HIGH]),207 {BugTaskImportance.LOW, BugTaskImportance.HIGH},
208 self.subscription_filter.importances)208 self.subscription_filter.importances)
209209
210 def test_delete(self):210 def test_delete(self):
diff --git a/lib/lp/bugs/browser/tests/test_bugtask.py b/lib/lp/bugs/browser/tests/test_bugtask.py
index 4cc1c9c..5eb97d6 100644
--- a/lib/lp/bugs/browser/tests/test_bugtask.py
+++ b/lib/lp/bugs/browser/tests/test_bugtask.py
@@ -2491,7 +2491,7 @@ class TestBugTaskSearchListingView(BrowserTestCase):
2491 view = self.makeView()2491 view = self.makeView()
2492 cache = IJSONRequestCache(view.request)2492 cache = IJSONRequestCache(view.request)
2493 json_sort_keys = cache.objects['sort_keys']2493 json_sort_keys = cache.objects['sort_keys']
2494 json_sort_keys = set(key[0] for key in json_sort_keys)2494 json_sort_keys = {key[0] for key in json_sort_keys}
2495 valid_keys = set(orderby_expression.keys())2495 valid_keys = set(orderby_expression.keys())
2496 self.assertEqual(2496 self.assertEqual(
2497 valid_keys, json_sort_keys,2497 valid_keys, json_sort_keys,
diff --git a/lib/lp/bugs/externalbugtracker/bugzilla.py b/lib/lp/bugs/externalbugtracker/bugzilla.py
index 7a84697..a84a575 100644
--- a/lib/lp/bugs/externalbugtracker/bugzilla.py
+++ b/lib/lp/bugs/externalbugtracker/bugzilla.py
@@ -845,8 +845,8 @@ class BugzillaAPI(Bugzilla):
845 del comments[comment_id]845 del comments[comment_id]
846846
847 # Ensure that comment IDs are converted to ints.847 # Ensure that comment IDs are converted to ints.
848 comments_with_int_ids = dict(848 comments_with_int_ids = {
849 (int(id), comments[id]) for id in comments)849 int(id): comments[id] for id in comments}
850 self._bugs[actual_bug_id]['comments'] = comments_with_int_ids850 self._bugs[actual_bug_id]['comments'] = comments_with_int_ids
851851
852 def getPosterForComment(self, remote_bug_id, comment_id):852 def getPosterForComment(self, remote_bug_id, comment_id):
@@ -1090,8 +1090,8 @@ class BugzillaLPPlugin(BugzillaAPI):
1090 comment_list = bug_comments_dict['bugs'][str(actual_bug_id)]1090 comment_list = bug_comments_dict['bugs'][str(actual_bug_id)]
10911091
1092 # Transfer the comment list into a dict.1092 # Transfer the comment list into a dict.
1093 bug_comments = dict(1093 bug_comments = {
1094 (comment['id'], comment) for comment in comment_list)1094 comment['id']: comment for comment in comment_list}
10951095
1096 self._bugs[actual_bug_id]['comments'] = bug_comments1096 self._bugs[actual_bug_id]['comments'] = bug_comments
10971097
diff --git a/lib/lp/bugs/interfaces/bugtasksearch.py b/lib/lp/bugs/interfaces/bugtasksearch.py
index ce3970a..7c18d58 100644
--- a/lib/lp/bugs/interfaces/bugtasksearch.py
+++ b/lib/lp/bugs/interfaces/bugtasksearch.py
@@ -217,7 +217,7 @@ class BugTaskSearchParams:
217 if isinstance(information_type, collections.Iterable):217 if isinstance(information_type, collections.Iterable):
218 self.information_type = set(information_type)218 self.information_type = set(information_type)
219 elif information_type:219 elif information_type:
220 self.information_type = set((information_type,))220 self.information_type = {information_type}
221 else:221 else:
222 self.information_type = None222 self.information_type = None
223 self.ignore_privacy = ignore_privacy223 self.ignore_privacy = ignore_privacy
@@ -674,7 +674,7 @@ def get_person_bugtasks_search_params(user, context, **kwargs):
674 # modified the query in an invalid way by overwriting all user674 # modified the query in an invalid way by overwriting all user
675 # related parameters675 # related parameters
676 raise IllegalRelatedBugTasksParams(676 raise IllegalRelatedBugTasksParams(
677 ('Cannot search for related tasks to \'%s\', at least one '677 'Cannot search for related tasks to \'%s\', at least one '
678 'of these parameter has to be empty: %s'678 'of these parameter has to be empty: %s'
679 % (context.name, ", ".join(relevant_fields))))679 % (context.name, ", ".join(relevant_fields)))
680 return search_params680 return search_params
diff --git a/lib/lp/bugs/interfaces/tests/test_bugtask.py b/lib/lp/bugs/interfaces/tests/test_bugtask.py
index 3c33527..f940c15 100644
--- a/lib/lp/bugs/interfaces/tests/test_bugtask.py
+++ b/lib/lp/bugs/interfaces/tests/test_bugtask.py
@@ -17,9 +17,9 @@ class TestFunctions(TestCase):
1717
18 def test_get_bugtask_status(self):18 def test_get_bugtask_status(self):
19 # Compose a map of BugTaskStatusSearch members from their values.19 # Compose a map of BugTaskStatusSearch members from their values.
20 expected = dict(20 expected = {
21 (status.value, status)21 status.value: status
22 for status in BugTaskStatusSearch.items)22 for status in BugTaskStatusSearch.items}
23 # Update the expected status map - overwriting some entries - from23 # Update the expected status map - overwriting some entries - from
24 # BugTaskStatus members and their values.24 # BugTaskStatus members and their values.
25 expected.update(25 expected.update(
@@ -27,9 +27,9 @@ class TestFunctions(TestCase):
27 for status in BugTaskStatus.items)27 for status in BugTaskStatus.items)
28 # Compose a map of statuses as discovered by value for each member of28 # Compose a map of statuses as discovered by value for each member of
29 # BugTaskStatusSearch.29 # BugTaskStatusSearch.
30 observed = dict(30 observed = {
31 (status.value, get_bugtask_status(status.value))31 status.value: get_bugtask_status(status.value)
32 for status in BugTaskStatusSearch.items)32 for status in BugTaskStatusSearch.items}
33 # Update the expected status map with statuses discovered by value for33 # Update the expected status map with statuses discovered by value for
34 # each member of BugTaskStatus.34 # each member of BugTaskStatus.
35 observed.update(35 observed.update(
@@ -52,9 +52,9 @@ class TestFunctions(TestCase):
52 BugTaskStatus.UNKNOWN: BugTaskStatus.UNKNOWN,52 BugTaskStatus.UNKNOWN: BugTaskStatus.UNKNOWN,
53 BugTaskStatus.WONTFIX: BugTaskStatus.WONTFIX,53 BugTaskStatus.WONTFIX: BugTaskStatus.WONTFIX,
54 }54 }
55 observed = dict(55 observed = {
56 (status, normalize_bugtask_status(status))56 status: normalize_bugtask_status(status)
57 for status in BugTaskStatus.items)57 for status in BugTaskStatus.items}
58 self.assertEqual(expected, observed)58 self.assertEqual(expected, observed)
5959
60 def test_normalize_bugtask_status_from_BugTaskStatusSearch(self):60 def test_normalize_bugtask_status_from_BugTaskStatusSearch(self):
@@ -75,9 +75,9 @@ class TestFunctions(TestCase):
75 BugTaskStatusSearch.TRIAGED: BugTaskStatus.TRIAGED,75 BugTaskStatusSearch.TRIAGED: BugTaskStatus.TRIAGED,
76 BugTaskStatusSearch.WONTFIX: BugTaskStatus.WONTFIX,76 BugTaskStatusSearch.WONTFIX: BugTaskStatus.WONTFIX,
77 }77 }
78 observed = dict(78 observed = {
79 (status, normalize_bugtask_status(status))79 status: normalize_bugtask_status(status)
80 for status in BugTaskStatusSearch.items)80 for status in BugTaskStatusSearch.items}
81 self.assertEqual(expected, observed)81 self.assertEqual(expected, observed)
8282
83 def test_normalize_bugtask_status_from_BugTaskStatusSearchDisplay(self):83 def test_normalize_bugtask_status_from_BugTaskStatusSearchDisplay(self):
@@ -99,7 +99,7 @@ class TestFunctions(TestCase):
99 BugTaskStatusSearchDisplay.TRIAGED: BugTaskStatus.TRIAGED,99 BugTaskStatusSearchDisplay.TRIAGED: BugTaskStatus.TRIAGED,
100 BugTaskStatusSearchDisplay.WONTFIX: BugTaskStatus.WONTFIX,100 BugTaskStatusSearchDisplay.WONTFIX: BugTaskStatus.WONTFIX,
101 }101 }
102 observed = dict(102 observed = {
103 (status, normalize_bugtask_status(status))103 status: normalize_bugtask_status(status)
104 for status in BugTaskStatusSearchDisplay.items)104 for status in BugTaskStatusSearchDisplay.items}
105 self.assertEqual(expected, observed)105 self.assertEqual(expected, observed)
diff --git a/lib/lp/bugs/mail/bugnotificationbuilder.py b/lib/lp/bugs/mail/bugnotificationbuilder.py
index 9c95348..7b381a1 100644
--- a/lib/lp/bugs/mail/bugnotificationbuilder.py
+++ b/lib/lp/bugs/mail/bugnotificationbuilder.py
@@ -117,7 +117,7 @@ class BugNotificationBuilder:
117 # Add the -Bug-Commenters header, a space-separated list of117 # Add the -Bug-Commenters header, a space-separated list of
118 # distinct IDs of people who have commented on the bug. The118 # distinct IDs of people who have commented on the bug. The
119 # list is sorted to aid testing.119 # list is sorted to aid testing.
120 commenters = set(message.owner.name for message in bug.messages)120 commenters = {message.owner.name for message in bug.messages}
121 self.common_headers.append(121 self.common_headers.append(
122 ('X-Launchpad-Bug-Commenters', ' '.join(sorted(commenters))))122 ('X-Launchpad-Bug-Commenters', ' '.join(sorted(commenters))))
123123
diff --git a/lib/lp/bugs/mail/handler.py b/lib/lp/bugs/mail/handler.py
index 7265336..fadb5bc 100644
--- a/lib/lp/bugs/mail/handler.py
+++ b/lib/lp/bugs/mail/handler.py
@@ -360,14 +360,14 @@ class MaloneHandler:
360 # application/ms-tnef attachment are created by Outlook; they360 # application/ms-tnef attachment are created by Outlook; they
361 # seem to store no more than an RTF representation of an email.361 # seem to store no more than an RTF representation of an email.
362362
363 irrelevant_content_types = set((363 irrelevant_content_types = {
364 'application/applefile', # the resource fork of a MacOS file364 'application/applefile', # the resource fork of a MacOS file
365 'application/pgp-signature',365 'application/pgp-signature',
366 'application/pkcs7-signature',366 'application/pkcs7-signature',
367 'application/x-pkcs7-signature',367 'application/x-pkcs7-signature',
368 'text/x-vcard',368 'text/x-vcard',
369 'application/ms-tnef',369 'application/ms-tnef',
370 ))370 }
371371
372 def processAttachments(self, bug, message, signed_mail):372 def processAttachments(self, bug, message, signed_mail):
373 """Create Bugattachments for "reasonable" mail attachments.373 """Create Bugattachments for "reasonable" mail attachments.
diff --git a/lib/lp/bugs/model/bug.py b/lib/lp/bugs/model/bug.py
index 6088100..52c413a 100644
--- a/lib/lp/bugs/model/bug.py
+++ b/lib/lp/bugs/model/bug.py
@@ -287,7 +287,7 @@ def get_bug_tags_open_count(context_condition, user, tag_limit=0,
287 )287 )
288 tags = {}288 tags = {}
289 if include_tags:289 if include_tags:
290 tags = dict((tag, 0) for tag in include_tags)290 tags = {tag: 0 for tag in include_tags}
291 where_conditions = [291 where_conditions = [
292 BugSummary.status.is_in(UNRESOLVED_BUGTASK_STATUSES),292 BugSummary.status.is_in(UNRESOLVED_BUGTASK_STATUSES),
293 BugSummary.tag != None,293 BugSummary.tag != None,
@@ -560,7 +560,7 @@ class Bug(SQLBase, InformationTypeMixin):
560 # in storm with very large bugs by not joining and instead560 # in storm with very large bugs by not joining and instead
561 # querying a second time. If this starts to show high db561 # querying a second time. If this starts to show high db
562 # time, we can left outer join instead.562 # time, we can left outer join instead.
563 owner_ids = set(message.ownerID for message in messages)563 owner_ids = {message.ownerID for message in messages}
564 owner_ids.discard(None)564 owner_ids.discard(None)
565 if not owner_ids:565 if not owner_ids:
566 return566 return
@@ -571,7 +571,7 @@ class Bug(SQLBase, InformationTypeMixin):
571 # message, or joining in the database (though perhaps in571 # message, or joining in the database (though perhaps in
572 # future we should do that), we do a single separate query572 # future we should do that), we do a single separate query
573 # for the message content.573 # for the message content.
574 message_ids = set(message.id for message in messages)574 message_ids = {message.id for message in messages}
575 chunks = store.find(575 chunks = store.find(
576 MessageChunk, MessageChunk.messageID.is_in(message_ids))576 MessageChunk, MessageChunk.messageID.is_in(message_ids))
577 chunks.order_by(MessageChunk.id)577 chunks.order_by(MessageChunk.id)
@@ -896,7 +896,7 @@ class Bug(SQLBase, InformationTypeMixin):
896 clear_property_cache(self)896 clear_property_cache(self)
897 # Ensure the unsubscriber is in the _known_viewer cache for the bug so897 # Ensure the unsubscriber is in the _known_viewer cache for the bug so
898 # that the permissions are such that the operation can succeed.898 # that the permissions are such that the operation can succeed.
899 get_property_cache(self)._known_viewers = set([unsubscribed_by.id])899 get_property_cache(self)._known_viewers = {unsubscribed_by.id}
900 if person is None:900 if person is None:
901 person = unsubscribed_by901 person = unsubscribed_by
902902
@@ -1431,8 +1431,8 @@ class Bug(SQLBase, InformationTypeMixin):
14311431
1432 def getVisibleLinkedMergeProposals(self, user, eager_load=False):1432 def getVisibleLinkedMergeProposals(self, user, eager_load=False):
1433 """See `IBug`."""1433 """See `IBug`."""
1434 linked_merge_proposal_ids = set(1434 linked_merge_proposal_ids = {
1435 bmp.id for bmp in self.linked_merge_proposals)1435 bmp.id for bmp in self.linked_merge_proposals}
1436 if not linked_merge_proposal_ids:1436 if not linked_merge_proposal_ids:
1437 return EmptyResultSet()1437 return EmptyResultSet()
1438 else:1438 else:
@@ -1863,7 +1863,7 @@ class Bug(SQLBase, InformationTypeMixin):
1863 """Set the tags from a list of strings."""1863 """Set the tags from a list of strings."""
1864 # Sets provide an easy way to get the difference between the old and1864 # Sets provide an easy way to get the difference between the old and
1865 # new tags.1865 # new tags.
1866 new_tags = set([tag.lower() for tag in tags])1866 new_tags = {tag.lower() for tag in tags}
1867 old_tags = set(self.tags)1867 old_tags = set(self.tags)
1868 # The cache will be stale after we add/remove tags, clear it.1868 # The cache will be stale after we add/remove tags, clear it.
1869 del get_property_cache(self)._cached_tags1869 del get_property_cache(self)._cached_tags
diff --git a/lib/lp/bugs/model/bugsubscriptionfilter.py b/lib/lp/bugs/model/bugsubscriptionfilter.py
index c3568d6..bf01a36 100644
--- a/lib/lp/bugs/model/bugsubscriptionfilter.py
+++ b/lib/lp/bugs/model/bugsubscriptionfilter.py
@@ -186,11 +186,11 @@ class BugSubscriptionFilter(StormBase):
186 # Deal with other tags.186 # Deal with other tags.
187 tags = tags - wildcards187 tags = tags - wildcards
188 store = IStore(BugSubscriptionFilterTag)188 store = IStore(BugSubscriptionFilterTag)
189 current_tag_filters = dict(189 current_tag_filters = {
190 (tag_filter.qualified_tag, tag_filter)190 tag_filter.qualified_tag: tag_filter
191 for tag_filter in store.find(191 for tag_filter in store.find(
192 BugSubscriptionFilterTag,192 BugSubscriptionFilterTag,
193 BugSubscriptionFilterTag.filter == self))193 BugSubscriptionFilterTag.filter == self)}
194 # Remove unused tags.194 # Remove unused tags.
195 for tag in set(current_tag_filters).difference(tags):195 for tag in set(current_tag_filters).difference(tags):
196 tag_filter = current_tag_filters.pop(tag)196 tag_filter = current_tag_filters.pop(tag)
diff --git a/lib/lp/bugs/model/bugtarget.py b/lib/lp/bugs/model/bugtarget.py
index f7272d3..0f7f748 100644
--- a/lib/lp/bugs/model/bugtarget.py
+++ b/lib/lp/bugs/model/bugtarget.py
@@ -150,7 +150,7 @@ class OfficialBugTagTargetMixin:
150150
151 def _setOfficialTags(self, tags):151 def _setOfficialTags(self, tags):
152 """Set the official bug tags from a list of strings."""152 """Set the official bug tags from a list of strings."""
153 new_tags = set([tag.lower() for tag in tags])153 new_tags = {tag.lower() for tag in tags}
154 old_tags = set(self.official_bug_tags)154 old_tags = set(self.official_bug_tags)
155 added_tags = new_tags.difference(old_tags)155 added_tags = new_tags.difference(old_tags)
156 removed_tags = old_tags.difference(new_tags)156 removed_tags = old_tags.difference(new_tags)
diff --git a/lib/lp/bugs/model/bugtask.py b/lib/lp/bugs/model/bugtask.py
index 14eeec1..dff8df5 100644
--- a/lib/lp/bugs/model/bugtask.py
+++ b/lib/lp/bugs/model/bugtask.py
@@ -1397,8 +1397,8 @@ class BugTaskSet:
1397 Bug,1397 Bug,
1398 BugTag,1398 BugTag,
1399 )1399 )
1400 bugtask_ids = set(bugtask.id for bugtask in bugtasks)1400 bugtask_ids = {bugtask.id for bugtask in bugtasks}
1401 bug_ids = set(bugtask.bug_id for bugtask in bugtasks)1401 bug_ids = {bugtask.bug_id for bugtask in bugtasks}
1402 tags = IStore(BugTag).find(1402 tags = IStore(BugTag).find(
1403 (BugTag.tag, BugTask.id),1403 (BugTag.tag, BugTask.id),
1404 BugTask.bug == Bug.id,1404 BugTask.bug == Bug.id,
@@ -1418,8 +1418,8 @@ class BugTaskSet:
1418 [bugtask.assignee_id for bugtask in bugtasks] +1418 [bugtask.assignee_id for bugtask in bugtasks] +
1419 [bugtask.bug.ownerID for bugtask in bugtasks])1419 [bugtask.bug.ownerID for bugtask in bugtasks])
1420 people = getUtility(IPersonSet).getPrecachedPersonsFromIDs(people_ids)1420 people = getUtility(IPersonSet).getPrecachedPersonsFromIDs(people_ids)
1421 return dict(1421 return {
1422 (person.id, person) for person in people)1422 person.id: person for person in people}
14231423
1424 def getBugTaskBadgeProperties(self, bugtasks):1424 def getBugTaskBadgeProperties(self, bugtasks):
1425 """See `IBugTaskSet`."""1425 """See `IBugTaskSet`."""
@@ -1427,11 +1427,11 @@ class BugTaskSet:
1427 from lp.bugs.model.bug import Bug1427 from lp.bugs.model.bug import Bug
1428 from lp.bugs.model.bugbranch import BugBranch1428 from lp.bugs.model.bugbranch import BugBranch
14291429
1430 bug_ids = set(bugtask.bug_id for bugtask in bugtasks)1430 bug_ids = {bugtask.bug_id for bugtask in bugtasks}
1431 bug_ids_with_specifications = set(1431 bug_ids_with_specifications = {
1432 int(id) for _, id in getUtility(IXRefSet).findFromMany(1432 int(id) for _, id in getUtility(IXRefSet).findFromMany(
1433 [(u'bug', six.text_type(bug_id)) for bug_id in bug_ids],1433 [(u'bug', six.text_type(bug_id)) for bug_id in bug_ids],
1434 types=[u'specification']).keys())1434 types=[u'specification']).keys()}
1435 bug_ids_with_branches = set(IStore(BugBranch).find(1435 bug_ids_with_branches = set(IStore(BugBranch).find(
1436 BugBranch.bug_id, BugBranch.bug_id.is_in(bug_ids)))1436 BugBranch.bug_id, BugBranch.bug_id.is_in(bug_ids)))
1437 # Badging looks up milestones too : eager load into the storm cache.1437 # Badging looks up milestones too : eager load into the storm cache.
@@ -1445,9 +1445,9 @@ class BugTaskSet:
1445 # Check if the bugs are cached. If not, cache all uncached bugs1445 # Check if the bugs are cached. If not, cache all uncached bugs
1446 # at once to avoid one query per bugtask. We could rely on the1446 # at once to avoid one query per bugtask. We could rely on the
1447 # Storm cache, but this is explicit.1447 # Storm cache, but this is explicit.
1448 bugs = dict(1448 bugs = {
1449 (bug.id, bug)1449 bug.id: bug
1450 for bug in IStore(Bug).find(Bug, Bug.id.is_in(bug_ids)).cached())1450 for bug in IStore(Bug).find(Bug, Bug.id.is_in(bug_ids)).cached()}
1451 uncached_ids = bug_ids.difference(bug_id for bug_id in bugs)1451 uncached_ids = bug_ids.difference(bug_id for bug_id in bugs)
1452 if len(uncached_ids) > 0:1452 if len(uncached_ids) > 0:
1453 bugs.update(dict(IStore(Bug).find((Bug.id, Bug),1453 bugs.update(dict(IStore(Bug).find((Bug.id, Bug),
@@ -1474,7 +1474,7 @@ class BugTaskSet:
1474 # Query the database, returning the results in a dictionary:1474 # Query the database, returning the results in a dictionary:
1475 if len(task_ids) > 0:1475 if len(task_ids) > 0:
1476 tasks = IStore(BugTask).find(BugTask, BugTask.id.is_in(task_ids))1476 tasks = IStore(BugTask).find(BugTask, BugTask.id.is_in(task_ids))
1477 return dict([(task.id, task) for task in tasks])1477 return {task.id: task for task in tasks}
1478 else:1478 else:
1479 return {}1479 return {}
14801480
@@ -1715,9 +1715,9 @@ class BugTaskSet:
1715 privacy=bug_privacy_filter)1715 privacy=bug_privacy_filter)
1716 cur = cursor()1716 cur = cursor()
1717 cur.execute(query)1717 cur.execute(query)
1718 return dict(1718 return {
1719 (get_bugtask_status(status_id), count)1719 get_bugtask_status(status_id): count
1720 for (status_id, count) in cur.fetchall())1720 for (status_id, count) in cur.fetchall()}
17211721
1722 def findExpirableBugTasks(self, min_days_old, user,1722 def findExpirableBugTasks(self, min_days_old, user,
1723 bug=None, target=None, limit=None):1723 bug=None, target=None, limit=None):
@@ -1894,7 +1894,7 @@ class BugTaskSet:
1894 def getBugCountsForPackages(self, user, packages):1894 def getBugCountsForPackages(self, user, packages):
1895 """See `IBugTaskSet`."""1895 """See `IBugTaskSet`."""
1896 distributions = sorted(1896 distributions = sorted(
1897 set(package.distribution for package in packages),1897 {package.distribution for package in packages},
1898 key=attrgetter('name'))1898 key=attrgetter('name'))
1899 counts = []1899 counts = []
1900 for distribution in distributions:1900 for distribution in distributions:
@@ -1955,9 +1955,9 @@ class BugTaskSet:
19551955
1956 # Only packages with open bugs were included in the query. Let's1956 # Only packages with open bugs were included in the query. Let's
1957 # add the rest of the packages as well.1957 # add the rest of the packages as well.
1958 all_packages = set(1958 all_packages = {
1959 (distro_package.distribution, distro_package.sourcepackagename)1959 (distro_package.distribution, distro_package.sourcepackagename)
1960 for distro_package in packages)1960 for distro_package in packages}
1961 for distribution, sourcepackagename in all_packages.difference(1961 for distribution, sourcepackagename in all_packages.difference(
1962 packages_with_bugs):1962 packages_with_bugs):
1963 package_counts = dict(1963 package_counts = dict(
diff --git a/lib/lp/bugs/model/bugtasksearch.py b/lib/lp/bugs/model/bugtasksearch.py
index 4599d67..fd1ec25 100644
--- a/lib/lp/bugs/model/bugtasksearch.py
+++ b/lib/lp/bugs/model/bugtasksearch.py
@@ -558,9 +558,9 @@ def _build_query(params):
558558
559 # It's much faster to query for a single archive, so don't559 # It's much faster to query for a single archive, so don't
560 # include partner unless we have to.560 # include partner unless we have to.
561 archive_ids = set(561 archive_ids = {
562 distroseries.distribution.getArchiveByComponent(c.name).id562 distroseries.distribution.getArchiveByComponent(c.name).id
563 for c in components)563 for c in components}
564564
565 extra_clauses.append(565 extra_clauses.append(
566 BugTaskFlat.sourcepackagename_id.is_in(566 BugTaskFlat.sourcepackagename_id.is_in(
@@ -806,13 +806,13 @@ def _process_order_by(params):
806 else:806 else:
807 in_unique_context = False807 in_unique_context = False
808808
809 unambiguous_cols = set([809 unambiguous_cols = {
810 BugTaskFlat.date_last_updated,810 BugTaskFlat.date_last_updated,
811 BugTaskFlat.datecreated,811 BugTaskFlat.datecreated,
812 BugTaskFlat.bugtask_id,812 BugTaskFlat.bugtask_id,
813 Bug.datecreated,813 Bug.datecreated,
814 BugTask.date_assigned,814 BugTask.date_assigned,
815 ])815 }
816 if in_unique_context:816 if in_unique_context:
817 unambiguous_cols.add(BugTaskFlat.bug)817 unambiguous_cols.add(BugTaskFlat.bug)
818818
@@ -907,7 +907,7 @@ def _build_status_clause(col, status):
907 values = list(status.query_values)907 values = list(status.query_values)
908 # Since INCOMPLETE isn't stored as a single value any more, we need to908 # Since INCOMPLETE isn't stored as a single value any more, we need to
909 # expand it before generating the SQL.909 # expand it before generating the SQL.
910 old = set([BugTaskStatus.INCOMPLETE, BugTaskStatusSearch.INCOMPLETE])910 old = {BugTaskStatus.INCOMPLETE, BugTaskStatusSearch.INCOMPLETE}
911 accepted_values = list(set(values) - old)911 accepted_values = list(set(values) - old)
912 if len(accepted_values) < len(values):912 if len(accepted_values) < len(values):
913 accepted_values.extend(DB_INCOMPLETE_BUGTASK_STATUSES)913 accepted_values.extend(DB_INCOMPLETE_BUGTASK_STATUSES)
@@ -1345,7 +1345,7 @@ def _make_cache_user_can_view_bug(user):
1345 userid = user.id1345 userid = user.id
13461346
1347 def cache_user_can_view_bug(bugtask):1347 def cache_user_can_view_bug(bugtask):
1348 get_property_cache(bugtask.bug)._known_viewers = set([userid])1348 get_property_cache(bugtask.bug)._known_viewers = {userid}
1349 return bugtask1349 return bugtask
1350 return cache_user_can_view_bug1350 return cache_user_can_view_bug
13511351
diff --git a/lib/lp/bugs/model/bugtracker.py b/lib/lp/bugs/model/bugtracker.py
index d89145d..57edcb6 100644
--- a/lib/lp/bugs/model/bugtracker.py
+++ b/lib/lp/bugs/model/bugtracker.py
@@ -558,7 +558,7 @@ class BugTracker(SQLBase):
558558
559 def _get_aliases(self):559 def _get_aliases(self):
560 """See `IBugTracker.aliases`."""560 """See `IBugTracker.aliases`."""
561 alias_urls = set(alias.base_url for alias in self._bugtracker_aliases)561 alias_urls = {alias.base_url for alias in self._bugtracker_aliases}
562 # Although it does no harm if the current baseurl is also an562 # Although it does no harm if the current baseurl is also an
563 # alias, we hide it and all its permutations to avoid563 # alias, we hide it and all its permutations to avoid
564 # confusion.564 # confusion.
@@ -572,8 +572,8 @@ class BugTracker(SQLBase):
572 else:572 else:
573 alias_urls = set(alias_urls)573 alias_urls = set(alias_urls)
574574
575 current_aliases_by_url = dict(575 current_aliases_by_url = {
576 (alias.base_url, alias) for alias in self._bugtracker_aliases)576 alias.base_url: alias for alias in self._bugtracker_aliases}
577 # Make a set of the keys, i.e. a set of current URLs.577 # Make a set of the keys, i.e. a set of current URLs.
578 current_alias_urls = set(current_aliases_by_url)578 current_alias_urls = set(current_aliases_by_url)
579579
diff --git a/lib/lp/bugs/model/cve.py b/lib/lp/bugs/model/cve.py
index 7e37d78..07c26db 100644
--- a/lib/lp/bugs/model/cve.py
+++ b/lib/lp/bugs/model/cve.py
@@ -203,10 +203,10 @@ class CveSet:
203 Cve, Cve.sequence.is_in([seq for _, seq in bugcve_ids]))203 Cve, Cve.sequence.is_in([seq for _, seq in bugcve_ids]))
204204
205 if cve_mapper is None:205 if cve_mapper is None:
206 cvemap = dict((cve.sequence, cve) for cve in cves)206 cvemap = {cve.sequence: cve for cve in cves}
207 else:207 else:
208 cvemap = dict((cve.sequence, cve_mapper(cve)) for cve in cves)208 cvemap = {cve.sequence: cve_mapper(cve) for cve in cves}
209 bugmap = dict((bug.id, bug) for bug in bugs)209 bugmap = {bug.id: bug for bug in bugs}
210 return [210 return [
211 (bugmap[bug_id], cvemap[cve_sequence])211 (bugmap[bug_id], cvemap[cve_sequence])
212 for bug_id, cve_sequence in bugcve_ids212 for bug_id, cve_sequence in bugcve_ids
diff --git a/lib/lp/bugs/model/personsubscriptioninfo.py b/lib/lp/bugs/model/personsubscriptioninfo.py
index a5a6651..d0da76e 100644
--- a/lib/lp/bugs/model/personsubscriptioninfo.py
+++ b/lib/lp/bugs/model/personsubscriptioninfo.py
@@ -267,9 +267,9 @@ class PersonSubscriptions(object):
267 'subscription': get_id(info.subscription),267 'subscription': get_id(info.subscription),
268 'principal_is_reporter': info.principal_is_reporter,268 'principal_is_reporter': info.principal_is_reporter,
269 # We won't add bugtasks yet unless we need them.269 # We won't add bugtasks yet unless we need them.
270 'bug_supervisor_pillars': sorted(set(270 'bug_supervisor_pillars': sorted({
271 get_id(d['pillar']) for d271 get_id(d['pillar']) for d
272 in info.bug_supervisor_tasks)),272 in info.bug_supervisor_tasks}),
273 }273 }
274 direct = {}274 direct = {}
275 from_duplicate = {}275 from_duplicate = {}
diff --git a/lib/lp/bugs/model/structuralsubscription.py b/lib/lp/bugs/model/structuralsubscription.py
index 8f02d00..c964d95 100644
--- a/lib/lp/bugs/model/structuralsubscription.py
+++ b/lib/lp/bugs/model/structuralsubscription.py
@@ -563,7 +563,7 @@ def _get_structural_subscriptions(find, targets, *conditions):
563 get_structural_subscription_targets.563 get_structural_subscription_targets.
564 :param conditions: additional conditions to filter the results.564 :param conditions: additional conditions to filter the results.
565 """565 """
566 targets = set(target for bugtask, target in targets)566 targets = {target for bugtask, target in targets}
567 target_descriptions = [567 target_descriptions = [
568 IStructuralSubscriptionTargetHelper(bugtarget).join568 IStructuralSubscriptionTargetHelper(bugtarget).join
569 for bugtarget in targets]569 for bugtarget in targets]
diff --git a/lib/lp/bugs/model/tests/test_bug.py b/lib/lp/bugs/model/tests/test_bug.py
index 3ce02e0..d5bda2a 100644
--- a/lib/lp/bugs/model/tests/test_bug.py
+++ b/lib/lp/bugs/model/tests/test_bug.py
@@ -133,7 +133,7 @@ class TestBug(TestCaseWithFactory):
133 bug.subscribe(team2, person)133 bug.subscribe(team2, person)
134 bug.subscribe(person, person)134 bug.subscribe(person, person)
135 self.assertEqual(135 self.assertEqual(
136 set([person, team1, team2]),136 {person, team1, team2},
137 set(bug.getSubscribersForPerson(person)))137 set(bug.getSubscribersForPerson(person)))
138138
139 def test_get_subscribers_for_person_from_duplicates_too(self):139 def test_get_subscribers_for_person_from_duplicates_too(self):
@@ -148,7 +148,7 @@ class TestBug(TestCaseWithFactory):
148 bug.subscribe(person, person)148 bug.subscribe(person, person)
149 bug.markAsDuplicate(real_bug)149 bug.markAsDuplicate(real_bug)
150 self.assertEqual(150 self.assertEqual(
151 set([person, team1, team2]),151 {person, team1, team2},
152 set(real_bug.getSubscribersForPerson(person)))152 set(real_bug.getSubscribersForPerson(person)))
153153
154 def test_getSubscriptionsFromDuplicates(self):154 def test_getSubscriptionsFromDuplicates(self):
@@ -704,9 +704,9 @@ class TestBugPrivateAndSecurityRelatedUpdatesProject(TestCaseWithFactory):
704704
705 (bug, bug_owner, bugtask_a, bugtask_b, default_bugtask) = (705 (bug, bug_owner, bugtask_a, bugtask_b, default_bugtask) = (
706 self.createBugTasksAndSubscribers())706 self.createBugTasksAndSubscribers())
707 initial_subscribers = set((707 initial_subscribers = {
708 self.factory.makePerson(name='subscriber'), bugtask_a.owner,708 self.factory.makePerson(name='subscriber'), bugtask_a.owner,
709 bug_owner))709 bug_owner}
710 initial_subscribers.update(bug.getDirectSubscribers())710 initial_subscribers.update(bug.getDirectSubscribers())
711711
712 with person_logged_in(bug_owner):712 with person_logged_in(bug_owner):
@@ -726,8 +726,8 @@ class TestBugPrivateAndSecurityRelatedUpdatesProject(TestCaseWithFactory):
726726
727 (bug, bug_owner, bugtask_a, bugtask_b, default_bugtask) = (727 (bug, bug_owner, bugtask_a, bugtask_b, default_bugtask) = (
728 self.createBugTasksAndSubscribers())728 self.createBugTasksAndSubscribers())
729 initial_subscribers = set((729 initial_subscribers = {
730 self.factory.makePerson(name='subscriber'), bug_owner))730 self.factory.makePerson(name='subscriber'), bug_owner}
731731
732 with person_logged_in(bug_owner):732 with person_logged_in(bug_owner):
733 for subscriber in initial_subscribers:733 for subscriber in initial_subscribers:
@@ -745,9 +745,9 @@ class TestBugPrivateAndSecurityRelatedUpdatesProject(TestCaseWithFactory):
745745
746 (bug, bug_owner, bugtask_a, bugtask_b, default_bugtask) = (746 (bug, bug_owner, bugtask_a, bugtask_b, default_bugtask) = (
747 self.createBugTasksAndSubscribers(private_security_related=True))747 self.createBugTasksAndSubscribers(private_security_related=True))
748 initial_subscribers = set((748 initial_subscribers = {
749 self.factory.makePerson(), bug_owner, bugtask_a.pillar.driver,749 self.factory.makePerson(), bug_owner, bugtask_a.pillar.driver,
750 bugtask_a.pillar.bug_supervisor))750 bugtask_a.pillar.bug_supervisor}
751751
752 with person_logged_in(bug_owner):752 with person_logged_in(bug_owner):
753 for subscriber in initial_subscribers:753 for subscriber in initial_subscribers:
@@ -756,7 +756,7 @@ class TestBugPrivateAndSecurityRelatedUpdatesProject(TestCaseWithFactory):
756 bug.transitionToInformationType(756 bug.transitionToInformationType(
757 InformationType.PUBLICSECURITY, who)757 InformationType.PUBLICSECURITY, who)
758 subscribers = bug.getDirectSubscribers()758 subscribers = bug.getDirectSubscribers()
759 expected_subscribers = set((default_bugtask.pillar.driver, bug_owner))759 expected_subscribers = {default_bugtask.pillar.driver, bug_owner}
760 expected_subscribers.update(initial_subscribers)760 expected_subscribers.update(initial_subscribers)
761 self.assertContentEqual(expected_subscribers, subscribers)761 self.assertContentEqual(expected_subscribers, subscribers)
762762
@@ -766,9 +766,9 @@ class TestBugPrivateAndSecurityRelatedUpdatesProject(TestCaseWithFactory):
766766
767 (bug, bug_owner, bugtask_a, bugtask_b, default_bugtask) = (767 (bug, bug_owner, bugtask_a, bugtask_b, default_bugtask) = (
768 self.createBugTasksAndSubscribers(private_security_related=True))768 self.createBugTasksAndSubscribers(private_security_related=True))
769 initial_subscribers = set((769 initial_subscribers = {
770 self.factory.makePerson(name='subscriber'), bug_owner,770 self.factory.makePerson(name='subscriber'), bug_owner,
771 bugtask_a.pillar.driver))771 bugtask_a.pillar.driver}
772772
773 with person_logged_in(bug_owner):773 with person_logged_in(bug_owner):
774 for subscriber in initial_subscribers:774 for subscriber in initial_subscribers:
diff --git a/lib/lp/bugs/model/tests/test_bugsubscriptioninfo.py b/lib/lp/bugs/model/tests/test_bugsubscriptioninfo.py
index b3d6a24..9a1ad47 100644
--- a/lib/lp/bugs/model/tests/test_bugsubscriptioninfo.py
+++ b/lib/lp/bugs/model/tests/test_bugsubscriptioninfo.py
@@ -61,9 +61,9 @@ class TestSubscriptionRelatedSets(TestCaseWithFactory):
61 super(TestSubscriptionRelatedSets, self).setUp()61 super(TestSubscriptionRelatedSets, self).setUp()
62 make_person = lambda displayname, name: (62 make_person = lambda displayname, name: (
63 self.factory.makePerson(displayname=displayname, name=name))63 self.factory.makePerson(displayname=displayname, name=name))
64 subscribers = dict(64 subscribers = {
65 (name_pair, make_person(*name_pair))65 name_pair: make_person(*name_pair)
66 for name_pair in self.name_pairs)66 for name_pair in self.name_pairs}
67 self.subscribers_set = frozenset(six.itervalues(subscribers))67 self.subscribers_set = frozenset(six.itervalues(subscribers))
68 self.subscribers_sorted = tuple(68 self.subscribers_sorted = tuple(
69 subscribers[name_pair] for name_pair in self.name_pairs_sorted)69 subscribers[name_pair] for name_pair in self.name_pairs_sorted)
diff --git a/lib/lp/bugs/model/tests/test_bugtask.py b/lib/lp/bugs/model/tests/test_bugtask.py
index e16ca9e..fdf666b 100644
--- a/lib/lp/bugs/model/tests/test_bugtask.py
+++ b/lib/lp/bugs/model/tests/test_bugtask.py
@@ -759,8 +759,8 @@ class TestBugTaskDelta(TestCaseWithFactory):
759 # expected_delta is assumed to be None in the delta.759 # expected_delta is assumed to be None in the delta.
760 delta = bug_task_after.getDelta(bug_task_before)760 delta = bug_task_after.getDelta(bug_task_before)
761 expected_delta.setdefault('bugtask', bug_task_after)761 expected_delta.setdefault('bugtask', bug_task_after)
762 names = set(762 names = {
763 name for interface in providedBy(delta) for name in interface)763 name for interface in providedBy(delta) for name in interface}
764 for name in names:764 for name in names:
765 self.assertEqual(getattr(delta, name), expected_delta.get(name))765 self.assertEqual(getattr(delta, name), expected_delta.get(name))
766766
@@ -3282,8 +3282,8 @@ class TestTargetNameCache(TestCase):
3282 stderr=subprocess.PIPE, universal_newlines=True)3282 stderr=subprocess.PIPE, universal_newlines=True)
3283 (out, err) = process.communicate()3283 (out, err) = process.communicate()
32843284
3285 self.assertTrue(err.startswith(("INFO Creating lockfile: "3285 self.assertTrue(err.startswith("INFO Creating lockfile: "
3286 "/var/lock/launchpad-launchpad-targetnamecacheupdater.lock")))3286 "/var/lock/launchpad-launchpad-targetnamecacheupdater.lock"))
3287 self.assertTrue('INFO Updating targetname cache of bugtasks' in err)3287 self.assertTrue('INFO Updating targetname cache of bugtasks' in err)
3288 self.assertTrue('INFO Calculating targets.' in err)3288 self.assertTrue('INFO Calculating targets.' in err)
3289 self.assertTrue('INFO Will check ' in err)3289 self.assertTrue('INFO Will check ' in err)
diff --git a/lib/lp/bugs/model/tests/test_bugtasksearch.py b/lib/lp/bugs/model/tests/test_bugtasksearch.py
index d4c909f..5357a66 100644
--- a/lib/lp/bugs/model/tests/test_bugtasksearch.py
+++ b/lib/lp/bugs/model/tests/test_bugtasksearch.py
@@ -1775,7 +1775,7 @@ class TestBugTaskSetStatusSearchClauses(TestCase):
1775 # in a "NOT".1775 # in a "NOT".
1776 status = BugTaskStatus.INCOMPLETE1776 status = BugTaskStatus.INCOMPLETE
1777 base_query = self.searchClause(status)1777 base_query = self.searchClause(status)
1778 expected_negative_query = 'NOT ({0})'.format(base_query)1778 expected_negative_query = 'NOT ({})'.format(base_query)
1779 self.assertEqual(1779 self.assertEqual(
1780 expected_negative_query,1780 expected_negative_query,
1781 self.searchClause(not_equals(status)))1781 self.searchClause(not_equals(status)))
diff --git a/lib/lp/bugs/scripts/bugsummaryrebuild.py b/lib/lp/bugs/scripts/bugsummaryrebuild.py
index ab72f5a..58daf6b 100644
--- a/lib/lp/bugs/scripts/bugsummaryrebuild.py
+++ b/lib/lp/bugs/scripts/bugsummaryrebuild.py
@@ -76,9 +76,9 @@ def get_bugtask_targets():
76 )).config(distinct=True))76 )).config(distinct=True))
77 # BugSummary counts package tasks in the packageless totals, so77 # BugSummary counts package tasks in the packageless totals, so
78 # ensure that there's also a packageless total for each distro(series).78 # ensure that there's also a packageless total for each distro(series).
79 new_targets.update(set(79 new_targets.update({
80 (p, ps, d, ds, None, None)80 (p, ps, d, ds, None, None)
81 for (p, ps, d, ds, spn, ocip) in new_targets))81 for (p, ps, d, ds, spn, ocip) in new_targets})
82 return new_targets82 return new_targets
8383
8484
@@ -111,8 +111,8 @@ def format_target(target):
111def _get_bugsummary_constraint_bits(target):111def _get_bugsummary_constraint_bits(target):
112 raw_key = bug_target_to_key(target)112 raw_key = bug_target_to_key(target)
113 # Map to ID columns to work around Storm bug #682989.113 # Map to ID columns to work around Storm bug #682989.
114 return dict(114 return {
115 ('%s_id' % k, v.id if v else None) for (k, v) in raw_key.items())115 '%s_id' % k: v.id if v else None for (k, v) in raw_key.items()}
116116
117117
118def get_bugsummary_constraint(target, cls=RawBugSummary):118def get_bugsummary_constraint(target, cls=RawBugSummary):
@@ -233,10 +233,10 @@ def apply_bugsummary_changes(target, added, updated, removed):
233233
234def rebuild_bugsummary_for_target(target, log):234def rebuild_bugsummary_for_target(target, log):
235 log.debug("Rebuilding %s" % format_target(target))235 log.debug("Rebuilding %s" % format_target(target))
236 existing = dict(236 existing = {
237 (v[:-1], v[-1]) for v in get_bugsummary_rows(target))237 v[:-1]: v[-1] for v in get_bugsummary_rows(target)}
238 expected = dict(238 expected = {
239 (v[:-1], v[-1]) for v in calculate_bugsummary_rows(target))239 v[:-1]: v[-1] for v in calculate_bugsummary_rows(target)}
240 added, updated, removed = calculate_bugsummary_changes(existing, expected)240 added, updated, removed = calculate_bugsummary_changes(existing, expected)
241 if added:241 if added:
242 log.debug('Added %r' % added)242 log.debug('Added %r' % added)
diff --git a/lib/lp/bugs/scripts/checkwatches/core.py b/lib/lp/bugs/scripts/checkwatches/core.py
index c659a77..db59005 100644
--- a/lib/lp/bugs/scripts/checkwatches/core.py
+++ b/lib/lp/bugs/scripts/checkwatches/core.py
@@ -486,9 +486,9 @@ class CheckwatchesMaster(WorkingBase):
486486
487 with self.transaction:487 with self.transaction:
488 reload(bug_watches)488 reload(bug_watches)
489 old_bug_watches = set(489 old_bug_watches = {
490 bug_watch for bug_watch in bug_watches490 bug_watch for bug_watch in bug_watches
491 if bug_watch.lastchecked is not None)491 if bug_watch.lastchecked is not None}
492 if len(old_bug_watches) == 0:492 if len(old_bug_watches) == 0:
493 oldest_lastchecked = None493 oldest_lastchecked = None
494 else:494 else:
@@ -500,10 +500,10 @@ class CheckwatchesMaster(WorkingBase):
500 ACCEPTABLE_TIME_SKEW + timedelta(minutes=1))500 ACCEPTABLE_TIME_SKEW + timedelta(minutes=1))
501 # Collate the remote IDs.501 # Collate the remote IDs.
502 remote_old_ids = sorted(502 remote_old_ids = sorted(
503 set(bug_watch.remotebug for bug_watch in old_bug_watches))503 {bug_watch.remotebug for bug_watch in old_bug_watches})
504 remote_new_ids = sorted(504 remote_new_ids = sorted(
505 set(bug_watch.remotebug for bug_watch in bug_watches505 {bug_watch.remotebug for bug_watch in bug_watches
506 if bug_watch not in old_bug_watches))506 if bug_watch not in old_bug_watches})
507 # If the remote system is not configured to sync comments,507 # If the remote system is not configured to sync comments,
508 # don't bother checking for any to push.508 # don't bother checking for any to push.
509 if remotesystem.sync_comments:509 if remotesystem.sync_comments:
diff --git a/lib/lp/bugs/scripts/tests/test_bugnotification.py b/lib/lp/bugs/scripts/tests/test_bugnotification.py
index d56ddf2..d5ec852 100644
--- a/lib/lp/bugs/scripts/tests/test_bugnotification.py
+++ b/lib/lp/bugs/scripts/tests/test_bugnotification.py
@@ -192,9 +192,9 @@ class FakeBugNotificationSetUtility:
192192
193 def getRecipientFilterData(self, bug, recipient_to_sources,193 def getRecipientFilterData(self, bug, recipient_to_sources,
194 notifications):194 notifications):
195 return dict(195 return {
196 (recipient, {'sources': sources, 'filter descriptions': []})196 recipient: {'sources': sources, 'filter descriptions': []}
197 for recipient, sources in recipient_to_sources.items())197 for recipient, sources in recipient_to_sources.items()}
198198
199199
200class MockBugActivity:200class MockBugActivity:
diff --git a/lib/lp/bugs/tests/externalbugtracker.py b/lib/lp/bugs/tests/externalbugtracker.py
index cdce45f..5caceae 100644
--- a/lib/lp/bugs/tests/externalbugtracker.py
+++ b/lib/lp/bugs/tests/externalbugtracker.py
@@ -115,8 +115,8 @@ def print_bugwatches(bug_watches, convert_remote_status=None):
115 used to convert the watches' remote statuses to Launchpad115 used to convert the watches' remote statuses to Launchpad
116 BugTaskStatuses and these will be output instead.116 BugTaskStatuses and these will be output instead.
117 """117 """
118 watches = dict((int(bug_watch.remotebug), bug_watch)118 watches = {int(bug_watch.remotebug): bug_watch
119 for bug_watch in bug_watches)119 for bug_watch in bug_watches}
120120
121 for remote_bug_id in sorted(watches.keys()):121 for remote_bug_id in sorted(watches.keys()):
122 status = watches[remote_bug_id].remotestatus122 status = watches[remote_bug_id].remotestatus
@@ -542,7 +542,7 @@ class TestBugzillaXMLRPCTransport(RequestsTransport):
542542
543 @property543 @property
544 def auth_cookie(self):544 def auth_cookie(self):
545 if len(set(cookie.domain for cookie in self.cookie_jar)) > 1:545 if len({cookie.domain for cookie in self.cookie_jar}) > 1:
546 raise AssertionError(546 raise AssertionError(
547 "There should only be cookies for one domain.")547 "There should only be cookies for one domain.")
548548
@@ -719,9 +719,9 @@ class TestBugzillaXMLRPCTransport(RequestsTransport):
719719
720 def _copy_comment(self, comment, fields_to_return=None):720 def _copy_comment(self, comment, fields_to_return=None):
721 # Copy wanted fields.721 # Copy wanted fields.
722 return dict(722 return {
723 (key, value) for (key, value) in six.iteritems(comment)723 key: value for (key, value) in six.iteritems(comment)
724 if fields_to_return is None or key in fields_to_return)724 if fields_to_return is None or key in fields_to_return}
725725
726 def comments(self, arguments):726 def comments(self, arguments):
727 """Return comments for a given set of bugs."""727 """Return comments for a given set of bugs."""
@@ -1389,7 +1389,7 @@ class TestTracXMLRPCTransport(RequestsTransport):
1389 # this method. See bugs 203564, 158703 and 158705.1389 # this method. See bugs 203564, 158703 and 158705.
13901390
1391 # We sort the list of bugs for the sake of testing.1391 # We sort the list of bugs for the sake of testing.
1392 bug_ids = sorted([bug_id for bug_id in self.remote_bugs.keys()])1392 bug_ids = sorted(bug_id for bug_id in self.remote_bugs.keys())
1393 bugs_to_return = []1393 bugs_to_return = []
1394 missing_bugs = []1394 missing_bugs = []
13951395
@@ -1476,8 +1476,8 @@ class TestTracXMLRPCTransport(RequestsTransport):
14761476
1477 # For each of the missing ones, return a dict with a type of1477 # For each of the missing ones, return a dict with a type of
1478 # 'missing'.1478 # 'missing'.
1479 comment_ids_to_return = sorted([1479 comment_ids_to_return = sorted(
1480 comment['id'] for comment in comments_to_return])1480 comment['id'] for comment in comments_to_return)
1481 missing_comments = [1481 missing_comments = [
1482 {'id': comment_id, 'type': 'missing'}1482 {'id': comment_id, 'type': 'missing'}
1483 for comment_id in comments1483 for comment_id in comments
diff --git a/lib/lp/bugs/tests/test_bug_messages_webservice.py b/lib/lp/bugs/tests/test_bug_messages_webservice.py
index 44393d5..96c7f2e 100644
--- a/lib/lp/bugs/tests/test_bug_messages_webservice.py
+++ b/lib/lp/bugs/tests/test_bug_messages_webservice.py
@@ -91,16 +91,16 @@ class TestBugMessage(TestCaseWithFactory):
91 # are the same set.91 # are the same set.
92 with admin_logged_in():92 with admin_logged_in():
93 bug = self.factory.makeBug()93 bug = self.factory.makeBug()
94 created_attachment_ids = set(94 created_attachment_ids = {
95 self.factory.makeBugAttachment(bug).id for i in range(3))95 self.factory.makeBugAttachment(bug).id for i in range(3)}
96 bug_url = api_url(bug)96 bug_url = api_url(bug)
97 self.assertThat(created_attachment_ids, HasLength(3))97 self.assertThat(created_attachment_ids, HasLength(3))
9898
99 webservice = webservice_for_person(None)99 webservice = webservice_for_person(None)
100 bug_attachments = webservice.get(100 bug_attachments = webservice.get(
101 bug_url + '/attachments').jsonBody()['entries']101 bug_url + '/attachments').jsonBody()['entries']
102 bug_attachment_ids = set(102 bug_attachment_ids = {
103 int(att['self_link'].rsplit('/', 1)[1]) for att in bug_attachments)103 int(att['self_link'].rsplit('/', 1)[1]) for att in bug_attachments}
104 self.assertContentEqual(created_attachment_ids, bug_attachment_ids)104 self.assertContentEqual(created_attachment_ids, bug_attachment_ids)
105105
106 messages = webservice.get(bug_url + '/messages').jsonBody()['entries']106 messages = webservice.get(bug_url + '/messages').jsonBody()['entries']
@@ -110,9 +110,9 @@ class TestBugMessage(TestCaseWithFactory):
110 attachments = webservice.get(attachments_url).jsonBody()['entries']110 attachments = webservice.get(attachments_url).jsonBody()['entries']
111 self.assertThat(attachments, HasLength(1))111 self.assertThat(attachments, HasLength(1))
112 message_attachments.append(attachments[0])112 message_attachments.append(attachments[0])
113 message_attachment_ids = set(113 message_attachment_ids = {
114 int(att['self_link'].rsplit('/', 1)[1])114 int(att['self_link'].rsplit('/', 1)[1])
115 for att in message_attachments)115 for att in message_attachments}
116 self.assertContentEqual(bug_attachment_ids, message_attachment_ids)116 self.assertContentEqual(bug_attachment_ids, message_attachment_ids)
117117
118118
diff --git a/lib/lp/bugs/tests/test_bugchanges.py b/lib/lp/bugs/tests/test_bugchanges.py
index 5786c0e..71daeab 100644
--- a/lib/lp/bugs/tests/test_bugchanges.py
+++ b/lib/lp/bugs/tests/test_bugchanges.py
@@ -83,9 +83,9 @@ class TestBugChanges(TestCaseWithFactory):
83 if bug is None:83 if bug is None:
84 bug = self.bug84 bug = self.bug
85 old_activities = set(bug.activity)85 old_activities = set(bug.activity)
86 old_notification_ids = set(86 old_notification_ids = {
87 notification.id for notification in IStore(BugNotification).find(87 notification.id for notification in IStore(BugNotification).find(
88 BugNotification, bug=bug))88 BugNotification, bug=bug)}
8989
90 if append:90 if append:
91 self.old_activities.update(old_activities)91 self.old_activities.update(old_activities)
@@ -173,23 +173,23 @@ class TestBugChanges(TestCaseWithFactory):
173 level=BugNotificationLevel.METADATA)173 level=BugNotificationLevel.METADATA)
174 self.assertEqual(174 self.assertEqual(
175 set(expected_recipients),175 set(expected_recipients),
176 set(recipient.person176 {recipient.person
177 for recipient in added_notification.recipients))177 for recipient in added_notification.recipients})
178 if expected_recipient_reasons:178 if expected_recipient_reasons:
179 self.assertEqual(179 self.assertEqual(
180 set(expected_recipient_reasons),180 set(expected_recipient_reasons),
181 set(recipient.reason_header181 {recipient.reason_header
182 for recipient in added_notification.recipients))182 for recipient in added_notification.recipients})
183183
184 def assertRecipients(self, expected_recipients):184 def assertRecipients(self, expected_recipients):
185 notifications = self.getNewNotifications()185 notifications = self.getNewNotifications()
186 notifications, omitted, messages = construct_email_notifications(186 notifications, omitted, messages = construct_email_notifications(
187 notifications)187 notifications)
188 recipients = set(message['to'] for message in messages)188 recipients = {message['to'] for message in messages}
189189
190 self.assertEqual(190 self.assertEqual(
191 set(recipient.preferredemail.email191 {recipient.preferredemail.email
192 for recipient in expected_recipients),192 for recipient in expected_recipients},
193 recipients)193 recipients)
194194
195 def test_subscribe(self):195 def test_subscribe(self):
diff --git a/lib/lp/bugs/tests/test_bugnotification.py b/lib/lp/bugs/tests/test_bugnotification.py
index c1d673e..e58328d 100644
--- a/lib/lp/bugs/tests/test_bugnotification.py
+++ b/lib/lp/bugs/tests/test_bugnotification.py
@@ -373,9 +373,9 @@ class TestNotificationsForDuplicates(TestCaseWithFactory):
373 self.dupe_bug.owner, subject='subject', content='content')373 self.dupe_bug.owner, subject='subject', content='content')
374 latest_notification = IStore(BugNotification).find(374 latest_notification = IStore(BugNotification).find(
375 BugNotification).order_by(BugNotification.id).last()375 BugNotification).order_by(BugNotification.id).last()
376 recipients = set(376 recipients = {
377 recipient.person377 recipient.person
378 for recipient in latest_notification.recipients)378 for recipient in latest_notification.recipients}
379 self.assertEqual(self.dupe_subscribers, recipients)379 self.assertEqual(self.dupe_subscribers, recipients)
380380
381 def test_duplicate_edit_notifications(self):381 def test_duplicate_edit_notifications(self):
@@ -385,9 +385,9 @@ class TestNotificationsForDuplicates(TestCaseWithFactory):
385 self.dupe_bug.description = 'A changed description'385 self.dupe_bug.description = 'A changed description'
386 latest_notification = IStore(BugNotification).find(386 latest_notification = IStore(BugNotification).find(
387 BugNotification).order_by(BugNotification.id).last()387 BugNotification).order_by(BugNotification.id).last()
388 recipients = set(388 recipients = {
389 recipient.person389 recipient.person
390 for recipient in latest_notification.recipients)390 for recipient in latest_notification.recipients}
391 self.assertEqual(self.dupe_subscribers, recipients)391 self.assertEqual(self.dupe_subscribers, recipients)
392392
393 def test_branch_linked_notification(self):393 def test_branch_linked_notification(self):
@@ -400,9 +400,9 @@ class TestNotificationsForDuplicates(TestCaseWithFactory):
400 self.dupe_bug.linkBranch(branch, self.dupe_bug.owner)400 self.dupe_bug.linkBranch(branch, self.dupe_bug.owner)
401 latest_notification = IStore(BugNotification).find(401 latest_notification = IStore(BugNotification).find(
402 BugNotification).order_by(BugNotification.id).last()402 BugNotification).order_by(BugNotification.id).last()
403 recipients = set(403 recipients = {
404 recipient.person404 recipient.person
405 for recipient in latest_notification.recipients)405 for recipient in latest_notification.recipients}
406 self.assertEqual(self.dupe_subscribers, recipients)406 self.assertEqual(self.dupe_subscribers, recipients)
407407
408408
diff --git a/lib/lp/bugs/tests/test_bugwatch.py b/lib/lp/bugs/tests/test_bugwatch.py
index 7b1ac7c..6dca2df 100644
--- a/lib/lp/bugs/tests/test_bugwatch.py
+++ b/lib/lp/bugs/tests/test_bugwatch.py
@@ -584,7 +584,7 @@ class TestBugWatchSetBulkOperations(TestCaseWithFactory):
584 def test_bulkAddActivity_with_iterator(self):584 def test_bulkAddActivity_with_iterator(self):
585 # Any iterator can be passed in.585 # Any iterator can be passed in.
586 getUtility(IBugWatchSet).bulkAddActivity(586 getUtility(IBugWatchSet).bulkAddActivity(
587 (bug_watch for bug_watch in self.bug_watches))587 bug_watch for bug_watch in self.bug_watches)
588 self._checkActivityForBugWatches(588 self._checkActivityForBugWatches(
589 BugWatchActivityStatus.SYNC_SUCCEEDED, None, None)589 BugWatchActivityStatus.SYNC_SUCCEEDED, None, None)
590590
diff --git a/lib/lp/bugs/tests/test_structuralsubscription.py b/lib/lp/bugs/tests/test_structuralsubscription.py
index 334cfcf..d67bba2 100644
--- a/lib/lp/bugs/tests/test_structuralsubscription.py
+++ b/lib/lp/bugs/tests/test_structuralsubscription.py
@@ -491,8 +491,8 @@ class TestGetStructuralSubscriptionTargets(TestCaseWithFactory):
491 bug = self.factory.makeBug(target=product, milestone=milestone)491 bug = self.factory.makeBug(target=product, milestone=milestone)
492 bugtask = bug.bugtasks[0]492 bugtask = bug.bugtasks[0]
493 result = get_structural_subscription_targets(bug.bugtasks)493 result = get_structural_subscription_targets(bug.bugtasks)
494 self.assertEqual(set(result), set(494 self.assertEqual(set(result), {
495 ((bugtask, product), (bugtask, milestone))))495 (bugtask, product), (bugtask, milestone)})
496496
497 def test_sourcepackage_target(self):497 def test_sourcepackage_target(self):
498 actor = self.factory.makePerson()498 actor = self.factory.makePerson()
@@ -506,9 +506,9 @@ class TestGetStructuralSubscriptionTargets(TestCaseWithFactory):
506 product_bugtask = bug.bugtasks[0]506 product_bugtask = bug.bugtasks[0]
507 sourcepackage_bugtask = bug.bugtasks[1]507 sourcepackage_bugtask = bug.bugtasks[1]
508 result = get_structural_subscription_targets(bug.bugtasks)508 result = get_structural_subscription_targets(bug.bugtasks)
509 self.assertEqual(set(result), set(509 self.assertEqual(set(result), {
510 ((product_bugtask, product),510 (product_bugtask, product),
511 (sourcepackage_bugtask, distroseries))))511 (sourcepackage_bugtask, distroseries)})
512512
513 def test_distribution_source_package_target(self):513 def test_distribution_source_package_target(self):
514 actor = self.factory.makePerson()514 actor = self.factory.makePerson()
@@ -522,10 +522,10 @@ class TestGetStructuralSubscriptionTargets(TestCaseWithFactory):
522 product_bugtask = bug.bugtasks[0]522 product_bugtask = bug.bugtasks[0]
523 dist_sourcepackage_bugtask = bug.bugtasks[1]523 dist_sourcepackage_bugtask = bug.bugtasks[1]
524 result = get_structural_subscription_targets(bug.bugtasks)524 result = get_structural_subscription_targets(bug.bugtasks)
525 self.assertEqual(set(result), set(525 self.assertEqual(set(result), {
526 ((product_bugtask, product),526 (product_bugtask, product),
527 (dist_sourcepackage_bugtask, dist_sourcepackage),527 (dist_sourcepackage_bugtask, dist_sourcepackage),
528 (dist_sourcepackage_bugtask, distribution))))528 (dist_sourcepackage_bugtask, distribution)})
529529
530 def test_product_with_project_group(self):530 def test_product_with_project_group(self):
531 # get_structural_subscription_targets() will yield both a531 # get_structural_subscription_targets() will yield both a
@@ -541,7 +541,7 @@ class TestGetStructuralSubscriptionTargets(TestCaseWithFactory):
541 bug = self.factory.makeBug(target=product)541 bug = self.factory.makeBug(target=product)
542 result = get_structural_subscription_targets(bug.bugtasks)542 result = get_structural_subscription_targets(bug.bugtasks)
543 self.assertEqual(543 self.assertEqual(
544 set([(bug.bugtasks[0], product), (bug.bugtasks[0], projectgroup)]),544 {(bug.bugtasks[0], product), (bug.bugtasks[0], projectgroup)},
545 set(result))545 set(result))
546546
547547
@@ -580,7 +580,7 @@ class TestGetStructuralSubscriptionsForBug(TestCaseWithFactory):
580 sub2 = self.milestone.addBugSubscription(580 sub2 = self.milestone.addBugSubscription(
581 self.subscriber, self.subscriber)581 self.subscriber, self.subscriber)
582 subscriptions = self.getSubscriptions(self.subscriber)582 subscriptions = self.getSubscriptions(self.subscriber)
583 self.assertEqual(set([sub1, sub2]), set(subscriptions))583 self.assertEqual({sub1, sub2}, set(subscriptions))
584584
585 def test_two_bugtasks_one_subscription(self):585 def test_two_bugtasks_one_subscription(self):
586 sub = self.product.addBugSubscription(586 sub = self.product.addBugSubscription(
@@ -598,7 +598,7 @@ class TestGetStructuralSubscriptionsForBug(TestCaseWithFactory):
598 sub2 = product2.addBugSubscription(598 sub2 = product2.addBugSubscription(
599 self.subscriber, self.subscriber)599 self.subscriber, self.subscriber)
600 subscriptions = self.getSubscriptions(self.subscriber)600 subscriptions = self.getSubscriptions(self.subscriber)
601 self.assertEqual(set([sub1, sub2]), set(subscriptions))601 self.assertEqual({sub1, sub2}, set(subscriptions))
602602
603 def test_ignore_other_subscriptions(self):603 def test_ignore_other_subscriptions(self):
604 sub1 = self.product.addBugSubscription(604 sub1 = self.product.addBugSubscription(
@@ -626,7 +626,7 @@ class TestGetStructuralSubscriptionsForBug(TestCaseWithFactory):
626 team_sub = self.product.addBugSubscription(626 team_sub = self.product.addBugSubscription(
627 self.team, self.team.teamowner)627 self.team, self.team.teamowner)
628 subscriptions = self.getSubscriptions(self.subscriber)628 subscriptions = self.getSubscriptions(self.subscriber)
629 self.assertEqual(set([self_sub, team_sub]), set(subscriptions))629 self.assertEqual({self_sub, team_sub}, set(subscriptions))
630630
631 def test_subscriptions_from_parent(self):631 def test_subscriptions_from_parent(self):
632 # get_structural_subscriptions_for_bug() will return any632 # get_structural_subscriptions_for_bug() will return any
@@ -642,7 +642,7 @@ class TestGetStructuralSubscriptionsForBug(TestCaseWithFactory):
642 bug = self.factory.makeBug(target=product)642 bug = self.factory.makeBug(target=product)
643 subscriptions = get_structural_subscriptions_for_bug(643 subscriptions = get_structural_subscriptions_for_bug(
644 bug, subscriber)644 bug, subscriber)
645 self.assertEqual(set([self_sub]), set(subscriptions))645 self.assertEqual({self_sub}, set(subscriptions))
646646
647647
648class TestGetStructuralSubscriptions(TestCaseWithFactory):648class TestGetStructuralSubscriptions(TestCaseWithFactory):
@@ -783,7 +783,7 @@ class TestGetStructuralSubscribers(TestCaseWithFactory):
783783
784 subscribers = get_structural_subscribers(bug, None, None, None)784 subscribers = get_structural_subscribers(bug, None, None, None)
785 self.assertIsInstance(subscribers, RESULT_SETS)785 self.assertIsInstance(subscribers, RESULT_SETS)
786 self.assertEqual(set([subscriber1, subscriber2]), set(subscribers))786 self.assertEqual({subscriber1, subscriber2}, set(subscribers))
787787
788 def test_getStructuralSubscribers_recipients(self):788 def test_getStructuralSubscribers_recipients(self):
789 # If provided, get_structural_subscribers() calls the appropriate789 # If provided, get_structural_subscribers() calls the appropriate
diff --git a/lib/lp/bugs/tests/test_structuralsubscriptiontarget.py b/lib/lp/bugs/tests/test_structuralsubscriptiontarget.py
index 9d75005..696d7c5 100644
--- a/lib/lp/bugs/tests/test_structuralsubscriptiontarget.py
+++ b/lib/lp/bugs/tests/test_structuralsubscriptiontarget.py
@@ -473,7 +473,7 @@ class TestGetAllStructuralSubscriptionsForTarget(TestCaseWithFactory):
473 team_sub = self.product.addBugSubscription(473 team_sub = self.product.addBugSubscription(
474 self.team, self.team.teamowner)474 self.team, self.team.teamowner)
475 subscriptions = self.getSubscriptions()475 subscriptions = self.getSubscriptions()
476 self.assertEqual(set([self_sub, team_sub]), set(subscriptions))476 self.assertEqual({self_sub, team_sub}, set(subscriptions))
477477
478 def test_subscribed_to_project_group(self):478 def test_subscribed_to_project_group(self):
479 # If a user is subscribed to a project group, calls to479 # If a user is subscribed to a project group, calls to
@@ -486,7 +486,7 @@ class TestGetAllStructuralSubscriptionsForTarget(TestCaseWithFactory):
486 self.subscriber, self.subscriber)486 self.subscriber, self.subscriber)
487 subscriptions = get_structural_subscriptions_for_target(487 subscriptions = get_structural_subscriptions_for_target(
488 product, self.subscriber)488 product, self.subscriber)
489 self.assertEqual(set([projectgroup_sub]), set(subscriptions))489 self.assertEqual({projectgroup_sub}, set(subscriptions))
490490
491491
492def distributionSourcePackageSetUp(test):492def distributionSourcePackageSetUp(test):
diff --git a/lib/lp/bugs/vocabularies.py b/lib/lp/bugs/vocabularies.py
index 8801a71..b4e5f2d 100644
--- a/lib/lp/bugs/vocabularies.py
+++ b/lib/lp/bugs/vocabularies.py
@@ -352,8 +352,8 @@ class BugTaskMilestoneVocabulary:
352 self.default_bugtask = default_bugtask352 self.default_bugtask = default_bugtask
353 self._milestones = None353 self._milestones = None
354 if milestones is not None:354 if milestones is not None:
355 self._milestones = dict(355 self._milestones = {
356 (str(milestone.id), milestone) for milestone in milestones)356 str(milestone.id): milestone for milestone in milestones}
357357
358 def _load_milestones(self, bugtask):358 def _load_milestones(self, bugtask):
359 # If the milestones have not already been cached, load them for the359 # If the milestones have not already been cached, load them for the
@@ -362,8 +362,8 @@ class BugTaskMilestoneVocabulary:
362 bugtask_set = getUtility(IBugTaskSet)362 bugtask_set = getUtility(IBugTaskSet)
363 milestones = list(363 milestones = list(
364 bugtask_set.getBugTaskTargetMilestones([bugtask]))364 bugtask_set.getBugTaskTargetMilestones([bugtask]))
365 self._milestones = dict(365 self._milestones = {
366 (str(milestone.id), milestone) for milestone in milestones)366 str(milestone.id): milestone for milestone in milestones}
367 return self._milestones367 return self._milestones
368368
369 @property369 @property
diff --git a/lib/lp/buildmaster/manager.py b/lib/lp/buildmaster/manager.py
index f893d85..9cec957 100644
--- a/lib/lp/buildmaster/manager.py
+++ b/lib/lp/buildmaster/manager.py
@@ -140,9 +140,9 @@ class PrefetchedBuildCandidates:
140 # each builder group, and then re-sort the combined list in exactly140 # each builder group, and then re-sort the combined list in exactly
141 # the same way.141 # the same way.
142 grouped_candidates = sorted(142 grouped_candidates = sorted(
143 [(builder_group_key, self.candidates[builder_group_key][0])143 ((builder_group_key, self.candidates[builder_group_key][0])
144 for builder_group_key in builder_group_keys144 for builder_group_key in builder_group_keys
145 if self.candidates[builder_group_key]],145 if self.candidates[builder_group_key]),
146 key=lambda key_candidate: self.sort_keys[key_candidate[1]])146 key=lambda key_candidate: self.sort_keys[key_candidate[1]])
147 if grouped_candidates:147 if grouped_candidates:
148 builder_group_key, candidate_id = grouped_candidates[0]148 builder_group_key, candidate_id = grouped_candidates[0]
@@ -264,9 +264,9 @@ class PrefetchedBuilderFactory(BaseBuilderFactory):
264 ).find((Builder, BuildQueue)))264 ).find((Builder, BuildQueue)))
265 getUtility(IBuilderSet).preloadProcessors(265 getUtility(IBuilderSet).preloadProcessors(
266 [b for b, _ in builders_and_current_bqs])266 [b for b, _ in builders_and_current_bqs])
267 self.vitals_map = dict(267 self.vitals_map = {
268 (b.name, extract_vitals_from_db(b, bq))268 b.name: extract_vitals_from_db(b, bq)
269 for b, bq in builders_and_current_bqs)269 for b, bq in builders_and_current_bqs}
270 self.candidates = PrefetchedBuildCandidates(270 self.candidates = PrefetchedBuildCandidates(
271 list(self.vitals_map.values()))271 list(self.vitals_map.values()))
272 transaction.abort()272 transaction.abort()
@@ -736,8 +736,8 @@ class BuilddManager(service.Service):
736736
737 def checkForNewBuilders(self):737 def checkForNewBuilders(self):
738 """Add and return any new builders."""738 """Add and return any new builders."""
739 new_builders = set(739 new_builders = {
740 vitals.name for vitals in self.builder_factory.iterVitals())740 vitals.name for vitals in self.builder_factory.iterVitals()}
741 old_builders = set(self.current_builders)741 old_builders = set(self.current_builders)
742 extra_builders = new_builders.difference(old_builders)742 extra_builders = new_builders.difference(old_builders)
743 self.current_builders.extend(extra_builders)743 self.current_builders.extend(extra_builders)
diff --git a/lib/lp/buildmaster/model/buildqueue.py b/lib/lp/buildmaster/model/buildqueue.py
index ac1ece2..6556b64 100644
--- a/lib/lp/buildmaster/model/buildqueue.py
+++ b/lib/lp/buildmaster/model/buildqueue.py
@@ -141,7 +141,7 @@ class BuildQueue(StormBase):
141 from lp.buildmaster.model.buildfarmjob import BuildFarmJob141 from lp.buildmaster.model.buildfarmjob import BuildFarmJob
142 queues = [removeSecurityProxy(bq) for bq in queues]142 queues = [removeSecurityProxy(bq) for bq in queues]
143 load_related(BuildFarmJob, queues, ['_build_farm_job_id'])143 load_related(BuildFarmJob, queues, ['_build_farm_job_id'])
144 bfj_to_bq = dict((bq._build_farm_job, bq) for bq in queues)144 bfj_to_bq = {bq._build_farm_job: bq for bq in queues}
145 key = attrgetter('_build_farm_job.job_type')145 key = attrgetter('_build_farm_job.job_type')
146 for job_type, group in groupby(sorted(queues, key=key), key=key):146 for job_type, group in groupby(sorted(queues, key=key), key=key):
147 source = getUtility(ISpecificBuildFarmJobSource, job_type.name)147 source = getUtility(ISpecificBuildFarmJobSource, job_type.name)
@@ -267,8 +267,8 @@ class BuildQueueSet(object):
267 def preloadForBuilders(self, builders):267 def preloadForBuilders(self, builders):
268 # Populate builders' currentjob cachedproperty.268 # Populate builders' currentjob cachedproperty.
269 queues = load_referencing(BuildQueue, builders, ['builder_id'])269 queues = load_referencing(BuildQueue, builders, ['builder_id'])
270 queue_builders = dict(270 queue_builders = {
271 (queue.builder_id, queue) for queue in queues)271 queue.builder_id: queue for queue in queues}
272 for builder in builders:272 for builder in builders:
273 cache = get_property_cache(builder)273 cache = get_property_cache(builder)
274 cache.currentjob = queue_builders.get(builder.id, None)274 cache.currentjob = queue_builders.get(builder.id, None)
@@ -282,9 +282,9 @@ class BuildQueueSet(object):
282 BuildQueue._build_farm_job_id.is_in(282 BuildQueue._build_farm_job_id.is_in(
283 [removeSecurityProxy(b).build_farm_job_id for b in builds])))283 [removeSecurityProxy(b).build_farm_job_id for b in builds])))
284 load_related(Builder, bqs, ['builder_id'])284 load_related(Builder, bqs, ['builder_id'])
285 prefetched_data = dict(285 prefetched_data = {
286 (removeSecurityProxy(buildqueue)._build_farm_job_id, buildqueue)286 removeSecurityProxy(buildqueue)._build_farm_job_id: buildqueue
287 for buildqueue in bqs)287 for buildqueue in bqs}
288 for build in builds:288 for build in builds:
289 bq = prefetched_data.get(289 bq = prefetched_data.get(
290 removeSecurityProxy(build).build_farm_job_id)290 removeSecurityProxy(build).build_farm_job_id)
diff --git a/lib/lp/buildmaster/tests/test_manager.py b/lib/lp/buildmaster/tests/test_manager.py
index fd84f13..cd02bce 100644
--- a/lib/lp/buildmaster/tests/test_manager.py
+++ b/lib/lp/buildmaster/tests/test_manager.py
@@ -1214,10 +1214,10 @@ class TestBuilddManager(TestCase):
1214 self._stub_out_scheduleNextScanCycle()1214 self._stub_out_scheduleNextScanCycle()
12151215
1216 manager = BuilddManager()1216 manager = BuilddManager()
1217 builder_names = set(1217 builder_names = {
1218 builder.name for builder in getUtility(IBuilderSet))1218 builder.name for builder in getUtility(IBuilderSet)}
1219 scanners = manager.addScanForBuilders(builder_names)1219 scanners = manager.addScanForBuilders(builder_names)
1220 scanner_names = set(scanner.builder_name for scanner in scanners)1220 scanner_names = {scanner.builder_name for scanner in scanners}
1221 self.assertEqual(builder_names, scanner_names)1221 self.assertEqual(builder_names, scanner_names)
12221222
1223 def test_startService_adds_scanBuilders_loop(self):1223 def test_startService_adds_scanBuilders_loop(self):
diff --git a/lib/lp/buildmaster/tests/test_webservice.py b/lib/lp/buildmaster/tests/test_webservice.py
index 34aeb90..d39292d 100644
--- a/lib/lp/buildmaster/tests/test_webservice.py
+++ b/lib/lp/buildmaster/tests/test_webservice.py
@@ -66,8 +66,8 @@ class TestBuildersCollection(TestCaseWithFactory):
6666
67 builders = self.webservice.get(67 builders = self.webservice.get(
68 '/builders', api_version='devel').jsonBody()68 '/builders', api_version='devel').jsonBody()
69 current_builds = dict(69 current_builds = {
70 (b['name'], b['current_build_link']) for b in builders['entries'])70 b['name']: b['current_build_link'] for b in builders['entries']}
71 self.assertEqual(71 self.assertEqual(
72 'tag:launchpad.net:2008:redacted', current_builds['restricted'])72 'tag:launchpad.net:2008:redacted', current_builds['restricted'])
73 self.assertEqual(73 self.assertEqual(
diff --git a/lib/lp/charms/model/charmrecipe.py b/lib/lp/charms/model/charmrecipe.py
index 7629c1b..2ee38d4 100644
--- a/lib/lp/charms/model/charmrecipe.py
+++ b/lib/lp/charms/model/charmrecipe.py
@@ -487,7 +487,7 @@ class CharmRecipe(StormBase, WebhookTargetMixin):
487 for charm_base in store.find(487 for charm_base in store.find(
488 CharmBase,488 CharmBase,
489 CharmBase.distro_series_id.is_in(489 CharmBase.distro_series_id.is_in(
490 set(das.distroseriesID for das in all_buildable_dases)))}490 {das.distroseriesID for das in all_buildable_dases}))}
491 return [491 return [
492 das for das in all_buildable_dases492 das for das in all_buildable_dases
493 if self._isBuildableArchitectureAllowed(493 if self._isBuildableArchitectureAllowed(
diff --git a/lib/lp/code/browser/branch.py b/lib/lp/code/browser/branch.py
index 87b43b2..f6e5d03 100644
--- a/lib/lp/code/browser/branch.py
+++ b/lib/lp/code/browser/branch.py
@@ -676,7 +676,7 @@ class BranchEditFormView(LaunchpadEditFormView):
676 # If we're stacked on a private branch, only show that676 # If we're stacked on a private branch, only show that
677 # information type.677 # information type.
678 if self.context.stacked_on and self.context.stacked_on.private:678 if self.context.stacked_on and self.context.stacked_on.private:
679 shown_types = set([self.context.stacked_on.information_type])679 shown_types = {self.context.stacked_on.information_type}
680 else:680 else:
681 shown_types = (681 shown_types = (
682 InformationType.PUBLIC,682 InformationType.PUBLIC,
diff --git a/lib/lp/code/browser/branchlisting.py b/lib/lp/code/browser/branchlisting.py
index 64355b2..d3ecb66 100644
--- a/lib/lp/code/browser/branchlisting.py
+++ b/lib/lp/code/browser/branchlisting.py
@@ -354,7 +354,7 @@ class BranchListingItemsMixin:
354 spec_branches = getUtility(354 spec_branches = getUtility(
355 ISpecificationBranchSet).getSpecificationBranchesForBranches(355 ISpecificationBranchSet).getSpecificationBranchesForBranches(
356 self.visible_branches_for_view, self.view_user)356 self.visible_branches_for_view, self.view_user)
357 return set(spec_branch.branch.id for spec_branch in spec_branches)357 return {spec_branch.branch.id for spec_branch in spec_branches}
358358
359 @cachedproperty359 @cachedproperty
360 def branch_ids_with_merge_proposals(self):360 def branch_ids_with_merge_proposals(self):
@@ -366,7 +366,7 @@ class BranchListingItemsMixin:
366 branches = self.visible_branches_for_view366 branches = self.visible_branches_for_view
367 collection = self.getBranchCollection()367 collection = self.getBranchCollection()
368 proposals = collection.getMergeProposals(for_branches=branches)368 proposals = collection.getMergeProposals(for_branches=branches)
369 return set(proposal.source_branch.id for proposal in proposals)369 return {proposal.source_branch.id for proposal in proposals}
370370
371 @cachedproperty371 @cachedproperty
372 def tip_revisions(self):372 def tip_revisions(self):
@@ -378,8 +378,8 @@ class BranchListingItemsMixin:
378 revisions = []378 revisions = []
379379
380 # Key the revisions by revision id.380 # Key the revisions by revision id.
381 revision_map = dict(381 revision_map = {
382 (revision.revision_id, revision) for revision in revisions)382 revision.revision_id: revision for revision in revisions}
383383
384 # Cache display information for authors of branches' respective384 # Cache display information for authors of branches' respective
385 # last revisions.385 # last revisions.
@@ -388,9 +388,9 @@ class BranchListingItemsMixin:
388 need_icon=True)388 need_icon=True)
389389
390 # Return a dict keyed on branch id.390 # Return a dict keyed on branch id.
391 return dict(391 return {
392 (branch.id, revision_map.get(branch.last_scanned_id))392 branch.id: revision_map.get(branch.last_scanned_id)
393 for branch in self.visible_branches_for_view)393 for branch in self.visible_branches_for_view}
394394
395 def _createItem(self, branch):395 def _createItem(self, branch):
396 last_commit = self.tip_revisions[branch.id]396 last_commit = self.tip_revisions[branch.id]
@@ -1321,8 +1321,8 @@ class GroupedDistributionSourcePackageBranchesView(LaunchpadView,
1321 # Sort the branches by the last modified date, and ignore any that are1321 # Sort the branches by the last modified date, and ignore any that are
1322 # official.1322 # official.
1323 ordered_branches = sorted(1323 ordered_branches = sorted(
1324 [branch for branch in branches1324 (branch for branch in branches
1325 if branch not in official_branches],1325 if branch not in official_branches),
1326 key=attrgetter('date_last_modified'), reverse=True)1326 key=attrgetter('date_last_modified'), reverse=True)
1327 num_branches = len(ordered_branches)1327 num_branches = len(ordered_branches)
1328 num_official = len(official_branches)1328 num_official = len(official_branches)
diff --git a/lib/lp/code/browser/branchmergeproposal.py b/lib/lp/code/browser/branchmergeproposal.py
index 96b22d8..b7c157a 100644
--- a/lib/lp/code/browser/branchmergeproposal.py
+++ b/lib/lp/code/browser/branchmergeproposal.py
@@ -157,7 +157,7 @@ def latest_proposals_for_each_branch(proposals):
157 targets[target] = (proposal, date_created)157 targets[target] = (proposal, date_created)
158158
159 return sorted(159 return sorted(
160 [proposal for proposal, date_created in six.itervalues(targets)],160 (proposal for proposal, date_created in six.itervalues(targets)),
161 key=operator.attrgetter('date_created'), reverse=True)161 key=operator.attrgetter('date_created'), reverse=True)
162162
163163
diff --git a/lib/lp/code/browser/tests/test_branchlisting.py b/lib/lp/code/browser/tests/test_branchlisting.py
index 1c4ad36..3f33640 100644
--- a/lib/lp/code/browser/tests/test_branchlisting.py
+++ b/lib/lp/code/browser/tests/test_branchlisting.py
@@ -129,7 +129,7 @@ class TestPersonOwnedBranchesView(TestCaseWithFactory,
129 def test_branch_ids_with_bug_links(self):129 def test_branch_ids_with_bug_links(self):
130 # _branches_for_current_batch should return a list of all branches in130 # _branches_for_current_batch should return a list of all branches in
131 # the current batch.131 # the current batch.
132 branch_ids = set([self.branches[0].id])132 branch_ids = {self.branches[0].id}
133133
134 view = create_initialized_view(134 view = create_initialized_view(
135 self.barney, name="+branches", rootsite='code')135 self.barney, name="+branches", rootsite='code')
@@ -140,7 +140,7 @@ class TestPersonOwnedBranchesView(TestCaseWithFactory,
140 def test_branch_ids_with_spec_links(self):140 def test_branch_ids_with_spec_links(self):
141 # _branches_for_current_batch should return a list of all branches in141 # _branches_for_current_batch should return a list of all branches in
142 # the current batch.142 # the current batch.
143 branch_ids = set([self.branches[1].id])143 branch_ids = {self.branches[1].id}
144144
145 view = create_initialized_view(145 view = create_initialized_view(
146 self.barney, name="+branches", rootsite='code')146 self.barney, name="+branches", rootsite='code')
@@ -151,7 +151,7 @@ class TestPersonOwnedBranchesView(TestCaseWithFactory,
151 def test_branch_ids_with_merge_propoasls(self):151 def test_branch_ids_with_merge_propoasls(self):
152 # _branches_for_current_batch should return a list of all branches in152 # _branches_for_current_batch should return a list of all branches in
153 # the current batch.153 # the current batch.
154 branch_ids = set([])154 branch_ids = set()
155 view = create_initialized_view(155 view = create_initialized_view(
156 self.barney, name="+branches", rootsite='code')156 self.barney, name="+branches", rootsite='code')
157 self.assertEqual(157 self.assertEqual(
@@ -680,8 +680,8 @@ class TestProjectGroupBranches(TestCaseWithFactory,
680 self.projectgroup, name='+branches', rootsite='code')680 self.projectgroup, name='+branches', rootsite='code')
681 displayname = self.projectgroup.displayname681 displayname = self.projectgroup.displayname
682 expected_text = normalize_whitespace(682 expected_text = normalize_whitespace(
683 ("Launchpad does not know where any of %s's "683 "Launchpad does not know where any of %s's "
684 "projects host their code." % displayname))684 "projects host their code." % displayname)
685 no_branch_div = find_tag_by_id(view(), "no-branchtable")685 no_branch_div = find_tag_by_id(view(), "no-branchtable")
686 text = normalize_whitespace(extract_text(no_branch_div))686 text = normalize_whitespace(extract_text(no_branch_div))
687 self.assertEqual(expected_text, text)687 self.assertEqual(expected_text, text)
diff --git a/lib/lp/code/browser/tests/test_branchmergeproposal.py b/lib/lp/code/browser/tests/test_branchmergeproposal.py
index 18bd572..519ec9a 100644
--- a/lib/lp/code/browser/tests/test_branchmergeproposal.py
+++ b/lib/lp/code/browser/tests/test_branchmergeproposal.py
@@ -2044,16 +2044,16 @@ class TestBranchMergeProposalChangeStatusView(TestCaseWithFactory):
2044 # generated vocabulary.2044 # generated vocabulary.
2045 login_person(user)2045 login_person(user)
2046 vocabulary = self._createView()._createStatusVocabulary()2046 vocabulary = self._createView()._createStatusVocabulary()
2047 vocab_tokens = sorted([term.token for term in vocabulary])2047 vocab_tokens = sorted(term.token for term in vocabulary)
2048 self.assertEqual(2048 self.assertEqual(
2049 sorted(tokens), vocab_tokens)2049 sorted(tokens), vocab_tokens)
20502050
2051 def assertAllStatusesAvailable(self, user, except_for=None):2051 def assertAllStatusesAvailable(self, user, except_for=None):
2052 # All options should be available to the user, except for SUPERSEDED,2052 # All options should be available to the user, except for SUPERSEDED,
2053 # which is only provided through resubmit.2053 # which is only provided through resubmit.
2054 desired_statuses = set([2054 desired_statuses = {
2055 'WORK_IN_PROGRESS', 'NEEDS_REVIEW', 'MERGED', 'CODE_APPROVED',2055 'WORK_IN_PROGRESS', 'NEEDS_REVIEW', 'MERGED', 'CODE_APPROVED',
2056 'REJECTED'])2056 'REJECTED'}
2057 if except_for is not None:2057 if except_for is not None:
2058 desired_statuses -= set(except_for)2058 desired_statuses -= set(except_for)
2059 self.assertStatusVocabTokens(desired_statuses, user)2059 self.assertStatusVocabTokens(desired_statuses, user)
diff --git a/lib/lp/code/browser/tests/test_gitrepository.py b/lib/lp/code/browser/tests/test_gitrepository.py
index 367c2c0..faca389 100644
--- a/lib/lp/code/browser/tests/test_gitrepository.py
+++ b/lib/lp/code/browser/tests/test_gitrepository.py
@@ -1400,7 +1400,7 @@ class TestGitRepositoryPermissionsView(BrowserTestCase):
1400 def test__getRuleGrants(self):1400 def test__getRuleGrants(self):
1401 rule = self.factory.makeGitRule()1401 rule = self.factory.makeGitRule()
1402 grantees = sorted(1402 grantees = sorted(
1403 [self.factory.makePerson() for _ in range(3)],1403 (self.factory.makePerson() for _ in range(3)),
1404 key=attrgetter("name"))1404 key=attrgetter("name"))
1405 for grantee in (grantees[1], grantees[0], grantees[2]):1405 for grantee in (grantees[1], grantees[0], grantees[2]):
1406 self.factory.makeGitRuleGrant(rule=rule, grantee=grantee)1406 self.factory.makeGitRuleGrant(rule=rule, grantee=grantee)
diff --git a/lib/lp/code/browser/tests/test_sourcepackagerecipe.py b/lib/lp/code/browser/tests/test_sourcepackagerecipe.py
index 3f12008..a54af33 100644
--- a/lib/lp/code/browser/tests/test_sourcepackagerecipe.py
+++ b/lib/lp/code/browser/tests/test_sourcepackagerecipe.py
@@ -308,10 +308,10 @@ class TestSourcePackageRecipeAddViewInitialValuesMixin:
308 with person_logged_in(archive.owner):308 with person_logged_in(archive.owner):
309 view = create_initialized_view(branch, '+new-recipe')309 view = create_initialized_view(branch, '+new-recipe')
310 series = set(view.initial_values['distroseries'])310 series = set(view.initial_values['distroseries'])
311 initial_series = set([development, current])311 initial_series = {development, current}
312 self.assertEqual(initial_series, series.intersection(initial_series))312 self.assertEqual(initial_series, series.intersection(initial_series))
313 other_series = set(313 other_series = {
314 [experimental, frozen, supported, obsolete, future])314 experimental, frozen, supported, obsolete, future}
315 self.assertEqual(set(), series.intersection(other_series))315 self.assertEqual(set(), series.intersection(other_series))
316316
317317
@@ -440,7 +440,7 @@ class TestSourcePackageRecipeAddViewMixin:
440 options = browser.getControl(name='field.owner.owner').displayOptions440 options = browser.getControl(name='field.owner.owner').displayOptions
441 self.assertEqual(441 self.assertEqual(
442 ['Good Chefs (good-chefs)', 'Master Chef (chef)'],442 ['Good Chefs (good-chefs)', 'Master Chef (chef)'],
443 sorted([str(option) for option in options]))443 sorted(str(option) for option in options))
444444
445 def test_create_new_recipe_team_owner(self):445 def test_create_new_recipe_team_owner(self):
446 # New recipes can be owned by teams that the user is a member of.446 # New recipes can be owned by teams that the user is a member of.
@@ -1499,8 +1499,8 @@ class TestSourcePackageRecipeViewMixin:
1499 # Our recipe has a Warty distroseries1499 # Our recipe has a Warty distroseries
1500 self.assertEqual(['Warty'], build_distros)1500 self.assertEqual(['Warty'], build_distros)
1501 self.assertEqual(1501 self.assertEqual(
1502 set([2510]),1502 {2510},
1503 set(build.buildqueue_record.lastscore for build in builds))1503 {build.buildqueue_record.lastscore for build in builds})
15041504
1505 def test_request_daily_builds_disabled_archive(self):1505 def test_request_daily_builds_disabled_archive(self):
1506 # Requesting a daily build from a disabled archive is a user error.1506 # Requesting a daily build from a disabled archive is a user error.
diff --git a/lib/lp/code/browser/tests/test_tales.py b/lib/lp/code/browser/tests/test_tales.py
index 8452d35..1f928f7 100644
--- a/lib/lp/code/browser/tests/test_tales.py
+++ b/lib/lp/code/browser/tests/test_tales.py
@@ -165,8 +165,8 @@ class TestPreviewDiffFormatter(TestCaseWithFactory):
165165
166 def test_fmt_stale_non_empty_diff(self):166 def test_fmt_stale_non_empty_diff(self):
167 # If there is no diff, there is no link.167 # If there is no diff, there is no link.
168 diffstat = dict(168 diffstat = {
169 (self.factory.getUniqueString(), (2, 3)) for x in range(23))169 self.factory.getUniqueString(): (2, 3) for x in range(23)}
170 preview = self._createStalePreviewDiff(170 preview = self._createStalePreviewDiff(
171 500, 89, 340, diffstat=diffstat)171 500, 89, 340, diffstat=diffstat)
172 expected_diffstat = '<br/>'.join(172 expected_diffstat = '<br/>'.join(
@@ -183,8 +183,8 @@ class TestPreviewDiffFormatter(TestCaseWithFactory):
183183
184 def test_fmt_stale_non_empty_diff_with_conflicts(self):184 def test_fmt_stale_non_empty_diff_with_conflicts(self):
185 # If there is no diff, there is no link.185 # If there is no diff, there is no link.
186 diffstat = dict(186 diffstat = {
187 (self.factory.getUniqueString(), (2, 3)) for x in range(23))187 self.factory.getUniqueString(): (2, 3) for x in range(23)}
188 preview = self._createStalePreviewDiff(188 preview = self._createStalePreviewDiff(
189 500, 89, 340, 'conflicts', diffstat=diffstat)189 500, 89, 340, 'conflicts', diffstat=diffstat)
190 expected_diffstat = '<br/>'.join(190 expected_diffstat = '<br/>'.join(
diff --git a/lib/lp/code/interfaces/tests/test_branch.py b/lib/lp/code/interfaces/tests/test_branch.py
index b2c987a..a9bb02b 100644
--- a/lib/lp/code/interfaces/tests/test_branch.py
+++ b/lib/lp/code/interfaces/tests/test_branch.py
@@ -37,8 +37,8 @@ class TestFormatSupport(TestCase):
37 def breezy_is_subset(self, breezy_formats, launchpad_enum):37 def breezy_is_subset(self, breezy_formats, launchpad_enum):
38 """Ensure the Breezy format marker list is a subset of Launchpad."""38 """Ensure the Breezy format marker list is a subset of Launchpad."""
39 breezy_format_strings = set(breezy_formats)39 breezy_format_strings = set(breezy_formats)
40 launchpad_format_strings = set(40 launchpad_format_strings = {
41 six.ensure_binary(format.title) for format in launchpad_enum.items)41 six.ensure_binary(format.title) for format in launchpad_enum.items}
42 self.assertEqual(42 self.assertEqual(
43 set(), breezy_format_strings.difference(launchpad_format_strings))43 set(), breezy_format_strings.difference(launchpad_format_strings))
4444
diff --git a/lib/lp/code/mail/tests/test_branchmergeproposal.py b/lib/lp/code/mail/tests/test_branchmergeproposal.py
index 06bc638..537918f 100644
--- a/lib/lp/code/mail/tests/test_branchmergeproposal.py
+++ b/lib/lp/code/mail/tests/test_branchmergeproposal.py
@@ -147,7 +147,7 @@ class TestMergeProposalMailing(TestCaseWithFactory):
147 'Baz Qux <mp+%d@%s>' % (bmp.id, config.launchpad.code_domain),147 'Baz Qux <mp+%d@%s>' % (bmp.id, config.launchpad.code_domain),
148 ctrl.from_addr)148 ctrl.from_addr)
149 reviewer_id = format_address_for_person(reviewer)149 reviewer_id = format_address_for_person(reviewer)
150 self.assertEqual(set([reviewer_id, bmp.address]), set(ctrl.to_addrs))150 self.assertEqual({reviewer_id, bmp.address}, set(ctrl.to_addrs))
151 mailer.sendAll()151 mailer.sendAll()
152152
153 def test_forCreation_without_commit_message(self):153 def test_forCreation_without_commit_message(self):
@@ -304,7 +304,7 @@ class TestMergeProposalMailing(TestCaseWithFactory):
304 bmp.registrant)304 bmp.registrant)
305 reviewer = request.recipient305 reviewer = request.recipient
306 reviewer_id = format_address_for_person(reviewer)306 reviewer_id = format_address_for_person(reviewer)
307 self.assertEqual(set([reviewer_id, bmp.address]), set(ctrl.to_addrs))307 self.assertEqual({reviewer_id, bmp.address}, set(ctrl.to_addrs))
308308
309 def test_to_addrs_excludes_team_reviewers(self):309 def test_to_addrs_excludes_team_reviewers(self):
310 """Addresses for the to header exclude requested team reviewers."""310 """Addresses for the to header exclude requested team reviewers."""
@@ -318,7 +318,7 @@ class TestMergeProposalMailing(TestCaseWithFactory):
318 subscriber)318 subscriber)
319 reviewer = bmp.target_branch.owner319 reviewer = bmp.target_branch.owner
320 reviewer_id = format_address_for_person(reviewer)320 reviewer_id = format_address_for_person(reviewer)
321 self.assertEqual(set([reviewer_id, bmp.address]), set(ctrl.to_addrs))321 self.assertEqual({reviewer_id, bmp.address}, set(ctrl.to_addrs))
322322
323 def test_to_addrs_excludes_people_with_hidden_addresses(self):323 def test_to_addrs_excludes_people_with_hidden_addresses(self):
324 """The to header excludes those with hidden addresses."""324 """The to header excludes those with hidden addresses."""
diff --git a/lib/lp/code/model/branch.py b/lib/lp/code/model/branch.py
index c2a0de5..1a9bcc4 100644
--- a/lib/lp/code/model/branch.py
+++ b/lib/lp/code/model/branch.py
@@ -249,9 +249,9 @@ class Branch(SQLBase, WebhookTargetMixin, BzrIdentityMixin):
249 self.information_type not in PUBLIC_INFORMATION_TYPES):249 self.information_type not in PUBLIC_INFORMATION_TYPES):
250 aasource = getUtility(IAccessArtifactSource)250 aasource = getUtility(IAccessArtifactSource)
251 [abstract_artifact] = aasource.ensure([self])251 [abstract_artifact] = aasource.ensure([self])
252 wanted_links = set(252 wanted_links = {
253 (abstract_artifact, policy) for policy in253 (abstract_artifact, policy) for policy in
254 getUtility(IAccessPolicySource).findByTeam([self.owner]))254 getUtility(IAccessPolicySource).findByTeam([self.owner])}
255 else:255 else:
256 # We haven't yet quite worked out how distribution privacy256 # We haven't yet quite worked out how distribution privacy
257 # works, so only work for products for now.257 # works, so only work for products for now.
@@ -941,9 +941,9 @@ class Branch(SQLBase, WebhookTargetMixin, BzrIdentityMixin):
941 """See `IBranch`."""941 """See `IBranch`."""
942 alteration_operations, deletion_operations, = (942 alteration_operations, deletion_operations, = (
943 self._deletionRequirements(eager_load=eager_load))943 self._deletionRequirements(eager_load=eager_load))
944 result = dict(944 result = {
945 (operation.affected_object, ('alter', operation.rationale)) for945 operation.affected_object: ('alter', operation.rationale) for
946 operation in alteration_operations)946 operation in alteration_operations}
947 # Deletion entries should overwrite alteration entries.947 # Deletion entries should overwrite alteration entries.
948 result.update(948 result.update(
949 (operation.affected_object, ('delete', operation.rationale)) for949 (operation.affected_object, ('delete', operation.rationale)) for
diff --git a/lib/lp/code/model/branchcollection.py b/lib/lp/code/model/branchcollection.py
index 524fa69..6ba75ec 100644
--- a/lib/lp/code/model/branchcollection.py
+++ b/lib/lp/code/model/branchcollection.py
@@ -245,8 +245,8 @@ class GenericBranchCollection:
245 load_related(SourcePackageName, branches, ['sourcepackagenameID'])245 load_related(SourcePackageName, branches, ['sourcepackagenameID'])
246 load_related(DistroSeries, branches, ['distroseriesID'])246 load_related(DistroSeries, branches, ['distroseriesID'])
247 load_related(Product, branches, ['productID'])247 load_related(Product, branches, ['productID'])
248 caches = dict((branch.id, get_property_cache(branch))248 caches = {branch.id: get_property_cache(branch)
249 for branch in branches)249 for branch in branches}
250 branch_ids = caches.keys()250 branch_ids = caches.keys()
251 for cache in caches.values():251 for cache in caches.values():
252 cache._associatedProductSeries = []252 cache._associatedProductSeries = []
@@ -326,7 +326,7 @@ class GenericBranchCollection:
326 *self._convertListingSortToOrderBy(sort_by))326 *self._convertListingSortToOrderBy(sort_by))
327327
328 def do_eager_load(rows):328 def do_eager_load(rows):
329 branch_ids = set(branch.id for branch in rows)329 branch_ids = {branch.id for branch in rows}
330 if not branch_ids:330 if not branch_ids:
331 return331 return
332 GenericBranchCollection.preloadDataForBranches(rows)332 GenericBranchCollection.preloadDataForBranches(rows)
@@ -338,8 +338,8 @@ class GenericBranchCollection:
338338
339 def cache_permission(branch):339 def cache_permission(branch):
340 if self._user:340 if self._user:
341 get_property_cache(branch)._known_viewers = set(341 get_property_cache(branch)._known_viewers = {
342 [self._user.id])342 self._user.id}
343 return branch343 return branch
344344
345 eager_load_hook = (345 eager_load_hook = (
@@ -531,8 +531,8 @@ class GenericBranchCollection:
531 merge_proposals = self.getMergeProposals(531 merge_proposals = self.getMergeProposals(
532 target_branch=branch, merged_revnos=rev_nos,532 target_branch=branch, merged_revnos=rev_nos,
533 statuses=[BranchMergeProposalStatus.MERGED])533 statuses=[BranchMergeProposalStatus.MERGED])
534 merge_proposal_revs = dict(534 merge_proposal_revs = {
535 [(mp.merged_revno, mp) for mp in merge_proposals])535 mp.merged_revno: mp for mp in merge_proposals}
536 source_branch_ids = [mp.source_branch.id for mp in merge_proposals]536 source_branch_ids = [mp.source_branch.id for mp in merge_proposals]
537 linked_bugtasks = defaultdict(list)537 linked_bugtasks = defaultdict(list)
538538
diff --git a/lib/lp/code/model/branchjob.py b/lib/lp/code/model/branchjob.py
index 172f83c..5d7c0d8 100644
--- a/lib/lp/code/model/branchjob.py
+++ b/lib/lp/code/model/branchjob.py
@@ -690,7 +690,7 @@ class RevisionsAddedJob(BranchJobDerived):
690 proposals[source_id] = (proposal, date_created)690 proposals[source_id] = (proposal, date_created)
691691
692 return sorted(692 return sorted(
693 [proposal for proposal, date_created in six.itervalues(proposals)],693 (proposal for proposal, date_created in six.itervalues(proposals)),
694 key=operator.attrgetter('date_created'), reverse=True)694 key=operator.attrgetter('date_created'), reverse=True)
695695
696 def getRevisionMessage(self, revision_id, revno):696 def getRevisionMessage(self, revision_id, revno):
diff --git a/lib/lp/code/model/branchlookup.py b/lib/lp/code/model/branchlookup.py
index 9648e2a..80bda43 100644
--- a/lib/lp/code/model/branchlookup.py
+++ b/lib/lp/code/model/branchlookup.py
@@ -274,7 +274,7 @@ class BranchLookup:
274274
275 def getByUrls(self, urls):275 def getByUrls(self, urls):
276 """See `IBranchLookup`."""276 """See `IBranchLookup`."""
277 return dict((url, self.getByUrl(url)) for url in set(urls))277 return {url: self.getByUrl(url) for url in set(urls)}
278278
279 def getByUniqueName(self, unique_name):279 def getByUniqueName(self, unique_name):
280 """Find a branch by its unique name.280 """Find a branch by its unique name.
diff --git a/lib/lp/code/model/branchmergeproposal.py b/lib/lp/code/model/branchmergeproposal.py
index bb4d009..a0ff7d1 100644
--- a/lib/lp/code/model/branchmergeproposal.py
+++ b/lib/lp/code/model/branchmergeproposal.py
@@ -510,9 +510,9 @@ class BranchMergeProposal(SQLBase, BugLinkTargetMixin):
510 current_bug_ids = set(current_bug_ids_from_source)510 current_bug_ids = set(current_bug_ids_from_source)
511 new_bug_ids = self._fetchRelatedBugIDsFromSource()511 new_bug_ids = self._fetchRelatedBugIDsFromSource()
512 # Only remove links marked as originating in the source branch.512 # Only remove links marked as originating in the source branch.
513 remove_bugs = load(Bug, set(513 remove_bugs = load(Bug, {
514 bug_id for bug_id in current_bug_ids - new_bug_ids514 bug_id for bug_id in current_bug_ids - new_bug_ids
515 if current_bug_ids_from_source[bug_id]))515 if current_bug_ids_from_source[bug_id]})
516 add_bugs = load(Bug, new_bug_ids - current_bug_ids)516 add_bugs = load(Bug, new_bug_ids - current_bug_ids)
517 if remove_bugs or add_bugs:517 if remove_bugs or add_bugs:
518 janitor = getUtility(ILaunchpadCelebrities).janitor518 janitor = getUtility(ILaunchpadCelebrities).janitor
@@ -852,8 +852,8 @@ class BranchMergeProposal(SQLBase, BugLinkTargetMixin):
852 # a database query to identify if there are any active proposals852 # a database query to identify if there are any active proposals
853 # with the same source and target branches.853 # with the same source and target branches.
854 self.syncUpdate()854 self.syncUpdate()
855 review_requests = list(set(855 review_requests = list({
856 (vote.reviewer, vote.review_type) for vote in self.votes))856 (vote.reviewer, vote.review_type) for vote in self.votes})
857 proposal = merge_source.addLandingTarget(857 proposal = merge_source.addLandingTarget(
858 registrant=registrant,858 registrant=registrant,
859 merge_target=merge_target,859 merge_target=merge_target,
@@ -1215,9 +1215,9 @@ class BranchMergeProposal(SQLBase, BugLinkTargetMixin):
1215 """See `IBranchMergeProposal`."""1215 """See `IBranchMergeProposal`."""
1216 diffs = Store.of(self).find(IncrementalDiff,1216 diffs = Store.of(self).find(IncrementalDiff,
1217 IncrementalDiff.branch_merge_proposal_id == self.id)1217 IncrementalDiff.branch_merge_proposal_id == self.id)
1218 diff_dict = dict(1218 diff_dict = {
1219 ((diff.old_revision, diff.new_revision), diff)1219 (diff.old_revision, diff.new_revision): diff
1220 for diff in diffs)1220 for diff in diffs}
1221 return [diff_dict.get(revisions) for revisions in revision_list]1221 return [diff_dict.get(revisions) for revisions in revision_list]
12221222
1223 def scheduleDiffUpdates(self, return_jobs=True):1223 def scheduleDiffUpdates(self, return_jobs=True):
@@ -1344,8 +1344,8 @@ class BranchMergeProposal(SQLBase, BugLinkTargetMixin):
1344 mp.prerequisite_git_path))1344 mp.prerequisite_git_path))
1345 person_ids.add(mp.registrantID)1345 person_ids.add(mp.registrantID)
1346 person_ids.add(mp.merge_reporterID)1346 person_ids.add(mp.merge_reporterID)
1347 git_repository_ids = set(1347 git_repository_ids = {
1348 repository_id for repository_id, _ in git_ref_keys)1348 repository_id for repository_id, _ in git_ref_keys}
13491349
1350 branches = load_related(1350 branches = load_related(
1351 Branch, branch_merge_proposals, (1351 Branch, branch_merge_proposals, (
@@ -1476,7 +1476,7 @@ class BranchMergeProposalGetter:
1476 return {}1476 return {}
1477 ids = [proposal.id for proposal in proposals]1477 ids = [proposal.id for proposal in proposals]
1478 store = Store.of(proposals[0])1478 store = Store.of(proposals[0])
1479 result = dict([(proposal, []) for proposal in proposals])1479 result = {proposal: [] for proposal in proposals}
1480 # Make sure that the Person and the review comment are loaded in the1480 # Make sure that the Person and the review comment are loaded in the
1481 # storm cache as the reviewer is displayed in a title attribute on the1481 # storm cache as the reviewer is displayed in a title attribute on the
1482 # merge proposal listings page, and the message is needed to get to1482 # merge proposal listings page, and the message is needed to get to
diff --git a/lib/lp/code/model/codereviewcomment.py b/lib/lp/code/model/codereviewcomment.py
index be85747..4b18adc 100644
--- a/lib/lp/code/model/codereviewcomment.py
+++ b/lib/lp/code/model/codereviewcomment.py
@@ -122,7 +122,7 @@ class CodeReviewComment(StormBase):
122 attachments = [chunk.blob for chunk in self.message.chunks122 attachments = [chunk.blob for chunk in self.message.chunks
123 if chunk.blob is not None]123 if chunk.blob is not None]
124 # Attachments to show.124 # Attachments to show.
125 good_mimetypes = set(['text/plain', 'text/x-diff', 'text/x-patch'])125 good_mimetypes = {'text/plain', 'text/x-diff', 'text/x-patch'}
126 display_attachments = [126 display_attachments = [
127 attachment for attachment in attachments127 attachment for attachment in attachments
128 if ((attachment.mimetype in good_mimetypes) or128 if ((attachment.mimetype in good_mimetypes) or
diff --git a/lib/lp/code/model/diff.py b/lib/lp/code/model/diff.py
index abcb25c..13f633c 100644
--- a/lib/lp/code/model/diff.py
+++ b/lib/lp/code/model/diff.py
@@ -77,9 +77,9 @@ class Diff(SQLBase):
77 def _get_diffstat(self):77 def _get_diffstat(self):
78 if self._diffstat is None:78 if self._diffstat is None:
79 return None79 return None
80 return dict((key, tuple(value))80 return {key: tuple(value)
81 for key, value81 for key, value
82 in simplejson.loads(self._diffstat).items())82 in simplejson.loads(self._diffstat).items()}
8383
84 def _set_diffstat(self, diffstat):84 def _set_diffstat(self, diffstat):
85 if diffstat is None:85 if diffstat is None:
@@ -385,13 +385,13 @@ class PreviewDiff(Storm):
385 source_revision = bmp.source_branch.getBranchRevision(385 source_revision = bmp.source_branch.getBranchRevision(
386 revision_id=self.source_revision_id)386 revision_id=self.source_revision_id)
387 if source_revision and source_revision.sequence:387 if source_revision and source_revision.sequence:
388 source_rev = u'r{0}'.format(source_revision.sequence)388 source_rev = u'r{}'.format(source_revision.sequence)
389 else:389 else:
390 source_rev = self.source_revision_id390 source_rev = self.source_revision_id
391 target_revision = bmp.target_branch.getBranchRevision(391 target_revision = bmp.target_branch.getBranchRevision(
392 revision_id=self.target_revision_id)392 revision_id=self.target_revision_id)
393 if target_revision and target_revision.sequence:393 if target_revision and target_revision.sequence:
394 target_rev = u'r{0}'.format(target_revision.sequence)394 target_rev = u'r{}'.format(target_revision.sequence)
395 else:395 else:
396 target_rev = self.target_revision_id396 target_rev = self.target_revision_id
397 else:397 else:
@@ -402,7 +402,7 @@ class PreviewDiff(Storm):
402 source_rev = self.source_revision_id[:7]402 source_rev = self.source_revision_id[:7]
403 target_rev = self.target_revision_id[:7]403 target_rev = self.target_revision_id[:7]
404404
405 return u'{0} into {1}'.format(source_rev, target_rev)405 return u'{} into {}'.format(source_rev, target_rev)
406406
407 @property407 @property
408 def has_conflicts(self):408 def has_conflicts(self):
diff --git a/lib/lp/code/model/gitcollection.py b/lib/lp/code/model/gitcollection.py
index 444a8eb..966ea02 100644
--- a/lib/lp/code/model/gitcollection.py
+++ b/lib/lp/code/model/gitcollection.py
@@ -252,7 +252,7 @@ class GenericGitCollection:
252 *self._convertListingSortToOrderBy(sort_by)))252 *self._convertListingSortToOrderBy(sort_by)))
253253
254 def do_eager_load(rows):254 def do_eager_load(rows):
255 repository_ids = set(repository.id for repository in rows)255 repository_ids = {repository.id for repository in rows}
256 if not repository_ids:256 if not repository_ids:
257 return257 return
258 GenericGitCollection.preloadDataForRepositories(rows)258 GenericGitCollection.preloadDataForRepositories(rows)
@@ -262,8 +262,8 @@ class GenericGitCollection:
262262
263 def cache_permission(repository):263 def cache_permission(repository):
264 if self._user:264 if self._user:
265 get_property_cache(repository)._known_viewers = set(265 get_property_cache(repository)._known_viewers = {
266 [self._user.id])266 self._user.id}
267 return repository267 return repository
268268
269 eager_load_hook = (269 eager_load_hook = (
diff --git a/lib/lp/code/model/gitref.py b/lib/lp/code/model/gitref.py
index 41af46a..61a7526 100644
--- a/lib/lp/code/model/gitref.py
+++ b/lib/lp/code/model/gitref.py
@@ -456,7 +456,7 @@ class GitRefMixin:
456 from lp.code.model.sourcepackagerecipedata import (456 from lp.code.model.sourcepackagerecipedata import (
457 SourcePackageRecipeData,457 SourcePackageRecipeData,
458 )458 )
459 revspecs = set([self.path, self.name])459 revspecs = {self.path, self.name}
460 if self.path == self.repository.default_branch:460 if self.path == self.repository.default_branch:
461 revspecs.add(None)461 revspecs.add(None)
462 recipes = SourcePackageRecipeData.findRecipes(462 recipes = SourcePackageRecipeData.findRecipes(
diff --git a/lib/lp/code/model/gitrepository.py b/lib/lp/code/model/gitrepository.py
index 7210ec4..812f1d7 100644
--- a/lib/lp/code/model/gitrepository.py
+++ b/lib/lp/code/model/gitrepository.py
@@ -618,9 +618,9 @@ class GitRepository(StormBase, WebhookTargetMixin, AccessTokenTargetMixin,
618 self.information_type not in PUBLIC_INFORMATION_TYPES):618 self.information_type not in PUBLIC_INFORMATION_TYPES):
619 aasource = getUtility(IAccessArtifactSource)619 aasource = getUtility(IAccessArtifactSource)
620 [abstract_artifact] = aasource.ensure([self])620 [abstract_artifact] = aasource.ensure([self])
621 wanted_links = set(621 wanted_links = {
622 (abstract_artifact, policy) for policy in622 (abstract_artifact, policy) for policy in
623 getUtility(IAccessPolicySource).findByTeam([self.owner]))623 getUtility(IAccessPolicySource).findByTeam([self.owner])}
624 else:624 else:
625 # We haven't yet quite worked out how distribution privacy625 # We haven't yet quite worked out how distribution privacy
626 # works, so only work for projects for now.626 # works, so only work for projects for now.
@@ -847,7 +847,7 @@ class GitRepository(StormBase, WebhookTargetMixin, AccessTokenTargetMixin,
847 @staticmethod847 @staticmethod
848 def fetchRefCommits(hosting_path, refs, logger=None):848 def fetchRefCommits(hosting_path, refs, logger=None):
849 """See `IGitRepository`."""849 """See `IGitRepository`."""
850 oids = sorted(set(info["sha1"] for info in refs.values()))850 oids = sorted({info["sha1"] for info in refs.values()})
851 if not oids:851 if not oids:
852 return852 return
853 commits = parse_git_commits(853 commits = parse_git_commits(
@@ -1318,7 +1318,7 @@ class GitRepository(StormBase, WebhookTargetMixin, AccessTokenTargetMixin,
1318 proposals = list(group)1318 proposals = list(group)
1319 merges = hosting_client.detectMerges(1319 merges = hosting_client.detectMerges(
1320 self.getInternalPath(), proposals[0].target_git_commit_sha1,1320 self.getInternalPath(), proposals[0].target_git_commit_sha1,
1321 set(proposal.source_git_commit_sha1 for proposal in proposals))1321 {proposal.source_git_commit_sha1 for proposal in proposals})
1322 for proposal in proposals:1322 for proposal in proposals:
1323 merged_revision_id = merges.get(1323 merged_revision_id = merges.get(
1324 proposal.source_git_commit_sha1)1324 proposal.source_git_commit_sha1)
diff --git a/lib/lp/code/model/revision.py b/lib/lp/code/model/revision.py
index 4958e32..680f3a2 100644
--- a/lib/lp/code/model/revision.py
+++ b/lib/lp/code/model/revision.py
@@ -120,7 +120,7 @@ class Revision(SQLBase):
120120
121 def getProperties(self):121 def getProperties(self):
122 """See `IRevision`."""122 """See `IRevision`."""
123 return dict((prop.name, prop.value) for prop in self.properties)123 return {prop.name: prop.value for prop in self.properties}
124124
125 def allocateKarma(self, branch):125 def allocateKarma(self, branch):
126 """See `IRevision`."""126 """See `IRevision`."""
@@ -347,9 +347,9 @@ class RevisionSet:
347 author = None347 author = None
348 author_names.append(author)348 author_names.append(author)
349 # Get or make every RevisionAuthor for these revisions.349 # Get or make every RevisionAuthor for these revisions.
350 revision_authors = dict(350 revision_authors = {
351 (name, author.id) for name, author in351 name: author.id for name, author in
352 self.acquireRevisionAuthors(author_names).items())352 self.acquireRevisionAuthors(author_names).items()}
353353
354 # Collect all data for making Revision objects.354 # Collect all data for making Revision objects.
355 data = []355 data = []
@@ -367,8 +367,8 @@ class RevisionSet:
367 Revision.revision_author_id), data, get_objects=True)367 Revision.revision_author_id), data, get_objects=True)
368368
369 # Map revision_id to Revision database ID.369 # Map revision_id to Revision database ID.
370 revision_db_id = dict(370 revision_db_id = {
371 (rev.revision_id, rev.id) for rev in db_revisions)371 rev.revision_id: rev.id for rev in db_revisions}
372372
373 # Collect all data for making RevisionParent and RevisionProperty373 # Collect all data for making RevisionParent and RevisionProperty
374 # objects.374 # objects.
diff --git a/lib/lp/code/model/seriessourcepackagebranch.py b/lib/lp/code/model/seriessourcepackagebranch.py
index 5aa7d7d..051d86e 100644
--- a/lib/lp/code/model/seriessourcepackagebranch.py
+++ b/lib/lp/code/model/seriessourcepackagebranch.py
@@ -103,7 +103,7 @@ class SeriesSourcePackageBranchSet:
103103
104 def findForBranches(self, branches):104 def findForBranches(self, branches):
105 """See `IFindOfficialBranchLinks`."""105 """See `IFindOfficialBranchLinks`."""
106 branch_ids = set(branch.id for branch in branches)106 branch_ids = {branch.id for branch in branches}
107 return IStore(SeriesSourcePackageBranch).find(107 return IStore(SeriesSourcePackageBranch).find(
108 SeriesSourcePackageBranch,108 SeriesSourcePackageBranch,
109 SeriesSourcePackageBranch.branchID.is_in(branch_ids))109 SeriesSourcePackageBranch.branchID.is_in(branch_ids))
diff --git a/lib/lp/code/model/sourcepackagerecipebuild.py b/lib/lp/code/model/sourcepackagerecipebuild.py
index 3a4f0ba..f10ed3c 100644
--- a/lib/lp/code/model/sourcepackagerecipebuild.py
+++ b/lib/lp/code/model/sourcepackagerecipebuild.py
@@ -390,9 +390,9 @@ class SourcePackageRecipeBuild(SpecificBuildFarmJobSourceMixin,
390390
391 def getFileByName(self, filename):391 def getFileByName(self, filename):
392 """See `ISourcePackageRecipeBuild`."""392 """See `ISourcePackageRecipeBuild`."""
393 files = dict((lfa.filename, lfa)393 files = {lfa.filename: lfa
394 for lfa in [self.log, self.upload_log]394 for lfa in [self.log, self.upload_log]
395 if lfa is not None)395 if lfa is not None}
396 try:396 try:
397 return files[filename]397 return files[filename]
398 except KeyError:398 except KeyError:
diff --git a/lib/lp/code/model/tests/test_branch.py b/lib/lp/code/model/tests/test_branch.py
index 9379266..16858d2 100644
--- a/lib/lp/code/model/tests/test_branch.py
+++ b/lib/lp/code/model/tests/test_branch.py
@@ -1783,7 +1783,7 @@ class StackedBranches(TestCaseWithFactory):
1783 branch = self.factory.makeAnyBranch()1783 branch = self.factory.makeAnyBranch()
1784 stacked_branch = self.factory.makeAnyBranch(stacked_on=branch)1784 stacked_branch = self.factory.makeAnyBranch(stacked_on=branch)
1785 self.assertEqual(1785 self.assertEqual(
1786 set([stacked_branch]), set(branch.getStackedBranches()))1786 {stacked_branch}, set(branch.getStackedBranches()))
17871787
1788 def testMultipleBranchesStacked(self):1788 def testMultipleBranchesStacked(self):
1789 # some_branch.getStackedBranches returns a collection of branches1789 # some_branch.getStackedBranches returns a collection of branches
@@ -1792,7 +1792,7 @@ class StackedBranches(TestCaseWithFactory):
1792 stacked_a = self.factory.makeAnyBranch(stacked_on=branch)1792 stacked_a = self.factory.makeAnyBranch(stacked_on=branch)
1793 stacked_b = self.factory.makeAnyBranch(stacked_on=branch)1793 stacked_b = self.factory.makeAnyBranch(stacked_on=branch)
1794 self.assertEqual(1794 self.assertEqual(
1795 set([stacked_a, stacked_b]), set(branch.getStackedBranches()))1795 {stacked_a, stacked_b}, set(branch.getStackedBranches()))
17961796
1797 def testNoBranchesStackedOn(self):1797 def testNoBranchesStackedOn(self):
1798 # getStackedBranches returns an empty collection if there are no1798 # getStackedBranches returns an empty collection if there are no
@@ -1806,7 +1806,7 @@ class StackedBranches(TestCaseWithFactory):
1806 branch = self.factory.makeAnyBranch()1806 branch = self.factory.makeAnyBranch()
1807 stacked_branch = self.factory.makeAnyBranch(stacked_on=branch)1807 stacked_branch = self.factory.makeAnyBranch(stacked_on=branch)
1808 self.assertEqual(1808 self.assertEqual(
1809 set([branch]), set(stacked_branch.getStackedOnBranches()))1809 {branch}, set(stacked_branch.getStackedOnBranches()))
18101810
1811 def testMultipleBranchesStackedOn(self):1811 def testMultipleBranchesStackedOn(self):
1812 # some_branch.getStackedOnBranches returns a collection of branches1812 # some_branch.getStackedOnBranches returns a collection of branches
@@ -1815,7 +1815,7 @@ class StackedBranches(TestCaseWithFactory):
1815 stacked_b = self.factory.makeAnyBranch(stacked_on=stacked_a)1815 stacked_b = self.factory.makeAnyBranch(stacked_on=stacked_a)
1816 branch = self.factory.makeAnyBranch(stacked_on=stacked_b)1816 branch = self.factory.makeAnyBranch(stacked_on=stacked_b)
1817 self.assertEqual(1817 self.assertEqual(
1818 set([stacked_a, stacked_b]), set(branch.getStackedOnBranches()))1818 {stacked_a, stacked_b}, set(branch.getStackedOnBranches()))
18191819
18201820
1821class BranchAddLandingTarget(TestCaseWithFactory):1821class BranchAddLandingTarget(TestCaseWithFactory):
@@ -1976,9 +1976,9 @@ class BranchAddLandingTarget(TestCaseWithFactory):
1976 bmp = self.source._createMergeProposal(1976 bmp = self.source._createMergeProposal(
1977 self.user, self.target, reviewers=[person1, person2],1977 self.user, self.target, reviewers=[person1, person2],
1978 review_types=['review1', 'review2'])1978 review_types=['review1', 'review2'])
1979 votes = set((vote.reviewer, vote.review_type) for vote in bmp.votes)1979 votes = {(vote.reviewer, vote.review_type) for vote in bmp.votes}
1980 self.assertEqual(1980 self.assertEqual(
1981 set([(person1, 'review1'), (person2, 'review2')]), votes)1981 {(person1, 'review1'), (person2, 'review2')}, votes)
19821982
19831983
1984class TestLandingCandidates(TestCaseWithFactory):1984class TestLandingCandidates(TestCaseWithFactory):
@@ -3161,9 +3161,9 @@ class TestScheduleDiffUpdates(TestCaseWithFactory):
3161 removeSecurityProxy(bmp2).target_branch.last_scanned_id = 'rev2'3161 removeSecurityProxy(bmp2).target_branch.last_scanned_id = 'rev2'
3162 jobs = bmp1.source_branch.scheduleDiffUpdates()3162 jobs = bmp1.source_branch.scheduleDiffUpdates()
3163 self.assertEqual(2, len(jobs))3163 self.assertEqual(2, len(jobs))
3164 bmps_to_update = set(3164 bmps_to_update = {
3165 removeSecurityProxy(job).branch_merge_proposal for job in jobs)3165 removeSecurityProxy(job).branch_merge_proposal for job in jobs}
3166 self.assertEqual(set([bmp1, bmp2]), bmps_to_update)3166 self.assertEqual({bmp1, bmp2}, bmps_to_update)
31673167
3168 def test_scheduleDiffUpdates_ignores_final(self):3168 def test_scheduleDiffUpdates_ignores_final(self):
3169 """Diffs for proposals in final states aren't updated."""3169 """Diffs for proposals in final states aren't updated."""
diff --git a/lib/lp/code/model/tests/test_branchjob.py b/lib/lp/code/model/tests/test_branchjob.py
index ad2dd1b..d3b7592 100644
--- a/lib/lp/code/model/tests/test_branchjob.py
+++ b/lib/lp/code/model/tests/test_branchjob.py
@@ -576,7 +576,7 @@ class TestRevisionsAddedJob(TestCaseWithFactory):
576 graph = job.bzr_branch.repository.get_graph()576 graph = job.bzr_branch.repository.get_graph()
577 self.addCleanup(job.bzr_branch.unlock)577 self.addCleanup(job.bzr_branch.unlock)
578 self.assertEqual(578 self.assertEqual(
579 set([b'rev2a-id', b'rev3-id', b'rev2b-id', b'rev2c-id']),579 {b'rev2a-id', b'rev3-id', b'rev2b-id', b'rev2c-id'},
580 job.getMergedRevisionIDs(b'rev2d-id', graph))580 job.getMergedRevisionIDs(b'rev2d-id', graph))
581581
582 def test_findRelatedBMP(self):582 def test_findRelatedBMP(self):
@@ -622,7 +622,7 @@ class TestRevisionsAddedJob(TestCaseWithFactory):
622 self.addCleanup(job.bzr_branch.unlock)622 self.addCleanup(job.bzr_branch.unlock)
623 graph = job.bzr_branch.repository.get_graph()623 graph = job.bzr_branch.repository.get_graph()
624 revision_ids = [b'rev2a-id', b'rev3-id', b'rev2b-id']624 revision_ids = [b'rev2a-id', b'rev3-id', b'rev2b-id']
625 self.assertEqual(set(['foo@', 'bar@', 'baz@blaine.com', 'qux@']),625 self.assertEqual({'foo@', 'bar@', 'baz@blaine.com', 'qux@'},
626 job.getAuthors(revision_ids, graph))626 job.getAuthors(revision_ids, graph))
627627
628 def test_getAuthors_with_ghost(self):628 def test_getAuthors_with_ghost(self):
@@ -632,7 +632,7 @@ class TestRevisionsAddedJob(TestCaseWithFactory):
632 graph = job.bzr_branch.repository.get_graph()632 graph = job.bzr_branch.repository.get_graph()
633 self.addCleanup(job.bzr_branch.unlock)633 self.addCleanup(job.bzr_branch.unlock)
634 revision_ids = [b'rev2a-id', b'rev3-id', b'rev2b-id', b'rev2c-id']634 revision_ids = [b'rev2a-id', b'rev3-id', b'rev2b-id', b'rev2c-id']
635 self.assertEqual(set(['foo@', 'bar@', 'baz@blaine.com', 'qux@']),635 self.assertEqual({'foo@', 'bar@', 'baz@blaine.com', 'qux@'},
636 job.getAuthors(revision_ids, graph))636 job.getAuthors(revision_ids, graph))
637637
638 def test_getRevisionMessage(self):638 def test_getRevisionMessage(self):
diff --git a/lib/lp/code/model/tests/test_branchmergeproposal.py b/lib/lp/code/model/tests/test_branchmergeproposal.py
index 3e58e46..ed4fdd4 100644
--- a/lib/lp/code/model/tests/test_branchmergeproposal.py
+++ b/lib/lp/code/model/tests/test_branchmergeproposal.py
@@ -399,7 +399,7 @@ class TestBranchMergeProposalTransitions(TestCaseWithFactory):
399 proposal = self.factory.makeBranchMergeProposal()399 proposal = self.factory.makeBranchMergeProposal()
400 # It is always valid to go to the same state.400 # It is always valid to go to the same state.
401 self.assertValidTransitions(401 self.assertValidTransitions(
402 set([BranchMergeProposalStatus.REJECTED]),402 {BranchMergeProposalStatus.REJECTED},
403 proposal, BranchMergeProposalStatus.REJECTED,403 proposal, BranchMergeProposalStatus.REJECTED,
404 proposal.source_branch.owner)404 proposal.source_branch.owner)
405405
@@ -610,7 +610,7 @@ class TestMergeProposalAllComments(TestCase):
610 comment3 = self.merge_proposal.createComment(610 comment3 = self.merge_proposal.createComment(
611 self.merge_proposal.registrant, "Subject")611 self.merge_proposal.registrant, "Subject")
612 self.assertEqual(612 self.assertEqual(
613 set([comment1, comment2, comment3]),613 {comment1, comment2, comment3},
614 set(self.merge_proposal.all_comments))614 set(self.merge_proposal.all_comments))
615615
616616
@@ -816,7 +816,7 @@ class TestMergeProposalNotification(WithVCSScenarios, TestCaseWithFactory):
816 target_owner = bmp.merge_target.owner816 target_owner = bmp.merge_target.owner
817 recipients = bmp.getNotificationRecipients(817 recipients = bmp.getNotificationRecipients(
818 CodeReviewNotificationLevel.STATUS)818 CodeReviewNotificationLevel.STATUS)
819 subscriber_set = set([source_owner, target_owner])819 subscriber_set = {source_owner, target_owner}
820 self.assertEqual(subscriber_set, set(recipients.keys()))820 self.assertEqual(subscriber_set, set(recipients.keys()))
821 source_subscriber = self.factory.makePerson()821 source_subscriber = self.factory.makePerson()
822 bmp.merge_source.subscribe(822 bmp.merge_source.subscribe(
@@ -856,12 +856,12 @@ class TestMergeProposalNotification(WithVCSScenarios, TestCaseWithFactory):
856 # branches with full code review notification level set.856 # branches with full code review notification level set.
857 source_owner = bmp.merge_source.owner857 source_owner = bmp.merge_source.owner
858 target_owner = bmp.merge_target.owner858 target_owner = bmp.merge_target.owner
859 self.assertEqual(set([full_subscriber, status_subscriber,859 self.assertEqual({full_subscriber, status_subscriber,
860 source_owner, target_owner]),860 source_owner, target_owner},
861 set(recipients.keys()))861 set(recipients.keys()))
862 recipients = bmp.getNotificationRecipients(862 recipients = bmp.getNotificationRecipients(
863 CodeReviewNotificationLevel.FULL)863 CodeReviewNotificationLevel.FULL)
864 self.assertEqual(set([full_subscriber, source_owner, target_owner]),864 self.assertEqual({full_subscriber, source_owner, target_owner},
865 set(recipients.keys()))865 set(recipients.keys()))
866866
867 def test_getNotificationRecipientsAnyBranch(self):867 def test_getNotificationRecipientsAnyBranch(self):
@@ -873,7 +873,7 @@ class TestMergeProposalNotification(WithVCSScenarios, TestCaseWithFactory):
873 target_owner = bmp.merge_target.owner873 target_owner = bmp.merge_target.owner
874 prerequisite_owner = bmp.merge_prerequisite.owner874 prerequisite_owner = bmp.merge_prerequisite.owner
875 self.assertEqual(875 self.assertEqual(
876 set([source_owner, target_owner, prerequisite_owner]),876 {source_owner, target_owner, prerequisite_owner},
877 set(recipients.keys()))877 set(recipients.keys()))
878 source_subscriber = self.factory.makePerson()878 source_subscriber = self.factory.makePerson()
879 bmp.merge_source.subscribe(source_subscriber,879 bmp.merge_source.subscribe(source_subscriber,
@@ -890,9 +890,9 @@ class TestMergeProposalNotification(WithVCSScenarios, TestCaseWithFactory):
890 recipients = bmp.getNotificationRecipients(890 recipients = bmp.getNotificationRecipients(
891 CodeReviewNotificationLevel.FULL)891 CodeReviewNotificationLevel.FULL)
892 self.assertEqual(892 self.assertEqual(
893 set([source_subscriber, target_subscriber,893 {source_subscriber, target_subscriber,
894 prerequisite_subscriber, source_owner, target_owner,894 prerequisite_subscriber, source_owner, target_owner,
895 prerequisite_owner]),895 prerequisite_owner},
896 set(recipients.keys()))896 set(recipients.keys()))
897897
898 def test_getNotificationRecipientsIncludesReviewers(self):898 def test_getNotificationRecipientsIncludesReviewers(self):
@@ -906,7 +906,7 @@ class TestMergeProposalNotification(WithVCSScenarios, TestCaseWithFactory):
906 bmp.nominateReviewer(reviewer, registrant=source_owner)906 bmp.nominateReviewer(reviewer, registrant=source_owner)
907 recipients = bmp.getNotificationRecipients(907 recipients = bmp.getNotificationRecipients(
908 CodeReviewNotificationLevel.STATUS)908 CodeReviewNotificationLevel.STATUS)
909 subscriber_set = set([source_owner, target_owner, reviewer])909 subscriber_set = {source_owner, target_owner, reviewer}
910 self.assertEqual(subscriber_set, set(recipients.keys()))910 self.assertEqual(subscriber_set, set(recipients.keys()))
911911
912 def test_getNotificationRecipientsIncludesTeamReviewers(self):912 def test_getNotificationRecipientsIncludesTeamReviewers(self):
@@ -921,7 +921,7 @@ class TestMergeProposalNotification(WithVCSScenarios, TestCaseWithFactory):
921 bmp.nominateReviewer(reviewer, registrant=source_owner)921 bmp.nominateReviewer(reviewer, registrant=source_owner)
922 recipients = bmp.getNotificationRecipients(922 recipients = bmp.getNotificationRecipients(
923 CodeReviewNotificationLevel.STATUS)923 CodeReviewNotificationLevel.STATUS)
924 subscriber_set = set([source_owner, target_owner, reviewer])924 subscriber_set = {source_owner, target_owner, reviewer}
925 self.assertEqual(subscriber_set, set(recipients.keys()))925 self.assertEqual(subscriber_set, set(recipients.keys()))
926926
927 def test_getNotificationRecipients_Registrant(self):927 def test_getNotificationRecipients_Registrant(self):
@@ -971,7 +971,7 @@ class TestMergeProposalNotification(WithVCSScenarios, TestCaseWithFactory):
971 bmp = self.makeBranchMergeProposal(source=branch)971 bmp = self.makeBranchMergeProposal(source=branch)
972 recipients = bmp.getNotificationRecipients(972 recipients = bmp.getNotificationRecipients(
973 CodeReviewNotificationLevel.STATUS)973 CodeReviewNotificationLevel.STATUS)
974 headers = set([reason.mail_header for reason in recipients.values()])974 headers = {reason.mail_header for reason in recipients.values()}
975 self.assertFalse("Owner" in headers)975 self.assertFalse("Owner" in headers)
976976
977 def test_getNotificationRecipients_Owner_not_subscribed(self):977 def test_getNotificationRecipients_Owner_not_subscribed(self):
@@ -1325,7 +1325,7 @@ class TestBranchMergeProposalGetterGetProposals(TestCaseWithFactory):
1325 # Helper method to return tuples of source branch details.1325 # Helper method to return tuples of source branch details.
1326 results = BranchMergeProposalGetter.getProposalsForContext(1326 results = BranchMergeProposalGetter.getProposalsForContext(
1327 context, status, visible_by_user)1327 context, status, visible_by_user)
1328 return sorted([bmp.source_branch.unique_name for bmp in results])1328 return sorted(bmp.source_branch.unique_name for bmp in results)
13291329
1330 def test_getProposalsForParticipant(self):1330 def test_getProposalsForParticipant(self):
1331 # It's possible to get all the merge proposals for a single1331 # It's possible to get all the merge proposals for a single
@@ -1848,7 +1848,7 @@ class TestBranchMergeProposalNominateReviewer(
1848 votes = list(merge_proposal.votes)1848 votes = list(merge_proposal.votes)
1849 self.assertEqual(1849 self.assertEqual(
1850 ['general-1', 'general-2'],1850 ['general-1', 'general-2'],
1851 sorted([review.review_type for review in votes]))1851 sorted(review.review_type for review in votes))
18521852
1853 def test_nominate_multiple_with_same_types(self):1853 def test_nominate_multiple_with_same_types(self):
1854 # There can be multiple reviews for a team with the same review_type.1854 # There can be multiple reviews for a team with the same review_type.
@@ -2111,9 +2111,9 @@ class TestBranchMergeProposalResubmit(TestCaseWithFactory):
2111 review_type='specious')2111 review_type='specious')
2112 bmp2 = bmp1.resubmit(bmp1.registrant)2112 bmp2 = bmp1.resubmit(bmp1.registrant)
2113 self.assertEqual(2113 self.assertEqual(
2114 set([(bmp1.target_branch.owner, None), (nominee, 'nominee'),2114 {(bmp1.target_branch.owner, None), (nominee, 'nominee'),
2115 (reviewer, 'specious')]),2115 (reviewer, 'specious')},
2116 set((vote.reviewer, vote.review_type) for vote in bmp2.votes))2116 {(vote.reviewer, vote.review_type) for vote in bmp2.votes})
21172117
2118 def test_resubmit_no_reviewers(self):2118 def test_resubmit_no_reviewers(self):
2119 """Resubmitting a proposal with no reviewers should work."""2119 """Resubmitting a proposal with no reviewers should work."""
diff --git a/lib/lp/code/model/tests/test_codeimportjob.py b/lib/lp/code/model/tests/test_codeimportjob.py
index 4ff9155..d2785a6 100644
--- a/lib/lp/code/model/tests/test_codeimportjob.py
+++ b/lib/lp/code/model/tests/test_codeimportjob.py
@@ -474,7 +474,7 @@ class NewEvents(object):
474474
475 def __init__(self):475 def __init__(self):
476 event_set = getUtility(ICodeImportEventSet)476 event_set = getUtility(ICodeImportEventSet)
477 self.initial = set(event.id for event in event_set.getAll())477 self.initial = {event.id for event in event_set.getAll()}
478478
479 def summary(self):479 def summary(self):
480 """Render a summary of the newly created CodeImportEvent objects."""480 """Render a summary of the newly created CodeImportEvent objects."""
diff --git a/lib/lp/code/model/tests/test_diff.py b/lib/lp/code/model/tests/test_diff.py
index 9675214..794ffbe 100644
--- a/lib/lp/code/model/tests/test_diff.py
+++ b/lib/lp/code/model/tests/test_diff.py
@@ -282,47 +282,47 @@ class TestDiffInScripts(DiffTestCase):
282 self.checkExampleBzrMerge(diff.text)282 self.checkExampleBzrMerge(diff.text)
283283
284 diff_bytes = (284 diff_bytes = (
285 "--- bar\t2009-08-26 15:53:34.000000000 -0400\n"285 b"--- bar\t2009-08-26 15:53:34.000000000 -0400\n"
286 "+++ bar\t1969-12-31 19:00:00.000000000 -0500\n"286 b"+++ bar\t1969-12-31 19:00:00.000000000 -0500\n"
287 "@@ -1,3 +0,0 @@\n"287 b"@@ -1,3 +0,0 @@\n"
288 "-a\n"288 b"-a\n"
289 "-b\n"289 b"-b\n"
290 "-c\n"290 b"-c\n"
291 "--- baz\t1969-12-31 19:00:00.000000000 -0500\n"291 b"--- baz\t1969-12-31 19:00:00.000000000 -0500\n"
292 "+++ baz\t2009-08-26 15:53:57.000000000 -0400\n"292 b"+++ baz\t2009-08-26 15:53:57.000000000 -0400\n"
293 "@@ -0,0 +1,2 @@\n"293 b"@@ -0,0 +1,2 @@\n"
294 "+a\n"294 b"+a\n"
295 "+b\n"295 b"+b\n"
296 "--- foo\t2009-08-26 15:53:23.000000000 -0400\n"296 b"--- foo\t2009-08-26 15:53:23.000000000 -0400\n"
297 "+++ foo\t2009-08-26 15:56:43.000000000 -0400\n"297 b"+++ foo\t2009-08-26 15:56:43.000000000 -0400\n"
298 "@@ -1,3 +1,4 @@\n"298 b"@@ -1,3 +1,4 @@\n"
299 " a\n"299 b" a\n"
300 "-b\n"300 b"-b\n"
301 " c\n"301 b" c\n"
302 "+d\n"302 b"+d\n"
303 "+e\n").encode("UTF-8")303 b"+e\n")
304304
305 diff_bytes_2 = (305 diff_bytes_2 = (
306 "--- bar\t2009-08-26 15:53:34.000000000 -0400\n"306 b"--- bar\t2009-08-26 15:53:34.000000000 -0400\n"
307 "+++ bar\t1969-12-31 19:00:00.000000000 -0500\n"307 b"+++ bar\t1969-12-31 19:00:00.000000000 -0500\n"
308 "@@ -1,3 +0,0 @@\n"308 b"@@ -1,3 +0,0 @@\n"
309 "-a\n"309 b"-a\n"
310 "-b\n"310 b"-b\n"
311 "-c\n"311 b"-c\n"
312 "--- baz\t1969-12-31 19:00:00.000000000 -0500\n"312 b"--- baz\t1969-12-31 19:00:00.000000000 -0500\n"
313 "+++ baz\t2009-08-26 15:53:57.000000000 -0400\n"313 b"+++ baz\t2009-08-26 15:53:57.000000000 -0400\n"
314 "@@ -0,0 +1,2 @@\n"314 b"@@ -0,0 +1,2 @@\n"
315 "+a\n"315 b"+a\n"
316 "+b\n"316 b"+b\n"
317 "--- foo\t2009-08-26 15:53:23.000000000 -0400\n"317 b"--- foo\t2009-08-26 15:53:23.000000000 -0400\n"
318 "+++ foo\t2009-08-26 15:56:43.000000000 -0400\n"318 b"+++ foo\t2009-08-26 15:56:43.000000000 -0400\n"
319 "@@ -1,3 +1,5 @@\n"319 b"@@ -1,3 +1,5 @@\n"
320 " a\n"320 b" a\n"
321 "-b\n"321 b"-b\n"
322 " c\n"322 b" c\n"
323 "+d\n"323 b"+d\n"
324 "+e\n"324 b"+e\n"
325 "+f\n").encode("UTF-8")325 b"+f\n")
326326
327 def test_mergePreviewWithPrerequisite(self):327 def test_mergePreviewWithPrerequisite(self):
328 # Changes introduced in the prerequisite branch are ignored.328 # Changes introduced in the prerequisite branch are ignored.
@@ -354,10 +354,10 @@ class TestDiffInScripts(DiffTestCase):
354354
355 def test_generateDiffstat_with_CR(self):355 def test_generateDiffstat_with_CR(self):
356 diff_bytes = (356 diff_bytes = (
357 "--- foo\t2009-08-26 15:53:23.000000000 -0400\n"357 b"--- foo\t2009-08-26 15:53:23.000000000 -0400\n"
358 "+++ foo\t2009-08-26 15:56:43.000000000 -0400\n"358 b"+++ foo\t2009-08-26 15:56:43.000000000 -0400\n"
359 "@@ -1,1 +1,1 @@\n"359 b"@@ -1,1 +1,1 @@\n"
360 " a\r-b\r c\r+d\r+e\r+f\r").encode("UTF-8")360 b" a\r-b\r c\r+d\r+e\r+f\r")
361 self.assertEqual({'foo': (0, 0)}, Diff.generateDiffstat(diff_bytes))361 self.assertEqual({'foo': (0, 0)}, Diff.generateDiffstat(diff_bytes))
362362
363 def test_fromFileSetsDiffstat(self):363 def test_fromFileSetsDiffstat(self):
@@ -442,7 +442,7 @@ class TestPreviewDiff(DiffTestCase):
442 # canonical_url of the merge proposal itself.442 # canonical_url of the merge proposal itself.
443 mp = self._createProposalWithPreviewDiff()443 mp = self._createProposalWithPreviewDiff()
444 self.assertEqual(444 self.assertEqual(
445 '{0}/+preview-diff/{1}'.format(445 '{}/+preview-diff/{}'.format(
446 canonical_url(mp), mp.preview_diff.id),446 canonical_url(mp), mp.preview_diff.id),
447 canonical_url(mp.preview_diff))447 canonical_url(mp.preview_diff))
448448
diff --git a/lib/lp/code/model/tests/test_gitrepository.py b/lib/lp/code/model/tests/test_gitrepository.py
index dbdf8d9..548cb62 100644
--- a/lib/lp/code/model/tests/test_gitrepository.py
+++ b/lib/lp/code/model/tests/test_gitrepository.py
@@ -1288,7 +1288,7 @@ class TestGitRepositoryModifications(TestCaseWithFactory):
1288 repository = self.factory.makeGitRepository(1288 repository = self.factory.makeGitRepository(
1289 date_created=datetime(2015, 6, 1, tzinfo=pytz.UTC))1289 date_created=datetime(2015, 6, 1, tzinfo=pytz.UTC))
1290 [ref] = self.factory.makeGitRefs(repository=repository)1290 [ref] = self.factory.makeGitRefs(repository=repository)
1291 repository.removeRefs(set([ref.path]))1291 repository.removeRefs({ref.path})
1292 self.assertSqlAttributeEqualsDate(1292 self.assertSqlAttributeEqualsDate(
1293 repository, "date_last_modified", UTC_NOW)1293 repository, "date_last_modified", UTC_NOW)
12941294
@@ -1783,7 +1783,7 @@ class TestGitRepositoryRefs(TestCaseWithFactory):
1783 },1783 },
1784 }1784 }
1785 self.assertEqual(expected_upsert, refs_to_upsert)1785 self.assertEqual(expected_upsert, refs_to_upsert)
1786 self.assertEqual(set(["refs/heads/bar"]), refs_to_remove)1786 self.assertEqual({"refs/heads/bar"}, refs_to_remove)
17871787
1788 def test_planRefChanges_skips_non_commits(self):1788 def test_planRefChanges_skips_non_commits(self):
1789 # planRefChanges does not attempt to update refs that point to1789 # planRefChanges does not attempt to update refs that point to
@@ -1957,7 +1957,7 @@ class TestGitRepositoryRefs(TestCaseWithFactory):
1957 "type": GitObjectType.COMMIT,1957 "type": GitObjectType.COMMIT,
1958 },1958 },
1959 }1959 }
1960 refs_to_remove = set(["refs/heads/bar"])1960 refs_to_remove = {"refs/heads/bar"}
1961 repository.synchroniseRefs(refs_to_upsert, refs_to_remove)1961 repository.synchroniseRefs(refs_to_upsert, refs_to_remove)
1962 expected_sha1s = [1962 expected_sha1s = [
1963 ("refs/heads/master", "1111111111111111111111111111111111111111"),1963 ("refs/heads/master", "1111111111111111111111111111111111111111"),
@@ -2968,10 +2968,10 @@ class TestGitRepositoryDetectMerges(TestCaseWithFactory):
2968 "Work in progress => Merged",2968 "Work in progress => Merged",
2969 notifications[0].get_payload(decode=True).decode("UTF-8"))2969 notifications[0].get_payload(decode=True).decode("UTF-8"))
2970 self.assertEqual(proposal.address, notifications[0]["From"])2970 self.assertEqual(proposal.address, notifications[0]["From"])
2971 recipients = set(msg["x-envelope-to"] for msg in notifications)2971 recipients = {msg["x-envelope-to"] for msg in notifications}
2972 expected = set(2972 expected = {
2973 [proposal.source_git_repository.registrant.preferredemail.email,2973 proposal.source_git_repository.registrant.preferredemail.email,
2974 proposal.target_git_repository.registrant.preferredemail.email])2974 proposal.target_git_repository.registrant.preferredemail.email}
2975 self.assertEqual(expected, recipients)2975 self.assertEqual(expected, recipients)
29762976
2977 def test_update_detects_merges(self):2977 def test_update_detects_merges(self):
@@ -3009,9 +3009,9 @@ class TestGitRepositoryDetectMerges(TestCaseWithFactory):
3009 expected_events, True, repository.createOrUpdateRefs, refs_info)3009 expected_events, True, repository.createOrUpdateRefs, refs_info)
3010 expected_args = [3010 expected_args = [
3011 (repository.getInternalPath(), target_1.commit_sha1,3011 (repository.getInternalPath(), target_1.commit_sha1,
3012 set([source_1.commit_sha1, source_2.commit_sha1])),3012 {source_1.commit_sha1, source_2.commit_sha1}),
3013 (repository.getInternalPath(), target_2.commit_sha1,3013 (repository.getInternalPath(), target_2.commit_sha1,
3014 set([source_1.commit_sha1])),3014 {source_1.commit_sha1}),
3015 ]3015 ]
3016 self.assertContentEqual(3016 self.assertContentEqual(
3017 expected_args, hosting_fixture.detectMerges.extract_args())3017 expected_args, hosting_fixture.detectMerges.extract_args())
@@ -3027,9 +3027,9 @@ class TestGitRepositoryDetectMerges(TestCaseWithFactory):
3027 self.assertContentEqual(3027 self.assertContentEqual(
3028 [(BranchMergeProposalStatus.WORK_IN_PROGRESS,3028 [(BranchMergeProposalStatus.WORK_IN_PROGRESS,
3029 BranchMergeProposalStatus.MERGED)],3029 BranchMergeProposalStatus.MERGED)],
3030 set((event.object_before_modification.queue_status,3030 {(event.object_before_modification.queue_status,
3031 event.object.queue_status)3031 event.object.queue_status)
3032 for event in events[:2]))3032 for event in events[:2]})
30333033
30343034
3035class TestGitRepositoryGetBlob(TestCaseWithFactory):3035class TestGitRepositoryGetBlob(TestCaseWithFactory):
diff --git a/lib/lp/code/model/tests/test_revision.py b/lib/lp/code/model/tests/test_revision.py
index 376a32f..957f2ca 100644
--- a/lib/lp/code/model/tests/test_revision.py
+++ b/lib/lp/code/model/tests/test_revision.py
@@ -711,7 +711,7 @@ class TestOnlyPresent(TestCaseWithFactory):
711 # onlyPresent returns a revid that is present in the database.711 # onlyPresent returns a revid that is present in the database.
712 present = self.factory.makeRevision().revision_id712 present = self.factory.makeRevision().revision_id
713 self.assertEqual(713 self.assertEqual(
714 set([present]),714 {present},
715 set(getUtility(IRevisionSet).onlyPresent([present])))715 set(getUtility(IRevisionSet).onlyPresent([present])))
716716
717 def test_some_present(self):717 def test_some_present(self):
@@ -719,7 +719,7 @@ class TestOnlyPresent(TestCaseWithFactory):
719 not_present = self.factory.getUniqueString()719 not_present = self.factory.getUniqueString()
720 present = self.factory.makeRevision().revision_id720 present = self.factory.makeRevision().revision_id
721 self.assertEqual(721 self.assertEqual(
722 set([present]),722 {present},
723 set(getUtility(IRevisionSet).onlyPresent([present, not_present])))723 set(getUtility(IRevisionSet).onlyPresent([present, not_present])))
724724
725 def test_call_twice_in_one_transaction(self):725 def test_call_twice_in_one_transaction(self):
diff --git a/lib/lp/code/model/tests/test_sourcepackagerecipe.py b/lib/lp/code/model/tests/test_sourcepackagerecipe.py
index 274b1d9..719ab3b 100644
--- a/lib/lp/code/model/tests/test_sourcepackagerecipe.py
+++ b/lib/lp/code/model/tests/test_sourcepackagerecipe.py
@@ -552,7 +552,7 @@ class TestSourcePackageRecipeMixin:
552 (old_distroseries,) = recipe.distroseries552 (old_distroseries,) = recipe.distroseries
553 recipe.distroseries.add(distroseries)553 recipe.distroseries.add(distroseries)
554 self.assertEqual(554 self.assertEqual(
555 set([distroseries, old_distroseries]), set(recipe.distroseries))555 {distroseries, old_distroseries}, set(recipe.distroseries))
556 recipe.distroseries.remove(distroseries)556 recipe.distroseries.remove(distroseries)
557 self.assertEqual([old_distroseries], list(recipe.distroseries))557 self.assertEqual([old_distroseries], list(recipe.distroseries))
558 recipe.distroseries.clear()558 recipe.distroseries.clear()
@@ -1195,7 +1195,7 @@ class TestWebserviceMixin:
1195 # at the moment, distroseries is not exposed in the API.1195 # at the moment, distroseries is not exposed in the API.
1196 transaction.commit()1196 transaction.commit()
1197 db_recipe = owner.getRecipe(name='toaster-1')1197 db_recipe = owner.getRecipe(name='toaster-1')
1198 self.assertEqual(set([db_distroseries]), set(db_recipe.distroseries))1198 self.assertEqual({db_distroseries}, set(db_recipe.distroseries))
1199 return recipe, ws_owner, launchpad1199 return recipe, ws_owner, launchpad
12001200
1201 def test_createRecipe(self):1201 def test_createRecipe(self):
diff --git a/lib/lp/code/tests/test_bzr.py b/lib/lp/code/tests/test_bzr.py
index 24ccead..7f6939c 100644
--- a/lib/lp/code/tests/test_bzr.py
+++ b/lib/lp/code/tests/test_bzr.py
@@ -111,11 +111,11 @@ class TestGetAncestry(TestCaseWithTransport):
111 tree.commit('msg b', rev_id=b'B')111 tree.commit('msg b', rev_id=b'B')
112 tree.commit('msg c', rev_id=b'C')112 tree.commit('msg c', rev_id=b'C')
113 self.assertEqual(113 self.assertEqual(
114 set([b'A']), get_ancestry(branch.repository, b'A'))114 {b'A'}, get_ancestry(branch.repository, b'A'))
115 self.assertEqual(115 self.assertEqual(
116 set([b'A', b'B']), get_ancestry(branch.repository, b'B'))116 {b'A', b'B'}, get_ancestry(branch.repository, b'B'))
117 self.assertEqual(117 self.assertEqual(
118 set([b'A', b'B', b'C']), get_ancestry(branch.repository, b'C'))118 {b'A', b'B', b'C'}, get_ancestry(branch.repository, b'C'))
119119
120 def test_children(self):120 def test_children(self):
121 # Verify non-mainline children are included.121 # Verify non-mainline children are included.
@@ -129,8 +129,8 @@ class TestGetAncestry(TestCaseWithTransport):
129 tree.set_parent_ids([b'A', b'B'])129 tree.set_parent_ids([b'A', b'B'])
130 tree.commit('msg c', rev_id=b'C')130 tree.commit('msg c', rev_id=b'C')
131 self.assertEqual(131 self.assertEqual(
132 set([b'A']), get_ancestry(branch.repository, b'A'))132 {b'A'}, get_ancestry(branch.repository, b'A'))
133 self.assertEqual(133 self.assertEqual(
134 set([b'B']), get_ancestry(branch.repository, b'B'))134 {b'B'}, get_ancestry(branch.repository, b'B'))
135 self.assertEqual(135 self.assertEqual(
136 set([b'A', b'B', b'C']), get_ancestry(branch.repository, b'C'))136 {b'A', b'B', b'C'}, get_ancestry(branch.repository, b'C'))
diff --git a/lib/lp/code/vocabularies/tests/test_branch_vocabularies.py b/lib/lp/code/vocabularies/tests/test_branch_vocabularies.py
index 8e0cef4..7773c17 100644
--- a/lib/lp/code/vocabularies/tests/test_branch_vocabularies.py
+++ b/lib/lp/code/vocabularies/tests/test_branch_vocabularies.py
@@ -42,7 +42,7 @@ class TestBranchVocabulary(TestCaseWithFactory):
42 results = self.vocab.searchForTerms('fizzbuzz')42 results = self.vocab.searchForTerms('fizzbuzz')
43 expected = [43 expected = [
44 u'~scotty/sprocket/fizzbuzz', u'~scotty/widget/fizzbuzz']44 u'~scotty/sprocket/fizzbuzz', u'~scotty/widget/fizzbuzz']
45 branch_names = sorted([branch.token for branch in results])45 branch_names = sorted(branch.token for branch in results)
46 self.assertEqual(expected, branch_names)46 self.assertEqual(expected, branch_names)
4747
48 def test_singleQueryResult(self):48 def test_singleQueryResult(self):
@@ -99,7 +99,7 @@ class TestRestrictedBranchVocabularyOnProduct(TestCaseWithFactory):
99 """99 """
100 results = self.vocab.searchForTerms('main')100 results = self.vocab.searchForTerms('main')
101 expected = [u'~scotty/widget/main']101 expected = [u'~scotty/widget/main']
102 branch_names = sorted([branch.token for branch in results])102 branch_names = sorted(branch.token for branch in results)
103 self.assertEqual(expected, branch_names)103 self.assertEqual(expected, branch_names)
104104
105 def test_singleQueryResult(self):105 def test_singleQueryResult(self):
@@ -122,7 +122,7 @@ class TestRestrictedBranchVocabularyOnProduct(TestCaseWithFactory):
122 self.factory.makeProductBranch(122 self.factory.makeProductBranch(
123 owner=team, product=self.product, name='mountain')123 owner=team, product=self.product, name='mountain')
124 results = self.vocab.searchForTerms('mountain')124 results = self.vocab.searchForTerms('mountain')
125 branch_names = sorted([branch.token for branch in results])125 branch_names = sorted(branch.token for branch in results)
126 self.assertEqual(['~scotty/widget/mountain'], branch_names)126 self.assertEqual(['~scotty/widget/mountain'], branch_names)
127127
128128
diff --git a/lib/lp/code/vocabularies/tests/test_gitrepository_vocabularies.py b/lib/lp/code/vocabularies/tests/test_gitrepository_vocabularies.py
index 9d76025..774b0a1 100644
--- a/lib/lp/code/vocabularies/tests/test_gitrepository_vocabularies.py
+++ b/lib/lp/code/vocabularies/tests/test_gitrepository_vocabularies.py
@@ -40,7 +40,7 @@ class TestGitRepositoryVocabulary(TestCaseWithFactory):
40 results = self.vocab.searchForTerms("fizzbuzz")40 results = self.vocab.searchForTerms("fizzbuzz")
41 expected = [41 expected = [
42 u"~scotty/sprocket/+git/fizzbuzz", u"~scotty/widget/+git/fizzbuzz"]42 u"~scotty/sprocket/+git/fizzbuzz", u"~scotty/widget/+git/fizzbuzz"]
43 repository_names = sorted([repository.token for repository in results])43 repository_names = sorted(repository.token for repository in results)
44 self.assertEqual(expected, repository_names)44 self.assertEqual(expected, repository_names)
4545
46 def test_singleQueryResult(self):46 def test_singleQueryResult(self):
@@ -94,7 +94,7 @@ class TestRestrictedGitRepositoryVocabularyOnProduct(TestCaseWithFactory):
94 """94 """
95 results = self.vocab.searchForTerms('mountain')95 results = self.vocab.searchForTerms('mountain')
96 expected = [u'~scotty/widget/+git/mountain']96 expected = [u'~scotty/widget/+git/mountain']
97 repo_names = sorted([repo.token for repo in results])97 repo_names = sorted(repo.token for repo in results)
98 self.assertEqual(expected, repo_names)98 self.assertEqual(expected, repo_names)
9999
100 def test_singleQueryResult(self):100 def test_singleQueryResult(self):
diff --git a/lib/lp/codehosting/inmemory.py b/lib/lp/codehosting/inmemory.py
index d68cc22..522f9d1 100644
--- a/lib/lp/codehosting/inmemory.py
+++ b/lib/lp/codehosting/inmemory.py
@@ -565,9 +565,9 @@ class FakeCodehosting:
565 raise UnknownBranchTypeError(565 raise UnknownBranchTypeError(
566 'Unknown branch type: %r' % (branch_type_name,))566 'Unknown branch type: %r' % (branch_type_name,))
567 branches = sorted(567 branches = sorted(
568 [branch for branch in self._branch_set568 (branch for branch in self._branch_set
569 if branch.next_mirror_time is not None569 if branch.next_mirror_time is not None
570 and branch.branch_type in branch_types],570 and branch.branch_type in branch_types),
571 key=operator.attrgetter('next_mirror_time'))571 key=operator.attrgetter('next_mirror_time'))
572 if branches:572 if branches:
573 branch = branches[-1]573 branch = branches[-1]
@@ -655,8 +655,8 @@ class FakeCodehosting:
655 # exceptions.655 # exceptions.
656 if not registrant.inTeam(owner):656 if not registrant.inTeam(owner):
657 raise faults.PermissionDenied(657 raise faults.PermissionDenied(
658 ('%s cannot create branches owned by %s'658 '%s cannot create branches owned by %s'
659 % (registrant.displayname, owner.displayname)))659 % (registrant.displayname, owner.displayname))
660 product = sourcepackage = None660 product = sourcepackage = None
661 if data['product'] == '+junk':661 if data['product'] == '+junk':
662 product = None662 product = None
diff --git a/lib/lp/codehosting/scanner/bzrsync.py b/lib/lp/codehosting/scanner/bzrsync.py
index e4298ad..1f60b07 100755
--- a/lib/lp/codehosting/scanner/bzrsync.py
+++ b/lib/lp/codehosting/scanner/bzrsync.py
@@ -149,10 +149,10 @@ class BzrSync:
149 revisions = Store.of(self.db_branch).find(Revision,149 revisions = Store.of(self.db_branch).find(Revision,
150 BranchRevision.branch_id == self.db_branch.id,150 BranchRevision.branch_id == self.db_branch.id,
151 Revision.id == BranchRevision.revision_id)151 Revision.id == BranchRevision.revision_id)
152 parent_map = dict(152 parent_map = {
153 (six.ensure_binary(r.revision_id),153 six.ensure_binary(r.revision_id):
154 [six.ensure_binary(revid) for revid in r.parent_ids])154 [six.ensure_binary(revid) for revid in r.parent_ids]
155 for r in revisions)155 for r in revisions}
156 parents_provider = DictParentsProvider(parent_map)156 parents_provider = DictParentsProvider(parent_map)
157157
158 class PPSource:158 class PPSource:
diff --git a/lib/lp/codehosting/scanner/tests/test_bzrsync.py b/lib/lp/codehosting/scanner/tests/test_bzrsync.py
index 77ef3d5..7fe8ad3 100644
--- a/lib/lp/codehosting/scanner/tests/test_bzrsync.py
+++ b/lib/lp/codehosting/scanner/tests/test_bzrsync.py
@@ -443,25 +443,25 @@ class TestBzrSync(BzrSyncTestCase):
443 added_ancestry, removed_ancestry = get_delta(b'merge', None)443 added_ancestry, removed_ancestry = get_delta(b'merge', None)
444 # All revisions are new for an unscanned branch444 # All revisions are new for an unscanned branch
445 self.assertEqual(445 self.assertEqual(
446 set(['base', 'trunk', 'branch', 'merge']), added_ancestry)446 {'base', 'trunk', 'branch', 'merge'}, added_ancestry)
447 self.assertEqual(set(), removed_ancestry)447 self.assertEqual(set(), removed_ancestry)
448 added_ancestry, removed_ancestry = get_delta(b'merge', 'base')448 added_ancestry, removed_ancestry = get_delta(b'merge', 'base')
449 self.assertEqual(449 self.assertEqual(
450 set(['trunk', 'branch', 'merge']), added_ancestry)450 {'trunk', 'branch', 'merge'}, added_ancestry)
451 self.assertEqual(set(), removed_ancestry)451 self.assertEqual(set(), removed_ancestry)
452 added_ancestry, removed_ancestry = get_delta(NULL_REVISION, 'merge')452 added_ancestry, removed_ancestry = get_delta(NULL_REVISION, 'merge')
453 self.assertEqual(453 self.assertEqual(
454 set(), added_ancestry)454 set(), added_ancestry)
455 self.assertEqual(455 self.assertEqual(
456 set(['base', 'trunk', 'branch', 'merge']), removed_ancestry)456 {'base', 'trunk', 'branch', 'merge'}, removed_ancestry)
457 added_ancestry, removed_ancestry = get_delta(b'base', 'merge')457 added_ancestry, removed_ancestry = get_delta(b'base', 'merge')
458 self.assertEqual(458 self.assertEqual(
459 set(), added_ancestry)459 set(), added_ancestry)
460 self.assertEqual(460 self.assertEqual(
461 set(['trunk', 'branch', 'merge']), removed_ancestry)461 {'trunk', 'branch', 'merge'}, removed_ancestry)
462 added_ancestry, removed_ancestry = get_delta(b'trunk', 'branch')462 added_ancestry, removed_ancestry = get_delta(b'trunk', 'branch')
463 self.assertEqual(set(['trunk']), added_ancestry)463 self.assertEqual({'trunk'}, added_ancestry)
464 self.assertEqual(set(['branch']), removed_ancestry)464 self.assertEqual({'branch'}, removed_ancestry)
465465
466 def test_getAncestryDelta(self):466 def test_getAncestryDelta(self):
467 """"Test ancestry delta calculations with a dirty repository."""467 """"Test ancestry delta calculations with a dirty repository."""
@@ -510,8 +510,8 @@ class TestBzrSync(BzrSyncTestCase):
510 (db_branch, branch_tree), ignored = self.makeBranchWithMerge(510 (db_branch, branch_tree), ignored = self.makeBranchWithMerge(
511 b'r1', b'r2', b'r1.1.1', b'r3')511 b'r1', b'r2', b'r1.1.1', b'r3')
512 self.makeBzrSync(db_branch).syncBranchAndClose()512 self.makeBzrSync(db_branch).syncBranchAndClose()
513 expected = set(513 expected = {
514 [(1, 'r1'), (2, 'r2'), (3, 'r3'), (None, 'r1.1.1')])514 (1, 'r1'), (2, 'r2'), (3, 'r3'), (None, 'r1.1.1')}
515 self.assertEqual(self.getBranchRevisions(db_branch), expected)515 self.assertEqual(self.getBranchRevisions(db_branch), expected)
516516
517 def test_sync_merged_to_merging(self):517 def test_sync_merged_to_merging(self):
@@ -538,7 +538,7 @@ class TestBzrSync(BzrSyncTestCase):
538 self.syncBazaarBranchToDatabase(trunk_tree.branch, db_trunk)538 self.syncBazaarBranchToDatabase(trunk_tree.branch, db_trunk)
539 # Then sync with the merged branch.539 # Then sync with the merged branch.
540 self.syncBazaarBranchToDatabase(branch_tree.branch, db_trunk)540 self.syncBazaarBranchToDatabase(branch_tree.branch, db_trunk)
541 expected = set([(1, 'base'), (2, 'branch')])541 expected = {(1, 'base'), (2, 'branch')}
542 self.assertEqual(self.getBranchRevisions(db_trunk), expected)542 self.assertEqual(self.getBranchRevisions(db_trunk), expected)
543543
544 def test_retrieveDatabaseAncestry(self):544 def test_retrieveDatabaseAncestry(self):
@@ -556,8 +556,8 @@ class TestBzrSync(BzrSyncTestCase):
556 branch_revisions = IStore(BranchRevision).find(556 branch_revisions = IStore(BranchRevision).find(
557 BranchRevision, BranchRevision.branch == branch)557 BranchRevision, BranchRevision.branch == branch)
558 sampledata = list(branch_revisions.order_by(BranchRevision.sequence))558 sampledata = list(branch_revisions.order_by(BranchRevision.sequence))
559 expected_ancestry = set(branch_revision.revision.revision_id559 expected_ancestry = {branch_revision.revision.revision_id
560 for branch_revision in sampledata)560 for branch_revision in sampledata}
561 expected_history = [branch_revision.revision.revision_id561 expected_history = [branch_revision.revision.revision_id
562 for branch_revision in sampledata562 for branch_revision in sampledata
563 if branch_revision.sequence is not None]563 if branch_revision.sequence is not None]
diff --git a/lib/lp/codehosting/scanner/tests/test_mergedetection.py b/lib/lp/codehosting/scanner/tests/test_mergedetection.py
index 66c3521..4d3a93d 100644
--- a/lib/lp/codehosting/scanner/tests/test_mergedetection.py
+++ b/lib/lp/codehosting/scanner/tests/test_mergedetection.py
@@ -299,10 +299,10 @@ class TestBranchMergeDetectionHandler(TestCaseWithFactory):
299 'Work in progress => Merged',299 'Work in progress => Merged',
300 six.ensure_text(notifications[0].get_payload(decode=True)))300 six.ensure_text(notifications[0].get_payload(decode=True)))
301 self.assertEqual(proposal.address, notifications[0]['From'])301 self.assertEqual(proposal.address, notifications[0]['From'])
302 recipients = set(msg['x-envelope-to'] for msg in notifications)302 recipients = {msg['x-envelope-to'] for msg in notifications}
303 expected = set(303 expected = {
304 [proposal.source_branch.registrant.preferredemail.email,304 proposal.source_branch.registrant.preferredemail.email,
305 proposal.target_branch.registrant.preferredemail.email])305 proposal.target_branch.registrant.preferredemail.email}
306 self.assertEqual(expected, recipients)306 self.assertEqual(expected, recipients)
307307
308 def test_mergeProposalMergeDetected_not_series(self):308 def test_mergeProposalMergeDetected_not_series(self):
diff --git a/lib/lp/codehosting/scripts/tests/test_modifiedbranches.py b/lib/lp/codehosting/scripts/tests/test_modifiedbranches.py
index 2d72544..6d1faf2 100644
--- a/lib/lp/codehosting/scripts/tests/test_modifiedbranches.py
+++ b/lib/lp/codehosting/scripts/tests/test_modifiedbranches.py
@@ -165,23 +165,23 @@ class TestModifiedBranchesUpdateLocations(TestCase):
165 def test_single_path_element(self):165 def test_single_path_element(self):
166 # Adding a single element should just add that.166 # Adding a single element should just add that.
167 self.script.update_locations('foo')167 self.script.update_locations('foo')
168 self.assertEqual(set(['foo']), self.script.locations)168 self.assertEqual({'foo'}, self.script.locations)
169169
170 def test_single_root_element(self):170 def test_single_root_element(self):
171 # If the single element starts with a /, the locations do not include171 # If the single element starts with a /, the locations do not include
172 # an empty string.172 # an empty string.
173 self.script.update_locations('/foo')173 self.script.update_locations('/foo')
174 self.assertEqual(set(['/foo']), self.script.locations)174 self.assertEqual({'/foo'}, self.script.locations)
175175
176 def test_multi_path_element(self):176 def test_multi_path_element(self):
177 # Adding a "real" path will also include all the parents.177 # Adding a "real" path will also include all the parents.
178 self.script.update_locations('foo/bar/baz')178 self.script.update_locations('foo/bar/baz')
179 expected = set(['foo', 'foo/bar', 'foo/bar/baz'])179 expected = {'foo', 'foo/bar', 'foo/bar/baz'}
180 self.assertEqual(expected, self.script.locations)180 self.assertEqual(expected, self.script.locations)
181181
182 def test_duplicates(self):182 def test_duplicates(self):
183 # Adding paths with common parentage doesn't cause duplicates.183 # Adding paths with common parentage doesn't cause duplicates.
184 self.script.update_locations('foo/bar/baz')184 self.script.update_locations('foo/bar/baz')
185 self.script.update_locations('foo/bar/who')185 self.script.update_locations('foo/bar/who')
186 expected = set(['foo', 'foo/bar', 'foo/bar/baz', 'foo/bar/who'])186 expected = {'foo', 'foo/bar', 'foo/bar/baz', 'foo/bar/who'}
187 self.assertEqual(expected, self.script.locations)187 self.assertEqual(expected, self.script.locations)
diff --git a/lib/lp/codehosting/tests/test_sftp.py b/lib/lp/codehosting/tests/test_sftp.py
index 5d022dd..16df390 100644
--- a/lib/lp/codehosting/tests/test_sftp.py
+++ b/lib/lp/codehosting/tests/test_sftp.py
@@ -558,7 +558,7 @@ class TestSFTPServer(TestCaseInTempDir, SFTPTestMixin):
558 names = [entry[0] for entry in entries]558 names = [entry[0] for entry in entries]
559 self.assertEqual(559 self.assertEqual(
560 set(names),560 set(names),
561 set([child_dir.encode('UTF-8'), child_file.encode('UTF-8')]))561 {child_dir.encode('UTF-8'), child_file.encode('UTF-8')})
562562
563 def check_entry(entries, filename):563 def check_entry(entries, filename):
564 t = get_transport('.')564 t = get_transport('.')
diff --git a/lib/lp/oci/browser/tests/test_ocirecipe.py b/lib/lp/oci/browser/tests/test_ocirecipe.py
index 4cea71a..dab70d4 100644
--- a/lib/lp/oci/browser/tests/test_ocirecipe.py
+++ b/lib/lp/oci/browser/tests/test_ocirecipe.py
@@ -1786,7 +1786,7 @@ class TestOCIRecipeRequestBuildsView(BaseTestOCIRecipeView):
1786 ["amd64", "i386"],1786 ["amd64", "i386"],
1787 [build.distro_arch_series.architecturetag for build in builds])1787 [build.distro_arch_series.architecturetag for build in builds])
1788 self.assertContentEqual(1788 self.assertContentEqual(
1789 [2510], set(build.buildqueue_record.lastscore for build in builds))1789 [2510], {build.buildqueue_record.lastscore for build in builds})
17901790
1791 def test_request_builds_no_architectures(self):1791 def test_request_builds_no_architectures(self):
1792 # Selecting no architectures causes a validation failure.1792 # Selecting no architectures causes a validation failure.
diff --git a/lib/lp/registry/browser/distributionsourcepackage.py b/lib/lp/registry/browser/distributionsourcepackage.py
index bfbbb38..48def0c 100644
--- a/lib/lp/registry/browser/distributionsourcepackage.py
+++ b/lib/lp/registry/browser/distributionsourcepackage.py
@@ -310,11 +310,11 @@ class DistributionSourcePackageBaseView(LaunchpadView):
310 [spr.changelog_entry for spr in sprs310 [spr.changelog_entry for spr in sprs
311 if not_empty(spr.changelog_entry)])311 if not_empty(spr.changelog_entry)])
312 if self.user:312 if self.user:
313 self._person_data = dict(313 self._person_data = {
314 [(email.email, person) for (email, person) in314 email.email: person for (email, person) in
315 getUtility(IPersonSet).getByEmails(315 getUtility(IPersonSet).getByEmails(
316 extract_email_addresses(the_changelog),316 extract_email_addresses(the_changelog),
317 include_hidden=False)])317 include_hidden=False)}
318 else:318 else:
319 self._person_data = None319 self._person_data = None
320 # Collate diffs for relevant SourcePackageReleases320 # Collate diffs for relevant SourcePackageReleases
diff --git a/lib/lp/registry/browser/distroseries.py b/lib/lp/registry/browser/distroseries.py
index afc2290..6b162dc 100644
--- a/lib/lp/registry/browser/distroseries.py
+++ b/lib/lp/registry/browser/distroseries.py
@@ -1140,13 +1140,13 @@ class DistroSeriesDifferenceBaseView(LaunchpadFormView,
1140 """If specified, return Packagesets given in the GET form data."""1140 """If specified, return Packagesets given in the GET form data."""
1141 packageset_ids = (1141 packageset_ids = (
1142 self.request.query_string_params.get("field.packageset", []))1142 self.request.query_string_params.get("field.packageset", []))
1143 packageset_ids = set(1143 packageset_ids = {
1144 int(packageset_id) for packageset_id in packageset_ids1144 int(packageset_id) for packageset_id in packageset_ids
1145 if packageset_id.isdigit())1145 if packageset_id.isdigit()}
1146 packagesets = getUtility(IPackagesetSet).getBySeries(self.context)1146 packagesets = getUtility(IPackagesetSet).getBySeries(self.context)
1147 packagesets = set(1147 packagesets = {
1148 packageset for packageset in packagesets1148 packageset for packageset in packagesets
1149 if packageset.id in packageset_ids)1149 if packageset.id in packageset_ids}
1150 return None if len(packagesets) == 0 else packagesets1150 return None if len(packagesets) == 0 else packagesets
11511151
1152 @property1152 @property
@@ -1157,8 +1157,8 @@ class DistroSeriesDifferenceBaseView(LaunchpadFormView,
1157 self.request.query_string_params.get("field.changed_by", ()))1157 self.request.query_string_params.get("field.changed_by", ()))
1158 changed_by = (1158 changed_by = (
1159 get_person_by_name(name) for name in changed_by_names)1159 get_person_by_name(name) for name in changed_by_names)
1160 changed_by = set(1160 changed_by = {
1161 person for person in changed_by if person is not None)1161 person for person in changed_by if person is not None}
1162 return None if len(changed_by) == 0 else changed_by1162 return None if len(changed_by) == 0 else changed_by
11631163
1164 @property1164 @property
diff --git a/lib/lp/registry/browser/milestone.py b/lib/lp/registry/browser/milestone.py
index 1a2a171..3d2724e 100644
--- a/lib/lp/registry/browser/milestone.py
+++ b/lib/lp/registry/browser/milestone.py
@@ -384,7 +384,7 @@ class MilestoneView(
384384
385 def getReleases(self):385 def getReleases(self):
386 """See `ProductDownloadFileMixin`."""386 """See `ProductDownloadFileMixin`."""
387 return set([self.release])387 return {self.release}
388388
389 @cachedproperty389 @cachedproperty
390 def download_files(self):390 def download_files(self):
diff --git a/lib/lp/registry/browser/pillar.py b/lib/lp/registry/browser/pillar.py
index 4f185df..4c09eb2 100644
--- a/lib/lp/registry/browser/pillar.py
+++ b/lib/lp/registry/browser/pillar.py
@@ -221,8 +221,8 @@ class PillarInvolvementView(LaunchpadView):
221 def enabled_links(self):221 def enabled_links(self):
222 """The enabled involvement links."""222 """The enabled involvement links."""
223 menuapi = MenuAPI(self)223 menuapi = MenuAPI(self)
224 return sorted([224 return sorted((
225 link for link in menuapi.navigation.values() if link.enabled],225 link for link in menuapi.navigation.values() if link.enabled),
226 key=attrgetter('sort_key'))226 key=attrgetter('sort_key'))
227227
228 @cachedproperty228 @cachedproperty
@@ -239,8 +239,8 @@ class PillarInvolvementView(LaunchpadView):
239 important_links = [239 important_links = [
240 involved_menu[name]240 involved_menu[name]
241 for name in self.visible_disabled_link_names]241 for name in self.visible_disabled_link_names]
242 return sorted([242 return sorted((
243 link for link in important_links if not link.enabled],243 link for link in important_links if not link.enabled),
244 key=attrgetter('sort_key'))244 key=attrgetter('sort_key'))
245245
246 @property246 @property
@@ -451,7 +451,7 @@ class PillarPersonSharingView(LaunchpadView):
451 self.specifications = artifacts["specifications"]451 self.specifications = artifacts["specifications"]
452 self.ocirecipes = artifacts["ocirecipes"]452 self.ocirecipes = artifacts["ocirecipes"]
453453
454 bug_ids = set([bugtask.bug.id for bugtask in self.bugtasks])454 bug_ids = {bugtask.bug.id for bugtask in self.bugtasks}
455 self.shared_bugs_count = len(bug_ids)455 self.shared_bugs_count = len(bug_ids)
456 self.shared_branches_count = len(self.branches)456 self.shared_branches_count = len(self.branches)
457 self.shared_gitrepositories_count = len(self.gitrepositories)457 self.shared_gitrepositories_count = len(self.gitrepositories)
diff --git a/lib/lp/registry/browser/product.py b/lib/lp/registry/browser/product.py
index 3a853ae..942b4b9 100644
--- a/lib/lp/registry/browser/product.py
+++ b/lib/lp/registry/browser/product.py
@@ -755,7 +755,7 @@ class ProductWithSeries:
755 # Get all of the releases for all of the series in a single755 # Get all of the releases for all of the series in a single
756 # query. The query sorts the releases properly so we know the756 # query. The query sorts the releases properly so we know the
757 # resulting list is sorted correctly.757 # resulting list is sorted correctly.
758 series_by_id = dict((series.id, series) for series in self.series)758 series_by_id = {series.id: series for series in self.series}
759 self.release_by_id = {}759 self.release_by_id = {}
760 milestones_and_releases = list(760 milestones_and_releases = list(
761 self.product.getMilestonesAndReleases())761 self.product.getMilestonesAndReleases())
@@ -1989,7 +1989,7 @@ class ProductSetBranchView(ReturnToReferrerMixin, LaunchpadFormView,
19891989
1990 def _validSchemes(self, rcs_type):1990 def _validSchemes(self, rcs_type):
1991 """Return the valid schemes for the repository URL."""1991 """Return the valid schemes for the repository URL."""
1992 schemes = set(['http', 'https'])1992 schemes = {'http', 'https'}
1993 # Extend the allowed schemes for the repository URL based on1993 # Extend the allowed schemes for the repository URL based on
1994 # rcs_type.1994 # rcs_type.
1995 extra_schemes = {1995 extra_schemes = {
diff --git a/lib/lp/registry/browser/sourcepackage.py b/lib/lp/registry/browser/sourcepackage.py
index d5a676c..ea447c2 100644
--- a/lib/lp/registry/browser/sourcepackage.py
+++ b/lib/lp/registry/browser/sourcepackage.py
@@ -483,8 +483,8 @@ class SourcePackageView(LaunchpadView):
483 def binaries(self):483 def binaries(self):
484 """Format binary packages into binarypackagename and archtags"""484 """Format binary packages into binarypackagename and archtags"""
485 results = {}485 results = {}
486 all_arch = sorted([arch.architecturetag for arch in486 all_arch = sorted(arch.architecturetag for arch in
487 self.context.distroseries.architectures])487 self.context.distroseries.architectures)
488 for bin in self.context.currentrelease.getBinariesForSeries(488 for bin in self.context.currentrelease.getBinariesForSeries(
489 self.context.distroseries):489 self.context.distroseries):
490 distroarchseries = bin.build.distro_arch_series490 distroarchseries = bin.build.distro_arch_series
diff --git a/lib/lp/registry/browser/tests/test_mailinglists.py b/lib/lp/registry/browser/tests/test_mailinglists.py
index f9f28e9..b1154ba 100644
--- a/lib/lp/registry/browser/tests/test_mailinglists.py
+++ b/lib/lp/registry/browser/tests/test_mailinglists.py
@@ -1,4 +1,3 @@
1
2# Copyright 2010 Canonical Ltd. This software is licensed under the1# Copyright 2010 Canonical Ltd. This software is licensed under the
3# GNU Affero General Public License version 3 (see the file LICENSE).2# GNU Affero General Public License version 3 (see the file LICENSE).
43
diff --git a/lib/lp/registry/interfaces/pocket.py b/lib/lp/registry/interfaces/pocket.py
index 10443b2..47bfdc9 100644
--- a/lib/lp/registry/interfaces/pocket.py
+++ b/lib/lp/registry/interfaces/pocket.py
@@ -77,4 +77,4 @@ pocketsuffix = {
77 PackagePublishingPocket.BACKPORTS: "-backports",77 PackagePublishingPocket.BACKPORTS: "-backports",
78}78}
7979
80suffixpocket = dict((v, k) for (k, v) in pocketsuffix.items())80suffixpocket = {v: k for (k, v) in pocketsuffix.items()}
diff --git a/lib/lp/registry/model/accesspolicy.py b/lib/lp/registry/model/accesspolicy.py
index ef76153..89431c7 100644
--- a/lib/lp/registry/model/accesspolicy.py
+++ b/lib/lp/registry/model/accesspolicy.py
@@ -67,7 +67,7 @@ def reconcile_access_for_artifacts(artifacts, information_type, pillars,
67 abstract_artifacts = getUtility(IAccessArtifactSource).ensure(artifacts)67 abstract_artifacts = getUtility(IAccessArtifactSource).ensure(artifacts)
68 aps = getUtility(IAccessPolicySource).find(68 aps = getUtility(IAccessPolicySource).find(
69 (pillar, information_type) for pillar in pillars)69 (pillar, information_type) for pillar in pillars)
70 missing_pillars = set(pillars) - set([ap.pillar for ap in aps])70 missing_pillars = set(pillars) - {ap.pillar for ap in aps}
71 if len(missing_pillars):71 if len(missing_pillars):
72 pillar_str = ', '.join([p.name for p in missing_pillars])72 pillar_str = ', '.join([p.name for p in missing_pillars])
73 raise AssertionError(73 raise AssertionError(
@@ -79,9 +79,9 @@ def reconcile_access_for_artifacts(artifacts, information_type, pillars,
79 apasource = getUtility(IAccessPolicyArtifactSource)79 apasource = getUtility(IAccessPolicyArtifactSource)
80 wanted_links = (80 wanted_links = (
81 wanted_links or set(product(abstract_artifacts, aps)))81 wanted_links or set(product(abstract_artifacts, aps)))
82 existing_links = set([82 existing_links = {
83 (apa.abstract_artifact, apa.policy)83 (apa.abstract_artifact, apa.policy)
84 for apa in apasource.findByArtifact(abstract_artifacts)])84 for apa in apasource.findByArtifact(abstract_artifacts)}
85 apasource.create(wanted_links - existing_links)85 apasource.create(wanted_links - existing_links)
86 apasource.delete(existing_links - wanted_links)86 apasource.delete(existing_links - wanted_links)
8787
@@ -163,7 +163,7 @@ class AccessArtifact(StormBase):
163 # Not everything exists. Create missing ones.163 # Not everything exists. Create missing ones.
164 needed = (164 needed = (
165 set(concrete_artifacts) -165 set(concrete_artifacts) -
166 set(abstract.concrete_artifact for abstract in existing))166 {abstract.concrete_artifact for abstract in existing})
167167
168 insert_values = []168 insert_values = []
169 for concrete in needed:169 for concrete in needed:
@@ -489,7 +489,7 @@ class AccessPolicyGrantFlat(StormBase):
489 @classmethod489 @classmethod
490 def findGranteePermissionsByPolicy(cls, policies, grantees=None):490 def findGranteePermissionsByPolicy(cls, policies, grantees=None):
491 """See `IAccessPolicyGrantFlatSource`."""491 """See `IAccessPolicyGrantFlatSource`."""
492 policies_by_id = dict((policy.id, policy) for policy in policies)492 policies_by_id = {policy.id: policy for policy in policies}
493493
494 # A cache for the sharing permissions, keyed on grantee494 # A cache for the sharing permissions, keyed on grantee
495 permissions_cache = defaultdict(dict)495 permissions_cache = defaultdict(dict)
@@ -506,8 +506,8 @@ class AccessPolicyGrantFlat(StormBase):
506 def load_permissions(people):506 def load_permissions(people):
507 # We now have the grantees and policies we want in the result so507 # We now have the grantees and policies we want in the result so
508 # load any corresponding permissions and cache them.508 # load any corresponding permissions and cache them.
509 people_by_id = dict(509 people_by_id = {
510 (person[0].id, person[0]) for person in people)510 person[0].id: person[0] for person in people}
511 cls._populatePermissionsCache(511 cls._populatePermissionsCache(
512 permissions_cache, shared_artifact_info_types,512 permissions_cache, shared_artifact_info_types,
513 people_by_id.keys(), policies_by_id, people_by_id)513 people_by_id.keys(), policies_by_id, people_by_id)
diff --git a/lib/lp/registry/model/distributionsourcepackage.py b/lib/lp/registry/model/distributionsourcepackage.py
index 4606f0e..ca41f4c 100644
--- a/lib/lp/registry/model/distributionsourcepackage.py
+++ b/lib/lp/registry/model/distributionsourcepackage.py
@@ -426,9 +426,9 @@ class DistributionSourcePackage(BugTargetBase,
426 sprs = [SourcePackageRelease.get(spr_id) for spr_id in spr_ids]426 sprs = [SourcePackageRelease.get(spr_id) for spr_id in spr_ids]
427 pubs = DistributionSourcePackageRelease.getPublishingHistories(427 pubs = DistributionSourcePackageRelease.getPublishingHistories(
428 self.distribution, sprs)428 self.distribution, sprs)
429 sprs_by_id = dict(429 sprs_by_id = {
430 (spr, list(pubs)) for (spr, pubs) in430 spr: list(pubs) for (spr, pubs) in
431 itertools.groupby(pubs, attrgetter('sourcepackagereleaseID')))431 itertools.groupby(pubs, attrgetter('sourcepackagereleaseID'))}
432 return [432 return [
433 (DistributionSourcePackageRelease(433 (DistributionSourcePackageRelease(
434 distribution=self.distribution,434 distribution=self.distribution,
diff --git a/lib/lp/registry/model/distroseriesdifference.py b/lib/lp/registry/model/distroseriesdifference.py
index b68df3f..3845bb5 100644
--- a/lib/lp/registry/model/distroseriesdifference.py
+++ b/lib/lp/registry/model/distroseriesdifference.py
@@ -269,9 +269,9 @@ def eager_load_dsds(dsds):
269 dsds, statuses=active_publishing_status,269 dsds, statuses=active_publishing_status,
270 in_parent=True, match_version=True))270 in_parent=True, match_version=True))
271271
272 latest_comment_by_dsd_id = dict(272 latest_comment_by_dsd_id = {
273 (comment.distro_series_difference_id, comment)273 comment.distro_series_difference_id: comment
274 for comment in most_recent_comments(dsds))274 for comment in most_recent_comments(dsds)}
275 latest_comments = latest_comment_by_dsd_id.values()275 latest_comments = latest_comment_by_dsd_id.values()
276276
277 # SourcePackageReleases of the parent and source pubs are often277 # SourcePackageReleases of the parent and source pubs are often
diff --git a/lib/lp/registry/model/person.py b/lib/lp/registry/model/person.py
index b9f519e..36be643 100644
--- a/lib/lp/registry/model/person.py
+++ b/lib/lp/registry/model/person.py
@@ -842,10 +842,10 @@ class Person(
842 # Defaults for informationalness: we don't have to do anything842 # Defaults for informationalness: we don't have to do anything
843 # because the default if nothing is said is ANY.843 # because the default if nothing is said is ANY.
844844
845 roles = set([845 roles = {
846 SpecificationFilter.CREATOR, SpecificationFilter.ASSIGNEE,846 SpecificationFilter.CREATOR, SpecificationFilter.ASSIGNEE,
847 SpecificationFilter.DRAFTER, SpecificationFilter.APPROVER,847 SpecificationFilter.DRAFTER, SpecificationFilter.APPROVER,
848 SpecificationFilter.SUBSCRIBER])848 SpecificationFilter.SUBSCRIBER}
849 # If no roles are given, then we want everything.849 # If no roles are given, then we want everything.
850 if filter.intersection(roles) == set():850 if filter.intersection(roles) == set():
851 filter.update(roles)851 filter.update(roles)
@@ -2321,7 +2321,7 @@ class Person(
2321 # These tables will be skipped since they do not risk leaking2321 # These tables will be skipped since they do not risk leaking
2322 # team membership information.2322 # team membership information.
2323 # Note all of the table names and columns must be all lowercase.2323 # Note all of the table names and columns must be all lowercase.
2324 skip = set([2324 skip = {
2325 ('accessartifactgrant', 'grantee'),2325 ('accessartifactgrant', 'grantee'),
2326 ('accessartifactgrant', 'grantor'),2326 ('accessartifactgrant', 'grantor'),
2327 ('accesspolicy', 'person'),2327 ('accesspolicy', 'person'),
@@ -2381,7 +2381,7 @@ class Person(
2381 # user already has access to the team.2381 # user already has access to the team.
2382 ('latestpersonsourcepackagereleasecache', 'creator'),2382 ('latestpersonsourcepackagereleasecache', 'creator'),
2383 ('latestpersonsourcepackagereleasecache', 'maintainer'),2383 ('latestpersonsourcepackagereleasecache', 'maintainer'),
2384 ])2384 }
23852385
2386 warnings = set()2386 warnings = set()
2387 ref_query = []2387 ref_query = []
@@ -2755,7 +2755,7 @@ class Person(
2755 AND date_consumed IS NULL2755 AND date_consumed IS NULL
2756 """ % sqlvalues(self.id, LoginTokenType.VALIDATEEMAIL,2756 """ % sqlvalues(self.id, LoginTokenType.VALIDATEEMAIL,
2757 LoginTokenType.VALIDATETEAMEMAIL)2757 LoginTokenType.VALIDATETEAMEMAIL)
2758 return sorted(set(token.email for token in LoginToken.select(query)))2758 return sorted({token.email for token in LoginToken.select(query)})
27592759
2760 @property2760 @property
2761 def guessedemails(self):2761 def guessedemails(self):
@@ -2766,8 +2766,8 @@ class Person(
2766 def pending_gpg_keys(self):2766 def pending_gpg_keys(self):
2767 """See `IPerson`."""2767 """See `IPerson`."""
2768 logintokenset = getUtility(ILoginTokenSet)2768 logintokenset = getUtility(ILoginTokenSet)
2769 return sorted(set(token.fingerprint for token in2769 return sorted({token.fingerprint for token in
2770 logintokenset.getPendingGPGKeys(requesterid=self.id)))2770 logintokenset.getPendingGPGKeys(requesterid=self.id)})
27712771
2772 @property2772 @property
2773 def inactive_gpg_keys(self):2773 def inactive_gpg_keys(self):
@@ -3849,9 +3849,9 @@ class PersonSet:
3849 # This has the side effect of sucking in the ValidPersonCache3849 # This has the side effect of sucking in the ValidPersonCache
3850 # items into the cache, allowing Person.is_valid_person calls to3850 # items into the cache, allowing Person.is_valid_person calls to
3851 # not hit the DB.3851 # not hit the DB.
3852 valid_person_ids = set(3852 valid_person_ids = {
3853 person_id.id for person_id in ValidPersonCache.select(3853 person_id.id for person_id in ValidPersonCache.select(
3854 "id IN %s" % sqlvalues(person_ids)))3854 "id IN %s" % sqlvalues(person_ids))}
3855 return [3855 return [
3856 person for person in persons if person.id in valid_person_ids]3856 person for person in persons if person.id in valid_person_ids]
38573857
diff --git a/lib/lp/registry/model/product.py b/lib/lp/registry/model/product.py
index 471b997..e8422d1 100644
--- a/lib/lp/registry/model/product.py
+++ b/lib/lp/registry/model/product.py
@@ -736,8 +736,8 @@ class Product(SQLBase, BugTargetBase, MakesAnnouncements,
736 # information types.736 # information types.
737 aps = getUtility(IAccessPolicySource)737 aps = getUtility(IAccessPolicySource)
738 existing_policies = aps.findByPillar([self])738 existing_policies = aps.findByPillar([self])
739 existing_types = set([739 existing_types = {
740 access_policy.type for access_policy in existing_policies])740 access_policy.type for access_policy in existing_policies}
741 # Create the missing policies.741 # Create the missing policies.
742 required_types = set(information_types).difference(742 required_types = set(information_types).difference(
743 existing_types).intersection(PRIVATE_INFORMATION_TYPES)743 existing_types).intersection(PRIVATE_INFORMATION_TYPES)
@@ -1232,10 +1232,10 @@ class Product(SQLBase, BugTargetBase, MakesAnnouncements,
1232 @property1232 @property
1233 def translatable_packages(self):1233 def translatable_packages(self):
1234 """See `IProduct`."""1234 """See `IProduct`."""
1235 packages = set(1235 packages = {
1236 package1236 package
1237 for package in self.sourcepackages1237 for package in self.sourcepackages
1238 if package.has_current_translation_templates)1238 if package.has_current_translation_templates}
12391239
1240 # Sort packages by distroseries.name and package.name1240 # Sort packages by distroseries.name and package.name
1241 return sorted(packages, key=lambda p: (p.distroseries.name, p.name))1241 return sorted(packages, key=lambda p: (p.distroseries.name, p.name))
@@ -1245,10 +1245,10 @@ class Product(SQLBase, BugTargetBase, MakesAnnouncements,
1245 """See `IProduct`."""1245 """See `IProduct`."""
1246 if not service_uses_launchpad(self.translations_usage):1246 if not service_uses_launchpad(self.translations_usage):
1247 return []1247 return []
1248 translatable_product_series = set(1248 translatable_product_series = {
1249 product_series1249 product_series
1250 for product_series in self.series1250 for product_series in self.series
1251 if product_series.has_current_translation_templates)1251 if product_series.has_current_translation_templates}
1252 return sorted(1252 return sorted(
1253 translatable_product_series,1253 translatable_product_series,
1254 key=operator.attrgetter('datecreated'))1254 key=operator.attrgetter('datecreated'))
@@ -1283,9 +1283,9 @@ class Product(SQLBase, BugTargetBase, MakesAnnouncements,
1283 @property1283 @property
1284 def obsolete_translatable_series(self):1284 def obsolete_translatable_series(self):
1285 """See `IProduct`."""1285 """See `IProduct`."""
1286 obsolete_product_series = set(1286 obsolete_product_series = {
1287 product_series for product_series in self.series1287 product_series for product_series in self.series
1288 if product_series.has_obsolete_translation_templates)1288 if product_series.has_obsolete_translation_templates}
1289 return sorted(obsolete_product_series, key=lambda s: s.datecreated)1289 return sorted(obsolete_product_series, key=lambda s: s.datecreated)
12901290
1291 @property1291 @property
@@ -1525,12 +1525,12 @@ def get_precached_products(products, need_licences=False,
1525 from lp.code.interfaces.gitrepository import IGitRepositorySet1525 from lp.code.interfaces.gitrepository import IGitRepositorySet
1526 from lp.registry.model.projectgroup import ProjectGroup1526 from lp.registry.model.projectgroup import ProjectGroup
15271527
1528 product_ids = set(obj.id for obj in products)1528 product_ids = {obj.id for obj in products}
1529 if not product_ids:1529 if not product_ids:
1530 return1530 return
1531 products_by_id = dict((product.id, product) for product in products)1531 products_by_id = {product.id: product for product in products}
1532 caches = dict((product.id, get_property_cache(product))1532 caches = {product.id: get_property_cache(product)
1533 for product in products)1533 for product in products}
1534 for cache in caches.values():1534 for cache in caches.values():
1535 if not safe_hasattr(cache, 'commercial_subscription'):1535 if not safe_hasattr(cache, 'commercial_subscription'):
1536 cache.commercial_subscription = None1536 cache.commercial_subscription = None
diff --git a/lib/lp/registry/model/sourcepackage.py b/lib/lp/registry/model/sourcepackage.py
index f27672e..1df33ee 100644
--- a/lib/lp/registry/model/sourcepackage.py
+++ b/lib/lp/registry/model/sourcepackage.py
@@ -142,7 +142,7 @@ class SourcePackageQuestionTargetMixin(QuestionTargetMixin):
142 set(QuestionTargetMixin.getAnswerContactsForLanguage(142 set(QuestionTargetMixin.getAnswerContactsForLanguage(
143 self, language)))143 self, language)))
144 return sorted(144 return sorted(
145 [person for person in persons], key=attrgetter('displayname'))145 (person for person in persons), key=attrgetter('displayname'))
146146
147 def getAnswerContactRecipients(self, language):147 def getAnswerContactRecipients(self, language):
148 """See `IQuestionTarget`."""148 """See `IQuestionTarget`."""
@@ -761,7 +761,7 @@ class SourcePackage(BugTargetBase, HasCodeImportsMixin,
761761
762 def linkedBranches(self):762 def linkedBranches(self):
763 """See `ISourcePackage`."""763 """See `ISourcePackage`."""
764 return dict((p.name, b) for (p, b) in self.linked_branches)764 return {p.name: b for (p, b) in self.linked_branches}
765765
766 def getBugTaskWeightFunction(self):766 def getBugTaskWeightFunction(self):
767 """Provide a weight function to determine optimal bug task.767 """Provide a weight function to determine optimal bug task.
diff --git a/lib/lp/registry/scripts/teamparticipation.py b/lib/lp/registry/scripts/teamparticipation.py
index c332f51..cfca76a 100644
--- a/lib/lp/registry/scripts/teamparticipation.py
+++ b/lib/lp/registry/scripts/teamparticipation.py
@@ -155,7 +155,7 @@ def check_teamparticipation_consistency(log, info):
155155
156 log.debug("Checking consistency of %d people", len(people))156 log.debug("Checking consistency of %d people", len(people))
157 for person in report_progress(log, 50000, people, "people"):157 for person in report_progress(log, 50000, people, "people"):
158 participants_expected = set((person,))158 participants_expected = {person}
159 participants_observed = team_participations[person]159 participants_observed = team_participations[person]
160 errors.extend(160 errors.extend(
161 check_participants(161 check_participants(
diff --git a/lib/lp/registry/scripts/tests/test_populate_distroseriesdiff.py b/lib/lp/registry/scripts/tests/test_populate_distroseriesdiff.py
index 9854fa7..fdd599f 100644
--- a/lib/lp/registry/scripts/tests/test_populate_distroseriesdiff.py
+++ b/lib/lp/registry/scripts/tests/test_populate_distroseriesdiff.py
@@ -143,10 +143,10 @@ class TestFindLatestSourcePackageReleases(TestCaseWithFactory, FactoryHelper):
143143
144 def test_does_not_find_publication_outside_primary_archive(self):144 def test_does_not_find_publication_outside_primary_archive(self):
145 distroseries = self.factory.makeDistroSeries()145 distroseries = self.factory.makeDistroSeries()
146 spphs = dict(146 spphs = {
147 (purpose, self.makeSPPH(147 purpose: self.makeSPPH(
148 distroseries=distroseries, archive_purpose=purpose))148 distroseries=distroseries, archive_purpose=purpose)
149 for purpose in ArchivePurpose.items)149 for purpose in ArchivePurpose.items}
150 query = compose_sql_find_latest_source_package_releases(distroseries)150 query = compose_sql_find_latest_source_package_releases(distroseries)
151 self.assertContentEqual(151 self.assertContentEqual(
152 [self.getExpectedResultFor(spphs[ArchivePurpose.PRIMARY])],152 [self.getExpectedResultFor(spphs[ArchivePurpose.PRIMARY])],
@@ -154,9 +154,9 @@ class TestFindLatestSourcePackageReleases(TestCaseWithFactory, FactoryHelper):
154154
155 def test_does_not_find_publication_outside_release_pocket(self):155 def test_does_not_find_publication_outside_release_pocket(self):
156 distroseries = self.factory.makeDistroSeries()156 distroseries = self.factory.makeDistroSeries()
157 spphs = dict(157 spphs = {
158 (pocket, self.makeSPPH(distroseries=distroseries, pocket=pocket))158 pocket: self.makeSPPH(distroseries=distroseries, pocket=pocket)
159 for pocket in PackagePublishingPocket.items)159 for pocket in PackagePublishingPocket.items}
160 release_spph = spphs[PackagePublishingPocket.RELEASE]160 release_spph = spphs[PackagePublishingPocket.RELEASE]
161 query = compose_sql_find_latest_source_package_releases(distroseries)161 query = compose_sql_find_latest_source_package_releases(distroseries)
162 self.assertContentEqual(162 self.assertContentEqual(
@@ -165,9 +165,9 @@ class TestFindLatestSourcePackageReleases(TestCaseWithFactory, FactoryHelper):
165165
166 def test_finds_active_publication(self):166 def test_finds_active_publication(self):
167 distroseries = self.factory.makeDistroSeries()167 distroseries = self.factory.makeDistroSeries()
168 spphs = dict(168 spphs = {
169 (status, self.makeSPPH(distroseries=distroseries, status=status))169 status: self.makeSPPH(distroseries=distroseries, status=status)
170 for status in active_publishing_status)170 for status in active_publishing_status}
171 query = compose_sql_find_latest_source_package_releases(distroseries)171 query = compose_sql_find_latest_source_package_releases(distroseries)
172 self.assertContentEqual(172 self.assertContentEqual(
173 [self.getExpectedResultFor(spph)173 [self.getExpectedResultFor(spph)
diff --git a/lib/lp/registry/services/tests/test_sharingservice.py b/lib/lp/registry/services/tests/test_sharingservice.py
index 5aa3c5c..e0accd8 100644
--- a/lib/lp/registry/services/tests/test_sharingservice.py
+++ b/lib/lp/registry/services/tests/test_sharingservice.py
@@ -795,15 +795,15 @@ class TestSharingService(TestCaseWithFactory, OCIConfigHelperMixin):
795 another_person_data = (795 another_person_data = (
796 another, {access_policies[0]: SharingPermission.ALL}, [])796 another, {access_policies[0]: SharingPermission.ALL}, [])
797 expected_data.append(another_person_data)797 expected_data.append(another_person_data)
798 policy_permissions = dict([(798 policy_permissions = {
799 policy, SharingPermission.SOME) for policy in access_policies])799 policy: SharingPermission.SOME for policy in access_policies}
800 yet_another_person_data = (800 yet_another_person_data = (
801 yet_another, policy_permissions,801 yet_another, policy_permissions,
802 [InformationType.PRIVATESECURITY, InformationType.USERDATA])802 [InformationType.PRIVATESECURITY, InformationType.USERDATA])
803 expected_data.append(yet_another_person_data)803 expected_data.append(yet_another_person_data)
804 if pillar_type == 'product':804 if pillar_type == 'product':
805 policy_permissions = dict([(805 policy_permissions = {
806 policy, SharingPermission.ALL) for policy in access_policies])806 policy: SharingPermission.ALL for policy in access_policies}
807 owner_data = (pillar.owner, policy_permissions, [])807 owner_data = (pillar.owner, policy_permissions, [])
808 expected_data.append(owner_data)808 expected_data.append(owner_data)
809 self._assert_grantee_data(809 self._assert_grantee_data(
diff --git a/lib/lp/registry/tests/test_distributionmirror_prober.py b/lib/lp/registry/tests/test_distributionmirror_prober.py
index c2d89d5..0146ca4 100644
--- a/lib/lp/registry/tests/test_distributionmirror_prober.py
+++ b/lib/lp/registry/tests/test_distributionmirror_prober.py
@@ -929,7 +929,7 @@ class TestMirrorCDImageProberCallbacks(TestCaseWithFactory):
929 callbacks = self.makeMirrorProberCallbacks()929 callbacks = self.makeMirrorProberCallbacks()
930 self.assertEqual(930 self.assertEqual(
931 set(callbacks.expected_failures),931 set(callbacks.expected_failures),
932 set([932 {
933 BadResponseCode,933 BadResponseCode,
934 ProberTimeout,934 ProberTimeout,
935 ConnectionSkipped,935 ConnectionSkipped,
@@ -937,7 +937,7 @@ class TestMirrorCDImageProberCallbacks(TestCaseWithFactory):
937 UnknownURLSchemeAfterRedirect,937 UnknownURLSchemeAfterRedirect,
938 InvalidHTTPSCertificate,938 InvalidHTTPSCertificate,
939 InvalidHTTPSCertificateSkipped,939 InvalidHTTPSCertificateSkipped,
940 ]))940 })
941 exceptions = [BadResponseCode(http.client.NOT_FOUND),941 exceptions = [BadResponseCode(http.client.NOT_FOUND),
942 ProberTimeout('http://localhost/', 5),942 ProberTimeout('http://localhost/', 5),
943 ConnectionSkipped(),943 ConnectionSkipped(),
diff --git a/lib/lp/registry/tests/test_distroseries.py b/lib/lp/registry/tests/test_distroseries.py
index bb979c3..1543eca 100644
--- a/lib/lp/registry/tests/test_distroseries.py
+++ b/lib/lp/registry/tests/test_distroseries.py
@@ -660,7 +660,7 @@ class TestDistroSeriesSet(TestCaseWithFactory):
660 distro_series_set = getUtility(IDistroSeriesSet)660 distro_series_set = getUtility(IDistroSeriesSet)
661 # Get translatables as a sequence of names of the series.661 # Get translatables as a sequence of names of the series.
662 return sorted(662 return sorted(
663 [series.name for series in distro_series_set.translatables()])663 series.name for series in distro_series_set.translatables())
664664
665 def _ref_translatables(self, expected=None):665 def _ref_translatables(self, expected=None):
666 # Return the reference value, merged with expected data.666 # Return the reference value, merged with expected data.
diff --git a/lib/lp/registry/tests/test_distroseries_vocabularies.py b/lib/lp/registry/tests/test_distroseries_vocabularies.py
index e08ea8d..c5c30b8 100644
--- a/lib/lp/registry/tests/test_distroseries_vocabularies.py
+++ b/lib/lp/registry/tests/test_distroseries_vocabularies.py
@@ -73,7 +73,7 @@ class TestDistroSeriesDerivationVocabulary(TestCaseWithFactory):
73 expected_distroseries = (73 expected_distroseries = (
74 set(self.all_series_with_arch).difference(74 set(self.all_series_with_arch).difference(
75 distroseries.distribution.series))75 distroseries.distribution.series))
76 observed_distroseries = set(term.value for term in vocabulary)76 observed_distroseries = {term.value for term in vocabulary}
77 self.assertEqual(expected_distroseries, observed_distroseries)77 self.assertEqual(expected_distroseries, observed_distroseries)
7878
79 def test_distribution_with_non_derived_series_no_arch(self):79 def test_distribution_with_non_derived_series_no_arch(self):
@@ -83,7 +83,7 @@ class TestDistroSeriesDerivationVocabulary(TestCaseWithFactory):
83 distroseries = self.factory.makeDistroSeries()83 distroseries = self.factory.makeDistroSeries()
84 vocabulary = DistroSeriesDerivationVocabulary(distroseries)84 vocabulary = DistroSeriesDerivationVocabulary(distroseries)
85 another_parent_no_arch = self.factory.makeDistroSeries()85 another_parent_no_arch = self.factory.makeDistroSeries()
86 observed_distroseries = set(term.value for term in vocabulary)86 observed_distroseries = {term.value for term in vocabulary}
8787
88 self.assertNotIn(another_parent_no_arch, observed_distroseries)88 self.assertNotIn(another_parent_no_arch, observed_distroseries)
8989
@@ -106,7 +106,7 @@ class TestDistroSeriesDerivationVocabulary(TestCaseWithFactory):
106 derived_series=distroseries, parent_series=parent_distroseries)106 derived_series=distroseries, parent_series=parent_distroseries)
107 vocabulary = DistroSeriesDerivationVocabulary(distroseries)107 vocabulary = DistroSeriesDerivationVocabulary(distroseries)
108 expected_distroseries = set(parent_distroseries.distribution.series)108 expected_distroseries = set(parent_distroseries.distribution.series)
109 observed_distroseries = set(term.value for term in vocabulary)109 observed_distroseries = {term.value for term in vocabulary}
110 self.assertContentEqual(expected_distroseries, observed_distroseries)110 self.assertContentEqual(expected_distroseries, observed_distroseries)
111111
112 def test_distribution_with_derived_series_no_arch(self):112 def test_distribution_with_derived_series_no_arch(self):
@@ -119,7 +119,7 @@ class TestDistroSeriesDerivationVocabulary(TestCaseWithFactory):
119 self.factory.makeDistroSeriesParent(119 self.factory.makeDistroSeriesParent(
120 derived_series=distroseries, parent_series=parent_distroseries)120 derived_series=distroseries, parent_series=parent_distroseries)
121 vocabulary = DistroSeriesDerivationVocabulary(distroseries)121 vocabulary = DistroSeriesDerivationVocabulary(distroseries)
122 observed_distroseries = set(term.value for term in vocabulary)122 observed_distroseries = {term.value for term in vocabulary}
123123
124 self.assertIn(another_parent_no_arch, observed_distroseries)124 self.assertIn(another_parent_no_arch, observed_distroseries)
125125
@@ -142,7 +142,7 @@ class TestDistroSeriesDerivationVocabulary(TestCaseWithFactory):
142 expected_distroseries = set(142 expected_distroseries = set(
143 parent_distroseries.distribution.series).union(143 parent_distroseries.distribution.series).union(
144 set(another_parent_distroseries.distribution.series))144 set(another_parent_distroseries.distribution.series))
145 observed_distroseries = set(term.value for term in vocabulary)145 observed_distroseries = {term.value for term in vocabulary}
146 self.assertEqual(expected_distroseries, observed_distroseries)146 self.assertEqual(expected_distroseries, observed_distroseries)
147147
148 def test_distribution_with_derived_series_of_self(self):148 def test_distribution_with_derived_series_of_self(self):
@@ -159,7 +159,7 @@ class TestDistroSeriesDerivationVocabulary(TestCaseWithFactory):
159 expected_distroseries = (159 expected_distroseries = (
160 set(self.all_series_with_arch).difference(160 set(self.all_series_with_arch).difference(
161 distroseries.distribution.series))161 distroseries.distribution.series))
162 observed_distroseries = set(term.value for term in vocabulary)162 observed_distroseries = {term.value for term in vocabulary}
163 self.assertEqual(expected_distroseries, observed_distroseries)163 self.assertEqual(expected_distroseries, observed_distroseries)
164164
165 def test_distroseries(self):165 def test_distroseries(self):
@@ -170,7 +170,7 @@ class TestDistroSeriesDerivationVocabulary(TestCaseWithFactory):
170 expected_distroseries = (170 expected_distroseries = (
171 set(self.all_series_with_arch).difference(171 set(self.all_series_with_arch).difference(
172 distroseries.distribution.series))172 distroseries.distribution.series))
173 observed_distroseries = set(term.value for term in vocabulary)173 observed_distroseries = {term.value for term in vocabulary}
174 self.assertEqual(expected_distroseries, observed_distroseries)174 self.assertEqual(expected_distroseries, observed_distroseries)
175175
176 def test_ordering(self):176 def test_ordering(self):
diff --git a/lib/lp/registry/tests/test_distroseriesdifference.py b/lib/lp/registry/tests/test_distroseriesdifference.py
index 0163383..18bb640 100644
--- a/lib/lp/registry/tests/test_distroseriesdifference.py
+++ b/lib/lp/registry/tests/test_distroseriesdifference.py
@@ -436,7 +436,7 @@ class DistroSeriesDifferenceTestCase(TestCaseWithFactory):
436 ds_diff, ds_diff.parent_series, 5)436 ds_diff, ds_diff.parent_series, 5)
437 parent_packagesets = ds_diff.parent_packagesets437 parent_packagesets = ds_diff.parent_packagesets
438 self.assertEqual(438 self.assertEqual(
439 sorted([packageset.name for packageset in packagesets]),439 sorted(packageset.name for packageset in packagesets),
440 [packageset.name for packageset in parent_packagesets])440 [packageset.name for packageset in parent_packagesets])
441441
442 def test_packagesets(self):442 def test_packagesets(self):
@@ -445,7 +445,7 @@ class DistroSeriesDifferenceTestCase(TestCaseWithFactory):
445 packagesets = self._setupPackageSets(445 packagesets = self._setupPackageSets(
446 ds_diff, ds_diff.derived_series, 5)446 ds_diff, ds_diff.derived_series, 5)
447 self.assertEqual(447 self.assertEqual(
448 sorted([packageset.name for packageset in packagesets]),448 sorted(packageset.name for packageset in packagesets),
449 [packageset.name for packageset in ds_diff.packagesets])449 [packageset.name for packageset in ds_diff.packagesets])
450450
451 def test_blocklist_unauthorised(self):451 def test_blocklist_unauthorised(self):
@@ -998,17 +998,17 @@ class DistroSeriesDifferenceSourceTestCase(TestCaseWithFactory):
998998
999 def makeDifferencesForAllDifferenceTypes(self, derived_series):999 def makeDifferencesForAllDifferenceTypes(self, derived_series):
1000 """Create DSDs of all types for `derived_series`."""1000 """Create DSDs of all types for `derived_series`."""
1001 return dict(1001 return {
1002 (diff_type, self.factory.makeDistroSeriesDifference(1002 diff_type: self.factory.makeDistroSeriesDifference(
1003 derived_series, difference_type=diff_type))1003 derived_series, difference_type=diff_type)
1004 for diff_type in DistroSeriesDifferenceType.items)1004 for diff_type in DistroSeriesDifferenceType.items}
10051005
1006 def makeDifferencesForAllStatuses(self, derived_series):1006 def makeDifferencesForAllStatuses(self, derived_series):
1007 """Create DSDs of all statuses for `derived_series`."""1007 """Create DSDs of all statuses for `derived_series`."""
1008 return dict(1008 return {
1009 (status, self.factory.makeDistroSeriesDifference(1009 status: self.factory.makeDistroSeriesDifference(
1010 derived_series, status=status))1010 derived_series, status=status)
1011 for status in DistroSeriesDifferenceStatus.items)1011 for status in DistroSeriesDifferenceStatus.items}
10121012
1013 def makeDerivedSeries(self, derived_series=None):1013 def makeDerivedSeries(self, derived_series=None):
1014 """Create a derived `DistroSeries`."""1014 """Create a derived `DistroSeries`."""
@@ -1337,9 +1337,9 @@ class TestMostRecentComments(TestCaseWithFactory):
13371337
1338 def test_most_recent_comments(self):1338 def test_most_recent_comments(self):
1339 dsp = self.factory.makeDistroSeriesParent()1339 dsp = self.factory.makeDistroSeriesParent()
1340 dsds = set(1340 dsds = {
1341 self.factory.makeDistroSeriesDifference(1341 self.factory.makeDistroSeriesDifference(
1342 derived_series=dsp.derived_series) for index in range(5))1342 derived_series=dsp.derived_series) for index in range(5)}
1343 expected_comments = set()1343 expected_comments = set()
1344 for dsd in dsds:1344 for dsd in dsds:
1345 # Add a couple of comments.1345 # Add a couple of comments.
@@ -1377,9 +1377,9 @@ class TestMostRecentPublications(TestCaseWithFactory):
1377 self.create_difference(derived_series),1377 self.create_difference(derived_series),
1378 ]1378 ]
1379 # Derived publication.1379 # Derived publication.
1380 source_pubs_by_spn_id_expected = set(1380 source_pubs_by_spn_id_expected = {
1381 (dsd.source_package_name.id, dsd.source_pub)1381 (dsd.source_package_name.id, dsd.source_pub)
1382 for dsd in dsds)1382 for dsd in dsds}
1383 source_pubs_by_spn_id_found = most_recent_publications(1383 source_pubs_by_spn_id_found = most_recent_publications(
1384 dsds, in_parent=False, statuses=(1384 dsds, in_parent=False, statuses=(
1385 PackagePublishingStatus.PUBLISHED,1385 PackagePublishingStatus.PUBLISHED,
@@ -1388,9 +1388,9 @@ class TestMostRecentPublications(TestCaseWithFactory):
1388 source_pubs_by_spn_id_expected,1388 source_pubs_by_spn_id_expected,
1389 source_pubs_by_spn_id_found)1389 source_pubs_by_spn_id_found)
1390 # Parent publication1390 # Parent publication
1391 parent_source_pubs_by_spn_id_expected = set(1391 parent_source_pubs_by_spn_id_expected = {
1392 (dsd.source_package_name.id, dsd.parent_source_pub)1392 (dsd.source_package_name.id, dsd.parent_source_pub)
1393 for dsd in dsds)1393 for dsd in dsds}
1394 parent_source_pubs_by_spn_id_found = most_recent_publications(1394 parent_source_pubs_by_spn_id_found = most_recent_publications(
1395 dsds, in_parent=True, statuses=(1395 dsds, in_parent=True, statuses=(
1396 PackagePublishingStatus.PUBLISHED,1396 PackagePublishingStatus.PUBLISHED,
diff --git a/lib/lp/registry/tests/test_initderiveddistroseries.py b/lib/lp/registry/tests/test_initderiveddistroseries.py
index 07b5740..ade4a6d 100644
--- a/lib/lp/registry/tests/test_initderiveddistroseries.py
+++ b/lib/lp/registry/tests/test_initderiveddistroseries.py
@@ -84,9 +84,9 @@ class TestDeriveDistroSeriesMultipleParents(InitializationHelperTestCase):
84 pub_sources = series.main_archive.getPublishedSources(84 pub_sources = series.main_archive.getPublishedSources(
85 distroseries=series)85 distroseries=series)
86 binaries = sorted(86 binaries = sorted(
87 [(p.getBuiltBinaries()[0].binarypackagerelease.sourcepackagename,87 (p.getBuiltBinaries()[0].binarypackagerelease.sourcepackagename,
88 p.getBuiltBinaries()[0].binarypackagerelease.version)88 p.getBuiltBinaries()[0].binarypackagerelease.version)
89 for p in pub_sources])89 for p in pub_sources)
9090
91 self.assertEqual(pack_versions, binaries)91 self.assertEqual(pack_versions, binaries)
9292
diff --git a/lib/lp/registry/tests/test_mailinglistapi.py b/lib/lp/registry/tests/test_mailinglistapi.py
index be9f182..c7ea028 100644
--- a/lib/lp/registry/tests/test_mailinglistapi.py
+++ b/lib/lp/registry/tests/test_mailinglistapi.py
@@ -193,9 +193,9 @@ class MailingListAPITestCase(TestCaseWithFactory):
193 def getEmails(people):193 def getEmails(people):
194 email_address_set = getUtility(IEmailAddressSet)194 email_address_set = getUtility(IEmailAddressSet)
195 return {195 return {
196 person.name: set(196 person.name: {
197 removeSecurityProxy(email_address).email197 removeSecurityProxy(email_address).email
198 for email_address in email_address_set.getByPerson(person))198 for email_address in email_address_set.getByPerson(person)}
199 for person in people}199 for person in people}
200200
201 self.assertThat(201 self.assertThat(
diff --git a/lib/lp/registry/tests/test_milestone.py b/lib/lp/registry/tests/test_milestone.py
index 27764ab..f20894c 100644
--- a/lib/lp/registry/tests/test_milestone.py
+++ b/lib/lp/registry/tests/test_milestone.py
@@ -55,10 +55,10 @@ class MilestoneTest(unittest.TestCase):
5555
56 def testMilestoneSetIterator(self):56 def testMilestoneSetIterator(self):
57 """Test of MilestoneSet.__iter__()."""57 """Test of MilestoneSet.__iter__()."""
58 all_milestones_ids = set(58 all_milestones_ids = {
59 milestone.id for milestone in getUtility(IMilestoneSet))59 milestone.id for milestone in getUtility(IMilestoneSet)}
60 self.assertEqual(all_milestones_ids,60 self.assertEqual(all_milestones_ids,
61 set((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)))61 {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12})
6262
63 def testMilestoneSetGet(self):63 def testMilestoneSetGet(self):
64 """Test of MilestoneSet.get()"""64 """Test of MilestoneSet.get()"""
@@ -130,13 +130,13 @@ class MilestoneSecurityAdaperTestCase(TestCaseWithFactory):
130 product=self.proprietary_product)130 product=self.proprietary_product)
131131
132 expected_get_permissions = {132 expected_get_permissions = {
133 CheckerPublic: set((133 CheckerPublic: {
134 'id', 'checkAuthenticated', 'checkUnauthenticated',134 'id', 'checkAuthenticated', 'checkUnauthenticated',
135 'userCanView',135 'userCanView',
136 )),136 },
137 'launchpad.LimitedView': set((137 'launchpad.LimitedView': {
138 'displayname', 'name', 'target', 'title',)),138 'displayname', 'name', 'target', 'title'},
139 'launchpad.View': set((139 'launchpad.View': {
140 'active', 'bug_subscriptions', 'bugtasks', 'code_name',140 'active', 'bug_subscriptions', 'bugtasks', 'code_name',
141 'dateexpected', 'distribution', 'distroseries',141 'dateexpected', 'distribution', 'distroseries',
142 '_getOfficialTagClause', 'getBugSummaryContextWhereClause',142 '_getOfficialTagClause', 'getBugSummaryContextWhereClause',
@@ -148,15 +148,15 @@ class MilestoneSecurityAdaperTestCase(TestCaseWithFactory):
148 'summary', 'target_type_display', 'all_specifications',148 'summary', 'target_type_display', 'all_specifications',
149 'userCanAlterBugSubscription', 'userCanAlterSubscription',149 'userCanAlterBugSubscription', 'userCanAlterSubscription',
150 'userHasBugSubscriptions',150 'userHasBugSubscriptions',
151 )),151 },
152 'launchpad.AnyAllowedPerson': set((152 'launchpad.AnyAllowedPerson': {
153 'addBugSubscription', 'addBugSubscriptionFilter',153 'addBugSubscription', 'addBugSubscriptionFilter',
154 'addSubscription', 'removeBugSubscription',154 'addSubscription', 'removeBugSubscription',
155 )),155 },
156 'launchpad.Edit': set((156 'launchpad.Edit': {
157 'closeBugsAndBlueprints', 'createProductRelease',157 'closeBugsAndBlueprints', 'createProductRelease',
158 'destroySelf', 'setTags',158 'destroySelf', 'setTags',
159 )),159 },
160 }160 }
161161
162 def test_get_permissions(self):162 def test_get_permissions(self):
@@ -166,10 +166,10 @@ class MilestoneSecurityAdaperTestCase(TestCaseWithFactory):
166 self.expected_get_permissions, checker.get_permissions, 'get')166 self.expected_get_permissions, checker.get_permissions, 'get')
167167
168 expected_set_permissions = {168 expected_set_permissions = {
169 'launchpad.Edit': set((169 'launchpad.Edit': {
170 'active', 'code_name', 'dateexpected', 'distroseries', 'name',170 'active', 'code_name', 'dateexpected', 'distroseries', 'name',
171 'product_release', 'productseries', 'summary',171 'product_release', 'productseries', 'summary',
172 )),172 },
173 }173 }
174174
175 def test_set_permissions(self):175 def test_set_permissions(self):
@@ -640,7 +640,7 @@ class ProjectMilestoneSecurityAdaperTestCase(TestCaseWithFactory):
640 self.proprietary_projectgroup_milestone = milestone_1640 self.proprietary_projectgroup_milestone = milestone_1
641641
642 expected_get_permissions = {642 expected_get_permissions = {
643 'launchpad.View': set((643 'launchpad.View': {
644 '_getOfficialTagClause', 'active', 'addBugSubscription',644 '_getOfficialTagClause', 'active', 'addBugSubscription',
645 'addBugSubscriptionFilter', 'addSubscription',645 'addBugSubscriptionFilter', 'addSubscription',
646 'bug_subscriptions', 'bugtasks', 'closeBugsAndBlueprints',646 'bug_subscriptions', 'bugtasks', 'closeBugsAndBlueprints',
@@ -653,7 +653,7 @@ class ProjectMilestoneSecurityAdaperTestCase(TestCaseWithFactory):
653 'product_release', 'productseries', 'removeBugSubscription',653 'product_release', 'productseries', 'removeBugSubscription',
654 'searchTasks', 'series_target', 'summary', 'target',654 'searchTasks', 'series_target', 'summary', 'target',
655 'target_type_display', 'title', 'userCanAlterBugSubscription',655 'target_type_display', 'title', 'userCanAlterBugSubscription',
656 'userCanAlterSubscription', 'userHasBugSubscriptions')),656 'userCanAlterSubscription', 'userHasBugSubscriptions'},
657 }657 }
658658
659 def test_get_permissions(self):659 def test_get_permissions(self):
diff --git a/lib/lp/registry/tests/test_mlists.py b/lib/lp/registry/tests/test_mlists.py
index a581384..eedcfa2 100644
--- a/lib/lp/registry/tests/test_mlists.py
+++ b/lib/lp/registry/tests/test_mlists.py
@@ -85,7 +85,7 @@ class BaseMailingListImportTest(unittest.TestCase):
8585
86 def assertPeople(self, *people):86 def assertPeople(self, *people):
87 """Assert that `people` are members of the team."""87 """Assert that `people` are members of the team."""
88 members = set(person.name for person in self.team.allmembers)88 members = {person.name for person in self.team.allmembers}
89 expected = set(people)89 expected = set(people)
90 # Always add the team owner.90 # Always add the team owner.
91 expected.add(u'teamowner')91 expected.add(u'teamowner')
@@ -93,10 +93,10 @@ class BaseMailingListImportTest(unittest.TestCase):
9393
94 def assertAddresses(self, *addresses):94 def assertAddresses(self, *addresses):
95 """Assert that `addresses` are subscribed to the mailing list."""95 """Assert that `addresses` are subscribed to the mailing list."""
96 subscribers = set([96 subscribers = {
97 address for (name, address) in97 address for (name, address) in
98 getUtility(IMailingListSet).getSubscribedAddresses(98 getUtility(IMailingListSet).getSubscribedAddresses(
99 [self.team.name]).get(self.team.name, [])])99 [self.team.name]).get(self.team.name, [])}
100 expected = set(addresses)100 expected = set(addresses)
101 self.assertEqual(subscribers, expected)101 self.assertEqual(subscribers, expected)
102102
@@ -469,7 +469,7 @@ class TestMailingListImportScript(BaseMailingListImportTest):
469 messages = pop_notifications()469 messages = pop_notifications()
470 self.assertEqual(len(messages), 5)470 self.assertEqual(len(messages), 5)
471 # The messages are all being sent to the team owner.471 # The messages are all being sent to the team owner.
472 recipients = set(message['to'] for message in messages)472 recipients = {message['to'] for message in messages}
473 self.assertEqual(len(recipients), 1)473 self.assertEqual(len(recipients), 1)
474 self.assertEqual(474 self.assertEqual(
475 recipients.pop(),475 recipients.pop(),
diff --git a/lib/lp/registry/tests/test_ociproject.py b/lib/lp/registry/tests/test_ociproject.py
index 5b0924f..03036fb 100644
--- a/lib/lp/registry/tests/test_ociproject.py
+++ b/lib/lp/registry/tests/test_ociproject.py
@@ -464,8 +464,8 @@ class TestOCIProjectVocabulary(TestCaseWithFactory):
464 """464 """
465 naked = removeSecurityProxy465 naked = removeSecurityProxy
466 self.assertEqual(466 self.assertEqual(
467 set(naked(ociproject).id for ociproject in ociprojects),467 {naked(ociproject).id for ociproject in ociprojects},
468 set(naked(term.value).id for term in search_result))468 {naked(term.value).id for term in search_result})
469469
470 def test_search_with_name_substring(self):470 def test_search_with_name_substring(self):
471 vocabulary = self.getVocabulary()471 vocabulary = self.getVocabulary()
diff --git a/lib/lp/registry/tests/test_oopsreferences.py b/lib/lp/registry/tests/test_oopsreferences.py
index f06352c..175795e 100644
--- a/lib/lp/registry/tests/test_oopsreferences.py
+++ b/lib/lp/registry/tests/test_oopsreferences.py
@@ -38,7 +38,7 @@ class TestOopsReferences(TestCaseWithFactory):
38 now = datetime.now(tz=utc)38 now = datetime.now(tz=utc)
39 day = timedelta(days=1)39 day = timedelta(days=1)
40 self.assertEqual(40 self.assertEqual(
41 set([oopsid]),41 {oopsid},
42 referenced_oops(now - day, now, "product=1", {}))42 referenced_oops(now - day, now, "product=1", {}))
43 self.assertEqual(43 self.assertEqual(
44 set(),44 set(),
@@ -52,7 +52,7 @@ class TestOopsReferences(TestCaseWithFactory):
52 now = datetime.now(tz=utc)52 now = datetime.now(tz=utc)
53 day = timedelta(days=1)53 day = timedelta(days=1)
54 self.assertEqual(54 self.assertEqual(
55 set([oopsid]),55 {oopsid},
56 referenced_oops(now - day, now, "product=1", {}))56 referenced_oops(now - day, now, "product=1", {}))
57 self.assertEqual(57 self.assertEqual(
58 set(),58 set(),
@@ -67,7 +67,7 @@ class TestOopsReferences(TestCaseWithFactory):
67 now = datetime.now(tz=utc)67 now = datetime.now(tz=utc)
68 day = timedelta(days=1)68 day = timedelta(days=1)
69 self.assertEqual(69 self.assertEqual(
70 set([oopsid]),70 {oopsid},
71 referenced_oops(now - day, now, "product=1", {}))71 referenced_oops(now - day, now, "product=1", {}))
72 self.assertEqual(72 self.assertEqual(
73 set(),73 set(),
@@ -82,7 +82,7 @@ class TestOopsReferences(TestCaseWithFactory):
82 now = datetime.now(tz=utc)82 now = datetime.now(tz=utc)
83 day = timedelta(days=1)83 day = timedelta(days=1)
84 self.assertEqual(84 self.assertEqual(
85 set([oopsid]),85 {oopsid},
86 referenced_oops(now - day, now, "product=1", {}))86 referenced_oops(now - day, now, "product=1", {}))
87 self.assertEqual(87 self.assertEqual(
88 set(),88 set(),
@@ -95,11 +95,11 @@ class TestOopsReferences(TestCaseWithFactory):
95 now = datetime.now(tz=utc)95 now = datetime.now(tz=utc)
96 day = timedelta(days=1)96 day = timedelta(days=1)
97 self.assertEqual(97 self.assertEqual(
98 set([oopsid]),98 {oopsid},
99 referenced_oops(now - day, now, "product=%(product)s",99 referenced_oops(now - day, now, "product=%(product)s",
100 {'product': question.product.id}))100 {'product': question.product.id}))
101 self.assertEqual(101 self.assertEqual(
102 set([]),102 set(),
103 referenced_oops(now + day, now + day, "product=%(product)s",103 referenced_oops(now + day, now + day, "product=%(product)s",
104 {'product': question.product.id}))104 {'product': question.product.id}))
105105
@@ -123,11 +123,11 @@ class TestOopsReferences(TestCaseWithFactory):
123 now = datetime.now(tz=utc)123 now = datetime.now(tz=utc)
124 day = timedelta(days=1)124 day = timedelta(days=1)
125 self.assertEqual(125 self.assertEqual(
126 set([oopsid]),126 {oopsid},
127 referenced_oops(now - day, now, "product=%(product)s",127 referenced_oops(now - day, now, "product=%(product)s",
128 {'product': question.product.id}))128 {'product': question.product.id}))
129 self.assertEqual(129 self.assertEqual(
130 set([]),130 set(),
131 referenced_oops(now + day, now + day, "product=%(product)s",131 referenced_oops(now + day, now + day, "product=%(product)s",
132 {'product': question.product.id}))132 {'product': question.product.id}))
133133
@@ -140,11 +140,11 @@ class TestOopsReferences(TestCaseWithFactory):
140 now = datetime.now(tz=utc)140 now = datetime.now(tz=utc)
141 day = timedelta(days=1)141 day = timedelta(days=1)
142 self.assertEqual(142 self.assertEqual(
143 set([oopsid]),143 {oopsid},
144 referenced_oops(now - day, now, "product=%(product)s",144 referenced_oops(now - day, now, "product=%(product)s",
145 {'product': question.product.id}))145 {'product': question.product.id}))
146 self.assertEqual(146 self.assertEqual(
147 set([]),147 set(),
148 referenced_oops(now + day, now + day, "product=%(product)s",148 referenced_oops(now + day, now + day, "product=%(product)s",
149 {'product': question.product.id}))149 {'product': question.product.id}))
150150
@@ -158,11 +158,11 @@ class TestOopsReferences(TestCaseWithFactory):
158 now = datetime.now(tz=utc)158 now = datetime.now(tz=utc)
159 day = timedelta(days=1)159 day = timedelta(days=1)
160 self.assertEqual(160 self.assertEqual(
161 set([oopsid]),161 {oopsid},
162 referenced_oops(now - day, now, "distribution=%(distribution)s",162 referenced_oops(now - day, now, "distribution=%(distribution)s",
163 {'distribution': distro.id}))163 {'distribution': distro.id}))
164 self.assertEqual(164 self.assertEqual(
165 set([]),165 set(),
166 referenced_oops(now + day, now + day,166 referenced_oops(now + day, now + day,
167 "distribution=%(distribution)s", {'distribution': distro.id}))167 "distribution=%(distribution)s", {'distribution': distro.id}))
168168
@@ -187,8 +187,8 @@ class TestOopsReferences(TestCaseWithFactory):
187 now = datetime.now(tz=utc)187 now = datetime.now(tz=utc)
188 day = timedelta(days=1)188 day = timedelta(days=1)
189 self.assertEqual(189 self.assertEqual(
190 set([oopsid_old, oopsid_new]),190 {oopsid_old, oopsid_new},
191 referenced_oops(now - day, now, "product=1", {}))191 referenced_oops(now - day, now, "product=1", {}))
192 self.assertEqual(192 self.assertEqual(
193 set([]),193 set(),
194 referenced_oops(now + day, now + day, "product=1", {}))194 referenced_oops(now + day, now + day, "product=1", {}))
diff --git a/lib/lp/registry/tests/test_person.py b/lib/lp/registry/tests/test_person.py
index ee75a5b..a7df518 100644
--- a/lib/lp/registry/tests/test_person.py
+++ b/lib/lp/registry/tests/test_person.py
@@ -1305,7 +1305,7 @@ class TestGetRecipients(TestCaseWithFactory):
1305 team = self.factory.makeTeam(owner)1305 team = self.factory.makeTeam(owner)
1306 super_team = self.factory.makeTeam(team)1306 super_team = self.factory.makeTeam(team)
1307 recipients = get_recipients(super_team)1307 recipients = get_recipients(super_team)
1308 self.assertEqual(set([owner]), set(recipients))1308 self.assertEqual({owner}, set(recipients))
13091309
1310 def test_get_recipients_team(self):1310 def test_get_recipients_team(self):
1311 """Ensure get_recipients uses teams with preferredemail."""1311 """Ensure get_recipients uses teams with preferredemail."""
@@ -1314,7 +1314,7 @@ class TestGetRecipients(TestCaseWithFactory):
1314 team = self.factory.makeTeam(owner, email='team@bar.com')1314 team = self.factory.makeTeam(owner, email='team@bar.com')
1315 super_team = self.factory.makeTeam(team)1315 super_team = self.factory.makeTeam(team)
1316 recipients = get_recipients(super_team)1316 recipients = get_recipients(super_team)
1317 self.assertEqual(set([team]), set(recipients))1317 self.assertEqual({team}, set(recipients))
13181318
1319 def test_get_recipients_team_with_unvalidated_address(self):1319 def test_get_recipients_team_with_unvalidated_address(self):
1320 """Ensure get_recipients handles teams with non-preferred addresses.1320 """Ensure get_recipients handles teams with non-preferred addresses.
@@ -1336,7 +1336,7 @@ class TestGetRecipients(TestCaseWithFactory):
1336 def test_get_recipients_person(self):1336 def test_get_recipients_person(self):
1337 person = self.factory.makePerson()1337 person = self.factory.makePerson()
1338 recipients = get_recipients(person)1338 recipients = get_recipients(person)
1339 self.assertEqual(set([person]), set(recipients))1339 self.assertEqual({person}, set(recipients))
13401340
1341 def test_get_recipients_person_with_disabled_account(self):1341 def test_get_recipients_person_with_disabled_account(self):
1342 """Mail is not sent to a direct recipient whose account is disabled."""1342 """Mail is not sent to a direct recipient whose account is disabled."""
@@ -1367,9 +1367,9 @@ class TestGetRecipients(TestCaseWithFactory):
1367 super_team_member_team.acceptInvitationToBeMemberOf(1367 super_team_member_team.acceptInvitationToBeMemberOf(
1368 super_team, u'Go Team!')1368 super_team, u'Go Team!')
1369 recipients = list(get_recipients(super_team))1369 recipients = list(get_recipients(super_team))
1370 self.assertEqual(set([owner,1370 self.assertEqual({owner,
1371 super_team_member_person,1371 super_team_member_person,
1372 super_team_member_team]),1372 super_team_member_team},
1373 set(recipients))1373 set(recipients))
13741374
1375 def test_get_recipients_team_with_disabled_owner_account(self):1375 def test_get_recipients_team_with_disabled_owner_account(self):
diff --git a/lib/lp/registry/tests/test_person_vocabularies.py b/lib/lp/registry/tests/test_person_vocabularies.py
index e10da4d..ea0cfcc 100644
--- a/lib/lp/registry/tests/test_person_vocabularies.py
+++ b/lib/lp/registry/tests/test_person_vocabularies.py
@@ -223,10 +223,10 @@ class TestValidPersonOrTeamPreloading(VocabularyTestBase,
223223
224 # Remember the current values for checking later, and throw out224 # Remember the current values for checking later, and throw out
225 # the cache.225 # the cache.
226 expected_nicks = dict(226 expected_nicks = {
227 (person.id, list(person.ircnicknames)) for person in people)227 person.id: list(person.ircnicknames) for person in people}
228 expected_emails = dict(228 expected_emails = {
229 (person.id, person.preferredemail) for person in people)229 person.id: person.preferredemail for person in people}
230 Store.of(people[0]).invalidate()230 Store.of(people[0]).invalidate()
231231
232 results = list(self.searchVocabulary(None, u'foobar'))232 results = list(self.searchVocabulary(None, u'foobar'))
diff --git a/lib/lp/registry/tests/test_prf_finder.py b/lib/lp/registry/tests/test_prf_finder.py
index bbabb95..7b4c024 100644
--- a/lib/lp/registry/tests/test_prf_finder.py
+++ b/lib/lp/registry/tests/test_prf_finder.py
@@ -83,7 +83,7 @@ class FindReleasesDBTestCase(TestCaseWithFactory):
83 self.factory.makeProductReleaseFile(83 self.factory.makeProductReleaseFile(
84 productseries=series2, release=file2.productrelease,84 productseries=series2, release=file2.productrelease,
85 filename='foo-2.1.tar.gz')85 filename='foo-2.1.tar.gz')
86 expected = set(['foo-1.0.tar.gz', 'foo-2.0.tar.gz', 'foo-2.1.tar.gz'])86 expected = {'foo-1.0.tar.gz', 'foo-2.0.tar.gz', 'foo-2.1.tar.gz'}
87 transaction.commit()87 transaction.commit()
88 prf = ProductReleaseFinder(self.layer.txn, logging.getLogger())88 prf = ProductReleaseFinder(self.layer.txn, logging.getLogger())
89 found = prf.getReleaseFileNames(product.name)89 found = prf.getReleaseFileNames(product.name)
diff --git a/lib/lp/registry/tests/test_product.py b/lib/lp/registry/tests/test_product.py
index da0be15..656f7ec 100644
--- a/lib/lp/registry/tests/test_product.py
+++ b/lib/lp/registry/tests/test_product.py
@@ -339,8 +339,8 @@ class TestProduct(TestCaseWithFactory):
339 licenses=[License.MIT])339 licenses=[License.MIT])
340 policies = getUtility(IAccessPolicySource).findByPillar((product,))340 policies = getUtility(IAccessPolicySource).findByPillar((product,))
341 grants = getUtility(IAccessPolicyGrantSource).findByPolicy(policies)341 grants = getUtility(IAccessPolicyGrantSource).findByPolicy(policies)
342 expected_grantess = set([product.owner])342 expected_grantess = {product.owner}
343 grantees = set([grant.grantee for grant in grants])343 grantees = {grant.grantee for grant in grants}
344 self.assertEqual(expected_grantess, grantees)344 self.assertEqual(expected_grantess, grantees)
345345
346 def test_open_product_creation_sharing_policies(self):346 def test_open_product_creation_sharing_policies(self):
@@ -821,18 +821,18 @@ class TestProduct(TestCaseWithFactory):
821 product.information_type = InformationType.PROPRIETARY821 product.information_type = InformationType.PROPRIETARY
822822
823 expected_get_permissions = {823 expected_get_permissions = {
824 CheckerPublic: set((824 CheckerPublic: {
825 'active', 'id', 'information_type', 'pillar_category', 'private',825 'active', 'id', 'information_type', 'pillar_category', 'private',
826 'userCanLimitedView', 'userCanView',)),826 'userCanLimitedView', 'userCanView'},
827 'launchpad.LimitedView': set((827 'launchpad.LimitedView': {
828 'bugtargetdisplayname', 'display_name', 'displayname', 'drivers',828 'bugtargetdisplayname', 'display_name', 'displayname', 'drivers',
829 'enable_bug_expiration', 'getBugTaskWeightFunction',829 'enable_bug_expiration', 'getBugTaskWeightFunction',
830 'getOCIProject', 'getSpecification',830 'getOCIProject', 'getSpecification',
831 'icon', 'logo', 'name', 'official_answers', 'official_anything',831 'icon', 'logo', 'name', 'official_answers', 'official_anything',
832 'official_blueprints', 'official_codehosting', 'official_malone',832 'official_blueprints', 'official_codehosting', 'official_malone',
833 'owner', 'parent_subscription_target', 'pillar', 'projectgroup',833 'owner', 'parent_subscription_target', 'pillar', 'projectgroup',
834 'searchTasks', 'title')),834 'searchTasks', 'title'},
835 'launchpad.View': set((835 'launchpad.View': {
836 '_getOfficialTagClause', 'visible_specifications',836 '_getOfficialTagClause', 'visible_specifications',
837 'valid_specifications', 'api_valid_specifications',837 'valid_specifications', 'api_valid_specifications',
838 'active_or_packaged_series', 'aliases', 'all_milestones',838 'active_or_packaged_series', 'aliases', 'all_milestones',
@@ -894,21 +894,21 @@ class TestProduct(TestCaseWithFactory):
894 'translationpermission', 'translations_usage', 'ubuntu_packages',894 'translationpermission', 'translations_usage', 'ubuntu_packages',
895 'userCanAlterBugSubscription', 'userCanAlterSubscription',895 'userCanAlterBugSubscription', 'userCanAlterSubscription',
896 'userCanEdit', 'userHasBugSubscriptions', 'uses_launchpad',896 'userCanEdit', 'userHasBugSubscriptions', 'uses_launchpad',
897 'vcs', 'wikiurl')),897 'vcs', 'wikiurl'},
898 'launchpad.AnyAllowedPerson': set((898 'launchpad.AnyAllowedPerson': {
899 'addAnswerContact', 'addBugSubscription',899 'addAnswerContact', 'addBugSubscription',
900 'addBugSubscriptionFilter', 'addSubscription',900 'addBugSubscriptionFilter', 'addSubscription',
901 'createQuestionFromBug', 'newQuestion', 'removeAnswerContact',901 'createQuestionFromBug', 'newQuestion', 'removeAnswerContact',
902 'removeBugSubscription')),902 'removeBugSubscription'},
903 'launchpad.Append': set(('newFAQ', )),903 'launchpad.Append': {'newFAQ'},
904 'launchpad.Driver': set(('newSeries', )),904 'launchpad.Driver': {'newSeries'},
905 'launchpad.Edit': set((905 'launchpad.Edit': {
906 'addOfficialBugTag', 'removeOfficialBugTag',906 'addOfficialBugTag', 'removeOfficialBugTag',
907 'setBranchSharingPolicy', 'setBugSharingPolicy',907 'setBranchSharingPolicy', 'setBugSharingPolicy',
908 'setSpecificationSharingPolicy', 'checkInformationType')),908 'setSpecificationSharingPolicy', 'checkInformationType'},
909 'launchpad.Moderate': set((909 'launchpad.Moderate': {
910 'is_permitted', 'license_approved', 'project_reviewed',910 'is_permitted', 'license_approved', 'project_reviewed',
911 'reviewer_whiteboard', 'setAliases')),911 'reviewer_whiteboard', 'setAliases'},
912 }912 }
913913
914 def test_get_permissions(self):914 def test_get_permissions(self):
@@ -919,12 +919,12 @@ class TestProduct(TestCaseWithFactory):
919919
920 def test_set_permissions(self):920 def test_set_permissions(self):
921 expected_set_permissions = {921 expected_set_permissions = {
922 'launchpad.BugSupervisor': set((922 'launchpad.BugSupervisor': {
923 'bug_reported_acknowledgement', 'bug_reporting_guidelines',923 'bug_reported_acknowledgement', 'bug_reporting_guidelines',
924 'bugtracker', 'enable_bug_expiration',924 'bugtracker', 'enable_bug_expiration',
925 'enable_bugfiling_duplicate_search', 'official_bug_tags',925 'enable_bugfiling_duplicate_search', 'official_bug_tags',
926 'official_malone', 'remote_product')),926 'official_malone', 'remote_product'},
927 'launchpad.Edit': set((927 'launchpad.Edit': {
928 'answers_usage', 'blueprints_usage', 'bug_supervisor',928 'answers_usage', 'blueprints_usage', 'bug_supervisor',
929 'bug_tracking_usage', 'codehosting_usage',929 'bug_tracking_usage', 'codehosting_usage',
930 'commercial_subscription', 'description', 'development_focus',930 'commercial_subscription', 'description', 'development_focus',
@@ -935,15 +935,15 @@ class TestProduct(TestCaseWithFactory):
935 'official_codehosting', 'owner', 'private',935 'official_codehosting', 'owner', 'private',
936 'programminglang', 'projectgroup',936 'programminglang', 'projectgroup',
937 'releaseroot', 'screenshotsurl', 'sourceforgeproject',937 'releaseroot', 'screenshotsurl', 'sourceforgeproject',
938 'summary', 'uses_launchpad', 'wikiurl', 'vcs')),
939 'launchpad.Moderate': set((
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches

to status/vote changes: