← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] ~cjwatson/launchpad:doctest-want-line-length-exceptions into launchpad:master

 

Colin Watson has proposed merging ~cjwatson/launchpad:doctest-want-line-length-exceptions into launchpad:master.

Commit message:
lp-lint-doctest: Wrap long traceback lines

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/+git/launchpad/+merge/407469

We were stuck with the long lines while we were using `IGNORE_EXCEPTION_MODULE_IN_PYTHON2`, but now that we no longer need that we can rewrap all these.
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of ~cjwatson/launchpad:doctest-want-line-length-exceptions into launchpad:master.
diff --git a/lib/lp/answers/doc/faq.txt b/lib/lp/answers/doc/faq.txt
index c4af905..5399e4a 100644
--- a/lib/lp/answers/doc/faq.txt
+++ b/lib/lp/answers/doc/faq.txt
@@ -330,7 +330,8 @@ And it is not allowed to call linkFAQ() when the FAQ is already linked:
     ...     no_priv, firefox_faq, 'See the FAQ.')
     Traceback (most recent call last):
       ...
-    lp.answers.errors.FAQTargetError: Cannot call linkFAQ() with already linked FAQ.
+    lp.answers.errors.FAQTargetError: Cannot call linkFAQ() with already
+    linked FAQ.
 
 A FAQ can be linked to a 'solved' question, in which case, the status is
 not changed.
diff --git a/lib/lp/answers/doc/questiontarget.txt b/lib/lp/answers/doc/questiontarget.txt
index 252d463..1184fda 100644
--- a/lib/lp/answers/doc/questiontarget.txt
+++ b/lib/lp/answers/doc/questiontarget.txt
@@ -419,7 +419,8 @@ languages.
     >>> target.addAnswerContact(sample_person, sample_person)
     Traceback (most recent call last):
       ...
-    lp.answers.errors.AddAnswerContactError: An answer contact must speak a language...
+    lp.answers.errors.AddAnswerContactError: An answer contact must speak a
+    language...
 
 Answer contacts can be removed by using the removeAnswerContact() method.
 Like its counterpart, it returns True when the answer contact was removed and
diff --git a/lib/lp/answers/doc/workflow.txt b/lib/lp/answers/doc/workflow.txt
index 6f25e23..33ecd85 100644
--- a/lib/lp/answers/doc/workflow.txt
+++ b/lib/lp/answers/doc/workflow.txt
@@ -592,7 +592,8 @@ Users without launchpad.Moderator privileges cannot set the assignee.
     >>> question.assignee = sample_person
     Traceback (most recent call last):
       ...
-    zope.security.interfaces.Unauthorized: (<lp.answers.model.question.Question ...>, 'assignee', 'launchpad.Append')
+    zope.security.interfaces.Unauthorized:
+    (<lp.answers.model.question.Question ...>, 'assignee', 'launchpad.Append')
 
 
 Events
diff --git a/lib/lp/app/doc/batch-navigation.txt b/lib/lp/app/doc/batch-navigation.txt
index 7087dc2..36c5bfc 100644
--- a/lib/lp/app/doc/batch-navigation.txt
+++ b/lib/lp/app/doc/batch-navigation.txt
@@ -83,7 +83,8 @@ InvalidBatchSizeError is raised.
     >>> BatchNavigator(reindeer, request=request )
     Traceback (most recent call last):
       ...
-    lazr.batchnavigator.interfaces.InvalidBatchSizeError: Maximum for "batch" parameter is 5.
+    lazr.batchnavigator.interfaces.InvalidBatchSizeError:
+    Maximum for "batch" parameter is 5.
 
     >>> ignored = config.pop('max-batch-size')
 
diff --git a/lib/lp/app/doc/displaying-numbers.txt b/lib/lp/app/doc/displaying-numbers.txt
index 6da695d..1f4131b 100644
--- a/lib/lp/app/doc/displaying-numbers.txt
+++ b/lib/lp/app/doc/displaying-numbers.txt
@@ -61,7 +61,8 @@ Here's a set of exhaustive examples:
     >>> test_tales('foo/fmt:float', foo=12345.67890)
     Traceback (most recent call last):
     ...
-    zope.location.interfaces.LocationError: 'fmt:float requires a single decimal argument'
+    zope.location.interfaces.LocationError:
+    'fmt:float requires a single decimal argument'
 
     >>> test_tales('foo/fmt:float/0.3', foo=-12345.67890)
     '-12345.679'
diff --git a/lib/lp/app/doc/launchpadform.txt b/lib/lp/app/doc/launchpadform.txt
index 0bc55bd..db59937 100644
--- a/lib/lp/app/doc/launchpadform.txt
+++ b/lib/lp/app/doc/launchpadform.txt
@@ -571,7 +571,8 @@ request:
     >>> view.initialize()
     Traceback (most recent call last):
       ...
-    lp.services.webapp.interfaces.UnsafeFormGetSubmissionError: field.actions.change
+    lp.services.webapp.interfaces.UnsafeFormGetSubmissionError:
+    field.actions.change
 
     >>> request = LaunchpadTestRequest(
     ...     method='POST',
diff --git a/lib/lp/app/doc/tales.txt b/lib/lp/app/doc/tales.txt
index 8316cd9..e68f86d 100644
--- a/lib/lp/app/doc/tales.txt
+++ b/lib/lp/app/doc/tales.txt
@@ -1316,7 +1316,8 @@ with 'None/fmt:foo'.
     >>> test_tales('foo/fmt:shorten', foo=None)
     Traceback (most recent call last):
     ...
-    zope.location.interfaces.LocationError: 'you need to traverse a number after fmt:shorten'
+    zope.location.interfaces.LocationError: 'you need to traverse a number
+    after fmt:shorten'
 
     >>> test_tales('foo/fmt:shorten/8', foo=None)
     ''
@@ -1418,7 +1419,8 @@ DBSchema the item comes from.
     >>> test_tales('deb/enumvalue:CHEESEFISH', deb=udeb)
     Traceback (most recent call last):
     ...
-    zope.location.interfaces.LocationError: 'The enumerated type BinaryPackageFormat does not have a value CHEESEFISH.'
+    zope.location.interfaces.LocationError: 'The enumerated type
+    BinaryPackageFormat does not have a value CHEESEFISH.'
 
 It is possible for dbschemas to have a 'None' value.  This is a bit
 awkward, because when the value is None, we can't do any checking
@@ -1439,7 +1441,8 @@ dbschema items too:
     >>> test_tales('deb/enumvalue:CHEESEFISH', deb=wrapped_deb)
     Traceback (most recent call last):
     ...
-    zope.location.interfaces.LocationError: 'The enumerated type BinaryPackageFormat does not have a value CHEESEFISH.'
+    zope.location.interfaces.LocationError: 'The enumerated type
+    BinaryPackageFormat does not have a value CHEESEFISH.'
 
 
 Formatting timedelta objects
diff --git a/lib/lp/app/stories/basics/xx-offsite-form-post.txt b/lib/lp/app/stories/basics/xx-offsite-form-post.txt
index 12d4127..d3cd7aa 100644
--- a/lib/lp/app/stories/basics/xx-offsite-form-post.txt
+++ b/lib/lp/app/stories/basics/xx-offsite-form-post.txt
@@ -46,7 +46,8 @@ If we try to create a new team with with the referrer set to
     >>> browser.getControl('Create').click()
     Traceback (most recent call last):
       ...
-    lp.services.webapp.interfaces.OffsiteFormPostError: http://evil.people.com/
+    lp.services.webapp.interfaces.OffsiteFormPostError:
+    http://evil.people.com/
 
 
 Similarly, posting with a garbage referer fails:
@@ -151,7 +152,8 @@ a referrerless POST request to the browser-accessible API.
     ...     'http://launchpad.test/api/devel/people', 'ws.op=foo&x=1')
     Traceback (most recent call last):
     ...
-    lp.services.webapp.interfaces.OffsiteFormPostError: http://evil.people.com/
+    lp.services.webapp.interfaces.OffsiteFormPostError:
+    http://evil.people.com/
 
     >>> no_referrer_browser.post(
     ...     'http://launchpad.test/api/devel/people', 'ws.op=foo&x=1')
@@ -167,7 +169,8 @@ though it were signed with OAuth.
     ...     'oauth_consumer_key=foo&oauth_token=bar')
     Traceback (most recent call last):
     ...
-    lp.services.webapp.interfaces.OffsiteFormPostError: http://evil.people.com/
+    lp.services.webapp.interfaces.OffsiteFormPostError:
+    http://evil.people.com/
 
     >>> no_referrer_browser.post(
     ...     'http://launchpad.test/',
@@ -193,7 +196,8 @@ But the browser-accessible API ignores OAuth credentials altogether.
     ...     'http://launchpad.test/api/devel/projects', sig)
     Traceback (most recent call last):
     ...
-    lp.services.webapp.interfaces.OffsiteFormPostError: http://evil.people.com/
+    lp.services.webapp.interfaces.OffsiteFormPostError:
+    http://evil.people.com/
 
 If you go through the 'api' vhost, the signed request will be
 processed despite the bogus referrer, but...
@@ -201,7 +205,8 @@ processed despite the bogus referrer, but...
     >>> browser.post('http://api.launchpad.test/devel/projects', sig)
     Traceback (most recent call last):
     ...
-    storm.exceptions.NoneError: None isn't acceptable as a value for Product...
+    storm.exceptions.NoneError: None isn't acceptable as a value for
+    Product...
 
 You're making an _anonymous_ request. That's a request that 1) is not
 associated with any Launchpad user account (thus the NoneError when
diff --git a/lib/lp/app/stories/basics/xx-opstats.txt b/lib/lp/app/stories/basics/xx-opstats.txt
index de80e59..53a5396 100644
--- a/lib/lp/app/stories/basics/xx-opstats.txt
+++ b/lib/lp/app/stories/basics/xx-opstats.txt
@@ -354,7 +354,8 @@ But our database connections are broken.
     >>> IStore(Person).find(Person, name='janitor')
     Traceback (most recent call last):
     ...
-    storm.exceptions.DisconnectionError: FATAL:  database "nonexistant" does not exist
+    storm.exceptions.DisconnectionError:
+    FATAL:  database "nonexistant" does not exist
 
     >>> dummy = config.pop('no_db')
     >>> getUtility(IZStorm)._reset()
diff --git a/lib/lp/app/validators/tests/validation.txt b/lib/lp/app/validators/tests/validation.txt
index b66c031..1875b86 100644
--- a/lib/lp/app/validators/tests/validation.txt
+++ b/lib/lp/app/validators/tests/validation.txt
@@ -72,7 +72,8 @@ nominated.
     >>> can_be_nominated_for_series(firefox.series)
     Traceback (most recent call last):
     ...
-    lp.app.validators.LaunchpadValidationError: This bug has already been nominated for these series: 1.0, Trunk
+    lp.app.validators.LaunchpadValidationError:
+    This bug has already been nominated for these series: 1.0, Trunk
 
 Declined nominations can be re-nominated.
 
@@ -113,4 +114,5 @@ But you can't use Mark's name, of course. ;)
     >>> field.validate(u'mark')
     Traceback (most recent call last):
       ...
-    lp.app.validators.LaunchpadValidationError: ...mark is already in use by another person or team...
+    lp.app.validators.LaunchpadValidationError:
+    ...mark is already in use by another person or team...
diff --git a/lib/lp/app/widgets/doc/announcement-date-widget.txt b/lib/lp/app/widgets/doc/announcement-date-widget.txt
index a50a431..d90250c 100644
--- a/lib/lp/app/widgets/doc/announcement-date-widget.txt
+++ b/lib/lp/app/widgets/doc/announcement-date-widget.txt
@@ -59,7 +59,10 @@ If you choose to publish immediately, the date field must be empty.
     >>> print(widget.getInputValue())
     Traceback (most recent call last):
     ...
