launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #25976
[Merge] ~cjwatson/launchpad:py3-pretty into launchpad:master
Colin Watson has proposed merging ~cjwatson/launchpad:py3-pretty into launchpad:master.
Commit message:
Adjust "pretty" doctest helper to use Python 3 text representation
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/+git/launchpad/+merge/396032
Unfortunately we have to take some minor countermeasures against pprint.PrettyPrinter wrapping long strings in Python >= 3.5. At some point it may become necessary to implement our own pretty-printer, but we aren't there yet.
--
Your team Launchpad code reviewers is requested to review the proposed merge of ~cjwatson/launchpad:py3-pretty into launchpad:master.
diff --git a/lib/lp/bugs/browser/tests/person-bug-views.txt b/lib/lp/bugs/browser/tests/person-bug-views.txt
index 6a047b0..d4cd88a 100644
--- a/lib/lp/bugs/browser/tests/person-bug-views.txt
+++ b/lib/lp/bugs/browser/tests/person-bug-views.txt
@@ -411,7 +411,7 @@ search page allow selection of a milestone.
>>> print(pretty(related_bugs_view.getMilestoneWidgetValues()))
[{'checked': False,
- 'title': u'Coughing Bob 0.9',
+ 'title': 'Coughing Bob 0.9',
'value': ...}]
@@ -428,7 +428,7 @@ will already appear.
>>> print(pretty(reported_bugs_view.getMilestoneWidgetValues()))
[{'checked': False,
- 'title': u'Coughing Bob 0.9',
+ 'title': 'Coughing Bob 0.9',
'value': ...}]
Filing a new bug and assigning a new milestone will make the new
@@ -440,10 +440,10 @@ milestone appear amongst the possible options.
>>> print(pretty(reported_bugs_view.getMilestoneWidgetValues()))
[{'checked': False,
- 'title': u'Coughing Bob 1.0',
+ 'title': 'Coughing Bob 1.0',
'value': ...},
{'checked': False,
- 'title': u'Coughing Bob 0.9',
+ 'title': 'Coughing Bob 0.9',
'value': ...}]
@@ -465,7 +465,7 @@ Once a bug has been assigned, the milestone appears.
>>> print(pretty(assigned_bugs_view.getMilestoneWidgetValues()))
[{'checked': False,
- 'title': u'Coughing Bob 1.0',
+ 'title': 'Coughing Bob 1.0',
'value': ...}]
@@ -488,7 +488,7 @@ Once the user has commented, the related milestone does appear.
>>> print(pretty(commented_bugs_view.getMilestoneWidgetValues()))
[{'checked': False,
- 'title': u'Coughing Bob 1.0',
+ 'title': 'Coughing Bob 1.0',
'value': ...}]
@@ -512,5 +512,5 @@ Once new_user has subscribed, the related milestones appear.
>>> print(pretty(subscribed_bugs_view.getMilestoneWidgetValues()))
[{'checked': False,
- 'title': u'Coughing Bob 1.0',
+ 'title': 'Coughing Bob 1.0',
'value': ...}]
diff --git a/lib/lp/bugs/doc/bug-change.txt b/lib/lp/bugs/doc/bug-change.txt
index 881c389..49b15c8 100644
--- a/lib/lp/bugs/doc/bug-change.txt
+++ b/lib/lp/bugs/doc/bug-change.txt
@@ -239,9 +239,9 @@ method.
>>> activity_data = simple_change.getBugActivity()
>>> print(pretty(activity_data))
- {'newvalue': u'Spam',
- 'oldvalue': u'Reality is on the blink again',
- 'whatchanged': u'title'}
+ {'newvalue': 'Spam',
+ 'oldvalue': 'Reality is on the blink again',
+ 'whatchanged': 'title'}
=== BugDescriptionChange ===
@@ -334,9 +334,9 @@ other attribute change. The list of tags is converted to a
space-separated string for display.
>>> print(pretty(tags_change.getBugActivity()))
- {'newvalue': u'second-tag third-tag zillionth-tag',
- 'oldvalue': u'first-tag second-tag third-tag',
- 'whatchanged': u'tags'}
+ {'newvalue': 'second-tag third-tag zillionth-tag',
+ 'oldvalue': 'first-tag second-tag third-tag',
+ 'whatchanged': 'tags'}
Addtions and removals are expressed separately in the notification.
@@ -362,7 +362,7 @@ when a CVE is linked to a bug.
... when=nowish, person=example_person, cve=cve)
>>> print(pretty(bug_cve_linked.getBugActivity()))
- {'newvalue': u'1999-8979',
+ {'newvalue': '1999-8979',
'whatchanged': 'cve linked'}
>>> print(bug_cve_linked.getBugNotification()['text'])
@@ -374,7 +374,7 @@ And when a CVE is unlinked from a bug.
... when=nowish, person=example_person, cve=cve)
>>> print(pretty(bug_cve_unlinked.getBugActivity()))
- {'oldvalue': u'1999-8979',
+ {'oldvalue': '1999-8979',
'whatchanged': 'cve unlinked'}
>>> print(bug_cve_unlinked.getBugNotification()['text'])
@@ -400,7 +400,7 @@ You can add an attachment...
>>> print(pretty(attachment_change.getBugActivity()))
{'newvalue':
- u'sample-attachment http://bugs.launchpad.test/bugs/...+files/...',
+ 'sample-attachment http://bugs.launchpad.test/bugs/...+files/...',
'oldvalue': None,
'whatchanged': 'attachment added'}
@@ -418,7 +418,7 @@ Or remove one.
>>> print(pretty(attachment_change.getBugActivity()))
{'newvalue': None,
'oldvalue':
- u'sample-attachment http://bugs.launchpad.test/bugs/...+files/...',
+ 'sample-attachment http://bugs.launchpad.test/bugs/...+files/...',
'whatchanged': 'attachment removed'}
>>> print(attachment_change.getBugNotification()['text'])
@@ -482,7 +482,7 @@ the user what has changed.
>>> print(pretty(status_change.getBugActivity()))
{'newvalue': 'Fix Released',
'oldvalue': 'New',
- 'whatchanged': u'heart-of-gold: status'}
+ 'whatchanged': 'heart-of-gold: status'}
>>> notification_text = status_change.getBugNotification()['text']
>>> print(notification_text) #doctest: -NORMALIZE_WHITESPACE
@@ -506,7 +506,7 @@ describe to the user what has changed.
>>> print(pretty(importance_change.getBugActivity()))
{'newvalue': 'Critical',
'oldvalue': 'Undecided',
- 'whatchanged': u'heart-of-gold: importance'}
+ 'whatchanged': 'heart-of-gold: importance'}
>>> notification_text = importance_change.getBugNotification()['text']
>>> print(notification_text) #doctest: -NORMALIZE_WHITESPACE
@@ -531,9 +531,9 @@ the user what has changed.
... person=example_person, what_changed='milestone',
... old_value=None, new_value=milestone)
>>> print(pretty(milestone_change.getBugActivity()))
- {'newvalue': u'example-milestone',
+ {'newvalue': 'example-milestone',
'oldvalue': None,
- 'whatchanged': u'heart-of-gold: milestone'}
+ 'whatchanged': 'heart-of-gold: milestone'}
>>> notification_text = milestone_change.getBugNotification()['text']
>>> print(notification_text) #doctest: -NORMALIZE_WHITESPACE
@@ -560,9 +560,9 @@ user what has changed.
... person=example_person, what_changed='bugwatch',
... old_value=None, new_value=bug_watch)
>>> print(pretty(bug_watch_change.getBugActivity()))
- {'newvalue': u'bugs.example.com/ #1245',
+ {'newvalue': 'bugs.example.com/ #1245',
'oldvalue': None,
- 'whatchanged': u'heart-of-gold: remote watch'}
+ 'whatchanged': 'heart-of-gold: remote watch'}
>>> notification_text = bug_watch_change.getBugNotification()['text']
>>> print(notification_text) #doctest: -NORMALIZE_WHITESPACE
@@ -583,9 +583,9 @@ describe to the user what has changed.
... person=example_person, what_changed='assignee',
... old_value=None, new_value=example_person)
>>> print(pretty(assignee_change.getBugActivity()))
- {'newvalue': u'Ford Prefect (ford-prefect)',
+ {'newvalue': 'Ford Prefect (ford-prefect)',
'oldvalue': None,
- 'whatchanged': u'heart-of-gold: assignee'}
+ 'whatchanged': 'heart-of-gold: assignee'}
>>> notification_text = assignee_change.getBugNotification()['text']
>>> print(notification_text) #doctest: -NORMALIZE_WHITESPACE
@@ -610,8 +610,8 @@ attribute for the values to use in the activity log.
... old_value=example_bug_task.target,
... new_value=new_target)
>>> print(pretty(target_change.getBugActivity()))
- {'newvalue': u'magrathea',
- 'oldvalue': u'heart-of-gold',
+ {'newvalue': 'magrathea',
+ 'oldvalue': 'heart-of-gold',
'whatchanged': 'affects'}
>>> notification_text = target_change.getBugNotification()['text']
diff --git a/lib/lp/registry/doc/launchpadlib/project-registry.txt.disabled b/lib/lp/registry/doc/launchpadlib/project-registry.txt.disabled
index dab711c..4c9922a 100644
--- a/lib/lp/registry/doc/launchpadlib/project-registry.txt.disabled
+++ b/lib/lp/registry/doc/launchpadlib/project-registry.txt.disabled
@@ -339,36 +339,36 @@ Read-only attributes cannot be changed.
milestone and release.
>>> print pretty(firefox.get_timeline())
- [{u'is_development_focus': False,
- u'landmarks': [{u'code_name': u'First Stable Release',
- u'date': u'2004-06-28',
- u'name': u'1.0.0',
- u'type': u'release',
- u'uri': u'/firefox/1.0/1.0.0'}],
- u'name': u'1.0',
- u'status': u'Active Development',
- u'uri': u'/firefox/1.0'},
- {u'is_development_focus': True,
- u'landmarks': [{u'code_name': None,
- u'date': u'2056-10-16',
- u'name': u'1.0',
- u'type': u'milestone',
- u'uri': u'/firefox/+milestone/1.0'},
- {u'code_name': u'One (secure) Tree Hill',
- u'date': u'2004-10-15',
- u'name': u'0.9.2',
- u'type': u'release',
- u'uri': u'/firefox/trunk/0.9.2'},
- {u'code_name': u'One Tree Hill (v2)',
- u'date': u'2004-10-15',
- u'name': u'0.9.1',
- u'type': u'release',
- u'uri': u'/firefox/trunk/0.9.1'},
- {u'code_name': u'One Tree Hill',
- u'date': u'2004-10-15',
- u'name': u'0.9',
- u'type': u'release',
- u'uri': u'/firefox/trunk/0.9'}],
- u'name': u'trunk',
- u'status': u'Active Development',
- u'uri': u'/firefox/trunk'}]
+ [{'is_development_focus': False,
+ 'landmarks': [{'code_name': 'First Stable Release',
+ 'date': '2004-06-28',
+ 'name': '1.0.0',
+ 'type': 'release',
+ 'uri': '/firefox/1.0/1.0.0'}],
+ 'name': '1.0',
+ 'status': 'Active Development',
+ 'uri': '/firefox/1.0'},
+ {'is_development_focus': True,
+ 'landmarks': [{'code_name': None,
+ 'date': '2056-10-16',
+ 'name': '1.0',
+ 'type': 'milestone',
+ 'uri': '/firefox/+milestone/1.0'},
+ {'code_name': 'One (secure) Tree Hill',
+ 'date': '2004-10-15',
+ 'name': '0.9.2',
+ 'type': 'release',
+ 'uri': '/firefox/trunk/0.9.2'},
+ {'code_name': 'One Tree Hill (v2)',
+ 'date': '2004-10-15',
+ 'name': '0.9.1',
+ 'type': 'release',
+ 'uri': '/firefox/trunk/0.9.1'},
+ {'code_name': 'One Tree Hill',
+ 'date': '2004-10-15',
+ 'name': '0.9',
+ 'type': 'release',
+ 'uri': '/firefox/trunk/0.9'}],
+ 'name': 'trunk',
+ 'status': 'Active Development',
+ 'uri': '/firefox/trunk'}]
diff --git a/lib/lp/registry/stories/webservice/xx-distribution-source-package.txt b/lib/lp/registry/stories/webservice/xx-distribution-source-package.txt
index 418bed1..9711784 100644
--- a/lib/lp/registry/stories/webservice/xx-distribution-source-package.txt
+++ b/lib/lp/registry/stories/webservice/xx-distribution-source-package.txt
@@ -10,18 +10,18 @@ Source packages can be obtained from the context of a distribution.
... name='mozilla-firefox').jsonBody()
>>> print(pretty(mozilla_firefox))
- {u'bug_reported_acknowledgement': None,
- u'bug_reporting_guidelines': None,
- u'display_name': u'mozilla-firefox in Debian',
- u'distribution_link': u'http://.../debian',
- u'http_etag': u'...',
- u'name': u'mozilla-firefox',
- u'official_bug_tags': [],
- u'resource_type_link': u'http://.../#distribution_source_package',
- u'self_link': u'http://.../debian/+source/mozilla-firefox',
- u'title': u'mozilla-firefox package in Debian',
- u'upstream_product_link': None,
- u'web_link': u'http://launchpad.../debian/+source/mozilla-firefox'}
+ {'bug_reported_acknowledgement': None,
+ 'bug_reporting_guidelines': None,
+ 'display_name': 'mozilla-firefox in Debian',
+ 'distribution_link': 'http://.../debian',
+ 'http_etag': '...',
+ 'name': 'mozilla-firefox',
+ 'official_bug_tags': [],
+ 'resource_type_link': 'http://.../#distribution_source_package',
+ 'self_link': 'http://.../debian/+source/mozilla-firefox',
+ 'title': 'mozilla-firefox package in Debian',
+ 'upstream_product_link': None,
+ 'web_link': 'http://launchpad.../debian/+source/mozilla-firefox'}
It's also possible to search for tasks with the "searchTasks" method:
@@ -53,8 +53,8 @@ package.
>>> print(pretty(upstream_product))
{...
- u'display_name': u'Mozilla Firefox'...
- u'self_link': u'http://.../firefox'...}
+ 'display_name': 'Mozilla Firefox'...
+ 'self_link': 'http://.../firefox'...}
If the package isn't linked to an upstream product its
upstream_product_link will be None.
diff --git a/lib/lp/registry/stories/webservice/xx-project-registry.txt b/lib/lp/registry/stories/webservice/xx-project-registry.txt
index 06c53b7..c92b677 100644
--- a/lib/lp/registry/stories/webservice/xx-project-registry.txt
+++ b/lib/lp/registry/stories/webservice/xx-project-registry.txt
@@ -446,61 +446,61 @@ hierarchy of series, milestones, and releases.
... "get_timeline",
... include_inactive=True).jsonBody()
>>> print(pretty(timeline))
- {u'entries': [{u'http_etag': ...
- u'is_development_focus': True,
- u'landmarks': [{u'code_name': None,
- u'date': u'2056-10-16',
- u'name': u'1.0',
- u'type': u'milestone',
- u'uri': u'/firefox/+milestone/1.0'},
- {u'code_name': u'One (secure) Tree Hill',
- u'date': u'2004-10-15',
- u'name': u'0.9.2',
- u'type': u'release',
- u'uri': u'/firefox/trunk/0.9.2'},
- {u'code_name': u'One Tree Hill (v2)',
- u'date': u'2004-10-15',
- u'name': u'0.9.1',
- u'type': u'release',
- u'uri': u'/firefox/trunk/0.9.1'},
- {u'code_name': u'One Tree Hill',
- u'date': u'2004-10-15',
- u'name': u'0.9',
- u'type': u'release',
- u'uri': u'/firefox/trunk/0.9'}],
- u'name': u'trunk',
- u'project_link': u'http://.../firefox',
- u'resource_type_link': u'.../#timeline_project_series',
- u'self_link': u'http://.../firefox/trunk',
- u'status': u'Obsolete',
- u'uri': u'/firefox/trunk',
- u'web_link': u'http://launchpad.../firefox/trunk'},
- {u'http_etag': ...
- u'is_development_focus': False,
- u'landmarks': [{u'code_name': u'First Stable Release',
- u'date': u'2004-06-28',
- u'name': u'1.0.0',
- u'type': u'release',
- u'uri': u'/firefox/1.0/1.0.0'}],
- u'name': u'1.0',
- u'project_link': u'http://.../firefox',
- u'resource_type_link': u'.../#timeline_project_series',
- u'self_link': u'http://.../firefox/1.0',
- u'status': u'Active Development',
- u'uri': u'/firefox/1.0',
- u'web_link': u'http://launchpad.../firefox/1.0'},
- {u'http_etag': ...
- u'is_development_focus': False,
- u'landmarks': [],
- u'name': u'experimental',
- u'project_link': u'http://.../firefox',
- u'resource_type_link': u'.../#timeline_project_series',
- u'self_link': u'http://.../firefox/experimental',
- u'status': u'Active Development',
- u'uri': u'/firefox/experimental',
- u'web_link': u'http://launchpad.../firefox/experimental'}],
- u'start': 0,
- u'total_size': 3}
+ {'entries': [{'http_etag': ...
+ 'is_development_focus': True,
+ 'landmarks': [{'code_name': None,
+ 'date': '2056-10-16',
+ 'name': '1.0',
+ 'type': 'milestone',
+ 'uri': '/firefox/+milestone/1.0'},
+ {'code_name': 'One (secure) Tree Hill',
+ 'date': '2004-10-15',
+ 'name': '0.9.2',
+ 'type': 'release',
+ 'uri': '/firefox/trunk/0.9.2'},
+ {'code_name': 'One Tree Hill (v2)',
+ 'date': '2004-10-15',
+ 'name': '0.9.1',
+ 'type': 'release',
+ 'uri': '/firefox/trunk/0.9.1'},
+ {'code_name': 'One Tree Hill',
+ 'date': '2004-10-15',
+ 'name': '0.9',
+ 'type': 'release',
+ 'uri': '/firefox/trunk/0.9'}],
+ 'name': 'trunk',
+ 'project_link': 'http://.../firefox',
+ 'resource_type_link': '.../#timeline_project_series',
+ 'self_link': 'http://.../firefox/trunk',
+ 'status': 'Obsolete',
+ 'uri': '/firefox/trunk',
+ 'web_link': 'http://launchpad.../firefox/trunk'},
+ {'http_etag': ...
+ 'is_development_focus': False,
+ 'landmarks': [{'code_name': 'First Stable Release',
+ 'date': '2004-06-28',
+ 'name': '1.0.0',
+ 'type': 'release',
+ 'uri': '/firefox/1.0/1.0.0'}],
+ 'name': '1.0',
+ 'project_link': 'http://.../firefox',
+ 'resource_type_link': '.../#timeline_project_series',
+ 'self_link': 'http://.../firefox/1.0',
+ 'status': 'Active Development',
+ 'uri': '/firefox/1.0',
+ 'web_link': 'http://launchpad.../firefox/1.0'},
+ {'http_etag': ...
+ 'is_development_focus': False,
+ 'landmarks': [],
+ 'name': 'experimental',
+ 'project_link': 'http://.../firefox',
+ 'resource_type_link': '.../#timeline_project_series',
+ 'self_link': 'http://.../firefox/experimental',
+ 'status': 'Active Development',
+ 'uri': '/firefox/experimental',
+ 'web_link': 'http://launchpad.../firefox/experimental'}],
+ 'start': 0,
+ 'total_size': 3}
Project collection
@@ -756,16 +756,16 @@ milestones and releases.
>>> timeline = webservice.named_get(
... babadoo_foobadoo['self_link'], "get_timeline").jsonBody()
>>> print(pretty(timeline))
- {u'http_etag': ...
- u'is_development_focus': False,
- u'landmarks': [],
- u'name': u'foobadoo',
- u'project_link': u'http://.../babadoo',
- u'resource_type_link': u'http://.../#timeline_project_series',
- u'self_link': u'http://.../babadoo/foobadoo',
- u'status': u'Active Development',
- u'uri': u'/babadoo/foobadoo',
- u'web_link': u'http://launchpad.../babadoo/foobadoo'}
+ {'http_etag': ...
+ 'is_development_focus': False,
+ 'landmarks': [],
+ 'name': 'foobadoo',
+ 'project_link': 'http://.../babadoo',
+ 'resource_type_link': 'http://.../#timeline_project_series',
+ 'self_link': 'http://.../babadoo/foobadoo',
+ 'status': 'Active Development',
+ 'uri': '/babadoo/foobadoo',
+ 'web_link': 'http://launchpad.../babadoo/foobadoo'}
Creating a milestone on the product series
diff --git a/lib/lp/services/doc/sprites.txt b/lib/lp/services/doc/sprites.txt
index d1b85ac..c2483c4 100644
--- a/lib/lp/services/doc/sprites.txt
+++ b/lib/lp/services/doc/sprites.txt
@@ -116,9 +116,9 @@ changes without requiring the combined image file to be recreated.
The positions attribute can be cleared and loaded from the file.
>>> print pretty(sprite_util.positions)
- {u'../images/add.png': (0, -114),
- u'../images/blue-bar.png': (0, -342),
- u'../images/edit.png': (0, -228)}
+ {'../images/add.png': (0, -114),
+ '../images/blue-bar.png': (0, -342),
+ '../images/edit.png': (0, -228)}
>>> sprite_util.positions = None
>>> sprite_util.loadPositioning(new_positioning_file.name)
>>> print pretty(sprite_util.positions)
diff --git a/lib/lp/testing/pages.py b/lib/lp/testing/pages.py
index 2efabd0..e620147 100644
--- a/lib/lp/testing/pages.py
+++ b/lib/lp/testing/pages.py
@@ -13,7 +13,6 @@ import doctest
from io import BytesIO
from itertools import chain
import os
-import pprint
import re
import unittest
@@ -85,6 +84,7 @@ from lp.testing.factory import LaunchpadObjectFactory
from lp.testing.layers import PageTestLayer
from lp.testing.systemdocs import (
LayeredDocFileSuite,
+ PrettyPrinter,
stop,
)
@@ -876,7 +876,7 @@ def setUpGlobs(test, future=False):
test.globs['logout'] = logout
test.globs['parse_relationship_section'] = parse_relationship_section
test.globs['permissive_security_policy'] = permissive_security_policy
- test.globs['pretty'] = pprint.PrettyPrinter(width=1).pformat
+ test.globs['pretty'] = PrettyPrinter(width=1).pformat
test.globs['print_action_links'] = print_action_links
test.globs['print_errors'] = print_errors
test.globs['print_location'] = print_location
diff --git a/lib/lp/testing/systemdocs.py b/lib/lp/testing/systemdocs.py
index 3fb72bf..706fa75 100644
--- a/lib/lp/testing/systemdocs.py
+++ b/lib/lp/testing/systemdocs.py
@@ -9,6 +9,7 @@ __metaclass__ = type
__all__ = [
'default_optionflags',
'LayeredDocFileSuite',
+ 'PrettyPrinter',
'setUp',
'setGlobs',
'stop',
@@ -212,6 +213,33 @@ def stop():
sys.stdout = old_stdout
+class PrettyPrinter(pprint.PrettyPrinter, object):
+ """A pretty-printer that formats text in the Python 3 style.
+
+ This should only be used when the resulting ambiguity between str and
+ unicode representation on Python 2 is not a problem.
+ """
+
+ def format(self, obj, contexts, maxlevels, level):
+ if isinstance(obj, six.text_type):
+ obj = obj.encode('unicode_escape').decode('ASCII')
+ if "'" in obj and '"' not in obj:
+ return '"%s"' % obj, True, False
+ else:
+ return "'%s'" % obj.replace("'", "\\'"), True, False
+ else:
+ return super(PrettyPrinter, self).format(
+ obj, contexts, maxlevels, level)
+
+ # Disable wrapping of long strings on Python >= 3.5, which is unhelpful
+ # in doctests. There seems to be no reasonable public API for this.
+ if sys.version_info[:2] >= (3, 5):
+ _dispatch = dict(pprint.PrettyPrinter._dispatch)
+ del _dispatch[six.text_type.__repr__]
+ del _dispatch[bytes.__repr__]
+ del _dispatch[bytearray.__repr__]
+
+
# XXX cjwatson 2018-05-13: Once all doctests are made safe for the standard
# __future__ imports, the `future=True` behaviour should become
# unconditional.
@@ -230,7 +258,7 @@ def setGlobs(test, future=False):
test.globs['factory'] = LaunchpadObjectFactory()
test.globs['ordered_dict_as_string'] = ordered_dict_as_string
test.globs['verifyObject'] = verifyObject
- test.globs['pretty'] = pprint.PrettyPrinter(width=1).pformat
+ test.globs['pretty'] = PrettyPrinter(width=1).pformat
test.globs['stop'] = stop
test.globs['launchpadlib_for'] = launchpadlib_for
test.globs['launchpadlib_credentials_for'] = launchpadlib_credentials_for