Colin Watson has proposed merging lp:~cjwatson/launchpad/code-doctests-future-imports into lp:launchpad.
Commit message: Convert doctests under lp.code to Launchpad's preferred __future__ imports. Requested reviews: Launchpad code reviewers (launchpad-reviewers) For more details, see: https://code.launchpad.net/~cjwatson/launchpad/code-doctests-future-imports/+merge/345470 -- Your team Launchpad code reviewers is requested to review the proposed merge of lp:~cjwatson/launchpad/code-doctests-future-imports into lp:launchpad.
=== removed file 'lib/lp/code/browser/tests/test_views.py' --- lib/lp/code/browser/tests/test_views.py 2017-10-04 01:16:22 +0000 +++ lib/lp/code/browser/tests/test_views.py 1970-01-01 00:00:00 +0000 @@ -1,42 +0,0 @@ -# Copyright 2009-2017 Canonical Ltd. This software is licensed under the -# GNU Affero General Public License version 3 (see the file LICENSE). - -"""Run the view tests.""" - -from __future__ import absolute_import, print_function, unicode_literals - -import logging -import os -import unittest - -from lp.testing.layers import LaunchpadFunctionalLayer -from lp.testing.systemdocs import ( - LayeredDocFileSuite, - setUp, - tearDown, - ) - - -here = os.path.dirname(os.path.realpath(__file__)) - - -def test_suite(): - suite = unittest.TestSuite() - testsdir = os.path.abspath(here) - - # Add tests using default setup/teardown - filenames = [filename - for filename in os.listdir(testsdir) - if filename.endswith('.txt')] - # Sort the list to give a predictable order. - filenames.sort() - for filename in filenames: - path = filename - one_test = LayeredDocFileSuite( - path, setUp=setUp, tearDown=tearDown, - layer=LaunchpadFunctionalLayer, - stdout_logging_level=logging.WARNING - ) - suite.addTest(one_test) - - return suite === modified file 'lib/lp/code/doc/branch-karma.txt' --- lib/lp/code/doc/branch-karma.txt 2012-08-08 07:23:58 +0000 +++ lib/lp/code/doc/branch-karma.txt 2018-05-13 10:12:08 +0000 @@ -12,7 +12,7 @@ >>> code_karma_actions = code_category.karmaactions >>> for summary in sorted( ... [action.summary for action in code_karma_actions]): - ... print summary + ... print(summary) A new revision by the user is available through Launchpad. Reviewer commented on a code review. User approved a branch for merging. === modified file 'lib/lp/code/doc/branch-merge-proposal-notifications.txt' --- lib/lp/code/doc/branch-merge-proposal-notifications.txt 2015-09-11 14:48:53 +0000 +++ lib/lp/code/doc/branch-merge-proposal-notifications.txt 2018-05-13 10:12:08 +0000 @@ -83,9 +83,9 @@ values for the email headers and footers. >>> [reason] = recipients.values() - >>> print reason.mail_header + >>> print(reason.mail_header) Subscriber - >>> print reason.getReason() + >>> print(reason.getReason()) You are subscribed to branch ... @@ -122,25 +122,25 @@ An email is sent to subscribers of either branch and the default reviewer. >>> for notification in notifications: - ... print notification['X-Envelope-To'] + ... print(notification['X-Envelope-To']) sou...@example.com tar...@example.com target_ow...@example.com >>> notification = notifications[0] - >>> print notification['From'] + >>> print(notification['From']) Eric <e...@example.com> - >>> print notification['Subject'] + >>> print(notification['Subject']) [Merge] lp://dev/~person-name... into lp://dev/~person-name... - >>> print notification['X-Launchpad-Project'] + >>> print(notification['X-Launchpad-Project']) product-name... - >>> print notification['X-Launchpad-Branch'] + >>> print(notification['X-Launchpad-Branch']) ~person-name... - >>> print notification['X-Launchpad-Message-Rationale'] + >>> print(notification['X-Launchpad-Message-Rationale']) Subscriber - >>> print notification['X-Launchpad-Message-For'] + >>> print(notification['X-Launchpad-Message-For']) source-subscriber - >>> print notification.get_payload(decode=True) + >>> print(notification.get_payload(decode=True)) Eric has proposed merging lp://dev/~person-name...into lp://dev/~person-name... -- @@ -178,16 +178,16 @@ >>> notifications = pop_notifications( ... sort_key=lambda n: n.get('X-Envelope-To')) >>> for notification in notifications: - ... print "%s, %s, %s" % ( + ... print("%s, %s, %s" % ( ... notification['X-Envelope-To'], ... notification['X-Launchpad-Message-Rationale'], - ... notification['X-Launchpad-Message-For']) + ... notification['X-Launchpad-Message-For'])) b...@example.com, Reviewer, bob m...@example.com, Reviewer, mary sou...@example.com, Subscriber, source-subscriber tar...@example.com, Subscriber, target-subscriber >>> notification = notifications[0] - >>> print notification.get_payload()[0].get_payload(decode=True) + >>> print(notification.get_payload()[0].get_payload(decode=True)) Eric has proposed merging lp://dev/~person-name...into lp://dev/~person-name... <BLANKLINE> === modified file 'lib/lp/code/doc/branch-notifications.txt' --- lib/lp/code/doc/branch-notifications.txt 2018-02-02 10:06:24 +0000 +++ lib/lp/code/doc/branch-notifications.txt 2018-05-13 10:12:08 +0000 @@ -48,22 +48,22 @@ >>> len(notifications) 1 >>> branch_notification = notifications[0] - >>> print branch_notification['To'] + >>> print(branch_notification['To']) Sample Person <t...@canonical.com> - >>> print branch_notification['From'] + >>> print(branch_notification['From']) f...@canonical.com - >>> print branch_notification['Subject'] + >>> print(branch_notification['Subject']) Subject line - >>> print branch_notification['X-Launchpad-Project'] + >>> print(branch_notification['X-Launchpad-Project']) firefox - >>> print branch_notification['X-Launchpad-Branch'] + >>> print(branch_notification['X-Launchpad-Branch']) ~name12/firefox/main - >>> print branch_notification['X-Launchpad-Message-Rationale'] + >>> print(branch_notification['X-Launchpad-Message-Rationale']) Subscriber - >>> print branch_notification['X-Launchpad-Message-For'] + >>> print(branch_notification['X-Launchpad-Message-For']) name12 >>> notification_body = branch_notification.get_payload(decode=True) - >>> print notification_body #doctest: -NORMALIZE_WHITESPACE + >>> print(notification_body) #doctest: -NORMALIZE_WHITESPACE The contents. <BLANKLINE> -- @@ -153,7 +153,7 @@ And to make sure we have them: >>> for subscription in branch.subscriptions: - ... print subscription.person.name + ... print(subscription.person.name) no-priv name12 carlos @@ -183,7 +183,7 @@ >>> for email in recipients.getEmails(): ... subscription, header = recipients.getReason(email) ... if subscription.notification_level in interested_levels: - ... print email, subscription.max_diff_lines.title, header + ... print(email, subscription.max_diff_lines.title, header) car...@canonical.com Don't send diffs Subscriber celso.provid...@canonical.com 1000 lines Subscriber d...@canonical.com 5000 lines Subscriber @@ -205,7 +205,7 @@ ... attachment = '\n' + root[1].get_payload(decode=True) ... else: ... body = email.get_payload(decode=True) - ... print 'To: %s\n%s%s' % (email['To'], body, attachment) + ... print('To: %s\n%s%s' % (email['To'], body, attachment)) We need to create some sufficiently large diffs to compare against. @@ -230,11 +230,11 @@ There are also some useful headers for filtering emails. - >>> print msg['X-Launchpad-Branch'] + >>> print(msg['X-Launchpad-Branch']) ~name12/firefox/main - >>> print msg['X-Launchpad-Branch-Revision-Number'] + >>> print(msg['X-Launchpad-Branch-Revision-Number']) 1234 - >>> print msg['X-Launchpad-Project'] + >>> print(msg['X-Launchpad-Project']) firefox >>> print_to_and_body(notifications.pop(0)) To: Celso Providelo <celso.provid...@canonical.com> @@ -389,7 +389,7 @@ >>> for email in recipients.getEmails(): ... subscription, header = recipients.getReason(email) ... if subscription.notification_level in interested_levels: - ... print email, subscription.max_diff_lines.title, header + ... print(email, subscription.max_diff_lines.title, header) david.allou...@canonical.com 500 lines Subscriber foo....@canonical.com 5000 lines Subscriber @vcs-imports robe...@robertcollins.net 5000 lines Subscriber @vcs-imports @@ -406,8 +406,8 @@ ... body = body.decode(email.get_param('charset')) ... else: ... body = body.decode('iso-8859-1') - ... print u'To: %s\nFrom: %s\nSubject: %s\n%s' % ( - ... email['To'], email['From'], email['Subject'], body) + ... print(u'To: %s\nFrom: %s\nSubject: %s\n%s' % ( + ... email['To'], email['From'], email['Subject'], body)) It is the form infrastructure that fires off the ObjectModifedEvent, so we'll fake that bit here. The page tests will check the emails === modified file 'lib/lp/code/doc/branch-xmlrpc.txt' --- lib/lp/code/doc/branch-xmlrpc.txt 2017-05-23 12:42:38 +0000 +++ lib/lp/code/doc/branch-xmlrpc.txt 2018-05-13 10:12:08 +0000 @@ -27,7 +27,7 @@ >>> results = public_codehosting_api.resolve_lp_path( ... '~vcs-imports/evolution/main') - >>> print results.keys() + >>> print(results.keys()) ['urls'] @@ -37,7 +37,7 @@ >>> results = public_codehosting_api.resolve_lp_path( ... '~vcs-imports/evolution/main') >>> for url in results['urls']: - ... print url + ... print(url) bzr+ssh://bazaar.launchpad.dev/~vcs-imports/evolution/main http://bazaar.launchpad.dev/~vcs-imports/evolution/main === modified file 'lib/lp/code/doc/branch.txt' --- lib/lp/code/doc/branch.txt 2015-09-25 12:12:20 +0000 +++ lib/lp/code/doc/branch.txt 2018-05-13 10:12:08 +0000 @@ -78,12 +78,12 @@ The 'get' method on the branch set fetches branches by ID. >>> branch = factory.makeAnyBranch(name='foobar') - >>> print branch_lookup.get(branch.id).name + >>> print(branch_lookup.get(branch.id).name) foobar It returns None if there is no branch with the specified ID. - >>> print branch_lookup.get(-1) + >>> print(branch_lookup.get(-1)) None @@ -108,10 +108,10 @@ The registrant of the branch is the user that originally registered the branch, whereas the owner is the current owner of the branch. - >>> print new_branch.registrant.name + >>> print(new_branch.registrant.name) registrant - >>> print new_branch.owner.name + >>> print(new_branch.owner.name) registrant A user can create a branch where the owner is either themselves, or a @@ -126,10 +126,10 @@ >>> team = factory.makeTeam(name='new-owner', owner=new_branch.owner) >>> new_branch.setOwner(new_owner=team, user=new_branch.owner) - >>> print new_branch.registrant.name + >>> print(new_branch.registrant.name) registrant - >>> print new_branch.owner.name + >>> print(new_branch.owner.name) new-owner Branch names must start with a number or a letter (upper or lower case) @@ -205,17 +205,17 @@ ... 'imported', owner=vcs_imports, branch_type=BranchType.IMPORTED) >>> for branch in branchset.getRecentlyChangedBranches(5): - ... print branch.unique_name + ... print(branch.unique_name) ~user/product/young ~user/product/middling ~user/product/oldest >>> for branch in branchset.getRecentlyImportedBranches(5): - ... print branch.unique_name + ... print(branch.unique_name) ~vcs-imports/product/imported >>> for branch in branchset.getRecentlyRegisteredBranches(3): - ... print branch.unique_name + ... print(branch.unique_name) ~vcs-imports/product/imported ~user/product/young ~user/product/middling @@ -250,7 +250,7 @@ If no branch is found for the specified URL, getByUrl returns None. >>> not_there_url = factory.getUniqueURL() - >>> print branch_lookup.getByUrl(not_there_url) + >>> print(branch_lookup.getByUrl(not_there_url)) None @@ -295,7 +295,7 @@ >>> subscription.branch == branch and subscription.person == subscriber True - >>> print subscription.notification_level.name + >>> print(subscription.notification_level.name) FULL >>> subscription.max_diff_lines == BranchSubscriptionDiffSize.FIVEKLINES @@ -311,7 +311,7 @@ True >>> from lp.services.webapp import canonical_url - >>> print canonical_url(subscription) + >>> print(canonical_url(subscription)) http://code...dev/~user/product/subscribed/+subscription/subscriber The settings for a subscription can be changed by re-subscribing. @@ -346,7 +346,7 @@ >>> def print_names(persons): ... """Print the name of each person on a new line.""" ... for person in persons: - ... print person.person.name + ... print(person.person.name) >>> subscription = branch2.subscribe( ... subscriber, @@ -386,7 +386,7 @@ ... in references ... ]) >>> for name in listing: - ... print name + ... print(name) branch.stacked_on branchjob.branch branchmergeproposal.dependent_branch === modified file 'lib/lp/code/doc/codeimport-event.txt' --- lib/lp/code/doc/codeimport-event.txt 2012-12-26 01:32:19 +0000 +++ lib/lp/code/doc/codeimport-event.txt 2018-05-13 10:12:08 +0000 @@ -32,9 +32,9 @@ >>> from lp.code.interfaces.codeimportevent import ICodeImportEvent >>> def verify_event(event): ... if verifyObject(ICodeImportEvent, removeSecurityProxy(event)): - ... print event.event_type.name + ... print(event.event_type.name) ... else: - ... print "verifyObject failed" + ... print("verifyObject failed") To help us test the output of the items() method, we define a helper function that do not print values which are potentially unstable @@ -42,12 +42,12 @@ >>> def print_items(event): ... if len(event.items()) == 0: - ... print '<nothing>' + ... print('<nothing>') ... for k, v in sorted(event.items()): ... if k.name == 'CODE_IMPORT': - ... print k.name, '<muted>' + ... print(k.name, '<muted>') ... else: - ... print k.name, repr(v) + ... print(k.name, repr(v)) We want to concisely check that calling the CodeImportEventSet factory methods with required arguments set to None raise an AssertionError. @@ -67,7 +67,7 @@ ... else: ... raise ... else: - ... print "No exception raised, expected: %s" % (exc_type,) + ... print("No exception raised, expected: %s" % (exc_type,)) All CodeImportEvent creation methods explicitly check that their arguments are not None. See the implementation of CodeImportEventSet for @@ -108,7 +108,7 @@ >>> verify_event(svn_create_event) CREATE - >>> print svn_create_event.person.name + >>> print(svn_create_event.person.name) no-priv >>> svn_create_event.code_import == svn_import @@ -206,7 +206,7 @@ >>> verify_event(modify_event) MODIFY - >>> print modify_event.person.name + >>> print(modify_event.person.name) no-priv >>> modify_event.code_import == svn_import @@ -230,7 +230,7 @@ >>> old_event_set_len = len(list(event_set.getAll())) >>> token = event_set.beginModify(svn_import) - >>> print event_set.newModify(svn_import, nopriv, token) + >>> print(event_set.newModify(svn_import, nopriv, token)) None >>> len(list(event_set.getAll())) == old_event_set_len @@ -251,7 +251,7 @@ >>> verify_event(request_event) REQUEST - >>> print request_event.person.name + >>> print(request_event.person.name) no-priv >>> print_items(request_event) @@ -287,10 +287,10 @@ >>> verify_event(online_event) ONLINE - >>> print online_event.machine.hostname + >>> print(online_event.machine.hostname) bazaar-importer - >>> print online_event.person + >>> print(online_event.person) None >>> print_items(online_event) @@ -305,10 +305,10 @@ >>> verify_event(online_event) ONLINE - >>> print online_event.machine.hostname + >>> print(online_event.machine.hostname) apollo - >>> print online_event.person.name + >>> print(online_event.person.name) ddaa >>> print_items(online_event) @@ -333,7 +333,7 @@ >>> verify_event(offline_event) OFFLINE - >>> print offline_event.machine.hostname + >>> print(offline_event.machine.hostname) bazaar-importer >>> print_items(offline_event) @@ -359,10 +359,10 @@ >>> verify_event(offline_event) OFFLINE - >>> print offline_event.machine.hostname + >>> print(offline_event.machine.hostname) apollo - >>> print offline_event.person.name + >>> print(offline_event.person.name) ddaa >>> print_items(offline_event) @@ -388,10 +388,10 @@ >>> verify_event(quiesce_event) QUIESCE - >>> print quiesce_event.machine.hostname + >>> print(quiesce_event.machine.hostname) bazaar-importer - >>> print quiesce_event.person.name + >>> print(quiesce_event.person.name) ddaa >>> print_items(quiesce_event) @@ -414,10 +414,10 @@ >>> verify_event(start_event) START - >>> print start_event.machine.hostname + >>> print(start_event.machine.hostname) bazaar-importer - >>> print start_event.code_import == svn_import + >>> print(start_event.code_import == svn_import) True >>> start_event.items() @@ -440,10 +440,10 @@ >>> verify_event(finish_event) FINISH - >>> print finish_event.machine.hostname + >>> print(finish_event.machine.hostname) bazaar-importer - >>> print finish_event.code_import == svn_import + >>> print(finish_event.code_import == svn_import) True >>> finish_event.items() @@ -466,13 +466,13 @@ >>> verify_event(kill_event) KILL - >>> print kill_event.code_import == svn_import + >>> print(kill_event.code_import == svn_import) True - >>> print kill_event.person + >>> print(kill_event.person) None - >>> print kill_event.machine.hostname + >>> print(kill_event.machine.hostname) bazaar-importer >>> kill_event.items() @@ -503,13 +503,13 @@ >>> verify_event(reclaim_event) RECLAIM - >>> print reclaim_event.code_import == svn_import + >>> print(reclaim_event.code_import == svn_import) True - >>> print reclaim_event.person + >>> print(reclaim_event.person) None - >>> print reclaim_event.machine.hostname + >>> print(reclaim_event.machine.hostname) bazaar-importer The job id is the only datum stored in the key-value data associated === modified file 'lib/lp/code/doc/codeimport-job.txt' --- lib/lp/code/doc/codeimport-job.txt 2017-10-04 03:00:14 +0000 +++ lib/lp/code/doc/codeimport-job.txt 2018-05-13 10:12:08 +0000 @@ -59,7 +59,7 @@ >>> new_import_branch = branch_lookup.getByUniqueName( ... '~vcs-imports/evolution/import') >>> new_import = code_import_set.getByBranch(new_import_branch) - >>> print new_import.review_status.name + >>> print(new_import.review_status.name) NEW The other one has review_status set to REVIEWED. @@ -67,7 +67,7 @@ >>> reviewed_import_branch = branch_lookup.getByUniqueName( ... '~vcs-imports/gnome-terminal/import') >>> reviewed_import = code_import_set.getByBranch(reviewed_import_branch) - >>> print reviewed_import.review_status.name + >>> print(reviewed_import.review_status.name) REVIEWED Some workflow methods expect the user that is requesting the action. We @@ -145,12 +145,12 @@ >>> unproxied_new_import = removeSecurityProxy(new_import) >>> unproxied_new_import.review_status = CodeImportReviewStatus.REVIEWED >>> new_job = workflow.newJob(new_import) - >>> print new_import.import_job + >>> print(new_import.import_job) <security proxied ...CodeImportJob instance at 0x...> Jobs are always created in PENDING state. - >>> print new_job.state.name + >>> print(new_job.state.name) PENDING When the code import is associated to existing CodeImportResult objects, @@ -169,7 +169,7 @@ >>> unproxied_new_import.review_status = CodeImportReviewStatus.INVALID >>> workflow.deletePendingJob(new_import) - >>> print new_import.import_job + >>> print(new_import.import_job) None @@ -192,12 +192,12 @@ This records the requesting user in the job object and sets its date due for running as soon as possible. - >>> print pending_job.requesting_user.name + >>> print(pending_job.requesting_user.name) no-priv The job request is also recorded in the CodeImportEvent audit trail. - >>> print new_events.summary() + >>> print(new_events.summary()) REQUEST ~vcs-imports/gnome-terminal/import no-priv Once a job has been requested by a user, it cannot be requested a @@ -231,7 +231,7 @@ The event is also recorded in the CodeImportEvent audit trail. - >>> print new_events.summary() + >>> print(new_events.summary()) START ~vcs-imports/gnome-terminal/import bazaar-importer === modified file 'lib/lp/code/doc/codeimport-machine.txt' --- lib/lp/code/doc/codeimport-machine.txt 2012-12-26 01:32:19 +0000 +++ lib/lp/code/doc/codeimport-machine.txt 2018-05-13 10:12:08 +0000 @@ -36,16 +36,16 @@ >>> sample_machine.hostname u'bazaar-importer' - >>> print sample_machine.state.name + >>> print(sample_machine.state.name) ONLINE getByHostname looks for a machine of the given hostname, and returns None if there is no machine by that name in the database. - >>> print machine_set.getByHostname('bazaar-importer') + >>> print(machine_set.getByHostname('bazaar-importer')) <...CodeImportMachine...> - >>> print machine_set.getByHostname('unlikely-to-exist') + >>> print(machine_set.getByHostname('unlikely-to-exist')) None @@ -57,13 +57,13 @@ canonical URL for set based views. >>> from lp.services.webapp import canonical_url - >>> print canonical_url(machine_set) + >>> print(canonical_url(machine_set)) http://code.launchpad.dev/+code-imports/+machines A single code import machine is identified by the hostname of the machine directly after the canonical URL of the code import machine set. - >>> print canonical_url(sample_machine) + >>> print(canonical_url(sample_machine)) http://code.launchpad.dev/+code-imports/+machines/bazaar-importer @@ -75,7 +75,7 @@ or OFFLINE states, but are in the OFFLINE state by default. >>> new_machine = machine_set.new('frobisher') - >>> print new_machine.state.name + >>> print(new_machine.state.name) OFFLINE If they are created in the ONLINE state, an ONLINE event is created in @@ -90,10 +90,10 @@ >>> new_events = NewEvents() >>> new_machine2 = machine_set.new( ... 'innocent', CodeImportMachineState.ONLINE) - >>> print new_machine2.state.name + >>> print(new_machine2.state.name) ONLINE - >>> print new_events.summary() + >>> print(new_events.summary()) ONLINE innocent @@ -103,7 +103,7 @@ Directly setting the state information on CodeImportMachines is not permitted. - >>> print new_machine.state.name + >>> print(new_machine.state.name) OFFLINE >>> new_machine.state = CodeImportMachineState.ONLINE @@ -125,10 +125,10 @@ >>> new_events = NewEvents() >>> new_machine.setOnline() - >>> print new_machine.state.name + >>> print(new_machine.state.name) ONLINE - >>> print new_events.summary() + >>> print(new_events.summary()) ONLINE frobisher @@ -142,10 +142,10 @@ >>> new_events = NewEvents() >>> new_machine.setOffline(CodeImportMachineOfflineReason.STOPPED) - >>> print new_machine.state.name + >>> print(new_machine.state.name) OFFLINE - >>> print new_events.summary() + >>> print(new_events.summary()) OFFLINE frobisher >>> [new_event] = new_events @@ -167,7 +167,7 @@ >>> new_machine.setOnline() >>> new_events = NewEvents() >>> new_machine.setQuiescing(admin, "1.1.42 rollout") - >>> print new_events.summary() + >>> print(new_events.summary()) QUIESCE frobisher name16 >>> [new_event] = new_events @@ -237,12 +237,12 @@ >>> online_machine = new_machine_with_state(ONLINE) >>> online_machine.setQuiescing(admin, "Because.") - >>> print online_machine.state.name + >>> print(online_machine.state.name) QUIESCING >>> online_machine = new_machine_with_state(ONLINE) >>> online_machine.setOffline(some_reason) - >>> print online_machine.state.name + >>> print(online_machine.state.name) OFFLINE >>> online_machine = new_machine_with_state(ONLINE) @@ -256,7 +256,7 @@ >>> quiescing_machine = new_machine_with_state(QUIESCING) >>> quiescing_machine.setOnline() - >>> print quiescing_machine.state.name + >>> print(quiescing_machine.state.name) ONLINE >>> quiescing_machine = new_machine_with_state(QUIESCING) @@ -267,7 +267,7 @@ >>> quiescing_machine = new_machine_with_state(QUIESCING) >>> quiescing_machine.setOffline(some_reason) - >>> print quiescing_machine.state.name + >>> print(quiescing_machine.state.name) OFFLINE === modified file 'lib/lp/code/doc/codeimport-result.txt' --- lib/lp/code/doc/codeimport-result.txt 2012-12-26 01:32:19 +0000 +++ lib/lp/code/doc/codeimport-result.txt 2018-05-13 10:12:08 +0000 @@ -61,27 +61,27 @@ CodeImportResult objects themselves have no behaviour, they are just read-only records of what happened. - >>> print new_result.machine.hostname + >>> print(new_result.machine.hostname) odin - >>> print new_result.requesting_user + >>> print(new_result.requesting_user) None - >>> print new_result.log_excerpt + >>> print(new_result.log_excerpt) log data In order to read the actual log file, the transaction needs to be committed for the Librarian to save the file. - >>> print new_result.log_file.read() + >>> print(new_result.log_file.read()) several lines of log data - >>> print new_result.status.name + >>> print(new_result.status.name) SUCCESS A helper property exists to give the duration of the job run. - >>> print new_result.job_duration + >>> print(new_result.job_duration) 4:00:00 === modified file 'lib/lp/code/doc/codeimport.txt' --- lib/lp/code/doc/codeimport.txt 2016-11-12 02:24:09 +0000 +++ lib/lp/code/doc/codeimport.txt 2018-05-13 10:12:08 +0000 @@ -59,7 +59,7 @@ ... TargetRevisionControlSystems, ... ) >>> for item in RevisionControlSystems: - ... print item.title + ... print(item.title) Concurrent Versions System Subversion via CSCVS Subversion via bzr-svn @@ -67,7 +67,7 @@ Mercurial Bazaar >>> for item in TargetRevisionControlSystems: - ... print item.title + ... print(item.title) Bazaar Git @@ -105,13 +105,13 @@ 3 >>> import email >>> message = email.message_from_string(stub.test_emails[0][2]) - >>> print message['subject'] + >>> print(message['subject']) New code import: ~import-person/widget/trunk-cvs - >>> print message['X-Launchpad-Message-Rationale'] + >>> print(message['X-Launchpad-Message-Rationale']) Operator @vcs-imports - >>> print message['X-Launchpad-Message-For'] + >>> print(message['X-Launchpad-Message-For']) vcs-imports - >>> print message.get_payload(decode=True) + >>> print(message.get_payload(decode=True)) A new CVS code import has been requested by Code Import Person: http://code.launchpad.dev/~import-person/widget/trunk-cvs from @@ -230,7 +230,7 @@ >>> code_import = factory.makeProductCodeImport( ... svn_branch_url='http://svn.example.com/project') - >>> print code_import.review_status.title + >>> print(code_import.review_status.title) Reviewed When an import operator updates the code import emails are sent out to @@ -336,9 +336,9 @@ By default, code imports are created with an unspecified update interval. - >>> print cvs_import.update_interval + >>> print(cvs_import.update_interval) None - >>> print svn_import.update_interval + >>> print(svn_import.update_interval) None When the update interval interval is unspecified, the effective update @@ -442,16 +442,16 @@ site: >>> from lp.services.webapp import canonical_url - >>> print canonical_url(code_import_set) + >>> print(canonical_url(code_import_set)) http://code.launchpad.dev/+code-imports The code imports themselves have a canonical URL that is subordinate of the branches, though they cannot currently be viewed that way in the webapp, only over the API. - >>> print canonical_url(svn_import.branch) + >>> print(canonical_url(svn_import.branch)) http://code.launchpad.dev/~import-person/widget/trunk-svn - >>> print canonical_url(svn_import) + >>> print(canonical_url(svn_import)) http://code.launchpad.dev/~import-person/widget/trunk-svn/+code-import @@ -507,8 +507,8 @@ >>> login('david.allou...@canonical.com') >>> data = {'cvs_root': ':pserver:anon...@cvs.example.com:/var/cvsroot'} >>> modify_event = cvs_import.updateFromData(data, nopriv) - >>> print make_email_body_for_code_import_update( - ... cvs_import, modify_event, None) + >>> print(make_email_body_for_code_import_update( + ... cvs_import, modify_event, None)) ~import-person/widget/trunk-cvs is now being imported from: hello from :pserver:anon...@cvs.example.com:/var/cvsroot instead of: @@ -518,8 +518,8 @@ >>> data = {'url': 'git://git.example.com/goodbye.git'} >>> modify_event = git_import.updateFromData(data, nopriv) - >>> print make_email_body_for_code_import_update( - ... git_import, modify_event, None) + >>> print(make_email_body_for_code_import_update( + ... git_import, modify_event, None)) ~import-person/widget/trunk-git is now being imported from: git://git.example.com/goodbye.git instead of: @@ -529,8 +529,8 @@ >>> data = {'url': 'http://svn.example.com/for-bzr-svn/trunk'} >>> modify_event = svn_import.updateFromData(data, nopriv) - >>> print make_email_body_for_code_import_update( - ... svn_import, modify_event, None) + >>> print(make_email_body_for_code_import_update( + ... svn_import, modify_event, None)) ~import-person/widget/trunk-svn is now being imported from: http://svn.example.com/for-bzr-svn/trunk instead of: @@ -541,20 +541,20 @@ >>> data = {'whiteboard': 'stuff'} >>> modify_event = cvs_import.updateFromData(data, nopriv) - >>> print make_email_body_for_code_import_update( - ... cvs_import, modify_event, 'stuff') + >>> print(make_email_body_for_code_import_update( + ... cvs_import, modify_event, 'stuff')) The branch whiteboard was changed to: <BLANKLINE> stuff - >>> print cvs_import.branch.whiteboard + >>> print(cvs_import.branch.whiteboard) stuff Setting the whiteboard to None is how it is deleted. >>> data = {'whiteboard': None} >>> modify_event = cvs_import.updateFromData(data, nopriv) - >>> print make_email_body_for_code_import_update( - ... cvs_import, modify_event, '') + >>> print(make_email_body_for_code_import_update( + ... cvs_import, modify_event, '')) The branch whiteboard was deleted. - >>> print cvs_import.branch.whiteboard + >>> print(cvs_import.branch.whiteboard) None === modified file 'lib/lp/code/doc/codereviewcomment.txt' --- lib/lp/code/doc/codereviewcomment.txt 2015-10-06 06:48:01 +0000 +++ lib/lp/code/doc/codereviewcomment.txt 2018-05-13 10:12:08 +0000 @@ -93,7 +93,7 @@ --... You are the owner of lp://dev/~... ---------------------------------------- - >>> print notifications[0]['X-Launchpad-Branch'] + >>> print(notifications[0]['X-Launchpad-Branch']) ~person-name.../product-name.../branch... >>> notifications[0]['Message-Id'] == comment.message.rfc822msgid True === modified file 'lib/lp/code/doc/revision.txt' --- lib/lp/code/doc/revision.txt 2013-06-20 05:50:00 +0000 +++ lib/lp/code/doc/revision.txt 2018-05-13 10:12:08 +0000 @@ -113,7 +113,7 @@ ... BranchRevision, BranchRevision.branch == branch) >>> for branch_revision in sorted(ancestry, ... key=lambda r:(r.sequence, r.revision.id), reverse=True): - ... print branch_revision.sequence, branch_revision.revision.id + ... print(branch_revision.sequence, branch_revision.revision.id) 6 9 5 8 4 11 @@ -136,7 +136,7 @@ of the branch. >>> for revision_id in sorted(ancestry): - ... print revision_id + ... print(revision_id) foo@localhost-20051031165758-48acedf2b6a2e898 foo@localhost-20051031170008-098959758bf79803 foo@localhost-20051031170239-5fce7d6bd3f01efc @@ -150,7 +150,7 @@ history of the branch. >>> for revision_id in history: - ... print revision_id + ... print(revision_id) t...@canonical.com-20051031165248-6f1bb97973c2b4f4 t...@canonical.com-20051031165338-5f2f3d6b10bb3bf0 foo@localhost-20051031165758-48acedf2b6a2e898 @@ -185,7 +185,7 @@ >>> revno_6.branch == branch True >>> rev_id = revno_6.revision.revision_id - >>> print rev_id + >>> print(rev_id) foo@localhost-20051031170357-1301ad6d387feb23 We remove the last revision from the branch. This is similar to what @@ -205,7 +205,7 @@ >>> from lp.code.interfaces.revision import IRevisionSet >>> revision = getUtility(IRevisionSet).getByRevisionId( ... 'foo@localhost-20051031170357-1301ad6d387feb23') - >>> print revision.revision_id + >>> print(revision.revision_id) foo@localhost-20051031170357-1301ad6d387feb23 @@ -222,17 +222,17 @@ ... revision_author='ddaa@localhost', ... parent_ids=['rev-1', 'rev-2'], ... properties={u'key': u'value'}) - >>> print revision.revision_id + >>> print(revision.revision_id) rev-3 - >>> print revision.log_body + >>> print(revision.log_body) commit message - >>> print revision.revision_date + >>> print(revision.revision_date) 2005-03-08 12:00:00+00:00 - >>> print revision.revision_author.name + >>> print(revision.revision_author.name) ddaa@localhost >>> for parent_id in revision.parent_ids: - ... print parent_id + ... print(parent_id) rev-1 rev-2 - >>> print revision.getProperties() + >>> print(revision.getProperties()) {u'key': u'value'} === modified file 'lib/lp/code/doc/xmlrpc-codeimport-scheduler.txt' --- lib/lp/code/doc/xmlrpc-codeimport-scheduler.txt 2012-12-26 01:32:19 +0000 +++ lib/lp/code/doc/xmlrpc-codeimport-scheduler.txt 2018-05-13 10:12:08 +0000 @@ -55,8 +55,8 @@ >>> from lp.code.interfaces.codeimportmachine import ( ... ICodeImportMachineSet) - >>> print getUtility(ICodeImportMachineSet).getByHostname( - ... 'doesnt-exist-yet') + >>> print(getUtility(ICodeImportMachineSet).getByHostname( + ... 'doesnt-exist-yet')) None >>> codeimportscheduler.getJobForMachine('doesnt-exist-yet', 1) 0 === modified file 'lib/lp/code/tests/test_doc.py' --- lib/lp/code/tests/test_doc.py 2017-10-04 01:53:48 +0000 +++ lib/lp/code/tests/test_doc.py 2018-05-13 10:12:08 +0000 @@ -1,4 +1,4 @@ -# Copyright 2009-2017 Canonical Ltd. This software is licensed under the +# Copyright 2009-2018 Canonical Ltd. This software is licensed under the # GNU Affero General Public License version 3 (see the file LICENSE). """ @@ -32,7 +32,7 @@ def branchscannerSetUp(test): """Setup the user for the branch scanner tests.""" switch_dbuser("branchscanner") - setUp(test) + setUp(test, future=True) def zopelessLaunchpadSecuritySetUp(test): @@ -44,7 +44,7 @@ functionality used in the webapp, it needs to use the LaunchpadSecurityPolicy. """ - setGlobs(test) + setGlobs(test, future=True) test.old_security_policy = setSecurityPolicy(LaunchpadSecurityPolicy) @@ -66,22 +66,27 @@ ), 'codeimport-result.txt': LayeredDocFileSuite( '../doc/codeimport-result.txt', - setUp=setUp, tearDown=tearDown, layer=LaunchpadFunctionalLayer, + setUp=lambda test: setUp(test, future=True), tearDown=tearDown, + layer=LaunchpadFunctionalLayer, ), 'branch-merge-proposal-notifications.txt': LayeredDocFileSuite( '../doc/branch-merge-proposal-notifications.txt', - setUp=setUp, tearDown=tearDown, layer=LaunchpadZopelessLayer, + setUp=lambda test: setUp(test, future=True), tearDown=tearDown, + layer=LaunchpadZopelessLayer, ), 'branch-notifications.txt': LayeredDocFileSuite( '../doc/branch-notifications.txt', - setUp=setUp, tearDown=tearDown, layer=LaunchpadZopelessLayer, + setUp=lambda test: setUp(test, future=True), tearDown=tearDown, + layer=LaunchpadZopelessLayer, ), 'codereviewcomment.txt': LayeredDocFileSuite( '../doc/codereviewcomment.txt', - setUp=setUp, tearDown=tearDown, layer=LaunchpadZopelessLayer, + setUp=lambda test: setUp(test, future=True), tearDown=tearDown, + layer=LaunchpadZopelessLayer, ), } def test_suite(): - return build_test_suite(here, special) + return build_test_suite( + here, special, setUp=lambda test: setUp(test, future=True)) === modified file 'lib/lp/testing/systemdocs.py' --- lib/lp/testing/systemdocs.py 2012-12-26 01:32:19 +0000 +++ lib/lp/testing/systemdocs.py 2018-05-13 10:12:08 +0000 @@ -1,4 +1,4 @@ -# Copyright 2009-2011 Canonical Ltd. This software is licensed under the +# Copyright 2009-2018 Canonical Ltd. This software is licensed under the # GNU Affero General Public License version 3 (see the file LICENSE). """Infrastructure for setting up doctests.""" @@ -187,7 +187,10 @@ sys.stdout = old_stdout -def setGlobs(test): +# XXX cjwatson 2018-05-13: Once all doctests are made safe for the standard +# __future__ imports, the `future=True` behaviour should become +# unconditional. +def setGlobs(test, future=False): """Add the common globals for testing system documentation.""" test.globs['ANONYMOUS'] = ANONYMOUS test.globs['login'] = login @@ -208,10 +211,16 @@ test.globs['launchpadlib_credentials_for'] = launchpadlib_credentials_for test.globs['oauth_access_token_for'] = oauth_access_token_for - -def setUp(test): + if future: + import __future__ + for future_item in ( + 'absolute_import', 'print_function', 'unicode_literals'): + test.globs[future_item] = getattr(__future__, future_item) + + +def setUp(test, future=False): """Setup the common globals and login for testing system documentation.""" - setGlobs(test) + setGlobs(test, future=future) # Set up an anonymous interaction. login(ANONYMOUS)
_______________________________________________ Mailing list: https://launchpad.net/~launchpad-reviewers Post to : launchpad-reviewers@lists.launchpad.net Unsubscribe : https://launchpad.net/~launchpad-reviewers More help : https://help.launchpad.net/ListHelp