-    zope.formlib.interfaces.WidgetInputError: ('field.foo', ...'Foo', LaunchpadValidationError(...'Please do not provide a date if you want to publish immediately.'))
+    zope.formlib.interfaces.WidgetInputError:
+    ('field.foo', 'Foo',
+     LaunchpadValidationError('Please do not provide a date if you want to
+                               publish immediately.'))
 
 If you choose to publish at a specific date in the future, the date field
 must be filled.
@@ -69,4 +72,6 @@ must be filled.
     >>> print(widget.getInputValue())
     Traceback (most recent call last):
     ...
-    zope.formlib.interfaces.WidgetInputError: ('field.foo', ...'Foo', LaunchpadValidationError(...'Please provide a publication date.'))
+    zope.formlib.interfaces.WidgetInputError:
+    ('field.foo', 'Foo',
+     LaunchpadValidationError('Please provide a publication date.'))
diff --git a/lib/lp/app/widgets/doc/image-widget.txt b/lib/lp/app/widgets/doc/image-widget.txt
index 35bc4ab..f21c21d 100644
--- a/lib/lp/app/widgets/doc/image-widget.txt
+++ b/lib/lp/app/widgets/doc/image-widget.txt
@@ -269,7 +269,9 @@ dimensions smaller than person_mugshot.dimensions, it must be rejected.
     >>> widget.getInputValue()
     Traceback (most recent call last):
     ...
-    zope.formlib.interfaces.WidgetInputError: ('field.mugshot', ...'Mugshot', LaunchpadValidationError(...'\nThis image is not exactly 192x192\npixels in size.'))
+    zope.formlib.interfaces.WidgetInputError: ('field.mugshot',
+    ...'Mugshot', LaunchpadValidationError(...'\nThis image is not exactly
+    192x192\npixels in size.'))
 
 This is what we see when the image is the correct dimensions, and within
 the max_size:
@@ -313,7 +315,9 @@ image, we'll get a validation error.
     >>> widget.getInputValue()
     Traceback (most recent call last):
     ...
-    zope.formlib.interfaces.WidgetInputError: ('field.mugshot', ...'Mugshot', LaunchpadValidationError(...'\nThis image exceeds the maximum allowed size in bytes.'))
+    zope.formlib.interfaces.WidgetInputError: ('field.mugshot',
+    ...'Mugshot', LaunchpadValidationError(...'\nThis image exceeds the
+    maximum allowed size in bytes.'))
 
 A similar error will be raised if the image's dimensions are bigger than
 the maximum we allow.
@@ -326,7 +330,9 @@ the maximum we allow.
     >>> widget.getInputValue()
     Traceback (most recent call last):
     ...
-    zope.formlib.interfaces.WidgetInputError: ('field.mugshot', ...'Mugshot', LaunchpadValidationError(...'\nThis image is not exactly 191x193\npixels in size.'))
+    zope.formlib.interfaces.WidgetInputError: ('field.mugshot',
+    ...'Mugshot', LaunchpadValidationError(...'\nThis image is not exactly
+    191x193\npixels in size.'))
 
     >>> person_mugshot.dimensions = (image.size[0] + 1, image.size[1] - 1)
     >>> _ = mugshot.seek(0)
@@ -335,7 +341,9 @@ the maximum we allow.
     >>> widget.getInputValue()
     Traceback (most recent call last):
     ...
-    zope.formlib.interfaces.WidgetInputError: ('field.mugshot', ...'Mugshot', LaunchpadValidationError(...'\nThis image is not exactly 193x191\npixels in size.'))
+    zope.formlib.interfaces.WidgetInputError: ('field.mugshot',
+    ...'Mugshot', LaunchpadValidationError(...'\nThis image is not exactly
+    193x191\npixels in size.'))
 
 Finally, if the user specifies the 'change' action they must also provide
 a file to be uploaded.
@@ -346,7 +354,9 @@ a file to be uploaded.
     >>> widget.getInputValue()
     Traceback (most recent call last):
     ...
-    zope.formlib.interfaces.WidgetInputError: ('field.mugshot', ...'Mugshot', LaunchpadValidationError(...'Please specify the image you want to use.'))
+    zope.formlib.interfaces.WidgetInputError: ('field.mugshot',
+    ...'Mugshot', LaunchpadValidationError(...'Please specify the image you
+    want to use.'))
 
 
 Non-exact Image Dimensions
@@ -368,7 +378,9 @@ by setting the exact_dimensions attribute of the field to False:
     >>> widget.getInputValue()
     Traceback (most recent call last):
     ...
-    zope.formlib.interfaces.WidgetInputError: ('field.mugshot', ...'Mugshot', LaunchpadValidationError(...'\nThis image is larger than 64x64\npixels in size.'))
+    zope.formlib.interfaces.WidgetInputError: ('field.mugshot',
+    ...'Mugshot', LaunchpadValidationError(...'\nThis image is larger than
+    64x64\npixels in size.'))
 
 If the image is smaller than the dimensions, the input validates:
 
diff --git a/lib/lp/app/widgets/doc/project-scope-widget.txt b/lib/lp/app/widgets/doc/project-scope-widget.txt
index 1f11593..5ba7152 100644
--- a/lib/lp/app/widgets/doc/project-scope-widget.txt
+++ b/lib/lp/app/widgets/doc/project-scope-widget.txt
@@ -122,7 +122,10 @@ raised:
     >>> selected_scope = widget.getInputValue()
     Traceback (most recent call last):
     ...
-    zope.formlib.interfaces.WidgetInputError: ('field.scope', ...'', LaunchpadValidationError(...'There is no project named &#x27;invalid&#x27; registered in Launchpad'))
+    zope.formlib.interfaces.WidgetInputError:
+    ('field.scope', '',
+     LaunchpadValidationError('There is no project named &#x27;invalid&#x27;
+                               registered in Launchpad'))
 
 The same error text is returned by error():
 
@@ -140,7 +143,9 @@ If no project name is given at all, a widget error is also raised:
     >>> selected_scope = widget.getInputValue()
     Traceback (most recent call last):
     ...
-    zope.formlib.interfaces.WidgetInputError: ('field.scope', ...'', LaunchpadValidationError(...'Please enter a project name'))
+    zope.formlib.interfaces.WidgetInputError:
+    ('field.scope', '',
+     LaunchpadValidationError('Please enter a project name'))
 
     >>> print(widget.error())
     Please enter a project name
@@ -154,7 +159,9 @@ If no project name is given at all, a widget error is also raised:
     >>> selected_scope = widget.getInputValue()
     Traceback (most recent call last):
     ...
-    zope.formlib.interfaces.WidgetInputError: ('field.scope', ...'', LaunchpadValidationError(...'Please enter a project name'))
+    zope.formlib.interfaces.WidgetInputError:
+    ('field.scope', '',
+     LaunchpadValidationError('Please enter a project name'))
 
     >>> print(widget.error())
     Please enter a project name
diff --git a/lib/lp/app/widgets/doc/stripped-text-widget.txt b/lib/lp/app/widgets/doc/stripped-text-widget.txt
index 7c393da..3343cd7 100644
--- a/lib/lp/app/widgets/doc/stripped-text-widget.txt
+++ b/lib/lp/app/widgets/doc/stripped-text-widget.txt
@@ -63,4 +63,5 @@ provided.
     >>> widget.getInputValue()
     Traceback (most recent call last):
     ...
-    zope.formlib.interfaces.WidgetInputError: ('field', ...'Title', RequiredMissing('field'))
+    zope.formlib.interfaces.WidgetInputError:
+    ('field', ...'Title', RequiredMissing('field'))
diff --git a/lib/lp/archivepublisher/tests/archive-signing.txt b/lib/lp/archivepublisher/tests/archive-signing.txt
index 266b42b..f142a01 100644
--- a/lib/lp/archivepublisher/tests/archive-signing.txt
+++ b/lib/lp/archivepublisher/tests/archive-signing.txt
@@ -459,7 +459,8 @@ have a 'signing_key' set,  it raises an error.
     >>> archive_signing_key.signRepository(test_suite)
     Traceback (most recent call last):
     ...
-    lp.archivepublisher.interfaces.archivegpgsigningkey.CannotSignArchive: No signing key available for PPA for Celso Providelo
+    lp.archivepublisher.interfaces.archivegpgsigningkey.CannotSignArchive: No
+    signing key available for PPA for Celso Providelo
 
 We'll purge 'signing_keys_root' and the PPA repository root so that
 other tests don't choke on it, and shut down the server.
diff --git a/lib/lp/archiveuploader/tests/nascentupload-announcements.txt b/lib/lp/archiveuploader/tests/nascentupload-announcements.txt
index fc12cfd..41fdd5d 100644
--- a/lib/lp/archiveuploader/tests/nascentupload-announcements.txt
+++ b/lib/lp/archiveuploader/tests/nascentupload-announcements.txt
@@ -757,7 +757,8 @@ And then try to upload using the changes file with the malformed name.
     >>> bar_src.process()
     Traceback (most recent call last):
     ...
-    lp.archiveuploader.nascentupload.EarlyReturnUploadError: An error occurred that prevented further processing.
+    lp.archiveuploader.nascentupload.EarlyReturnUploadError:
+    An error occurred that prevented further processing.
 
     >>> bar_src.logger = FakeLogger()
     >>> result = bar_src.do_accept()
diff --git a/lib/lp/archiveuploader/tests/nascentupload-epoch-handling.txt b/lib/lp/archiveuploader/tests/nascentupload-epoch-handling.txt
index cb4c2ef..bc91675 100644
--- a/lib/lp/archiveuploader/tests/nascentupload-epoch-handling.txt
+++ b/lib/lp/archiveuploader/tests/nascentupload-epoch-handling.txt
@@ -153,7 +153,8 @@ When publishing the 'epoched' bar source the collision is detected:
     >>> bar_src_queue_epoch.realiseUpload()
     Traceback (most recent call last):
     ...
-    lp.soyuz.interfaces.queue.QueueInconsistentStateError: bar_1.0-1.diff.gz is already published in archive for hoary
+    lp.soyuz.interfaces.queue.QueueInconsistentStateError: bar_1.0-1.diff.gz
+    is already published in archive for hoary
     >>> bar_src_queue_epoch.status.name
     'ACCEPTED'
 
@@ -171,7 +172,10 @@ published in 'non-epoched' version:
     >>> bar_src_queue_epoch2.realiseUpload()
     Traceback (most recent call last):
     ...
-    lp.soyuz.interfaces.queue.QueueInconsistentStateError: bar_1.0.orig.tar.gz is already published in archive for hoary with a different SHA1 hash (e918d6f5ec2184ae1d795a130da36c9a82c4beaf != 73a04163fee97fd2257ab266bd48f1d3d528e012)
+    lp.soyuz.interfaces.queue.QueueInconsistentStateError: bar_1.0.orig.tar.gz
+    is already published in archive for hoary with a different SHA1 hash
+    (e918d6f5ec2184ae1d795a130da36c9a82c4beaf !=
+    73a04163fee97fd2257ab266bd48f1d3d528e012)
 
     >>> bar_src_queue_epoch2.status.name
     'ACCEPTED'
diff --git a/lib/lp/archiveuploader/tests/nascentupload.txt b/lib/lp/archiveuploader/tests/nascentupload.txt
index 30272a4..e2d1ad7 100644
--- a/lib/lp/archiveuploader/tests/nascentupload.txt
+++ b/lib/lp/archiveuploader/tests/nascentupload.txt
@@ -57,7 +57,8 @@ on that.
     >>> nonexistent.process()
     Traceback (most recent call last):
     ...
-    lp.archiveuploader.nascentupload.EarlyReturnUploadError: An error occurred that prevented further processing.
+    lp.archiveuploader.nascentupload.EarlyReturnUploadError: An error occurred
+    that prevented further processing.
     >>> nonexistent.is_rejected
     True
     >>> print(nonexistent.rejection_message)
diff --git a/lib/lp/archiveuploader/tests/nascentuploadfile.txt b/lib/lp/archiveuploader/tests/nascentuploadfile.txt
index 0747315..fa9091c 100644
--- a/lib/lp/archiveuploader/tests/nascentuploadfile.txt
+++ b/lib/lp/archiveuploader/tests/nascentuploadfile.txt
@@ -46,7 +46,8 @@ The filename tries to use an epoch in an invalid way:
     >>> upload_file.checkNameIsTaintFree()
     Traceback (most recent call last):
     ...
-    lp.archiveuploader.utils.UploadError: Invalid character(s) in filename: 'package-1.1.2-3:0ubuntu4'.
+    lp.archiveuploader.utils.UploadError: Invalid character(s) in filename:
+    'package-1.1.2-3:0ubuntu4'.
 
 
 With a good filename, no exception is raised.
@@ -264,7 +265,8 @@ If the address is unparsable, we get an error.
     >>> sig_file.parseAddress("Cannot Parse Me <FOOO>")
     Traceback (most recent call last):
     ...
-    lp.archiveuploader.utils.UploadError: Cannot Parse Me <FOOO>: no @ found in email address part.
+    lp.archiveuploader.utils.UploadError: Cannot Parse Me <FOOO>: no @ found
+    in email address part.
 
 If the email address is not yet registered and policy.create_people is True,
 a new Person will be created.
diff --git a/lib/lp/archiveuploader/tests/upload-path-parsing.txt b/lib/lp/archiveuploader/tests/upload-path-parsing.txt
index 41a834e..c278e3e 100644
--- a/lib/lp/archiveuploader/tests/upload-path-parsing.txt
+++ b/lib/lp/archiveuploader/tests/upload-path-parsing.txt
@@ -50,7 +50,8 @@ If such distribution doesn't exist, parse_upload_path() raises
     >>> check_upload('does-not-exist')
     Traceback (most recent call last):
     ...
-    lp.archiveuploader.uploadprocessor.UploadPathError: Could not find distribution 'does-not-exist'.
+    lp.archiveuploader.uploadprocessor.UploadPathError: Could not find
+    distribution 'does-not-exist'.
 
 Upload to a distribution can have their 'changesfile' suite target
 overridden by including a specific suite name in the upload path.
@@ -71,7 +72,8 @@ is raised.
     >>> check_upload('debian/imaginary')
     Traceback (most recent call last):
     ...
-    lp.archiveuploader.uploadprocessor.UploadPathError: Could not find suite 'imaginary'.
+    lp.archiveuploader.uploadprocessor.UploadPathError: Could not find suite
+    'imaginary'.
 
 
 PPA uploads
@@ -104,12 +106,14 @@ up as a Person in Launchpad.
     >>> check_upload('~does-not-exist/ubuntu/ppa')
     Traceback (most recent call last):
     ...
-    lp.archiveuploader.uploadprocessor.PPAUploadPathError: Could not find person or team named 'does-not-exist'.
+    lp.archiveuploader.uploadprocessor.PPAUploadPathError: Could not find
+    person or team named 'does-not-exist'.
 
     >>> check_upload('~cprov/notbuntu/ppa')
     Traceback (most recent call last):
     ...
-    lp.archiveuploader.uploadprocessor.PPAUploadPathError: Could not find distribution 'notbuntu'.
+    lp.archiveuploader.uploadprocessor.PPAUploadPathError: Could not find
+    distribution 'notbuntu'.
 
 Two deprecated PPA paths are still supported for compatibility. Before
 mid-2014 all PPAs were for Ubuntu, and the distribution came after the
@@ -146,7 +150,8 @@ valid. It's also supported for uploads to the deprecated paths.
     >>> check_upload('~cprov/ppa/ubuntu/boing')
     Traceback (most recent call last):
     ...
-    lp.archiveuploader.uploadprocessor.PPAUploadPathError: Could not find suite 'boing'.
+    lp.archiveuploader.uploadprocessor.PPAUploadPathError: Could not find
+    suite 'boing'.
 
 We will disable Celso's default PPA and uploads to it will result in
 an error.
@@ -161,24 +166,28 @@ an error.
     >>> check_upload('~cprov/ubuntu/ppa')
     Traceback (most recent call last):
     ...
-    lp.archiveuploader.uploadprocessor.PPAUploadPathError: PPA for Celso Providelo is disabled.
+    lp.archiveuploader.uploadprocessor.PPAUploadPathError: PPA for Celso
+    Providelo is disabled.
 
     >>> check_upload('~cprov/ppa/ubuntu')
     Traceback (most recent call last):
     ...
-    lp.archiveuploader.uploadprocessor.PPAUploadPathError: PPA for Celso Providelo is disabled.
+    lp.archiveuploader.uploadprocessor.PPAUploadPathError: PPA for Celso
+    Providelo is disabled.
 
 Uploading to named PPA that does not exist fails.
 
     >>> check_upload('~cprov/ubuntu/beta')
     Traceback (most recent call last):
     ...
-    lp.archiveuploader.uploadprocessor.PPAUploadPathError: Could not find a PPA owned by 'cprov' for 'ubuntu' named 'beta'.
+    lp.archiveuploader.uploadprocessor.PPAUploadPathError: Could not find a
+    PPA owned by 'cprov' for 'ubuntu' named 'beta'.
 
     >>> check_upload('~cprov/beta/ubuntu')
     Traceback (most recent call last):
     ...
-    lp.archiveuploader.uploadprocessor.PPAUploadPathError: Could not find a PPA owned by 'cprov' for 'ubuntu' named 'beta'.
+    lp.archiveuploader.uploadprocessor.PPAUploadPathError: Could not find a
+    PPA owned by 'cprov' for 'ubuntu' named 'beta'.
 
 We will create a 'beta' PPA for Celso.
 
@@ -238,7 +247,8 @@ A old-style PPA upload missing '~':
     >>> check_upload('cprov/ubuntu')
     Traceback (most recent call last):
     ...
-    lp.archiveuploader.uploadprocessor.UploadPathError: Could not find distribution 'cprov'.
+    lp.archiveuploader.uploadprocessor.UploadPathError: Could not find
+    distribution 'cprov'.
 
 An old-style named PPA upload missing '~'.
 
@@ -288,4 +298,5 @@ is raised.
     >>> check_upload('1234567890/ubuntu')
     Traceback (most recent call last):
     ...
-    lp.archiveuploader.uploadprocessor.UploadPathError: Could not find archive with id=1234567890.
+    lp.archiveuploader.uploadprocessor.UploadPathError: Could not find archive
+    with id=1234567890.
diff --git a/lib/lp/blueprints/doc/specgraph.txt b/lib/lp/blueprints/doc/specgraph.txt
index 4e2f985..01c1aac 100644
--- a/lib/lp/blueprints/doc/specgraph.txt
+++ b/lib/lp/blueprints/doc/specgraph.txt
@@ -308,7 +308,8 @@ to the command is bad:
     >>> graph_view.renderGraphvizGraph('cmapx')
     Traceback (most recent call last):
      ...
-    lp.blueprints.browser.specification.ProblemRenderingGraph: (... syntax error in line 1 near 'bad'...)
+    lp.blueprints.browser.specification.ProblemRenderingGraph:
+    (... syntax error in line 1 near 'bad'...)
 
 The SpecificationTreeImageTag.render() method captures the raised error
 and directly converts it into an oops report. The markup contains a
diff --git a/lib/lp/bugs/doc/bug-change.txt b/lib/lp/bugs/doc/bug-change.txt
index 3e6acb7..84945cf 100644
--- a/lib/lp/bugs/doc/bug-change.txt
+++ b/lib/lp/bugs/doc/bug-change.txt
@@ -210,7 +210,8 @@ field that it doesn't know about, it will raise a NoBugChangeFoundError.
     >>> get_bug_change_class(object(), 'fooix')
     Traceback (most recent call last):
       ...
-    lp.bugs.adapters.bugchange.NoBugChangeFoundError: Unable to find a suitable BugChange for field 'fooix' on object <object object at ...>
+    lp.bugs.adapters.bugchange.NoBugChangeFoundError: Unable to find a
+    suitable BugChange for field 'fooix' on object <object object at ...>
 
 For fields it knows about, it will return a more suitable class.
 
diff --git a/lib/lp/bugs/doc/bug.txt b/lib/lp/bugs/doc/bug.txt
index 7ca7d2b..34e8de7 100644
--- a/lib/lp/bugs/doc/bug.txt
+++ b/lib/lp/bugs/doc/bug.txt
@@ -37,7 +37,7 @@ raised:
     >>> bugset.getByNameOrID('+bugs')
     Traceback (most recent call last):
       ...
-    lp.app.errors.NotFoundError: ...'Unable to locate bug with nickname +bugs.'
+    lp.app.errors.NotFoundError: 'Unable to locate bug with nickname +bugs.'
 
 It is also possible to retrieve a number of bugs by specifying the bug numbers
 of interest.
@@ -182,7 +182,8 @@ private. A bug cannot be made private by an anonymous user.
     >>> firefox_crashes.setPrivate(True, current_user())
     Traceback (most recent call last):
       ...
-    zope.security.interfaces.Unauthorized: (..., 'setPrivate', 'launchpad.Append')
+    zope.security.interfaces.Unauthorized:
+    (..., 'setPrivate', 'launchpad.Append')
 
 We have to be logged in, so let's do that:
 
diff --git a/lib/lp/bugs/doc/bugmessage-visibility.txt b/lib/lp/bugs/doc/bugmessage-visibility.txt
index 44f65e0..cc7f237 100644
--- a/lib/lp/bugs/doc/bugmessage-visibility.txt
+++ b/lib/lp/bugs/doc/bugmessage-visibility.txt
@@ -45,4 +45,5 @@ field.
     >>> abugmessage.message.visible = True
     Traceback (most recent call last):
     ...
-    zope.security.interfaces.Unauthorized: (<Message at ...>, 'visible', 'launchpad.Admin')
+    zope.security.interfaces.Unauthorized:
+    (<Message at ...>, 'visible', 'launchpad.Admin')
diff --git a/lib/lp/bugs/doc/bugtask-search.txt b/lib/lp/bugs/doc/bugtask-search.txt
index fcbd161..bf5b046 100644
--- a/lib/lp/bugs/doc/bugtask-search.txt
+++ b/lib/lp/bugs/doc/bugtask-search.txt
@@ -109,7 +109,8 @@ Passing invalid tsquery expressions as fast_searchtext raises an exception.
     >>> list(firefox.searchTasks(bad_search))
     Traceback (most recent call last):
     ...
-    storm.database.ProgrammingError: syntax error in tsquery: "happens pretty often" ...
+    storm.database.ProgrammingError:
+    syntax error in tsquery: "happens pretty often" ...
 
     >>> import transaction
     >>> transaction.abort()
diff --git a/lib/lp/bugs/doc/bugtracker-person.txt b/lib/lp/bugs/doc/bugtracker-person.txt
index d5599f0..6d74c4b 100644
--- a/lib/lp/bugs/doc/bugtracker-person.txt
+++ b/lib/lp/bugs/doc/bugtracker-person.txt
@@ -44,7 +44,9 @@ new person to a bugtracker using an existing name will cause an error.
     ...         'some-name-i-made-up', foo_bar)
     Traceback (most recent call last):
       ...
-    lp.bugs.interfaces.bugtrackerperson.BugTrackerPersonAlreadyExists: Name 'some-name-i-made-up' is already in use for bugtracker 'bugzilla-checkwatches'.
+    lp.bugs.interfaces.bugtrackerperson.BugTrackerPersonAlreadyExists: Name
+    'some-name-i-made-up' is already in use for bugtracker
+    'bugzilla-checkwatches'.
 
 The BugTrackerPerson record for a given name on a given bugtracker can
 be retrieved by calling BugTracker.getLinkedPersonByName().
diff --git a/lib/lp/bugs/doc/bugwidget.txt b/lib/lp/bugs/doc/bugwidget.txt
index c3f0012..8f62395 100644
--- a/lib/lp/bugs/doc/bugwidget.txt
+++ b/lib/lp/bugs/doc/bugwidget.txt
@@ -24,7 +24,8 @@ If non-existant bug number is entered, an error is raised.
     >>> bug_widget.getInputValue()
     Traceback (most recent call last):
     ...
-    zope.formlib.interfaces.ConversionError: ('Not a valid bug number or nickname.', None)
+    zope.formlib.interfaces.ConversionError: ('Not a valid bug number or
+    nickname.', None)
 
 It's quite common that bug ids are prefixed by '#', so such inputs are
 accepted as well.
diff --git a/lib/lp/bugs/doc/cve-update.txt b/lib/lp/bugs/doc/cve-update.txt
index ad7d8fd..5ca5f00 100644
--- a/lib/lp/bugs/doc/cve-update.txt
+++ b/lib/lp/bugs/doc/cve-update.txt
@@ -170,4 +170,5 @@ schema is changed.
     >>> cve_updater.processCVEXML('<some-xml />')
     Traceback (most recent call last):
     ...
-    lp.services.scripts.base.LaunchpadScriptFailure: No CVEs found in XML file.
+    lp.services.scripts.base.LaunchpadScriptFailure: No CVEs found in XML
+    file.
diff --git a/lib/lp/bugs/doc/externalbugtracker-bugzilla-api.txt b/lib/lp/bugs/doc/externalbugtracker-bugzilla-api.txt
index c7fb1fa..3506145 100644
--- a/lib/lp/bugs/doc/externalbugtracker-bugzilla-api.txt
+++ b/lib/lp/bugs/doc/externalbugtracker-bugzilla-api.txt
@@ -67,7 +67,8 @@ will raise an error:
     >>> non_auth_bugzilla._authenticate()
     Traceback (most recent call last):
       ...
-    lp.bugs.externalbugtracker.base.BugTrackerAuthenticationError: http://thiswillfail.example.com: No credentials found.
+    lp.bugs.externalbugtracker.base.BugTrackerAuthenticationError:
+    http://thiswillfail.example.com: No credentials found.
 
 Trying to log in to a Bugzilla with incorrect credentials will also
 raise an error.
@@ -83,7 +84,9 @@ raise an error.
     >>> non_auth_bugzilla._authenticate()
     Traceback (most recent call last):
         ...
-    lp.bugs.externalbugtracker.base.BugTrackerAuthenticationError: http://thiswillfail.example.com: Fault 300: The username or password you entered is not valid.
+    lp.bugs.externalbugtracker.base.BugTrackerAuthenticationError:
+    http://thiswillfail.example.com: Fault 300: The username or password you
+    entered is not valid.
 
 
 Getting the server time
@@ -315,7 +318,8 @@ error will be raised. We can add a sample bug to demonstrate this.
     >>> bugzilla.getRemoteStatus(999)
     Traceback (most recent call last):
       ...
-    lp.bugs.externalbugtracker.base.UnparsableBugData: No status or resolution defined for bug 999
+    lp.bugs.externalbugtracker.base.UnparsableBugData: No status or resolution
+    defined for bug 999
 
     >>> del bugzilla._bugs[999]
 
diff --git a/lib/lp/bugs/doc/externalbugtracker-bugzilla-lp-plugin.txt b/lib/lp/bugs/doc/externalbugtracker-bugzilla-lp-plugin.txt
index d6bfbf8..218e38d 100644
--- a/lib/lp/bugs/doc/externalbugtracker-bugzilla-lp-plugin.txt
+++ b/lib/lp/bugs/doc/externalbugtracker-bugzilla-lp-plugin.txt
@@ -149,7 +149,8 @@ If authentication fails, a BugTrackerAuthenticationError will be raised.
     >>> test_bugzilla._authenticate()
     Traceback (most recent call last):
       ...
-    lp.bugs.externalbugtracker.base.BugTrackerAuthenticationError: http://example.com: XML-RPC Fault: 100 "Sorry, you can't log in."
+    lp.bugs.externalbugtracker.base.BugTrackerAuthenticationError:
+    http://example.com: XML-RPC Fault: 100 "Sorry, you can't log in."
 
 This is also true if an error occurs at the protocol level:
 
@@ -158,7 +159,8 @@ This is also true if an error occurs at the protocol level:
     >>> test_bugzilla._authenticate()
     Traceback (most recent call last):
        ...
-    lp.bugs.externalbugtracker.base.BugTrackerAuthenticationError: http://example.com: Protocol error: 500 "Internal server error"
+    lp.bugs.externalbugtracker.base.BugTrackerAuthenticationError:
+    http://example.com: Protocol error: 500 "Internal server error"
 
 
 Getting the current time
diff --git a/lib/lp/bugs/doc/externalbugtracker-bugzilla-oddities.txt b/lib/lp/bugs/doc/externalbugtracker-bugzilla-oddities.txt
index 52b1cc7..cdc35cd 100644
--- a/lib/lp/bugs/doc/externalbugtracker-bugzilla-oddities.txt
+++ b/lib/lp/bugs/doc/externalbugtracker-bugzilla-oddities.txt
@@ -149,7 +149,8 @@ invalid XML:
     ...     broken_bugzilla.initializeRemoteBugDB(remote_bugs)
     Traceback (most recent call last):
     ...
-    lp.bugs.externalbugtracker.base.UnparsableBugData: Failed to parse XML description...
+    lp.bugs.externalbugtracker.base.UnparsableBugData:
+    Failed to parse XML description...
 
 However, embedded control characters do not generate errors.
 
diff --git a/lib/lp/bugs/doc/externalbugtracker-bugzilla.txt b/lib/lp/bugs/doc/externalbugtracker-bugzilla.txt
index 94cc309..d04257a 100644
--- a/lib/lp/bugs/doc/externalbugtracker-bugzilla.txt
+++ b/lib/lp/bugs/doc/externalbugtracker-bugzilla.txt
@@ -29,7 +29,8 @@ UnparsableBugTrackerVersion is raised:
     >>> external_bugzilla = Bugzilla('http://example.com/', version='A.B')
     Traceback (most recent call last):
       ...
-    lp.bugs.externalbugtracker.base.UnparsableBugTrackerVersion: Failed to parse version 'A.B' for http://...
+    lp.bugs.externalbugtracker.base.UnparsableBugTrackerVersion: Failed to
+    parse version 'A.B' for http://...
 
 The version parsing is carried out by the Bugzilla._parseVersion()
 method, which takes a version string and returns a tuple of
@@ -739,7 +740,8 @@ bug tracker, an error is logged.
     ...         external_bugzilla, [bug_watch1, bug_watch2])
     Traceback (most recent call last):
     ...
-    lp.bugs.externalbugtracker.base.UnparsableBugData: Failed to parse XML description for https://bugzilla.mozilla.org...
+    lp.bugs.externalbugtracker.base.UnparsableBugData: Failed to parse XML
+    description for https://bugzilla.mozilla.org...
 
 The error is also recorded in each bug watch's last_error_type field so that
 it can be displayed to the user.
diff --git a/lib/lp/bugs/doc/externalbugtracker-debbugs.txt b/lib/lp/bugs/doc/externalbugtracker-debbugs.txt
index 5dc2fe8..9dce3b5 100644
--- a/lib/lp/bugs/doc/externalbugtracker-debbugs.txt
+++ b/lib/lp/bugs/doc/externalbugtracker-debbugs.txt
@@ -65,7 +65,8 @@ If we pass a non-integer bug id, InvalidBugId is raised.
     >>> external_debbugs.getRemoteStatus('foo')
     Traceback (most recent call last):
     ...
-    lp.bugs.externalbugtracker.base.InvalidBugId: Debbugs bug number not an integer: foo
+    lp.bugs.externalbugtracker.base.InvalidBugId:
+    Debbugs bug number not an integer: foo
 
 The debbugs database has two subdirectories in it. The db-h directory
 contains current bugs, while the archive contains older bugs that have
diff --git a/lib/lp/bugs/doc/externalbugtracker-mantis-logging-in.txt b/lib/lp/bugs/doc/externalbugtracker-mantis-logging-in.txt
index 8b87b9f..07165be 100644
--- a/lib/lp/bugs/doc/externalbugtracker-mantis-logging-in.txt
+++ b/lib/lp/bugs/doc/externalbugtracker-mantis-logging-in.txt
@@ -58,7 +58,9 @@ the "return" parameter.
     >>> run_hook('http://mantis.example.com/login_page.php')
     Traceback (most recent call last):
       ...
-    lp.bugs.externalbugtracker.base.BugTrackerConnectError: http://mantis.example.com/login_page.php: Mantis redirected us to the login page but did not set a return path.
+    lp.bugs.externalbugtracker.base.BugTrackerConnectError:
+    http://mantis.example.com/login_page.php: Mantis redirected us to the
+    login page but did not set a return path.
 
 In all likelihood, this warning will be followed in the log by an
 error.
diff --git a/lib/lp/bugs/doc/externalbugtracker-roundup.txt b/lib/lp/bugs/doc/externalbugtracker-roundup.txt
index 49db154..f7d7949 100644
--- a/lib/lp/bugs/doc/externalbugtracker-roundup.txt
+++ b/lib/lp/bugs/doc/externalbugtracker-roundup.txt
@@ -60,7 +60,8 @@ values compared to the expected number of fields.
     >>> roundup.convertRemoteStatus('1:2')
     Traceback (most recent call last):
       ...
-    lp.bugs.externalbugtracker.base.UnknownRemoteStatusError: 1 field(s) expected, got 2: 1:2
+    lp.bugs.externalbugtracker.base.UnknownRemoteStatusError:
+    1 field(s) expected, got 2: 1:2
 
 If the status isn't something that our Roundup ExternalBugTracker can
 understand an UnknownRemoteStatusError will be raised.
@@ -68,7 +69,8 @@ understand an UnknownRemoteStatusError will be raised.
     >>> roundup.convertRemoteStatus('eggs').title
     Traceback (most recent call last):
       ...
-    lp.bugs.externalbugtracker.base.UnknownRemoteStatusError: Unrecognized value for field 1 (status): eggs
+    lp.bugs.externalbugtracker.base.UnknownRemoteStatusError:
+    Unrecognized value for field 1 (status): eggs
 
 
 Initialization
diff --git a/lib/lp/bugs/doc/externalbugtracker-sourceforge.txt b/lib/lp/bugs/doc/externalbugtracker-sourceforge.txt
index ddaf8b0..b409da8 100644
--- a/lib/lp/bugs/doc/externalbugtracker-sourceforge.txt
+++ b/lib/lp/bugs/doc/externalbugtracker-sourceforge.txt
@@ -101,7 +101,8 @@ resolution, to demonstrate this:
     ...     sourceforge.initializeRemoteBugDB([0])
     Traceback (most recent call last):
       ...
-    lp.bugs.externalbugtracker.base.UnparsableBugData: Remote bug 0 does not define a status.
+    lp.bugs.externalbugtracker.base.UnparsableBugData:
+    Remote bug 0 does not define a status.
 
 Some SourceForge bugs are marked private. Although we can't import a
 status from them, we don't raise an error when trying to initialize the
@@ -134,7 +135,8 @@ a PrivateRemoteBug error.
     >>> sourceforge.getRemoteStatus(99)
     Traceback (most recent call last):
      ...
-    lp.bugs.externalbugtracker.base.PrivateRemoteBug: Bug 99 on http://example.com is private.
+    lp.bugs.externalbugtracker.base.PrivateRemoteBug:
+    Bug 99 on http://example.com is private.
 
 
 Updating Bug Watches
diff --git a/lib/lp/bugs/doc/externalbugtracker-trac-lp-plugin.txt b/lib/lp/bugs/doc/externalbugtracker-trac-lp-plugin.txt
index e15b181..8c76531 100644
--- a/lib/lp/bugs/doc/externalbugtracker-trac-lp-plugin.txt
+++ b/lib/lp/bugs/doc/externalbugtracker-trac-lp-plugin.txt
@@ -134,7 +134,8 @@ If authentication fails, a BugTrackerAuthenticationError will be raised.
     ...     trac._authenticate()
     Traceback (most recent call last):
       ...
-    lp.bugs.externalbugtracker.base.BugTrackerAuthenticationError: http://example.com: 401 Client Error: Unauthorized
+    lp.bugs.externalbugtracker.base.BugTrackerAuthenticationError:
+    http://example.com: 401 Client Error: Unauthorized
 
 
 Current time
diff --git a/lib/lp/bugs/doc/externalbugtracker-trac.txt b/lib/lp/bugs/doc/externalbugtracker-trac.txt
index b3daf94..58c71c6 100644
--- a/lib/lp/bugs/doc/externalbugtracker-trac.txt
+++ b/lib/lp/bugs/doc/externalbugtracker-trac.txt
@@ -216,7 +216,9 @@ test.
     ...     trac.initializeRemoteBugDB([6, 7, 8, 9, 10])
     Traceback (most recent call last):
       ...
-    lp.bugs.externalbugtracker.base.UnparsableBugData: External bugtracker http://test.trac does not define all the necessary fields for bug status imports (Defined field names: ['<html>']).
+    lp.bugs.externalbugtracker.base.UnparsableBugData: External bugtracker
+    http://test.trac does not define all the necessary fields for bug status
+    imports (Defined field names: ['<html>']).
 
 This is also true of the single bug export mode.
 
@@ -224,7 +226,9 @@ This is also true of the single bug export mode.
     ...     trac.initializeRemoteBugDB([6])
     Traceback (most recent call last):
       ...
-    lp.bugs.externalbugtracker.base.UnparsableBugData: External bugtracker http://test.trac does not define all the necessary fields for bug status imports (Defined field names: ['<html>']).
+    lp.bugs.externalbugtracker.base.UnparsableBugData: External bugtracker
+    http://test.trac does not define all the necessary fields for bug status
+    imports (Defined field names: ['<html>']).
 
 Trying to get the remote status of the bug will raise a BugNotFound
 error since the bug was never imported.
@@ -261,7 +265,9 @@ export, it will raise an UnparsableBugData error.
     ...     trac._fetchBugData(query_url)
     Traceback (most recent call last):
       ...
-    lp.bugs.externalbugtracker.base.UnparsableBugData: External bugtracker http://test.trac does not define all the necessary fields for bug status imports (Defined field names: ['<html>']).
+    lp.bugs.externalbugtracker.base.UnparsableBugData: External bugtracker
+    http://test.trac does not define all the necessary fields for bug status
+    imports (Defined field names: ['<html>']).
 
 
 Updating Bug Watches
diff --git a/lib/lp/bugs/doc/externalbugtracker.txt b/lib/lp/bugs/doc/externalbugtracker.txt
index 9d22920..d867059 100644
--- a/lib/lp/bugs/doc/externalbugtracker.txt
+++ b/lib/lp/bugs/doc/externalbugtracker.txt
@@ -842,7 +842,7 @@ to make that assumption.
     ...     )
     Traceback (most recent call last):
     ...
-    TypeError: Result is not a member of BugTaskStatus: ...'Not a BugTaskStatus'
+    TypeError: Result is not a member of BugTaskStatus: 'Not a BugTaskStatus'
 
 
 Getting the remote product from a remote bug
diff --git a/lib/lp/bugs/doc/malone-xmlrpc.txt b/lib/lp/bugs/doc/malone-xmlrpc.txt
index 5df5db6..0be732d 100644
--- a/lib/lp/bugs/doc/malone-xmlrpc.txt
+++ b/lib/lp/bugs/doc/malone-xmlrpc.txt
@@ -167,7 +167,8 @@ Failing to specify a product or distribution.
     >>> filebug_api.filebug(params)
     Traceback (most recent call last):
     ...
-    xmlrpc.client.Fault: <Fault 60: 'Required arguments missing. You must specify either a product or distribution in which the bug exists.'>
+    xmlrpc.client.Fault: <Fault 60: 'Required arguments missing. You must
+    specify either a product or distribution in which the bug exists.'>
 
 Specifying *both* a product and distribution.
 
@@ -175,7 +176,8 @@ Specifying *both* a product and distribution.
     >>> filebug_api.filebug(params)
     Traceback (most recent call last):
     ...
-    xmlrpc.client.Fault: <Fault 70: 'Too many arguments. You may specify either a product or a distribution, but not both.'>
+    xmlrpc.client.Fault: <Fault 70: 'Too many arguments. You may specify
+    either a product or a distribution, but not both.'>
 
 Specifying a non-existent product.
 
@@ -225,7 +227,8 @@ Invalid subscriber.
     >>> filebug_api.filebug(params)
     Traceback (most recent call last):
     ...
-    xmlrpc.client.Fault: <Fault 20: 'Invalid subscriber: No user with the email address "nosuch@xxxxxxxxxxxxxx" was found'>
+    xmlrpc.client.Fault: <Fault 20: 'Invalid subscriber: No user with the
+    email address "nosuch@xxxxxxxxxxxxxx" was found'>
 
     >>> on_created_listener.cleanUp()
 
diff --git a/lib/lp/bugs/doc/official-bug-tags.txt b/lib/lp/bugs/doc/official-bug-tags.txt
index 44f7d93..754c045 100644
--- a/lib/lp/bugs/doc/official-bug-tags.txt
+++ b/lib/lp/bugs/doc/official-bug-tags.txt
@@ -117,22 +117,27 @@ Ordinary users cannot add and remove official bug tags.
     >>> ubuntu.addOfficialBugTag(u'foo')
     Traceback (most recent call last):
     ...
-    zope.security.interfaces.Unauthorized: (<Distribution 'Ubuntu' (ubuntu)>, 'addOfficialBugTag', 'launchpad.Edit')
+    zope.security.interfaces.Unauthorized:
+    (<Distribution 'Ubuntu' (ubuntu)>, 'addOfficialBugTag', 'launchpad.Edit')
 
     >>> ubuntu.removeOfficialBugTag(u'foo')
     Traceback (most recent call last):
     ...
-    zope.security.interfaces.Unauthorized: (<Distribution 'Ubuntu' (ubuntu)>, 'removeOfficialBugTag', 'launchpad.Edit')
+    zope.security.interfaces.Unauthorized:
+    (<Distribution 'Ubuntu' (ubuntu)>, 'removeOfficialBugTag',
+     'launchpad.Edit')
 
     >>> firefox.addOfficialBugTag(u'foo')
     Traceback (most recent call last):
     ...
-    zope.security.interfaces.Unauthorized: (<Product at ...>, 'addOfficialBugTag', 'launchpad.Edit')
+    zope.security.interfaces.Unauthorized:
+    (<Product at ...>, 'addOfficialBugTag', 'launchpad.Edit')
 
     >>> firefox.removeOfficialBugTag(u'foo')
     Traceback (most recent call last):
     ...
-    zope.security.interfaces.Unauthorized: (<Product at ...>, 'removeOfficialBugTag', 'launchpad.Edit')
+    zope.security.interfaces.Unauthorized:
+    (<Product at ...>, 'removeOfficialBugTag', 'launchpad.Edit')
 
 Official tags are accessible as a list property of official tag targets.
 
@@ -172,7 +177,9 @@ But only writable for users with edit permissions.
     >>> ubuntu.official_bug_tags = [u'foo', u'bar']
     Traceback (most recent call last):
     ...
-    zope.security.interfaces.Unauthorized: (<Distribution 'Ubuntu' (ubuntu)>, 'official_bug_tags', 'launchpad.BugSupervisor')
+    zope.security.interfaces.Unauthorized:
+    (<Distribution 'Ubuntu' (ubuntu)>, 'official_bug_tags',
+     'launchpad.BugSupervisor')
 
 The same is available for products.
 
diff --git a/lib/lp/bugs/stories/bugs/xx-bugs-advanced-search-upstream-status.txt b/lib/lp/bugs/stories/bugs/xx-bugs-advanced-search-upstream-status.txt
index b405996..bf2bed7 100644
--- a/lib/lp/bugs/stories/bugs/xx-bugs-advanced-search-upstream-status.txt
+++ b/lib/lp/bugs/stories/bugs/xx-bugs-advanced-search-upstream-status.txt
@@ -213,7 +213,9 @@ Other values for status_upstream lead to an error.
     ...         bookmark_params, True))
     Traceback (most recent call last):
     ...
-    lp.app.errors.UnexpectedFormData: Unexpected value for field 'status_upstream'. Perhaps your bookmarks are out of date or you changed the URL by hand?
+    lp.app.errors.UnexpectedFormData: Unexpected value for field
+    'status_upstream'. Perhaps your bookmarks are out of date or you changed
+    the URL by hand?
 
 Let's reset the statuses we set.
 
diff --git a/lib/lp/bugs/stories/bugtask-searches/xx-unexpected-form-data.txt b/lib/lp/bugs/stories/bugtask-searches/xx-unexpected-form-data.txt
index 07c8a85..27a5e65 100644
--- a/lib/lp/bugs/stories/bugtask-searches/xx-unexpected-form-data.txt
+++ b/lib/lp/bugs/stories/bugtask-searches/xx-unexpected-form-data.txt
@@ -19,7 +19,8 @@ is raised.
     ...     "field.status_upstream=hide_open")
     Traceback (most recent call last):
       ...
-    lp.app.errors.UnexpectedFormData: Unexpected value for field 'status_upstream'...
+    lp.app.errors.UnexpectedFormData: Unexpected value for field
+    'status_upstream'...
 
 When a UnexpectedFormData is raised, we display a custom error page to the
 user.
diff --git a/lib/lp/bugs/stories/patches-view/patches-view.txt b/lib/lp/bugs/stories/patches-view/patches-view.txt
index d652311..e90e90d 100644
--- a/lib/lp/bugs/stories/patches-view/patches-view.txt
+++ b/lib/lp/bugs/stories/patches-view/patches-view.txt
@@ -207,7 +207,8 @@ But we can't sort by things that aren't validated by the view.
     ...     '?orderby=star-sign')
     Traceback (most recent call last):
     ...
-    lp.app.errors.UnexpectedFormData: Unexpected value for field 'orderby': 'star-sign'
+    lp.app.errors.UnexpectedFormData:
+    Unexpected value for field 'orderby': 'star-sign'
 
 
 Bugs in a product series show up in the patches view for that series.
diff --git a/lib/lp/bugs/tests/bugzilla-api-xmlrpc-transport.txt b/lib/lp/bugs/tests/bugzilla-api-xmlrpc-transport.txt
index ce0f317..055e1d1 100644
--- a/lib/lp/bugs/tests/bugzilla-api-xmlrpc-transport.txt
+++ b/lib/lp/bugs/tests/bugzilla-api-xmlrpc-transport.txt
@@ -54,7 +54,8 @@ an error being raised.
     ...     {'login': 'test@xxxxxxxxxxxxx', 'password': 'test'})
     Traceback (most recent call last):
       ...
-    xmlrpc.client.Fault: <Fault 300: 'The username or password you entered is not valid.'>
+    xmlrpc.client.Fault:
+    <Fault 300: 'The username or password you entered is not valid.'>
 
 
 Getting the current time
@@ -544,7 +545,8 @@ Trying to add a non Bugzilla or Launchpad URL will raise a Fault.
     ...     'ids': [1], 'add': ['http://example.com/fail']});
     Traceback (most recent call last):
       ...
-    xmlrpc.client.Fault: <Fault 112: 'Bug URL http://example.com/fail is invalid.'>
+    xmlrpc.client.Fault:
+    <Fault 112: 'Bug URL http://example.com/fail is invalid.'>
 
 It's also possible to remove items from a bug's see_also list.
 
diff --git a/lib/lp/bugs/tests/externalbugtracker-xmlrpc-transport.txt b/lib/lp/bugs/tests/externalbugtracker-xmlrpc-transport.txt
index 53305fb..79fa0b0 100644
--- a/lib/lp/bugs/tests/externalbugtracker-xmlrpc-transport.txt
+++ b/lib/lp/bugs/tests/externalbugtracker-xmlrpc-transport.txt
@@ -91,7 +91,8 @@ If an error occurs trying to make the request, an
     ...     transport.request('www.example.com', 'xmlrpc', request_body)
     Traceback (most recent call last):
     ...
-    xmlrpc.client.ProtocolError: <ProtocolError for http://www.example.com/xmlrpc: 500 Internal Server Error>
+    xmlrpc.client.ProtocolError: <ProtocolError for
+    http://www.example.com/xmlrpc: 500 Internal Server Error>
 
 If the transport encounters a redirect response it will make its request
 to the location indicated in that response rather than the original
diff --git a/lib/lp/code/doc/branch.txt b/lib/lp/code/doc/branch.txt
index 0334752..f2dfdef 100644
--- a/lib/lp/code/doc/branch.txt
+++ b/lib/lp/code/doc/branch.txt
@@ -141,7 +141,8 @@ and -, +, _ and @ are allowed after that.
     ...     registrant=registrant)
     Traceback (most recent call last):
       ...
-    lp.app.validators.LaunchpadValidationError: Invalid branch name &#x27;invalid name!&#x27;.  Branch ...
+    lp.app.validators.LaunchpadValidationError: Invalid branch name
+    &#x27;invalid name!&#x27;.  Branch ...
 
 
 Determining the recently changed, registered and imported branches
diff --git a/lib/lp/code/doc/codeimport.txt b/lib/lp/code/doc/codeimport.txt
index f6770f0..e5f1fa3 100644
--- a/lib/lp/code/doc/codeimport.txt
+++ b/lib/lp/code/doc/codeimport.txt
@@ -497,7 +497,8 @@ The launchpad.Edit privilege is required to use CodeImport.updateFromData.
     >>> svn_import.updateFromData({}, nopriv)
     Traceback (most recent call last):
     ...
-    zope.security.interfaces.Unauthorized: (<CodeImport ...>, 'updateFromData', 'launchpad.Moderate')
+    zope.security.interfaces.Unauthorized: (<CodeImport ...>,
+    'updateFromData', 'launchpad.Moderate')
 
 We saw above how changes to SVN details are displayed in emails above.
 CVS details are displayed in a similar way.
diff --git a/lib/lp/registry/browser/tests/product-views.txt b/lib/lp/registry/browser/tests/product-views.txt
index fca5d24..1c7d580 100644
--- a/lib/lp/registry/browser/tests/product-views.txt
+++ b/lib/lp/registry/browser/tests/product-views.txt
@@ -128,7 +128,8 @@ cannot access the page.
     >>> view = create_initialized_view(firefox, name='+review-license')
     Traceback (most recent call last):
     ...
-    zope.security.interfaces.Unauthorized: (<Product..., 'project_reviewed', 'launchpad.Moderate')
+    zope.security.interfaces.Unauthorized:
+    (<Product..., 'project_reviewed', 'launchpad.Moderate')
 
 Mark is in the registry admins team and is allowed to access the page.
 
diff --git a/lib/lp/registry/browser/tests/team-views.txt b/lib/lp/registry/browser/tests/team-views.txt
index 9af0adb..2f6af76 100644
--- a/lib/lp/registry/browser/tests/team-views.txt
+++ b/lib/lp/registry/browser/tests/team-views.txt
@@ -63,7 +63,8 @@ Posting malformed data to the team home page raises an error.
     >>> team_home.initialize()
     Traceback (most recent call last):
     ...
-    lp.app.errors.UnexpectedFormData: The mailing list form did not receive the expected form fields.
+    lp.app.errors.UnexpectedFormData:
+    The mailing list form did not receive the expected form fields.
 
 
 Contacting the team
diff --git a/lib/lp/registry/doc/commercialsubscription.txt b/lib/lp/registry/doc/commercialsubscription.txt
index 851b264..88db1bc 100644
--- a/lib/lp/registry/doc/commercialsubscription.txt
+++ b/lib/lp/registry/doc/commercialsubscription.txt
@@ -359,7 +359,8 @@ No Privileges Person cannot access 'forReview'.
     >>> gnome =  product_set.forReview(commercial_member, search_text='gnome')
     Traceback (most recent call last):
     ...
-    zope.security.interfaces.Unauthorized: ... 'forReview', 'launchpad.Moderate'...
+    zope.security.interfaces.Unauthorized: ... 'forReview',
+    'launchpad.Moderate'...
 
 Members of the registry experts celebrity have permission to review
 IProduct and IProjectGroup objects and access an IProjectGroupSet.
diff --git a/lib/lp/registry/doc/distribution-mirror.txt b/lib/lp/registry/doc/distribution-mirror.txt
index 062b666..1e57fe2 100644
--- a/lib/lp/registry/doc/distribution-mirror.txt
+++ b/lib/lp/registry/doc/distribution-mirror.txt
@@ -964,7 +964,9 @@ for the status, however, they may not change it:
     >>> de_archive_mirror.transitionToCountryMirror(True)
     Traceback (most recent call last):
     ...
-    zope.security.interfaces.Unauthorized: (<DistributionMirror at ...>, 'transitionToCountryMirror', 'launchpad.Admin')
+    zope.security.interfaces.Unauthorized:
+    (<DistributionMirror at ...>, 'transitionToCountryMirror',
+     'launchpad.Admin')
 
 Mirror listing administrators may change the status however:
 
@@ -1005,7 +1007,8 @@ There cannot be multiple country mirrors of one type for one country:
     >>> archive_mirror2.transitionToCountryMirror(True)
     Traceback (most recent call last):
     ...
-    lp.registry.errors.CountryMirrorAlreadySet: Antarctica already has a country Archive mirror set.
+    lp.registry.errors.CountryMirrorAlreadySet:
+    Antarctica already has a country Archive mirror set.
 
 Mirrors which have not been probed may not be marked as country mirrors:
 
@@ -1017,7 +1020,8 @@ Mirrors which have not been probed may not be marked as country mirrors:
     >>> linux_au_mirror.transitionToCountryMirror(True)
     Traceback (most recent call last):
     ...
-    lp.registry.errors.MirrorNotProbed: This mirror may not be set as a country mirror as it has not been probed.
+    lp.registry.errors.MirrorNotProbed:
+    This mirror may not be set as a country mirror as it has not been probed.
 
 Mirrors which are not official or do not have an HTTP URL may not be set as
 country mirrors:
@@ -1037,10 +1041,13 @@ country mirrors:
     >>> osuosl_mirror.transitionToCountryMirror(None)
     Traceback (most recent call last):
     ...
-    storm.exceptions.NoneError: None isn't acceptable as a value for DistributionMirror.country_dns_mirror
+    storm.exceptions.NoneError:
+    None isn't acceptable as a value for DistributionMirror.country_dns_mirror
 
     >>> osuosl_mirror.transitionToCountryMirror(True)
     Traceback (most recent call last):
     ...
-    lp.registry.errors.MirrorHasNoHTTPURL: This mirror may not be set as a country mirror as it does not have an HTTP URL set.
+    lp.registry.errors.MirrorHasNoHTTPURL:
+    This mirror may not be set as a country mirror as it does not have an HTTP
+    URL set.
     >>> logout()
diff --git a/lib/lp/registry/doc/distribution.txt b/lib/lp/registry/doc/distribution.txt
index dc2941b..e21f674 100644
--- a/lib/lp/registry/doc/distribution.txt
+++ b/lib/lp/registry/doc/distribution.txt
@@ -468,13 +468,16 @@ But others can't.
     >>> login('no-priv@xxxxxxxxxxxxx')
     >>> debian.blueprints_usage = ServiceUsage.LAUNCHPAD
     Traceback (most recent call last):
-    zope.security.interfaces.Unauthorized: (..., 'blueprints_usage', 'launchpad.Edit')
+    zope.security.interfaces.Unauthorized:
+    (..., 'blueprints_usage', 'launchpad.Edit')
     >>> debian.official_malone = True
     Traceback (most recent call last):
-    zope.security.interfaces.Unauthorized: (..., 'official_malone', 'launchpad.Edit')
+    zope.security.interfaces.Unauthorized:
+    (..., 'official_malone', 'launchpad.Edit')
     >>> debian.translations_usage = ServiceUsage.LAUNCHPAD
     Traceback (most recent call last):
-    zope.security.interfaces.Unauthorized: (..., 'translations_usage', 'launchpad.TranslationsAdmin')
+    zope.security.interfaces.Unauthorized:
+    (..., 'translations_usage', 'launchpad.TranslationsAdmin')
 
 
 Specification Listings
@@ -592,7 +595,8 @@ Milestones for distros can only be created by distro owners or admins.
     ...     name='impossible', dateexpected=datetime(2028, 10, 1))
     Traceback (most recent call last):
     ...
-    zope.security.interfaces.Unauthorized: (<DistroSeries ...'woody'>, 'newMilestone', 'launchpad.Edit')
+    zope.security.interfaces.Unauthorized:
+    (<DistroSeries ...'woody'>, 'newMilestone', 'launchpad.Edit')
     >>> login('mark@xxxxxxxxxxx')
     >>> debian_milestone = woody.newMilestone(
     ...     name='woody-rc1', dateexpected=datetime(2028, 10, 1))
diff --git a/lib/lp/registry/doc/person.txt b/lib/lp/registry/doc/person.txt
index 21312ce..ecbb0f7 100644
--- a/lib/lp/registry/doc/person.txt
+++ b/lib/lp/registry/doc/person.txt
@@ -530,7 +530,8 @@ account_status is NOACCOUNT, though.
     >>> not_a_person.convertToTeam(team_owner=landscape_devs)
     Traceback (most recent call last):
     ...
-    lp.registry.interfaces.person.AlreadyConvertedException: foo-... has already been converted to a team.
+    lp.registry.interfaces.person.AlreadyConvertedException: foo-... has
+    already been converted to a team.
 
 
 Team members
@@ -1451,7 +1452,8 @@ be raised.
     ...     PersonCreationRationale.BUGIMPORT)
     Traceback (most recent call last):
       ...
-    lp.registry.errors.InvalidName: ThisIsn'tValid is not a valid name for a person.
+    lp.registry.errors.InvalidName: ThisIsn'tValid is not a valid name for a
+    person.
 
 
 Probationary users
diff --git a/lib/lp/registry/doc/pillar-aliases-field.txt b/lib/lp/registry/doc/pillar-aliases-field.txt
index f26605e..ca74d85 100644
--- a/lib/lp/registry/doc/pillar-aliases-field.txt
+++ b/lib/lp/registry/doc/pillar-aliases-field.txt
@@ -31,7 +31,8 @@ to be a valid alias for that pillar, but only for that pillar.
     >>> field.bind(getUtility(IProductSet)['bzr']).validate(u'iceweasel')
     Traceback (most recent call last):
     ...
-    lp.app.validators.LaunchpadValidationError: iceweasel is already used by another project
+    lp.app.validators.LaunchpadValidationError:
+    iceweasel is already used by another project
 
 If existing aliases are not passed to the field's set() method, they will be
 removed.
@@ -60,7 +61,8 @@ Each of these aliases must be valid names and must be unique.
     >>> bound_field.validate(u'ubuntu')
     Traceback (most recent call last):
     ...
-    lp.app.validators.LaunchpadValidationError: ubuntu is already used by another project
+    lp.app.validators.LaunchpadValidationError:
+    ubuntu is already used by another project
 
 Also, they must not be identical to the pillar's own name.
 
@@ -74,4 +76,5 @@ Black-listed names are not accepted as aliases either.
     >>> bound_field.validate(u'blacklisted')
     Traceback (most recent call last):
     ...
-    lp.app.validators.LaunchpadValidationError: The name &#x27;blacklisted&#x27; has been blocked...
+    lp.app.validators.LaunchpadValidationError:
+    The name &#x27;blacklisted&#x27; has been blocked...
diff --git a/lib/lp/registry/doc/private-team-roles.txt b/lib/lp/registry/doc/private-team-roles.txt
index c764699..6525d34 100644
--- a/lib/lp/registry/doc/private-team-roles.txt
+++ b/lib/lp/registry/doc/private-team-roles.txt
@@ -199,7 +199,8 @@ or private, can be the project registrant.
     >>> product = factory.makeProduct(registrant=priv_team)
     Traceback (most recent call last):
     ...
-    lp.registry.errors.PrivatePersonLinkageError: Cannot link person (name=private-team, visibility=PRIVATE) to <Product at...
+    lp.registry.errors.PrivatePersonLinkageError: Cannot link person
+    (name=private-team, visibility=PRIVATE) to <Product at...
 
 
 Maintainer/Owner
diff --git a/lib/lp/registry/doc/productrelease-file-download.txt b/lib/lp/registry/doc/productrelease-file-download.txt
index c1323ff..bf59241 100644
--- a/lib/lp/registry/doc/productrelease-file-download.txt
+++ b/lib/lp/registry/doc/productrelease-file-download.txt
@@ -116,7 +116,8 @@ delete a product file.
     >>> rel.files[0].destroySelf()
     Traceback (most recent call last):
     ...
-    zope.security.interfaces.Unauthorized: (<ProductReleaseFile...>, 'destroySelf', 'launchpad.Edit')
+    zope.security.interfaces.Unauthorized:
+    (<ProductReleaseFile...>, 'destroySelf', 'launchpad.Edit')
     >>> login('foo.bar@xxxxxxxxxxxxx')
     >>> for release_file in rel.files:
     ...     if release_file.libraryfile.id == file_alias.id:
@@ -194,7 +195,8 @@ Only the product owner can create a new release.
     >>> trunk.milestones[0].createProductRelease(firefox.owner, now)
     Traceback (most recent call last):
     ...
-    zope.security.interfaces.Unauthorized: (<Milestone ...>, 'createProductRelease', 'launchpad.Edit')
+    zope.security.interfaces.Unauthorized:
+    (<Milestone ...>, 'createProductRelease', 'launchpad.Edit')
     >>> login(owner_email)
     >>> milestone = trunk.newMilestone('8.0', code_name='ralph')
     >>> milestone.createProductRelease(firefox.owner, now,
diff --git a/lib/lp/registry/doc/productseries.txt b/lib/lp/registry/doc/productseries.txt
index 1ffd422..18d0c9c 100644
--- a/lib/lp/registry/doc/productseries.txt
+++ b/lib/lp/registry/doc/productseries.txt
@@ -72,7 +72,8 @@ owner or driver can call Product.newSeries().
     >>> emacs = firefox.newSeries(series_driver , 'emacs', summary)
     Traceback (most recent call last):
     ...
-    zope.security.interfaces.Unauthorized: (..., 'newSeries', 'launchpad.Driver')
+    zope.security.interfaces.Unauthorized:
+    (..., 'newSeries', 'launchpad.Driver')
 
     >>> ignored = login_person(firefox.owner)
     >>> emacs_series = firefox.newSeries(
diff --git a/lib/lp/registry/stories/distribution/xx-distribution-overview.txt b/lib/lp/registry/stories/distribution/xx-distribution-overview.txt
index 26d217a..5efd43c 100644
--- a/lib/lp/registry/stories/distribution/xx-distribution-overview.txt
+++ b/lib/lp/registry/stories/distribution/xx-distribution-overview.txt
@@ -126,7 +126,8 @@ If there is a development series alias, it becomes a redirect.
     >>> anon_browser.open("http://launchpad.test/ubuntu/devel";)
     Traceback (most recent call last):
     ...
-    zope.publisher.interfaces.NotFound: Object: <Distribution ...>, name: 'devel'
+    zope.publisher.interfaces.NotFound:
+    Object: <Distribution ...>, name: 'devel'
 
     >>> with celebrity_logged_in("admin"):
     ...     ubuntu = getUtility(IDistributionSet).getByName(u"ubuntu")
@@ -178,9 +179,11 @@ results in a NotFound error.
     >>> anon_browser.open("http://launchpad.test/ubuntu/+archive";)
     Traceback (most recent call last):
     ...
-    zope.publisher.interfaces.NotFound: Object: <Distribution ...>, name: '+archive'
+    zope.publisher.interfaces.NotFound:
+    Object: <Distribution ...>, name: '+archive'
 
     >>> anon_browser.open("http://launchpad.test/ubuntu/+archive/boing";)
     Traceback (most recent call last):
     ...
-    zope.publisher.interfaces.NotFound: Object: <Distribution ...>, name: 'boing'
+    zope.publisher.interfaces.NotFound:
+    Object: <Distribution ...>, name: 'boing'
diff --git a/lib/lp/services/database/doc/multitablecopy.txt b/lib/lp/services/database/doc/multitablecopy.txt
index f6ffd41..4c74ff5 100644
--- a/lib/lp/services/database/doc/multitablecopy.txt
+++ b/lib/lp/services/database/doc/multitablecopy.txt
@@ -329,7 +329,8 @@ which means that the attempt to insert it will violate a unique constraint.
     >>> copier.pour(transaction)
     Traceback (most recent call last):
     ...
-    storm.database.IntegrityError: duplicate ... violates unique constraint ...
+    storm.database.IntegrityError:
+    duplicate ... violates unique constraint ...
 
 Now we have a fun situation!  Some data has been copied back into our source
 tables, and we don't know how much.  And some data remains in our holding
diff --git a/lib/lp/services/feeds/doc/feeds.txt b/lib/lp/services/feeds/doc/feeds.txt
index 4cf0d54..76ce923 100644
--- a/lib/lp/services/feeds/doc/feeds.txt
+++ b/lib/lp/services/feeds/doc/feeds.txt
@@ -73,7 +73,9 @@ found.
     >>> verifyObject(IThing, thing)
     Traceback (most recent call last):
       ...
-    zope.interface.exceptions.MultipleInvalid: ... Does not declaratively implement the interface The lp.services.feeds.tests.helper.IThing.value attribute was not provided
+    zope.interface.exceptions.MultipleInvalid: ...
+    Does not declaratively implement the interface
+    The lp.services.feeds.tests.helper.IThing.value attribute was not provided
     >>> feed_view = getMultiAdapter((thing, request), name='thing-feed.atom')
     Traceback (most recent call last):
       ...
diff --git a/lib/lp/services/fields/doc/uri-field.txt b/lib/lp/services/fields/doc/uri-field.txt
index 55b93e2..d55670b 100644
--- a/lib/lp/services/fields/doc/uri-field.txt
+++ b/lib/lp/services/fields/doc/uri-field.txt
@@ -38,7 +38,8 @@ valid URI:
     >>> field.validate(u'not-a-uri')
     Traceback (most recent call last):
       ...
-    lp.app.validators.LaunchpadValidationError: &quot;not-a-uri&quot; is not a valid URI
+    lp.app.validators.LaunchpadValidationError: &quot;not-a-uri&quot; is not a
+    valid URI
 
 
 Scheme Restrictions
@@ -53,7 +54,9 @@ will result in a validation error:
     >>> sftp_only.validate(u'http://launchpad.net/')
     Traceback (most recent call last):
       ...
-    lp.app.validators.LaunchpadValidationError: The URI scheme &quot;http&quot; is not allowed. Only URIs with the following schemes may be used: sftp
+    lp.app.validators.LaunchpadValidationError: The URI scheme
+    &quot;http&quot; is not allowed. Only URIs with the following schemes may
+    be used: sftp
 
 
 Disallowing Userinfo
@@ -67,12 +70,14 @@ product home page, where authentication is not generally required:
     >>> no_userinfo.validate(u'http://launchpad.net:80@127.0.0.1/ubuntu')
     Traceback (most recent call last):
       ...
-    lp.app.validators.LaunchpadValidationError: A username may not be specified in the URI.
+    lp.app.validators.LaunchpadValidationError: A username may not be
+    specified in the URI.
 
     >>> no_userinfo.validate(u'http://launchpad.net@127.0.0.1/ubuntu')
     Traceback (most recent call last):
       ...
-    lp.app.validators.LaunchpadValidationError: A username may not be specified in the URI.
+    lp.app.validators.LaunchpadValidationError: A username may not be
+    specified in the URI.
 
 
 Disallowing Non-default Ports
@@ -85,7 +90,8 @@ URIs.  This can be done with the allow_port option:
     >>> no_port.validate(u'http://launchpad.net:21')
     Traceback (most recent call last):
       ...
-    lp.app.validators.LaunchpadValidationError: Non-default ports are not allowed.
+    lp.app.validators.LaunchpadValidationError: Non-default ports are not
+    allowed.
 
 Note that an error is not raised if the URI specifies a port but it is
 known to be the default for that scheme:
@@ -104,7 +110,8 @@ reject those URIs:
     >>> no_query.validate(u'http://launchpad.net/?key=value')
     Traceback (most recent call last):
       ...
-    lp.app.validators.LaunchpadValidationError: URIs with query strings are not allowed.
+    lp.app.validators.LaunchpadValidationError: URIs with query strings are
+    not allowed.
 
 
 Disallowing the Fragment Component
@@ -116,7 +123,8 @@ The fragment component can also be disallowed:
     >>> no_fragment.validate(u'http://launchpad.net/#fragment')
     Traceback (most recent call last):
       ...
-    lp.app.validators.LaunchpadValidationError: URIs with fragment identifiers are not allowed.
+    lp.app.validators.LaunchpadValidationError: URIs with fragment identifiers
+    are not allowed.
 
 
 Requiring or Forbidding a Trailing Slash
diff --git a/lib/lp/services/gpg/doc/gpg-signatures.txt b/lib/lp/services/gpg/doc/gpg-signatures.txt
index 6e09ab9..9c3d285 100644
--- a/lib/lp/services/gpg/doc/gpg-signatures.txt
+++ b/lib/lp/services/gpg/doc/gpg-signatures.txt
@@ -88,7 +88,8 @@ The text below was "clear signed" by 0xDFD20543 master key but tampered with:
     >>> master_sig = gpghandler.getVerifiedSignature(content)
     Traceback (most recent call last):
     ...
-    lp.services.gpg.interfaces.GPGVerificationError: (7, 8, ...'Bad signature')
+    lp.services.gpg.interfaces.GPGVerificationError:
+    (7, 8, ...'Bad signature')
 
 If no signed content is found, an exception is raised:
 
@@ -166,7 +167,8 @@ the GPGME error codes (they may be helpful).
     >>> gpghandler.getVerifiedSignature(content)
     Traceback (most recent call last):
     ...
-    lp.services.gpg.interfaces.GPGKeyDoesNotExistOnServer: GPG key E192C0543B1BB2EB does not exist on the keyserver.
+    lp.services.gpg.interfaces.GPGKeyDoesNotExistOnServer:
+    GPG key E192C0543B1BB2EB does not exist on the keyserver.
 
 Due to unpredictable behaviour between the production system and
 the external keyserver, we have a resilient signature verifier,
@@ -179,7 +181,11 @@ information for the 3 failures.
     >>> gpghandler.getVerifiedSignatureResilient(content)
     Traceback (most recent call last):
     ...
-    lp.services.gpg.interfaces.GPGVerificationError: Verification failed 3 times: ['GPG key E192C0543B1BB2EB does not exist on the keyserver.', 'GPG key E192C0543B1BB2EB does not exist on the keyserver.', 'GPG key E192C0543B1BB2EB does not exist on the keyserver.']
+    lp.services.gpg.interfaces.GPGVerificationError:
+    Verification failed 3 times:
+    ['GPG key E192C0543B1BB2EB does not exist on the keyserver.',
+     'GPG key E192C0543B1BB2EB does not exist on the keyserver.',
+     'GPG key E192C0543B1BB2EB does not exist on the keyserver.']
 
 
 Debugging exceptions
diff --git a/lib/lp/services/gpg/doc/gpghandler.txt b/lib/lp/services/gpg/doc/gpghandler.txt
index a82283a..93c7d99 100644
--- a/lib/lp/services/gpg/doc/gpghandler.txt
+++ b/lib/lp/services/gpg/doc/gpghandler.txt
@@ -220,7 +220,8 @@ An attempt to upload an unknown key will fail.
     >>> gpghandler.uploadPublicKey('F' * 40)
     Traceback (most recent call last):
     ...
-    lp.services.gpg.interfaces.GPGKeyDoesNotExistOnServer: GPG key FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF does not exist on the keyserver.
+    lp.services.gpg.interfaces.GPGKeyDoesNotExistOnServer: GPG key
+    FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF does not exist on the keyserver.
 
 Uploading the same key more than once is fine, it is handled on the
 keyserver side.
@@ -234,7 +235,8 @@ in a error.
     >>> gpghandler.uploadPublicKey(new_key.fingerprint)
     Traceback (most recent call last):
     ...
-    lp.services.gpg.interfaces.GPGUploadFailure: Could not reach keyserver at http://localhost:11371...Connection refused...
+    lp.services.gpg.interfaces.GPGUploadFailure: Could not reach keyserver at
+    http://localhost:11371...Connection refused...
 
 
 Fingerprint sanitizing
diff --git a/lib/lp/services/identity/doc/emailaddress.txt b/lib/lp/services/identity/doc/emailaddress.txt
index d1f26cb..123248d 100644
--- a/lib/lp/services/identity/doc/emailaddress.txt
+++ b/lib/lp/services/identity/doc/emailaddress.txt
@@ -38,14 +38,16 @@ exception.
     >>> emailset.new(email.email, foobar)
     Traceback (most recent call last):
     ...
-    lp.services.identity.interfaces.emailaddress.EmailAddressAlreadyTaken: The email address '...' is already registered.
+    lp.services.identity.interfaces.emailaddress.EmailAddressAlreadyTaken:
+    The email address '...' is already registered.
 
 The email address verification is case insensitive as well:
 
     >>> emailset.new(email.email.upper(), foobar)
     Traceback (most recent call last):
     ...
-    lp.services.identity.interfaces.emailaddress.EmailAddressAlreadyTaken: The email address '...' is already registered.
+    lp.services.identity.interfaces.emailaddress.EmailAddressAlreadyTaken:
+    The email address '...' is already registered.
 
 Registering a new email address works -- and preserves case -- though:
 
@@ -95,7 +97,8 @@ Otherwise, UndeletableEmailAddress is raised.
     >>> foobar.preferredemail.destroySelf()
     Traceback (most recent call last):
     ...
-    lp.services.identity.model.emailaddress.UndeletableEmailAddress: This is a person's preferred email...
+    lp.services.identity.model.emailaddress.UndeletableEmailAddress:
+    This is a person's preferred email...
 
     >>> from lp.registry.tests.mailinglists_helper import (
     ...     new_list_for_team)
@@ -104,4 +107,5 @@ Otherwise, UndeletableEmailAddress is raised.
     >>> email.destroySelf()
     Traceback (most recent call last):
     ...
-    lp.services.identity.model.emailaddress.UndeletableEmailAddress: This is the email address of a team's mailing list...
+    lp.services.identity.model.emailaddress.UndeletableEmailAddress:
+    This is the email address of a team's mailing list...
diff --git a/lib/lp/services/librarian/doc/librarian.txt b/lib/lp/services/librarian/doc/librarian.txt
index f2d2f6f..6c41957 100644
--- a/lib/lp/services/librarian/doc/librarian.txt
+++ b/lib/lp/services/librarian/doc/librarian.txt
@@ -366,12 +366,14 @@ you'll get a DownloadFailed error.
     >>> client.getFileByAlias(private_file_id)
     Traceback (most recent call last):
       ...
-    lp.services.librarian.interfaces.client.DownloadFailed: Alias ... cannot be downloaded from this client.
+    lp.services.librarian.interfaces.client.DownloadFailed:
+    Alias ... cannot be downloaded from this client.
 
     >>> client.getURLForAlias(private_file_id)
     Traceback (most recent call last):
       ...
-    lp.services.librarian.interfaces.client.DownloadFailed: Alias ... cannot be downloaded from this client.
+    lp.services.librarian.interfaces.client.DownloadFailed:
+    Alias ... cannot be downloaded from this client.
 
 But using the restricted librarian will work:
 
diff --git a/lib/lp/services/mail/doc/emailauthentication.txt b/lib/lp/services/mail/doc/emailauthentication.txt
index dbefd7d..efcdce9 100644
--- a/lib/lp/services/mail/doc/emailauthentication.txt
+++ b/lib/lp/services/mail/doc/emailauthentication.txt
@@ -124,7 +124,8 @@ message.
     ...     msg.signedContent, msg.signature)
     Traceback (most recent call last):
     ...
-    lp.services.gpg.interfaces.GPGVerificationError: (7, 8, ...'Bad signature')
+    lp.services.gpg.interfaces.GPGVerificationError: (7, 8, ...'Bad
+    signature')
 
     >>> getUtility(IGPGHandler).getVerifiedSignature(
     ...     msg.signedContent.replace(b'\n', b'\r\n'), msg.signature)
diff --git a/lib/lp/services/mail/tests/incomingmail.txt b/lib/lp/services/mail/tests/incomingmail.txt
index d139c02..6fa33ca 100644
--- a/lib/lp/services/mail/tests/incomingmail.txt
+++ b/lib/lp/services/mail/tests/incomingmail.txt
@@ -484,7 +484,8 @@ logged.
     >>> handleMailForTest()
     ERROR:...:Upload to Librarian failed...
     ...
-    lp.services.librarian.interfaces.client.UploadFailed: ...Connection refused...
+    lp.services.librarian.interfaces.client.UploadFailed:
+    ...Connection refused...
 
     >>> len(stub.test_emails)
     2
diff --git a/lib/lp/services/messages/doc/message.txt b/lib/lp/services/messages/doc/message.txt
index f51d39a..6d721af 100644
--- a/lib/lp/services/messages/doc/message.txt
+++ b/lib/lp/services/messages/doc/message.txt
@@ -391,7 +391,8 @@ explicitly told to do so:
     ... ''')
     Traceback (most recent call last):
         [...]
-    lp.services.messages.interfaces.message.UnknownSender: ...'invalid@xxxxxxxxxxx'
+    lp.services.messages.interfaces.message.UnknownSender:
+    'invalid@xxxxxxxxxxx'
 
     >>> msg = msgset.fromEmail(b'''\
     ... From: invalid@xxxxxxxxxxx
@@ -424,7 +425,8 @@ passed through a broken MTA and we have no choice but to bounce them.
     ... ''')
     Traceback (most recent call last):
         [...]
-    lp.services.messages.interfaces.message.InvalidEmailMessage: Missing Message-Id
+    lp.services.messages.interfaces.message.InvalidEmailMessage:
+    Missing Message-Id
 
     >>> msg = msgset.fromEmail(b'''\
     ... Date: Fri, 17 Jun 2005 10:45:13 +0100
@@ -435,7 +437,8 @@ passed through a broken MTA and we have no choice but to bounce them.
     ... ''')
     Traceback (most recent call last):
         [...]
-    lp.services.messages.interfaces.message.InvalidEmailMessage: No From: or Reply-To: header
+    lp.services.messages.interfaces.message.InvalidEmailMessage:
+    No From: or Reply-To: header
 
 Also, we generally insist that a message has a date associated with it.
 
@@ -448,7 +451,8 @@ Also, we generally insist that a message has a date associated with it.
     ... ''')
     Traceback (most recent call last):
         [...]
-    lp.services.messages.interfaces.message.InvalidEmailMessage: Invalid date...
+    lp.services.messages.interfaces.message.InvalidEmailMessage:
+    Invalid date...
 
 However, we can override this behaviour by passing a date_created
 parameter to fromEmail(). This is optional, and defaults to None, but it
diff --git a/lib/lp/services/oauth/stories/authorize-token.txt b/lib/lp/services/oauth/stories/authorize-token.txt
index dbce4e8..6634a7a 100644
--- a/lib/lp/services/oauth/stories/authorize-token.txt
+++ b/lib/lp/services/oauth/stories/authorize-token.txt
@@ -127,7 +127,9 @@ integration has its own section, below.)
     ...         % (urlencode(params), allow_permission))
     Traceback (most recent call last):
     ...
-    zope.security.interfaces.Unauthorized: Consumer "foobar123451432" asked for desktop integration, but didn't say what kind of desktop it is, or name the computer being integrated.
+    zope.security.interfaces.Unauthorized: Consumer "foobar123451432" asked
+    for desktop integration, but didn't say what kind of desktop it is, or
+    name the computer being integrated.
 
 An application may also specify a context, so that the access granted
 by the user is restricted to things related to that context.
@@ -365,13 +367,17 @@ level that specifically applies across the entire desktop.
     >>> print_access_levels_for('allow_permission=WRITE_PRIVATE')
     Traceback (most recent call last):
     ...
-    zope.security.interfaces.Unauthorized: Desktop integration token requested a permission ("Change Anything") not supported for desktop-wide use.
+    zope.security.interfaces.Unauthorized: Desktop integration token
+    requested a permission ("Change Anything") not supported for
+    desktop-wide use.
 
     >>> print_access_levels_for(
     ...     'allow_permission=WRITE_PUBLIC&' + allow_desktop)
     Traceback (most recent call last):
     ...
-    zope.security.interfaces.Unauthorized: Desktop integration token requested a permission ("Change Non-Private Data") not supported for desktop-wide use.
+    zope.security.interfaces.Unauthorized: Desktop integration token
+    requested a permission ("Change Non-Private Data") not supported for
+    desktop-wide use.
 
 You can't specify a callback URL when authorizing a desktop-wide
 token, since callback URLs should only be used when integrating
@@ -381,7 +387,8 @@ websites into Launchpad.
     >>> print_access_levels_for(allow_desktop)
     Traceback (most recent call last):
     ...
-    zope.security.interfaces.Unauthorized: A desktop integration may not specify an OAuth callback URL.
+    zope.security.interfaces.Unauthorized: A desktop integration may not
+    specify an OAuth callback URL.
 
 This is true even if the desktop token isn't asking for the
 DESKTOP_INTEGRATION permission.
@@ -389,7 +396,8 @@ DESKTOP_INTEGRATION permission.
     >>> print_access_levels_for('allow_permission=WRITE_PRIVATE')
     Traceback (most recent call last):
     ...
-    zope.security.interfaces.Unauthorized: A desktop integration may not specify an OAuth callback URL.
+    zope.security.interfaces.Unauthorized: A desktop integration may not
+    specify an OAuth callback URL.
 
     >>> del params['oauth_callback']
 
diff --git a/lib/lp/services/webapp/doc/canonical_url.txt b/lib/lp/services/webapp/doc/canonical_url.txt
index c0c35b9..e7a0ce5 100644
--- a/lib/lp/services/webapp/doc/canonical_url.txt
+++ b/lib/lp/services/webapp/doc/canonical_url.txt
@@ -115,7 +115,8 @@ mistyped 'countryOopsTypo', and there is no such name in ITown.
     ... """.format(module_name=module.__name__))
     Traceback (most recent call last):
     ...
-    zope.configuration.xmlconfig.ZopeXMLConfigurationError: File "<string>", line ... AttributeError: The name "countryOopsTypo" is not in ....ITown
+    zope.configuration.xmlconfig.ZopeXMLConfigurationError: File "<string>",
+    line ... AttributeError: The name "countryOopsTypo" is not in ....ITown
 
     >>> zcmlcontext = xmlconfig.string("""
     ... <configure xmlns:browser="http://namespaces.zope.org/browser";>
@@ -278,7 +279,8 @@ itself be adapted to ICanonicalUrlData.
     >>> canonical_url(object_that_has_no_url)
     Traceback (most recent call last):
     ...
-    lp.services.webapp.interfaces.NoCanonicalUrl: No url for <...object at ...> because <...object at ...> broke the chain.
+    lp.services.webapp.interfaces.NoCanonicalUrl: No url for <...object at
+    ...> because <...object at ...> broke the chain.
 
 Now, we must test the case where the object can be adapted to
 ICanonicalUrlData, but its parent or its parent's parent (and so on) cannot.
@@ -292,7 +294,8 @@ ICanonicalUrlData, but its parent or its parent's parent (and so on) cannot.
     >>> canonical_url(unrooted_object)
     Traceback (most recent call last):
     ...
-    lp.services.webapp.interfaces.NoCanonicalUrl: No url for <...ObjectThatHasUrl...> because <...object...> broke the chain.
+    lp.services.webapp.interfaces.NoCanonicalUrl: No url for
+    <...ObjectThatHasUrl...> because <...object...> broke the chain.
 
 The first argument to NoCanonicalUrl is the object that a canonical url was
 requested for.  The second argument is the object that broke the chain.
@@ -339,7 +342,8 @@ to work properly.
     >>> next(iterator)
     Traceback (most recent call last):
     ...
-    lp.services.webapp.interfaces.NoCanonicalUrl: No url for <...object...> because <...object...> broke the chain.
+    lp.services.webapp.interfaces.NoCanonicalUrl: No url for <...object...>
+    because <...object...> broke the chain.
 
     >>> iterator = canonical_url_iterator(unrooted_object)
     >>> next(iterator).__class__.__name__
@@ -349,7 +353,8 @@ to work properly.
     >>> next(iterator)
     Traceback (most recent call last):
     ...
-    lp.services.webapp.interfaces.NoCanonicalUrl: No url for <...ObjectThatHasUrl...> because <...object...> broke the chain.
+    lp.services.webapp.interfaces.NoCanonicalUrl: No url for
+    <...ObjectThatHasUrl...> because <...object...> broke the chain.
 
 
 canonical_url and requests
diff --git a/lib/lp/services/webapp/doc/renamed-view.txt b/lib/lp/services/webapp/doc/renamed-view.txt
index 19f5b7a..bed161e 100644
--- a/lib/lp/services/webapp/doc/renamed-view.txt
+++ b/lib/lp/services/webapp/doc/renamed-view.txt
@@ -93,7 +93,8 @@ raise an error. e.g. http://launchpad.test/ubuntu/+tickets/foo
     >>> view.publishTraverse(request, u'foo')
     Traceback (most recent call last):
      ...
-    zope.publisher.interfaces.NotFound: Object: <Distribution 'Ubuntu' (ubuntu)>, name: 'foo'
+    zope.publisher.interfaces.NotFound:
+    Object: <Distribution 'Ubuntu' (ubuntu)>, name: 'foo'
 
 
 Registering from ZCML
diff --git a/lib/lp/services/webapp/doc/test_adapter.txt b/lib/lp/services/webapp/doc/test_adapter.txt
index b115f8e..0b6712c 100644
--- a/lib/lp/services/webapp/doc/test_adapter.txt
+++ b/lib/lp/services/webapp/doc/test_adapter.txt
@@ -214,7 +214,11 @@ timeout by sleeping for 200ms with a 100ms statement timeout:
     >>> store.execute(six.ensure_str('SELECT pg_sleep(0.200)'), noresult=True)
     Traceback (most recent call last):
       ...
-    lp.services.webapp.adapter.LaunchpadTimeoutError: Statement: 'SELECT pg_sleep(0.200)' Parameters:() Original error: QueryCanceledError('canceling statement due to statement timeout\n',)
+    lp.services.webapp.adapter.LaunchpadTimeoutError:
+    Statement: 'SELECT pg_sleep(0.200)'
+    Parameters:()
+    Original error:
+    QueryCanceledError('canceling statement due to statement timeout\n',)
 
 Even though the statement timed out, it is recorded in the statement log:
 
@@ -284,7 +288,11 @@ timeout being reported by PostgreSQL is actually working:
     >>> store.execute(six.ensure_str('SELECT pg_sleep(0.2)'), noresult=True)
     Traceback (most recent call last):
       ...
-    lp.services.webapp.adapter.LaunchpadTimeoutError: Statement: 'SELECT pg_sleep(0.2)' Parameters:() Original error: QueryCanceledError('canceling statement due to statement timeout\n',)
+    lp.services.webapp.adapter.LaunchpadTimeoutError:
+    Statement: 'SELECT pg_sleep(0.2)'
+    Parameters:()
+    Original error:
+    QueryCanceledError('canceling statement due to statement timeout\n',)
     >>> clear_request_started()
 
 
@@ -361,7 +369,8 @@ transaction will be doomed:
     >>> transaction.commit()
     Traceback (most recent call last):
     ...
-    transaction.interfaces.DoomedTransaction: transaction doomed, cannot commit
+    transaction.interfaces.DoomedTransaction:
+    transaction doomed, cannot commit
 
 Cleanup:
 
@@ -444,7 +453,8 @@ config section.  By default we connect as "launchpad"
     ...     """, noresult=True)
     Traceback (most recent call last):
     ...
-    storm.database.ProgrammingError: permission denied for relation sourcepackagename
+    storm.database.ProgrammingError:
+    permission denied for relation sourcepackagename
 
 This is not reset at the end of the transaction:
 
@@ -456,7 +466,8 @@ This is not reset at the end of the transaction:
     ...     """, noresult=True)
     Traceback (most recent call last):
     ...
-    storm.database.ProgrammingError: permission denied for relation sourcepackagename
+    storm.database.ProgrammingError:
+    permission denied for relation sourcepackagename
     >>> transaction.abort()
 
 So you need to explicitly set the user back to the default:
diff --git a/lib/lp/services/webapp/doc/webapp-publication.txt b/lib/lp/services/webapp/doc/webapp-publication.txt
index 157d674..f0c2bcf 100644
--- a/lib/lp/services/webapp/doc/webapp-publication.txt
+++ b/lib/lp/services/webapp/doc/webapp-publication.txt
@@ -1203,7 +1203,8 @@ correct.
     >>> publication.getPrincipal(test_request)
     Traceback (most recent call last):
     ...
-    zope.security.interfaces.Unauthorized: Unknown consumer (foobar123451432z).
+    zope.security.interfaces.Unauthorized:
+    Unknown consumer (foobar123451432z).
 
     >>> form2 = form.copy()
     >>> form2['oauth_signature'] += 'z'
diff --git a/lib/lp/soyuz/browser/tests/archive-views.txt b/lib/lp/soyuz/browser/tests/archive-views.txt
index 727b1f5..b46d5fc 100644
--- a/lib/lp/soyuz/browser/tests/archive-views.txt
+++ b/lib/lp/soyuz/browser/tests/archive-views.txt
@@ -1344,7 +1344,9 @@ value is submitted.
     >>> print(archive_widget.getInputValue())
     Traceback (most recent call last):
     ...
-    zope.formlib.interfaces.WidgetInputError: ('destination_archive', ...'Destination PPA', RequiredMissing('destination_archive'))
+    zope.formlib.interfaces.WidgetInputError:
+    ('destination_archive', 'Destination PPA',
+     RequiredMissing('destination_archive'))
 
 
 Copy private files to public archives
diff --git a/lib/lp/soyuz/doc/archive.txt b/lib/lp/soyuz/doc/archive.txt
index 01b4bdf..f2a80fe 100644
--- a/lib/lp/soyuz/doc/archive.txt
+++ b/lib/lp/soyuz/doc/archive.txt
@@ -91,7 +91,8 @@ Amending it as an unprivileged user results in failure:
     >>> cprov_archive.external_dependencies = "test"
     Traceback (most recent call last):
     ...
-    zope.security.interfaces.Unauthorized: (..., 'external_dependencies', 'launchpad.Admin')
+    zope.security.interfaces.Unauthorized:
+    (..., 'external_dependencies', 'launchpad.Admin')
 
 As a Launchpad admin, setting this property will work.
 
@@ -343,13 +344,15 @@ filter is not passed too.
     ...     version='1.0')
     Traceback (most recent call last):
     ...
-    lp.soyuz.interfaces.archive.VersionRequiresName: The 'version' parameter can be used only together with the 'name' parameter.
+    lp.soyuz.interfaces.archive.VersionRequiresName: The 'version' parameter
+    can be used only together with the 'name' parameter.
 
     >>> moz_version_lookup = cprov_archive.getPublishedOnDiskBinaries(
     ...     version='1.0')
     Traceback (most recent call last):
     ...
-    lp.soyuz.interfaces.archive.VersionRequiresName: The 'version' parameter can be used only together with the 'name' parameter.
+    lp.soyuz.interfaces.archive.VersionRequiresName: The 'version' parameter
+    can be used only together with the 'name' parameter.
 
 Both methods support 'status' filter:
 
@@ -823,7 +826,8 @@ dependency is published in Mark's PPA.
     ...     cprov.archive, release_pocket, main_component)
     Traceback (most recent call last):
     ...
-    lp.soyuz.interfaces.archive.ArchiveDependencyError: This dependency is already registered.
+    lp.soyuz.interfaces.archive.ArchiveDependencyError: This dependency is
+    already registered.
 
 'dependency' and target archive are the same.
 
@@ -831,7 +835,8 @@ dependency is published in Mark's PPA.
     ...     no_priv.archive, release_pocket, main_component)
     Traceback (most recent call last):
     ...
-    lp.soyuz.interfaces.archive.ArchiveDependencyError: An archive should not depend on itself.
+    lp.soyuz.interfaces.archive.ArchiveDependencyError: An archive should not
+    depend on itself.
 
 A 'dependency' can be added for any type of archive, PPA, PRIMARY, PARTNER or
 COPY.
@@ -863,7 +868,8 @@ Only one dependency per archive can be added.
     ...     getUtility(IComponentSet)['main'])
     Traceback (most recent call last):
     ...
-    lp.soyuz.interfaces.archive.ArchiveDependencyError: This dependency is already registered.
+    lp.soyuz.interfaces.archive.ArchiveDependencyError: This dependency is
+    already registered.
 
 Thus archive dependency removal can be performed simply by passing the
 dependency target.
@@ -892,14 +898,16 @@ RELEASE or other components than 'main'.
     ...     main_component)
     Traceback (most recent call last):
     ...
-    lp.soyuz.interfaces.archive.ArchiveDependencyError: Non-primary archives only support the RELEASE pocket.
+    lp.soyuz.interfaces.archive.ArchiveDependencyError: Non-primary archives
+    only support the RELEASE pocket.
 
     >>> no_priv.archive.addArchiveDependency(
     ...     mark.archive, release_pocket,
     ...     getUtility(IComponentSet)['universe'])
     Traceback (most recent call last):
     ...
-    lp.soyuz.interfaces.archive.ArchiveDependencyError: Non-primary archives only support the 'main' component.
+    lp.soyuz.interfaces.archive.ArchiveDependencyError: Non-primary archives
+    only support the 'main' component.
 
 'removeArchiveDependency' allow us to purge a recorded
 `ArchiveDependency` corresponding to the given 'dependency', 'pocket'
@@ -1671,7 +1679,8 @@ anacronism can be removed.
     ...     carlos, "universe")
     Traceback (most recent call last):
     ...
-    lp.soyuz.interfaces.archive.InvalidComponent: Component for PPAs should be 'main'
+    lp.soyuz.interfaces.archive.InvalidComponent: Component for PPAs should be
+    'main'
 
 You'll get the same error if you use a component object that's not main.
 
@@ -1680,7 +1689,8 @@ You'll get the same error if you use a component object that's not main.
     ...     carlos, universe)
     Traceback (most recent call last):
     ...
-    lp.soyuz.interfaces.archive.InvalidComponent: Component for PPAs should be 'main'
+    lp.soyuz.interfaces.archive.InvalidComponent: Component for PPAs should be
+    'main'
 
 As important as the right to upload packages to Joe's PPA, Carlos
 also got the corresponding permissions on it.
@@ -1916,7 +1926,10 @@ Repeating this source copy gives an error:
     ...     sources, cprov.archive, "release", person=mark)
     Traceback (most recent call last):
     ...
-    lp.soyuz.interfaces.archive.CannotCopy: package1 1.1 in hoary (same version already building in the destination archive for Hoary) package2 1.0 in hoary (same version already building in the destination archive for Hoary)
+    lp.soyuz.interfaces.archive.CannotCopy: package1 1.1 in hoary (same
+    version already building in the destination archive for Hoary) package2
+    1.0 in hoary (same version already building in the destination archive for
+    Hoary)
 
 Repeating this copy with binaries also gives an error:
 
@@ -1925,7 +1938,9 @@ Repeating this copy with binaries also gives an error:
     ...     person=mark)
     Traceback (most recent call last):
     ...
-    lp.soyuz.interfaces.archive.CannotCopy: package1 1.1 in hoary (source has no binaries to be copied) package2 1.0 in hoary (source has no binaries to be copied)
+    lp.soyuz.interfaces.archive.CannotCopy: package1 1.1 in hoary (source has
+    no binaries to be copied) package2 1.0 in hoary (source has no binaries to
+    be copied)
 
 Specifying non-existent source names, pocket names or distroseries names
 all result in a NotFound exception:
@@ -1934,7 +1949,8 @@ all result in a NotFound exception:
     ...     person=mark)
     Traceback (most recent call last):
     ...
-    lp.registry.errors.NoSuchSourcePackageName: No such source package: 'bogus'.
+    lp.registry.errors.NoSuchSourcePackageName: No such source package:
+    'bogus'.
 
     >>> mark.archive.syncSources(sources, cprov.archive, "badpocket",
     ...     person=mark)
@@ -1947,14 +1963,16 @@ all result in a NotFound exception:
     ...     person=mark)
     Traceback (most recent call last):
     ...
-    lp.registry.errors.NoSuchDistroSeries: No such distribution series: 'badseries'.
+    lp.registry.errors.NoSuchDistroSeries: No such distribution series:
+    'badseries'.
 
 If a package exists but not in the source archive, we get an error:
 
     >>> mark.archive.syncSources(["pack"], mark.archive, "release")
     Traceback (most recent call last):
     ...
-    lp.soyuz.interfaces.archive.CannotCopy: None of the supplied package names are published in PPA for Mark Shuttleworth.
+    lp.soyuz.interfaces.archive.CannotCopy: None of the supplied package names
+    are published in PPA for Mark Shuttleworth.
 
 If a package exists in multiple distroseries, we can use the `from_series`
 parameter to select the distroseries to synchronise from:
@@ -2020,7 +2038,8 @@ If the supplied package exists but not in the source archive, we get an error:
     >>> mark.archive.syncSource("package3", "1.0", mark.archive, "release")
     Traceback (most recent call last):
     ...
-    lp.soyuz.interfaces.archive.CannotCopy: package3 is not published in PPA for Mark Shuttleworth.
+    lp.soyuz.interfaces.archive.CannotCopy: package3 is not published in PPA
+    for Mark Shuttleworth.
 
 Copy package3 1.0 explicitly:
 
@@ -2067,7 +2086,8 @@ or a CannotCopy exception is thrown.
     ...     "package3", "1.2", cprov.archive, "updates", person=mark)
     Traceback (most recent call last):
     ...
-    lp.soyuz.interfaces.archive.CannotCopy: PPA uploads must be for the RELEASE pocket.
+    lp.soyuz.interfaces.archive.CannotCopy: PPA uploads must be for the
+    RELEASE pocket.
 
 syncSource() will always use only the latest publication of the
 specific source, ignoring the previous ones. Multiple publications can
diff --git a/lib/lp/soyuz/doc/archiveauthtoken.txt b/lib/lp/soyuz/doc/archiveauthtoken.txt
index 88cb9c2..81bf15c 100644
--- a/lib/lp/soyuz/doc/archiveauthtoken.txt
+++ b/lib/lp/soyuz/doc/archiveauthtoken.txt
@@ -46,7 +46,8 @@ It is not possible to create a token for the subscribed team.
     >>> joe_private_ppa.newAuthToken(teambrad)
     Traceback (most recent call last):
     ...
-    lp.soyuz.interfaces.archive.NoTokensForTeams: Subscription tokens can be created for individuals only.
+    lp.soyuz.interfaces.archive.NoTokensForTeams:
+    Subscription tokens can be created for individuals only.
 
 But now that the subscription is there, we can create a token as Brad.
 
@@ -62,7 +63,8 @@ It is not possible to create a second token when one already exists:
     >>> new_token = joe_private_ppa.newAuthToken(bradsmith)
     Traceback (most recent call last):
     ...
-    lp.soyuz.interfaces.archivesubscriber.ArchiveSubscriptionError: Brad Smith already has a token for PPA for Joe Smith.
+    lp.soyuz.interfaces.archivesubscriber.ArchiveSubscriptionError:
+    Brad Smith already has a token for PPA for Joe Smith.
 
 So deactivate the old token so that we can create a new token:
 
diff --git a/lib/lp/soyuz/doc/archivepermission.txt b/lib/lp/soyuz/doc/archivepermission.txt
index 6675914..d010a5c 100644
--- a/lib/lp/soyuz/doc/archivepermission.txt
+++ b/lib/lp/soyuz/doc/archivepermission.txt
@@ -149,7 +149,8 @@ If the string is not a valid component, a NotFound exception is thrown:
     ...     ubuntu.main_archive, "badcomponent")
     Traceback (most recent call last):
     ...
-    lp.soyuz.interfaces.archive.ComponentNotFound: No such component: 'badcomponent'.
+    lp.soyuz.interfaces.archive.ComponentNotFound:
+    No such component: 'badcomponent'.
 
 If the component argument is not passed, it will return
 ArchivePermission records for all matching components:
@@ -196,7 +197,8 @@ NoSuchSourcePackageName to be thrown.
     ...     ubuntu.main_archive, "fakepackage")
     Traceback (most recent call last):
     ...
-    lp.registry.errors.NoSuchSourcePackageName: No such source package: 'fakepackage'.
+    lp.registry.errors.NoSuchSourcePackageName:
+    No such source package: 'fakepackage'.
 
 Similarly, packagesForUploader() returns the ArchivePermission records where
 the supplied user has permission to upload to packages.
diff --git a/lib/lp/soyuz/doc/archivesubscriber.txt b/lib/lp/soyuz/doc/archivesubscriber.txt
index 62db1c2..0d43bfd 100644
--- a/lib/lp/soyuz/doc/archivesubscriber.txt
+++ b/lib/lp/soyuz/doc/archivesubscriber.txt
@@ -65,7 +65,8 @@ public:
     ...     joesmith, cprov, description=u"subscription for joesmith")
     Traceback (most recent call last):
     ...
-    lp.soyuz.interfaces.archive.ArchiveNotPrivate: Only private archives can have subscriptions.
+    lp.soyuz.interfaces.archive.ArchiveNotPrivate:
+    Only private archives can have subscriptions.
 
 If we create a private ppa for Celso, then he can create a
 subscription for joesmith:
@@ -180,7 +181,8 @@ cannot be created:
     ...     joesmith, cprov, description=u"subscription for joesmith")
     Traceback (most recent call last):
     ...
-    lp.soyuz.interfaces.archive.AlreadySubscribed: Joe Smith already has a current subscription for 'PPA named p3a for Celso Providelo'.
+    lp.soyuz.interfaces.archive.AlreadySubscribed: Joe Smith already has a
+    current subscription for 'PPA named p3a for Celso Providelo'.
 
 
 Add another subscription for the test user, this time to mark's ppa:
diff --git a/lib/lp/soyuz/doc/build-failedtoupload-workflow.txt b/lib/lp/soyuz/doc/build-failedtoupload-workflow.txt
index 5099978..a942148 100644
--- a/lib/lp/soyuz/doc/build-failedtoupload-workflow.txt
+++ b/lib/lp/soyuz/doc/build-failedtoupload-workflow.txt
@@ -41,7 +41,8 @@ FAILEDTOUPLOAD notification requires 'extra_info' argument to be filled:
     >>> failedtoupload_candidate.notify()
     Traceback (most recent call last):
     ...
-    AssertionError: Extra information is required for FAILEDTOUPLOAD notifications.
+    AssertionError: Extra information is required for FAILEDTOUPLOAD
+    notifications.
 
 Normally 'extra_info' will contain the output generated by the binary
 upload procedure with instructions to reprocess it:
diff --git a/lib/lp/soyuz/doc/distroseriesqueue.txt b/lib/lp/soyuz/doc/distroseriesqueue.txt
index 29a4c67..52e1d05 100644
--- a/lib/lp/soyuz/doc/distroseriesqueue.txt
+++ b/lib/lp/soyuz/doc/distroseriesqueue.txt
@@ -396,7 +396,10 @@ remain in the original queue
     >>> dup_two.setAccepted()
     Traceback (most recent call last):
     ...
-    lp.soyuz.interfaces.queue.QueueInconsistentStateError: The source cnews - 1.0 is already accepted in ubuntu/breezy-autotest and you cannot upload the same version within the same distribution. You have to modify the source version and re-upload.
+    lp.soyuz.interfaces.queue.QueueInconsistentStateError: The source cnews -
+    1.0 is already accepted in ubuntu/breezy-autotest and you cannot upload
+    the same version within the same distribution. You have to modify the
+    source version and re-upload.
     >>> dup_two.status.name
     'UNAPPROVED'
 
@@ -426,7 +429,10 @@ The protection code should also identify dups with items in DONE queue
     >>> dup_two.setAccepted()
     Traceback (most recent call last):
     ...
-    lp.soyuz.interfaces.queue.QueueInconsistentStateError: The source cnews - 1.0 is already accepted in ubuntu/breezy-autotest and you cannot upload the same version within the same distribution. You have to modify the source version and re-upload.
+    lp.soyuz.interfaces.queue.QueueInconsistentStateError: The source cnews -
+    1.0 is already accepted in ubuntu/breezy-autotest and you cannot upload
+    the same version within the same distribution. You have to modify the
+    source version and re-upload.
 
 The ubuntu policy allows unofficial sections to live sometime in the
 repository, until someone find time to override them. It's better than
@@ -594,7 +600,8 @@ an error:
     ...     allowed_components=(universe,)))
     Traceback (most recent call last):
     ...
-    lp.soyuz.interfaces.queue.QueueAdminUnauthorizedError: No rights to override to restricted
+    lp.soyuz.interfaces.queue.QueueAdminUnauthorizedError:
+    No rights to override to restricted
 
 Allowing "restricted" still won't work because the original component
 is "main":
@@ -604,7 +611,8 @@ is "main":
     ...     allowed_components=(restricted,)))
     Traceback (most recent call last):
     ...
-    lp.soyuz.interfaces.queue.QueueAdminUnauthorizedError: No rights to override from main
+    lp.soyuz.interfaces.queue.QueueAdminUnauthorizedError:
+    No rights to override from main
 
 Specifying both main and restricted allows the override to restricted/web.
 overrideSource() returns True if it completed the task.
@@ -640,13 +648,15 @@ Similarly for binaries:
     ...     binary_changes, allowed_components=(universe,)))
     Traceback (most recent call last):
     ...
-    lp.soyuz.interfaces.queue.QueueAdminUnauthorizedError: No rights to override to restricted
+    lp.soyuz.interfaces.queue.QueueAdminUnauthorizedError:
+    No rights to override to restricted
 
     >>> print(item.overrideBinaries(
     ...     binary_changes, allowed_components=(restricted,)))
     Traceback (most recent call last):
     ...
-    lp.soyuz.interfaces.queue.QueueAdminUnauthorizedError: No rights to override from main
+    lp.soyuz.interfaces.queue.QueueAdminUnauthorizedError:
+    No rights to override from main
 
     >>> print(item.overrideBinaries(
     ...     binary_changes, allowed_components=(main, restricted)))
diff --git a/lib/lp/soyuz/doc/package-diff.txt b/lib/lp/soyuz/doc/package-diff.txt
index 5bea8f8..2c0d2c7 100644
--- a/lib/lp/soyuz/doc/package-diff.txt
+++ b/lib/lp/soyuz/doc/package-diff.txt
@@ -104,7 +104,8 @@ error:
     ...     requester=cprov, to_sourcepackagerelease=pmount_to)
     Traceback (most recent call last):
     ...
-    lp.soyuz.interfaces.packagediff.PackageDiffAlreadyRequested: diff from 0.1-1 to 0.1-2 has already been requested
+    lp.soyuz.interfaces.packagediff.PackageDiffAlreadyRequested:
+    diff from 0.1-1 to 0.1-2 has already been requested
 
 
 Diff request for source uploads
diff --git a/lib/lp/soyuz/stories/ppa/xx-ubuntu-ppas.txt b/lib/lp/soyuz/stories/ppa/xx-ubuntu-ppas.txt
index 8b5a993..94ba469 100644
--- a/lib/lp/soyuz/stories/ppa/xx-ubuntu-ppas.txt
+++ b/lib/lp/soyuz/stories/ppa/xx-ubuntu-ppas.txt
@@ -695,9 +695,11 @@ result in a NotFound error.
     >>> admin_browser.open("http://launchpad.test/~name16/+archive/ppa";)
     Traceback (most recent call last):
     ...
-    zope.publisher.interfaces.NotFound: Object: <Person at ... name16 (Foo Bar)>, name: '+archive'
+    zope.publisher.interfaces.NotFound:
+    Object: <Person at ... name16 (Foo Bar)>, name: '+archive'
 
     >>> admin_browser.open("http://launchpad.test/~name16/+archive";)
     Traceback (most recent call last):
     ...
-    zope.publisher.interfaces.NotFound: Object: <Person at ... name16 (Foo Bar)>, name: '+archive'
+    zope.publisher.interfaces.NotFound:
+    Object: <Person at ... name16 (Foo Bar)>, name: '+archive'
diff --git a/lib/lp/soyuz/stories/soyuz/xx-builds-pages.txt b/lib/lp/soyuz/stories/soyuz/xx-builds-pages.txt
index 31b4c17..6b1ab8c 100644
--- a/lib/lp/soyuz/stories/soyuz/xx-builds-pages.txt
+++ b/lib/lp/soyuz/stories/soyuz/xx-builds-pages.txt
@@ -292,7 +292,8 @@ form values are submitted:
     ...     "&build_text=binutils&build_state=all")
     Traceback (most recent call last):
     ...
-    lp.app.errors.UnexpectedFormData: No suitable state found for value "[...'building', ...'all']"
+    lp.app.errors.UnexpectedFormData: No suitable state found for value
+    "[...'building', ...'all']"
 
 
 Builder history
diff --git a/lib/lp/soyuz/stories/soyuz/xx-person-packages.txt b/lib/lp/soyuz/stories/soyuz/xx-person-packages.txt
index 82fcbcd..d3de61a 100644
--- a/lib/lp/soyuz/stories/soyuz/xx-person-packages.txt
+++ b/lib/lp/soyuz/stories/soyuz/xx-person-packages.txt
@@ -435,4 +435,5 @@ Please note also that disabled archives are not viewable by anonymous users.
     >>> anon_browser.open("http://launchpad.test/~cprov/+archive/ppa";)
     Traceback (most recent call last):
     ...
-    zope.security.interfaces.Unauthorized: (..., 'browserDefault', 'launchpad.SubscriberView')
+    zope.security.interfaces.Unauthorized:
+    (..., 'browserDefault', 'launchpad.SubscriberView')
diff --git a/lib/lp/translations/doc/browser-helpers.txt b/lib/lp/translations/doc/browser-helpers.txt
index 924441e..a69b3f0 100644
--- a/lib/lp/translations/doc/browser-helpers.txt
+++ b/lib/lp/translations/doc/browser-helpers.txt
@@ -191,7 +191,8 @@ Test bad format strings are caught and passed through.
     >>> parse_cformat_string(text)
     Traceback (most recent call last):
     ...
-    lp.translations.browser.browser_helpers.UnrecognisedCFormatString: foo %z bar
+    lp.translations.browser.browser_helpers.UnrecognisedCFormatString:
+    foo %z bar
 
     >>> text_to_html(text, ['c-format']) == text
     True