launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #26391
[Merge] ~cjwatson/launchpad:py3-services-webapp-doctests-future-imports into launchpad:master
Colin Watson has proposed merging ~cjwatson/launchpad:py3-services-webapp-doctests-future-imports into launchpad:master.
Commit message:
Convert lp.services.webapp doctests to __future__ imports
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/+git/launchpad/+merge/398506
--
Your team Launchpad code reviewers is requested to review the proposed merge of ~cjwatson/launchpad:py3-services-webapp-doctests-future-imports into launchpad:master.
diff --git a/lib/lp/services/webapp/doc/canonical_url.txt b/lib/lp/services/webapp/doc/canonical_url.txt
index 2730fa2..b08a560 100644
--- a/lib/lp/services/webapp/doc/canonical_url.txt
+++ b/lib/lp/services/webapp/doc/canonical_url.txt
@@ -16,7 +16,8 @@ will put in a temporary module.
>>> from lp.services.webapp.interfaces import ICanonicalUrlData
>>> from zope.interface import Interface, Attribute, implementer
- >>> module = types.ModuleType(factory.getUniqueString().replace('-', '_'))
+ >>> module = types.ModuleType(
+ ... six.ensure_str(factory.getUniqueString().replace('-', '_')))
>>> sys.modules[module.__name__] = module
>>> class ICountrySet(Interface):
@@ -101,7 +102,7 @@ Configure a browser:url for ITown. Our first attempt fails because we mistyped
>>> from zope.configuration import xmlconfig
>>> zcmlcontext = xmlconfig.string("""
... <configure xmlns:browser="http://namespaces.zope.org/browser">
- ... <include package="zope.component" file="meta.zcml" />
+ ... <include package="zope.component" file="meta.zcml" />
... <include package="lp.services.webapp" file="meta.zcml" />
... <browser:url
... for="{module_name}.ITown"
@@ -171,8 +172,8 @@ Now, there is an ICanonicalUrlData registered for ICountry.
>>> from lp.testing import verifyObject
>>> verifyObject(ICanonicalUrlData, country_urldata)
True
- >>> country_urldata.path
- 'England'
+ >>> print(country_urldata.path)
+ England
>>> country_urldata.inside is countryset_instance
True
@@ -222,8 +223,8 @@ Now, there is an ICanonicalUrlData registered for ICountrySet.
>>> from lp.testing import verifyObject
>>> verifyObject(ICanonicalUrlData, countryset_urldata)
True
- >>> countryset_urldata.path
- 'countries'
+ >>> print(countryset_urldata.path)
+ countries
>>> countryset_urldata.inside is getUtility(ILaunchpadRoot)
True
@@ -260,7 +261,7 @@ and the objects it is inside of (or in other words, hierarchically below).
We can see that this is the mainsite rooturl as configured in launchpad.conf.
>>> from lp.services.webapp.vhosts import allvhosts
- >>> print allvhosts.configs['mainsite'].rooturl
+ >>> print(allvhosts.configs['mainsite'].rooturl)
http://launchpad.test/
If anywhere in the chain we have an object that cannot be adapted to
@@ -311,7 +312,7 @@ First, let's define a helper function to help us test canonical_url_iterator.
>>> def print_url_iterator(obj):
... for obj in canonical_url_iterator(obj):
- ... print obj.__class__.__name__
+ ... print(obj.__class__.__name__)
>>> print_url_iterator(getUtility(ILaunchpadRoot))
RootObject
@@ -432,7 +433,7 @@ And if the configuration does provide a rootsite:
... <configure
... xmlns="http://namespaces.zope.org/zope"
... xmlns:browser="http://namespaces.zope.org/browser">
- ... <include package="zope.component" file="meta.zcml" />
+ ... <include package="zope.component" file="meta.zcml" />
... <include package="lp.services.webapp" file="meta.zcml" />
... <utility
... provides="{module_name}.ICountrySet"
@@ -503,7 +504,7 @@ canonical url chain that provides at least one of the interfaces given.
True
>>> nearest(town_instance, ICountry) is country_instance
True
- >>> print nearest(unrooted_object, ICountry)
+ >>> print(nearest(unrooted_object, ICountry))
None
diff --git a/lib/lp/services/webapp/doc/canonical_url_examples.txt b/lib/lp/services/webapp/doc/canonical_url_examples.txt
index ec107a5..761581b 100644
--- a/lib/lp/services/webapp/doc/canonical_url_examples.txt
+++ b/lib/lp/services/webapp/doc/canonical_url_examples.txt
@@ -354,7 +354,7 @@ Set up example Branch Merge Proposal
Branch merge proposals should have a canonical URL. (Based on their source
branch.)
- >>> print canonical_url(merge_proposal)
+ >>> print(canonical_url(merge_proposal))
http://code.launchpad.test/~name12/gnome-terminal/main/+merge/...
Create example CodeReviewComment.
@@ -365,7 +365,7 @@ Create example CodeReviewComment.
CodeReviewComment should have a canonical URL. (It should extend the URL of
the merge proposal)
- >>> print canonical_url(comment)
+ >>> print(canonical_url(comment))
http://code....test/~name12/gnome-terminal/main/+merge/.../comments/...
@@ -377,7 +377,7 @@ that they import to.
>>> from lp.code.interfaces.codeimport import ICodeImportSet
>>> code_import = getUtility(ICodeImportSet).get(1)
- >>> print canonical_url(code_import)
+ >>> print(canonical_url(code_import))
http://code.launchpad.test/~vcs-imports/gnome-terminal/import/+code-import
Specifications
diff --git a/lib/lp/services/webapp/doc/canonicalurl.txt b/lib/lp/services/webapp/doc/canonicalurl.txt
index 75a67b3..547954e 100644
--- a/lib/lp/services/webapp/doc/canonicalurl.txt
+++ b/lib/lp/services/webapp/doc/canonicalurl.txt
@@ -62,11 +62,11 @@ directions.
>>> from lp.services.webapp.canonicalurl import (nearest_adapter,
... nearest_context_with_adapter)
- >>> print nearest_adapter(root, ICookingDirections)
+ >>> print(nearest_adapter(root, ICookingDirections))
None
- >>> print nearest_adapter(cookbook, ICookingDirections)
+ >>> print(nearest_adapter(cookbook, ICookingDirections))
None
- >>> print nearest_adapter(recipe, ICookingDirections)
+ >>> print(nearest_adapter(recipe, ICookingDirections))
None
The same holds true for nearest_context_with_adapter():
@@ -88,26 +88,26 @@ that has the requested adaptation.
"recipe" does not provide ICookingDirections, but "cookbook" does, so
cookbook's adapter will be returned.
- >>> print nearest_adapter(recipe, ICookingDirections)
+ >>> print(nearest_adapter(recipe, ICookingDirections))
<...CookingDirections ...>
We can verify that the adapter is actually for the Cookbook using
nearest_adapter_with_context().
- >>> print nearest_context_with_adapter(recipe, ICookingDirections)
+ >>> print(nearest_context_with_adapter(recipe, ICookingDirections))
(<...Cookbook ...>, <...CookingDirections ...>)
Calling nearest_adapter() on "cookbook" itself will return the
CookingDirections:
- >>> print nearest_adapter(cookbook, ICookingDirections)
+ >>> print(nearest_adapter(cookbook, ICookingDirections))
<...CookingDirections ...>
Calling nearest_adapter() on the hierarchy root returns nothing:
the root does not have the requested adaptation, and there are no higher
objects to search.
- >>> print nearest_adapter(root, ICookingDirections)
+ >>> print(nearest_adapter(root, ICookingDirections))
None
@@ -130,7 +130,7 @@ First we need a named adapter to use:
>>> provideAdapter(LabelledCookbook, [ICookbook], ILabelledCookbook,
... name='foo')
- >>> print queryAdapter(cookbook, ILabelledCookbook)
+ >>> print(queryAdapter(cookbook, ILabelledCookbook))
None
>>> queryAdapter(cookbook, ILabelledCookbook, name='foo')
<...LabelledCookbook ...>
@@ -145,14 +145,14 @@ For a recipe, this is the adapter for the cookbook:
We can verify that the adapter is for the Cookbook using
nearest_context_with_adapter():
- >>> print nearest_context_with_adapter(
- ... recipe, ILabelledCookbook, name='foo')
+ >>> print(nearest_context_with_adapter(
+ ... recipe, ILabelledCookbook, name='foo'))
(<...Cookbook ...>, <...LabelledCookbook ...>)
And we can see that the adapter is not returned if we omit the 'name'
keyword argument:
- >>> print nearest_adapter(recipe, ILabelledCookbook)
+ >>> print(nearest_adapter(recipe, ILabelledCookbook))
None
If we search for the adapter on the cookbook object, the lookup works as
@@ -163,5 +163,5 @@ expected:
And searching for the adapter on the root object returns nothing:
- >>> print nearest_adapter(root, ILabelledCookbook, name='foo')
+ >>> print(nearest_adapter(root, ILabelledCookbook, name='foo'))
None
diff --git a/lib/lp/services/webapp/doc/launchbag.txt b/lib/lp/services/webapp/doc/launchbag.txt
index f846331..d5bb810 100644
--- a/lib/lp/services/webapp/doc/launchbag.txt
+++ b/lib/lp/services/webapp/doc/launchbag.txt
@@ -35,7 +35,7 @@ First, we'll set up various imports and stub objects.
There have been no logins, so launchbag.login will be None.
>>> launchbag = getUtility(ILaunchBag)
->>> print launchbag.login
+>>> print(launchbag.login)
None
Let's send a basic auth login event.
@@ -47,19 +47,19 @@ Let's send a basic auth login event.
Now, launchbag.login will be 'foo.bar@xxxxxxxxxxxxx'.
->>> print launchbag.login
+>>> print(launchbag.login)
foo.bar@xxxxxxxxxxxxx
Login should be set back to None on a logout.
>>> event = LoggedOutEvent(request)
>>> notify(event)
->>> print launchbag.login
+>>> print(launchbag.login)
None
'user' will also be set to None:
->>> print launchbag.user
+>>> print(launchbag.user)
None
Let's do a cookie auth principal identification. In this case, the login
@@ -68,7 +68,7 @@ will be cookie@xxxxxxxxxxx.
>>> event = CookieAuthPrincipalIdentifiedEvent(
... principal, request, 'cookie@xxxxxxxxxxx')
>>> notify(event)
->>> print launchbag.login
+>>> print(launchbag.login)
cookie@xxxxxxxxxxx
diff --git a/lib/lp/services/webapp/doc/menus.txt b/lib/lp/services/webapp/doc/menus.txt
index ada19bd..620a889 100644
--- a/lib/lp/services/webapp/doc/menus.txt
+++ b/lib/lp/services/webapp/doc/menus.txt
@@ -78,16 +78,16 @@ defined in ILink and IFacetLink.
>>> ILinkData.providedBy(no_summary_link)
True
- >>> no_summary_link.target
- 'target'
+ >>> print(no_summary_link.target)
+ target
- >>> no_summary_link.text
- 'text -->'
+ >>> print(no_summary_link.text)
+ text -->
- >>> print no_summary_link.summary
+ >>> print(no_summary_link.summary)
None
- >>> print no_summary_link.icon
+ >>> print(no_summary_link.icon)
None
>>> no_summary_link.enabled
@@ -103,17 +103,17 @@ mark is as being "structured".
>>> ILinkData.providedBy(full_link)
True
- >>> full_link.target
- 'target'
+ >>> print(full_link.target)
+ target
>>> full_link.text
<structured-string 'some <b>%s</b> text'>
- >>> full_link.summary
- 'summary'
+ >>> print(full_link.summary)
+ summary
- >>> full_link.icon
- 'icon'
+ >>> print(full_link.icon)
+ icon
>>> full_link.enabled
False
@@ -142,11 +142,11 @@ not shared or reused.
>>> link2 = Link('target', 'text', 'summary', icon='icon', enabled=False)
>>> for menu_link in ILink(link1), IFacetLink(link2):
- ... print menu_link.name, menu_link.url, menu_link.linked
+ ... print(menu_link.name, menu_link.url, menu_link.linked)
... menu_link.name = 'name'
... menu_link.url = 'url'
... menu_link.linked = False
- ... print menu_link.name, menu_link.url, menu_link.linked
+ ... print(menu_link.name, menu_link.url, menu_link.linked)
None None True
name url False
None None True
@@ -209,9 +209,9 @@ We can go through each attribute of each of the links, checking that
they are as we expect.
>>> for link in facetmenu.iterlinks():
- ... print '--- link %s ---' % link.name
+ ... print('--- link %s ---' % link.name)
... for attrname in sorted(IFacetLink.names(all=True)):
- ... print '%s: %s' % (attrname, getattr(link, attrname))
+ ... print('%s: %s' % (attrname, getattr(link, attrname)))
--- link foo ---
enabled: True
escapedtext: Foo
@@ -277,17 +277,17 @@ links.
>>> IFacetLink.providedBy(adaptedtolink)
False
- >>> adaptedtolink.target
- 'target'
+ >>> print(adaptedtolink.target)
+ target
- >>> adaptedtolink.text
- 'text'
+ >>> print(adaptedtolink.text)
+ text
- >>> adaptedtolink.summary
- 'summary'
+ >>> print(adaptedtolink.summary)
+ summary
- >>> adaptedtolink.icon
- 'icon'
+ >>> print(adaptedtolink.icon)
+ icon
>>> adaptedtolink.enabled
True
@@ -333,7 +333,7 @@ Next, we return the link as HTML.
>>> login(ANONYMOUS, request)
>>> link = Link('+target', 'text-->', 'summary', icon='icon')
- >>> print ILink(link).render() #doctest: +NORMALIZE_WHITESPACE
+ >>> print(ILink(link).render()) #doctest: +NORMALIZE_WHITESPACE
<a class="menu-link-None sprite icon" title="summary">text--></a>
# Clean up our special login.
@@ -342,7 +342,7 @@ Next, we return the link as HTML.
A menu item can be marked as hidden even though it is enabled.
>>> link = Link('z', 'text', 'summary', icon='icon', hidden=True)
- >>> print ILink(link).render() #doctest: +NORMALIZE_WHITESPACE
+ >>> print(ILink(link).render()) #doctest: +NORMALIZE_WHITESPACE
<a class="menu-link-None sprite icon hidden" title="summary">text</a>
@@ -352,8 +352,8 @@ A link will be selected if its name is passed to the facet menu's
iterlinks method, or otherwise, if its name is the defaultlink.
>>> for link in facetmenu.iterlinks(selectedfacetname='bar'):
- ... print '--- link %s ---' % link.name
- ... print 'selected:', link.selected
+ ... print('--- link %s ---' % link.name)
+ ... print('selected:', link.selected)
--- link foo ---
selected: False
--- link bar ---
@@ -363,8 +363,8 @@ When a link name is passed in, but no link of that name is in the menu,
it is not an error. No link is selected.
>>> for link in facetmenu.iterlinks(selectedfacetname='nosuchname'):
- ... print '--- link %s ---' % link.name
- ... print 'selected:', link.selected
+ ... print('--- link %s ---' % link.name)
+ ... print('selected:', link.selected)
--- link foo ---
selected: False
--- link bar ---
@@ -375,8 +375,8 @@ selected.
>>> facetmenu.defaultlink = 'foo'
>>> for link in facetmenu.iterlinks():
- ... print '--- link %s ---' % link.name
- ... print 'selected:', link.selected
+ ... print('--- link %s ---' % link.name)
+ ... print('selected:', link.selected)
--- link foo ---
selected: True
--- link bar ---
@@ -386,8 +386,8 @@ Now, 'foo' is still the default, but 'bar' has been selected. So only
'bar' will be selected.
>>> for link in facetmenu.iterlinks(selectedfacetname='bar'):
- ... print '--- link %s ---' % link.name
- ... print 'selected:', link.selected
+ ... print('--- link %s ---' % link.name)
+ ... print('selected:', link.selected)
--- link foo ---
selected: False
--- link bar ---
@@ -397,8 +397,8 @@ We still have 'foo' as the default. This time, 'nosuchlink' has been
selected. As there is no such link, nothing will be selected.
>>> for link in facetmenu.iterlinks(selectedfacetname='nosuchlink'):
- ... print '--- link %s ---' % link.name
- ... print 'selected:', link.selected
+ ... print('--- link %s ---' % link.name)
+ ... print('selected:', link.selected)
--- link foo ---
selected: False
--- link bar ---
@@ -455,9 +455,9 @@ We can go through each attribute of each of the links, checking that
they are as we expect.
>>> for link in housefooappmenu.iterlinks():
- ... print '--- link %s ---' % link.name
+ ... print('--- link %s ---' % link.name)
... for attrname in sorted(ILink.names(all=True)):
- ... print '%s: %s' % (attrname, getattr(link, attrname))
+ ... print('%s: %s' % (attrname, getattr(link, attrname)))
--- link first ---
enabled: True
escapedtext: First menu
@@ -522,9 +522,9 @@ We can go through each attribute of each of the links, checking that
they are as we expect.
>>> for link in housefoocontextmenu.iterlinks():
- ... print '--- link %s ---' % link.name
+ ... print('--- link %s ---' % link.name)
... for attrname in sorted(ILink.names(all=True)):
- ... print '%s: %s' % (attrname, getattr(link, attrname))
+ ... print('%s: %s' % (attrname, getattr(link, attrname)))
--- link first ---
enabled: True
escapedtext: First context menu item
@@ -551,7 +551,8 @@ First, we define a couple of interfaces, and put them in a temporary module.
>>> import sys
>>> import types
- >>> module = types.ModuleType(factory.getUniqueString().replace('-', '_'))
+ >>> module = types.ModuleType(
+ ... six.ensure_str(factory.getUniqueString().replace('-', '_')))
>>> sys.modules[module.__name__] = module
>>> class IThingHavingFacets(Interface):
@@ -616,12 +617,12 @@ We also need to check that we have no IApplicationMenu adapter named
... class SomeOtherThing:
... pass
>>> something_with_menus = SomeOtherThing()
- >>> print queryAdapter(something_with_menus, IApplicationMenu, 'foo')
+ >>> print(queryAdapter(something_with_menus, IApplicationMenu, 'foo'))
None
Same for an IContextMenu adapter.
- >>> print queryAdapter(something_with_menus, IContextMenu, 'foo')
+ >>> print(queryAdapter(something_with_menus, IContextMenu, 'foo'))
None
>>> from zope.configuration import xmlconfig
@@ -725,7 +726,7 @@ link should appear linked. The request is also set as the menu's
>>> links = test_tales('view/menu:facet', view=view)
>>> for link in links:
- ... print link.url, link.selected, link.linked, link.summary
+ ... print(link.url, link.selected, link.linked, link.summary)
http://launchpad.test/sesamestreet/+foo False True None
http://launchpad.test/sesamestreet/+bar True False More explanation about
Bar of sesamestreet
@@ -742,7 +743,7 @@ Let's try again, this time with a request from the participation.
>>> links = test_tales('context/menu:facet', context=house)
>>> for link in links:
- ... print link.url, link.selected, link.linked
+ ... print(link.url, link.selected, link.linked)
http://launchpad.test/sesamestreet/+foo False True
http://launchpad.test/sesamestreet/+bar False False
http://launchpad.test/sesamestreet False True
@@ -772,8 +773,8 @@ name.
... url1='http://launchpad.test/sesamestreet/')
>>> from zope.publisher.defaultview import getDefaultViewName
- >>> getDefaultViewName(street, request)
- '+baz'
+ >>> print(getDefaultViewName(street, request))
+ +baz
So, in this example, the last link should not be 'linked' because it is
equivalent to the default view name for a street. The TALES
@@ -783,7 +784,7 @@ infrastructure actually calculates a shortened URL for this case.
>>> view.__launchpad_facetname__ = 'bar'
>>> links = test_tales('view/menu:facet', view=view)
>>> for link in links:
- ... print link.url, link.linked
+ ... print(link.url, link.linked)
http://launchpad.test/sesamestreet/+foo True
http://launchpad.test/sesamestreet/+bar True
http://launchpad.test/sesamestreet False
@@ -795,7 +796,7 @@ You can traverse to an individual menu item from the facet menu:
>>> view = LaunchpadView(house, request)
>>> view.__launchpad_facetname__ = 'bar'
>>> link = test_tales('view/menu:foo/first', view=view, request=request)
- >>> print link.url
+ >>> print(link.url)
http://launchpad.test/sesamestreet/number73/+first
But if a non-existing entry is requested, a KeyError is raised:
@@ -821,13 +822,13 @@ object.
>>> links = test_tales('view/menu:context', view=view)
>>> for link in links.values():
- ... print link.url
+ ... print(link.url)
http://launchpad.test/sesamestreet/number73/+firstcontext
The link is also reachable by name:
>>> link = test_tales('context/menu:context/first', context=house)
- >>> print link.url
+ >>> print(link.url)
http://launchpad.test/sesamestreet/number73/+firstcontext
When there is no menu for a thing, we get an empty iterator.
@@ -864,7 +865,7 @@ render() method.
>>> html = test_tales('context/menu:foo/first/render',
... context=house, view=view, request=request)
- >>> print html #doctest: +NORMALIZE_WHITESPACE
+ >>> print(html) #doctest: +NORMALIZE_WHITESPACE
<a...class="menu-link-first"
...href="http://127.0.0.1/sesamestreet/number73/+first">First menu</a>
@@ -903,8 +904,8 @@ If we're logged in as an anonymous user, then the link will be disabled.
>>> login(ANONYMOUS)
>>> foolink = somemenu.foo()
- >>> foolink.text
- 'Admin the foo'
+ >>> print(foolink.text)
+ Admin the foo
>>> foolink.enabled
False
diff --git a/lib/lp/services/webapp/doc/navigation.txt b/lib/lp/services/webapp/doc/navigation.txt
index cd96dcf..6a09124 100644
--- a/lib/lp/services/webapp/doc/navigation.txt
+++ b/lib/lp/services/webapp/doc/navigation.txt
@@ -287,8 +287,8 @@ This time, we get the view object for the page that was registered.
>>> navigation.publishTraverse(request, 'thingview')
<...ThingSetView object...>
- >>> navigation.publishTraverse(request, 'thingview')()
- 'a view on a thingset'
+ >>> print(navigation.publishTraverse(request, 'thingview')())
+ a view on a thingset
== stepto traversals ==
@@ -328,10 +328,10 @@ Let's create a subclass of ThingSetNavigation, and add a 'stepto'.
>>> navigation2.publishTraverse(request, 'ttt')
<Thing 'TTT'>
- >>> navigation2.publishTraverse(request, 'thingview')()
- 'a view on a thingset'
- >>> navigation2.publishTraverse(request, 'thistle')
- 'A little thistle'
+ >>> print(navigation2.publishTraverse(request, 'thingview')())
+ a view on a thingset
+ >>> print(navigation2.publishTraverse(request, 'thistle'))
+ A little thistle
>>> navigation2.publishTraverse(request, 'neverthere')
... # doctest: +IGNORE_EXCEPTION_MODULE_IN_PYTHON2
Traceback (most recent call last):
@@ -379,8 +379,8 @@ Let's create another subclass and add a stepthrough.
>>> request.traversal_stack = ['prince', 'charming']
>>> navigation3 = ThingSetNavigation3(thingset, request)
- >>> navigation3.publishTraverse(request, 'toad')
- 'the toad called charming'
+ >>> print(navigation3.publishTraverse(request, 'toad'))
+ the toad called charming
>>> request.traversal_stack = ['prince', 'charming']
>>> navigation3 = ThingSetNavigation3(thingset, request)
>>> navigation3.publishTraverse(request, 'neverland')
@@ -399,7 +399,7 @@ Let's create another subclass and add a stepthrough.
Check that the request's state is as it should be.
- >>> request.traversal_stack
+ >>> print(pretty(request.traversal_stack))
['prince']
@@ -457,38 +457,38 @@ Let's make another navigation class to test redirection.
<...RedirectionView...>
>>> print(navigation4.publishTraverse(request, 'tree')())
<BLANKLINE>
- >>> request.response.redirected_to
- 'trees'
- >>> print request.response.status
+ >>> print(request.response.redirected_to)
+ trees
+ >>> print(request.response.status)
301
>>> print(navigation4.publishTraverse(request, 'toad')())
<BLANKLINE>
- >>> request.response.redirected_to
- 'toads'
- >>> print request.response.status
+ >>> print(request.response.redirected_to)
+ toads
+ >>> print(request.response.status)
None
>>> print(navigation4.publishTraverse(request, 'something')())
<BLANKLINE>
- >>> request.response.redirected_to
- '/another/place'
- >>> print request.response.status
+ >>> print(request.response.redirected_to)
+ /another/place
+ >>> print(request.response.status)
301
>>> request.traversal_stack = ['tundra']
>>> print(navigation4.publishTraverse(request, 'outerspace')())
<BLANKLINE>
- >>> request.response.redirected_to
- '/siberia/tundra'
- >>> print request.response.status
+ >>> print(request.response.redirected_to)
+ /siberia/tundra
+ >>> print(request.response.status)
None
>>> print(navigation4.publishTraverse(request, 'here')())
<BLANKLINE>
- >>> request.response.redirected_to
- '/there'
- >>> print request.response.status
+ >>> print(request.response.redirected_to)
+ /there
+ >>> print(request.response.status)
301
@@ -511,18 +511,18 @@ with the remainder of the URL and or query string.
<...RedirectionView...>
>>> print(navigation5.publishTraverse(request, 'jobs')())
<BLANKLINE>
- >>> request.response.redirected_to
- 'http://ubuntu.com/jobs'
- >>> print request.response.status
+ >>> print(request.response.redirected_to)
+ http://ubuntu.com/jobs
+ >>> print(request.response.status)
301
>>> request.traversal_stack = ['LaunchpadMeeting']
>>> request.query_string = 'hilight=Time'
>>> print(navigation5.publishTraverse(request, '+foo')())
<BLANKLINE>
- >>> request.response.redirected_to
- 'http://wiki.canonical.com/LaunchpadMeeting?hilight=Time'
- >>> print request.response.status
+ >>> print(request.response.redirected_to)
+ http://wiki.canonical.com/LaunchpadMeeting?hilight=Time
+ >>> print(request.response.status)
303
@@ -565,36 +565,36 @@ so far, and also defining some more stepthroughs and steptos and redirections.
Check out the traversals defined directly.
- >>> ubernav.publishTraverse(request, 'teeth')
- 'some teeth'
+ >>> print(ubernav.publishTraverse(request, 'teeth'))
+ some teeth
>>> ubernav.publishTraverse(request, 'diplodocus')
<...RedirectionView...>
>>> request.traversal_stack = ['frank']
- >>> ubernav.publishTraverse(request, 'diplodocus')
- 'diplodocus called frank'
+ >>> print(ubernav.publishTraverse(request, 'diplodocus'))
+ diplodocus called frank
>>> print(ubernav.publishTraverse(request, 'topology')())
<BLANKLINE>
- >>> request.response.redirected_to
- 'topologies'
+ >>> print(request.response.redirected_to)
+ topologies
Check those from ThingSetNavigation, implicitly:
- >>> ubernav.publishTraverse(request, 'thingview')()
- 'a view on a thingset'
+ >>> print(ubernav.publishTraverse(request, 'thingview')())
+ a view on a thingset
Check those from ThingSetNavigation2:
- >>> ubernav.publishTraverse(request, 'thistle')
- 'A little thistle'
+ >>> print(ubernav.publishTraverse(request, 'thistle'))
+ A little thistle
Check those from ThingSetNavigation3:
>>> request.traversal_stack = ['prince', 'charming']
- >>> ubernav.publishTraverse(request, 'toad')
- 'the toad called charming'
+ >>> print(ubernav.publishTraverse(request, 'toad'))
+ the toad called charming
>>> request.traversal_stack = []
@@ -602,18 +602,18 @@ Check those from ThingSetNavigation4:
>>> print(ubernav.publishTraverse(request, 'tree')())
<BLANKLINE>
- >>> request.response.redirected_to
- 'trees'
+ >>> print(request.response.redirected_to)
+ trees
>>> print(ubernav.publishTraverse(request, 'toad')())
<BLANKLINE>
- >>> request.response.redirected_to
- 'toads'
+ >>> print(request.response.redirected_to)
+ toads
>>> print(ubernav.publishTraverse(request, 'ttt')())
<BLANKLINE>
- >>> request.response.redirected_to
- '/another/place'
+ >>> print(request.response.redirected_to)
+ /another/place
== Testing that multiple inheritance involving decorators works ==
@@ -645,14 +645,14 @@ Check those from ThingSetNavigation4:
... return 'foo2 from C'
>>> instance_of_c = C(thingset, request)
- >>> instance_of_c.publishTraverse(request, 'foo')
- 'foo'
- >>> instance_of_c.publishTraverse(request, 'bar')
- 'bar'
- >>> instance_of_c.publishTraverse(request, 'baz')
- 'baz'
- >>> instance_of_c.publishTraverse(request, 'foo2')
- 'foo2 from C'
+ >>> print(instance_of_c.publishTraverse(request, 'foo'))
+ foo
+ >>> print(instance_of_c.publishTraverse(request, 'bar'))
+ bar
+ >>> print(instance_of_c.publishTraverse(request, 'baz'))
+ baz
+ >>> print(instance_of_c.publishTraverse(request, 'foo2'))
+ foo2 from C
== Showing that the name of the function really doesn't matter ==
@@ -668,12 +668,12 @@ Check those from ThingSetNavigation4:
... return 'bar'
>>> instance_of_dupenames = DupeNames(thingset, request)
- >>> instance_of_dupenames.publishTraverse(request, 'foo')
- 'foo'
- >>> instance_of_dupenames.publishTraverse(request, 'bar')
- 'bar'
+ >>> print(instance_of_dupenames.publishTraverse(request, 'foo'))
+ foo
+ >>> print(instance_of_dupenames.publishTraverse(request, 'bar'))
+ bar
The doit_*() methods still work though.
- >>> instance_of_dupenames.doit_bar()
- 'bar'
+ >>> print(instance_of_dupenames.doit_bar())
+ bar
diff --git a/lib/lp/services/webapp/doc/notification-text-escape.txt b/lib/lp/services/webapp/doc/notification-text-escape.txt
index 3275f9b..ad6b26f 100644
--- a/lib/lp/services/webapp/doc/notification-text-escape.txt
+++ b/lib/lp/services/webapp/doc/notification-text-escape.txt
@@ -25,7 +25,7 @@ unchanged:
>>> response = new_response()
>>> response.addNotification('clean')
>>> for notification in response.notifications:
- ... print notification.message
+ ... print(notification.message)
clean
But text containing markup is CGI-escaped:
diff --git a/lib/lp/services/webapp/doc/renamed-view.txt b/lib/lp/services/webapp/doc/renamed-view.txt
index 5d12bec..2b125a1 100644
--- a/lib/lp/services/webapp/doc/renamed-view.txt
+++ b/lib/lp/services/webapp/doc/renamed-view.txt
@@ -33,7 +33,7 @@ update bookmarks.
<BLANKLINE>
>>> request.response.getStatus()
301
- >>> print request.response.getHeader('Location')
+ >>> print(request.response.getHeader('Location'))
http://launchpad.test/ubuntu/+questions
The view can also work for names registered on the root, and the
@@ -46,7 +46,7 @@ new_name can be a relative path.
<BLANKLINE>
>>> request.response.getStatus()
301
- >>> print view.request.response.getHeader('Location')
+ >>> print(view.request.response.getHeader('Location'))
http://launchpad.test/+tour/index.html
@@ -60,7 +60,7 @@ to the redirected URL.
>>> view = RenamedView(ubuntu, request, '+questions')
>>> print(view())
<BLANKLINE>
- >>> print request.response.getHeader('Location')
+ >>> print(request.response.getHeader('Location'))
http://launchpad.test/ubuntu/+questions?field.status=Open
@@ -74,7 +74,7 @@ change the virtual host used for the redirection.
... ubuntu, request, '+questions', rootsite='answers')
>>> print(view())
<BLANKLINE>
- >>> print request.response.getHeader('Location')
+ >>> print(request.response.getHeader('Location'))
http://answers.launchpad.test/ubuntu/+questions
@@ -117,5 +117,5 @@ browser:renamed-page is available for this purpose.
>>> view = getMultiAdapter((ubuntu, request), name='+old_tickets_page')
>>> print(view())
<BLANKLINE>
- >>> print request.response.getHeader('Location')
+ >>> print(request.response.getHeader('Location'))
http://answers.launchpad.test/ubuntu/+questions
diff --git a/lib/lp/services/webapp/doc/test_adapter.txt b/lib/lp/services/webapp/doc/test_adapter.txt
index d91cfb2..bd8d2e0 100644
--- a/lib/lp/services/webapp/doc/test_adapter.txt
+++ b/lib/lp/services/webapp/doc/test_adapter.txt
@@ -27,7 +27,7 @@ IStoreSelector utility.
>>> store = getUtility(IStoreSelector).get(MAIN_STORE, MASTER_FLAVOR)
>>> dbname = DatabaseLayer._db_fixture.dbname
>>> active_name = store.execute("SELECT current_database()").get_one()[0]
- >>> if active_name != dbname: print '%s != %s' % (active_name, dbname)
+ >>> if active_name != dbname: print('%s != %s' % (active_name, dbname))
>>> active_name == dbname
True
@@ -63,7 +63,7 @@ correctly, especially for the case of LIKE which uses % characters.
>>> store.execute("SELECT * FROM person where name like '%d foo'||'%%'",
... noresult=True)
>>> for _, _, _, statement, _ in get_request_statements():
- ... print statement
+ ... print(statement)
SELECT 1
SELECT 2
SELECT * FROM person where name = E'fred'
@@ -78,7 +78,7 @@ A timeline is created too:
>>> for action in timeline.actions:
... if not action.category.startswith("SQL-"):
... continue
- ... print action.detail
+ ... print(action.detail)
SELECT 1
SELECT 2
SELECT * FROM person where name = E'fred'
@@ -104,7 +104,7 @@ statements.
>>> store.execute('SELECT 2', noresult=True)
>>> store.execute('SELECT 3', noresult=True)
>>> for _, _, _, statement, _ in get_request_statements():
- ... print statement
+ ... print(statement)
SELECT 2
SELECT 3
>>> clear_request_started()
@@ -120,7 +120,7 @@ that aborted transactions are still in the status "Active".
>>> store.execute('SELECT 3', noresult=True)
>>> transaction.abort()
>>> for _, _, _, statement, _ in get_request_statements():
- ... print statement
+ ... print(statement)
SELECT 1
SELECT 2
Transaction completed, status: Committed
@@ -135,7 +135,7 @@ it pass.
>>> import warnings
>>> with warnings.catch_warnings(record=True) as no_request_warning:
... clear_request_started()
- >>> print no_request_warning[0].message
+ >>> print(no_request_warning[0].message)
clear_request_started() called outside of a request
Some requests are expected to log actions with very large details, such as
@@ -151,7 +151,7 @@ memory on logging.
>>> store.execute('SELECT 1', noresult=True)
>>> transaction.abort()
>>> for _, _, _, statement, _ in get_request_statements():
- ... print statement
+ ... print(statement)
<redacted>
Transaction completed, status: Active
>>> clear_request_started()
@@ -163,7 +163,7 @@ Statement Timeout
The timeout is set in launchpad.conf file. By default it is unset,
which corresponds to no timeout:
- >>> print config.database.db_statement_timeout
+ >>> print(config.database.db_statement_timeout)
None
@@ -193,7 +193,7 @@ the Postgres statement timeout (a value of zero means no timeout):
... store = getUtility(IStoreSelector).get(MAIN_STORE, MASTER_FLAVOR)
>>> set_request_started()
- >>> print current_statement_timeout(store)
+ >>> print(current_statement_timeout(store))
0ms
>>> clear_request_started()
@@ -209,9 +209,9 @@ timeout by sleeping for 200ms with a 100ms statement timeout:
>>> config.push('base_test_data', test_data)
>>> reset_store()
>>> set_request_started()
- >>> print current_statement_timeout(store)
+ >>> print(current_statement_timeout(store))
100ms
- >>> store.execute('SELECT pg_sleep(0.200)', noresult=True)
+ >>> store.execute(six.ensure_str('SELECT pg_sleep(0.200)'), noresult=True)
... # doctest: +IGNORE_EXCEPTION_MODULE_IN_PYTHON2
Traceback (most recent call last):
...
@@ -219,7 +219,7 @@ timeout by sleeping for 200ms with a 100ms statement timeout:
Even though the statement timed out, it is recorded in the statement log:
- >>> print get_request_statements()[-1][3]
+ >>> print(get_request_statements()[-1][3])
SELECT pg_sleep(0.200)
>>> clear_request_started()
@@ -229,7 +229,7 @@ set_request_started() is called in scripts.
>>> reset_store()
>>> set_request_started(enable_timeout=False)
- >>> print current_statement_timeout(store)
+ >>> print(current_statement_timeout(store))
0ms
>>> store.execute('SELECT pg_sleep(0.200)', noresult=True)
>>> clear_request_started()
@@ -261,12 +261,12 @@ to fake how long things take.
>>> set_request_started()
>>> store.execute('SELECT TRUE', noresult=True)
- >>> print current_statement_timeout(store)
+ >>> print(current_statement_timeout(store))
10000ms
>>> time_travel(0.5) # Forward in time 0.5 seconds
>>> store.execute('SELECT TRUE', noresult=True)
- >>> print current_statement_timeout(store)
+ >>> print(current_statement_timeout(store))
10000ms
>>> time_travel(0.6) # Forward in time 0.6 seconds, now over precision
@@ -274,7 +274,7 @@ This invokation, the PostgreSQL statement timeout will be updated before
issuing the SQL command as we have exceeded the precision period:
>>> store.execute('SELECT TRUE', noresult=True)
- >>> print current_statement_timeout(store)
+ >>> print(current_statement_timeout(store))
8900ms
>>> time_travel(8.89) # 0.01s remaining before hard timeout
@@ -282,7 +282,7 @@ issuing the SQL command as we have exceeded the precision period:
This final invokation, we will actually sleep to ensure that the
timeout being reported by PostgreSQL is actually working:
- >>> store.execute('SELECT pg_sleep(0.2)', noresult=True)
+ >>> store.execute(six.ensure_str('SELECT pg_sleep(0.2)'), noresult=True)
... # doctest: +IGNORE_EXCEPTION_MODULE_IN_PYTHON2
Traceback (most recent call last):
...
@@ -299,7 +299,7 @@ Set the timeout to 5000ms for the next tests:
>>> config.push('test', test_data)
>>> reset_store()
>>> set_request_started()
- >>> print current_statement_timeout(store)
+ >>> print(current_statement_timeout(store))
5000ms
>>> clear_request_started()
@@ -436,13 +436,13 @@ The Launchpad store uses lp.services.config to configure its
connection. This can be adjusted by choosing a different database
config section. By default we connect as "launchpad"
- >>> print store.execute("select current_user").get_one()[0]
+ >>> print(store.execute("select current_user").get_one()[0])
launchpad_main
>>> from lp.services.config import dbconfig
>>> dbconfig.override(dbuser='statistician')
>>> reset_store()
- >>> print store.execute("select current_user").get_one()[0]
+ >>> print(store.execute("select current_user").get_one()[0])
statistician
>>> store.execute("""
... INSERT INTO SourcePackageName(name) VALUES ('fnord4')
@@ -455,7 +455,7 @@ config section. By default we connect as "launchpad"
This is not reset at the end of the transaction:
>>> transaction.abort()
- >>> print store.execute("select current_user").get_one()[0]
+ >>> print(store.execute("select current_user").get_one()[0])
statistician
>>> store.execute("""
... INSERT INTO SourcePackageName(name) VALUES ('fnord4')
@@ -470,7 +470,7 @@ So you need to explicitly set the user back to the default:
>>> dbconfig.override(dbuser=None)
>>> reset_store()
- >>> print store.execute("select current_user").get_one()[0]
+ >>> print(store.execute("select current_user").get_one()[0])
launchpad_main
>>> store.execute("""
... INSERT INTO SourcePackageName(name) VALUES ('fnord4')
diff --git a/lib/lp/services/webapp/doc/test_adapter_timeout.txt.disabled b/lib/lp/services/webapp/doc/test_adapter_timeout.txt.disabled
index b2fe604..c1955cf 100644
--- a/lib/lp/services/webapp/doc/test_adapter_timeout.txt.disabled
+++ b/lib/lp/services/webapp/doc/test_adapter_timeout.txt.disabled
@@ -91,12 +91,12 @@ Now we actually demonstrate the behaviour. The view did raise a TimeoutError.
The exception view did not.
- >>> print timeout_in_exception_view
+ >>> print(timeout_in_exception_view)
False
The OOPS has the SQL from the main view.
- >>> print oops_capture.oopses[-1]['timeline']
+ >>> print(oops_capture.oopses[-1]['timeline'])
[(0, 0, 'SELECT ... FROM ... WHERE ...'), ...]
All that's left is to clean up after ourselves.
diff --git a/lib/lp/services/webapp/doc/timeout.txt b/lib/lp/services/webapp/doc/timeout.txt
index 9a80f1d..102eb93 100644
--- a/lib/lp/services/webapp/doc/timeout.txt
+++ b/lib/lp/services/webapp/doc/timeout.txt
@@ -98,7 +98,7 @@ and a TimeoutError is never raised.
... [database]
... db_statement_timeout = None'''))
- >>> print timeout_func()
+ >>> print(timeout_func())
None
>>> wait_a_little()
diff --git a/lib/lp/services/webapp/doc/uri.txt b/lib/lp/services/webapp/doc/uri.txt
index c356db0..d76f851 100644
--- a/lib/lp/services/webapp/doc/uri.txt
+++ b/lib/lp/services/webapp/doc/uri.txt
@@ -15,23 +15,23 @@ security proxies.
We can access the various URI components:
- >>> print proxied_uri1.scheme
+ >>> print(proxied_uri1.scheme)
http
- >>> print proxied_uri1.userinfo
+ >>> print(proxied_uri1.userinfo)
None
- >>> print proxied_uri1.host
+ >>> print(proxied_uri1.host)
a
- >>> print proxied_uri1.port
+ >>> print(proxied_uri1.port)
None
- >>> print proxied_uri1.path
+ >>> print(proxied_uri1.path)
/b/c/d;p
- >>> print proxied_uri1.query
+ >>> print(proxied_uri1.query)
q
- >>> print proxied_uri1.fragment
+ >>> print(proxied_uri1.fragment)
None
- >>> print proxied_uri1.authority
+ >>> print(proxied_uri1.authority)
a
- >>> print proxied_uri1.hier_part
+ >>> print(proxied_uri1.hier_part)
//a/b/c/d;p
We can test for equality:
@@ -55,19 +55,19 @@ Similarly, inequality can be checked:
We can get the string value and representation of a URI:
- >>> print str(proxied_uri1)
+ >>> print(str(proxied_uri1))
http://a/b/c/d;p?q
- >>> print repr(proxied_uri1)
+ >>> print(repr(proxied_uri1))
URI('http://a/b/c/d;p?q')
We can replace components:
- >>> print proxied_uri1.replace(scheme='https')
+ >>> print(proxied_uri1.replace(scheme='https'))
https://a/b/c/d;p?q
We can append a component:
- >>> print proxied_uri1.append('e/f')
+ >>> print(proxied_uri1.append('e/f'))
http://a/b/c/d;p/e/f
We can check for containment:
@@ -80,7 +80,7 @@ We can check for containment:
We can create a URI that ensures it has or does not have a trailing
slash:
- >>> print proxied_uri1.ensureSlash()
+ >>> print(proxied_uri1.ensureSlash())
http://a/b/c/d;p/?q
- >>> print proxied_uri1.ensureNoSlash()
+ >>> print(proxied_uri1.ensureNoSlash())
http://a/b/c/d;p?q
diff --git a/lib/lp/services/webapp/doc/webapp-publication.txt b/lib/lp/services/webapp/doc/webapp-publication.txt
index fa178cd..8af06ab 100644
--- a/lib/lp/services/webapp/doc/webapp-publication.txt
+++ b/lib/lp/services/webapp/doc/webapp-publication.txt
@@ -31,10 +31,10 @@ These are parsed into webapp.vhost.allvhosts.
>>> allvhosts.use_https
False
>>> for confname, vhost in sorted(allvhosts.configs.items()):
- ... print confname, '@', vhost.hostname
- ... print 'rooturl:', vhost.rooturl
- ... print 'althosts:', (', '.join(vhost.althostnames))
- ... print '----'
+ ... print(confname, '@', vhost.hostname)
+ ... print('rooturl:', vhost.rooturl)
+ ... print('althosts:', (', '.join(vhost.althostnames)))
+ ... print('----')
answers @ answers.launchpad.test
rooturl: http://answers.launchpad.test/
althosts:
@@ -85,7 +85,7 @@ collected into a set. This provides a quick way to determine if a
request is headed to one of the officialy-used Launchpad host names:
>>> for hostname in sorted(allvhosts.hostnames):
- ... print hostname
+ ... print(hostname)
answers.launchpad.test
api.launchpad.test
blueprints.launchpad.test
@@ -162,7 +162,7 @@ canHandle() by saving the environment to a thread-local variable. This
information is retrieved later on, in __call__().
>>> for key, value in sorted(factory._thread_local.environment.items()):
- ... print '%s: %s' % (key, value)
+ ... print('%s: %s' % (key, value))
HTTP_HOST: launchpad.test
REQUEST_METHOD: GET
SERVER_PORT: 1234
@@ -459,13 +459,13 @@ less nice.
>>> logout()
>>> from lp.testing.pages import http
- >>> print http("GET / HTTP/1.1\n"
- ... "Host: nosuchhost.launchpad.test")
+ >>> print(http("GET / HTTP/1.1\n"
+ ... "Host: nosuchhost.launchpad.test"))
HTTP/1.1 404 Not Found
...
- >>> print http("GET /foo/bar HTTP/1.1\n"
- ... "Host: xmlrpc.launchpad.test")
+ >>> print(http("GET /foo/bar HTTP/1.1\n"
+ ... "Host: xmlrpc.launchpad.test"))
HTTP/1.1 405 Method Not Allowed
Allow: POST
...
@@ -580,7 +580,7 @@ no value was submitted with the field.
All the submitted field names can be iterated over:
>>> for name in sorted(request.form_ng):
- ... print name
+ ... print(name)
a_field
items_field
@@ -622,7 +622,7 @@ name of the context class and the view class name.
>>> view = TestView(TestContext(), request)
>>> publication.beforeTraversal(request)
>>> publication.afterTraversal(request, view)
- >>> print request._orig_env['launchpad.pageid']
+ >>> print(request._orig_env['launchpad.pageid'])
TestContext:TestView
>>> from lp.services.webapp.adapter import (
... clear_request_started, set_request_started)
@@ -875,7 +875,7 @@ The user attribute is an empty string, when no user is logged in.
>>> import transaction
>>> txn = transaction.begin()
>>> request, publication = get_request_and_publication()
- >>> print request.principal
+ >>> print(request.principal)
None
# Our afterCall() implementation expects to find _publication_start and
@@ -885,7 +885,7 @@ The user attribute is an empty string, when no user is logged in.
>>> request._publication_start = 1.345
>>> request._publication_thread_start = None
>>> publication.afterCall(request, None)
- >>> print txn.user
+ >>> print(txn.user)
<BLANKLINE>
But if there is a logged in user, the transaction user attribute will
@@ -900,7 +900,7 @@ allowing different authentication based on the traversed objects):
16
>>> request.setPrincipal(foo_bar)
>>> publication.afterCall(request, None)
- >>> print txn.user
+ >>> print(txn.user)
/ 16
@@ -918,7 +918,7 @@ some string in its finishReadOnlyRequest().
>>> class MyPublication(LaunchpadBrowserPublication):
... def finishReadOnlyRequest(self, request, ob, txn):
- ... print "booo!"
+ ... print("booo!")
>>> publication = MyPublication(None)
>>> publication.afterCall(request, None)
@@ -938,7 +938,7 @@ be automatically reverted in a GET request.
... Person.id == EmailAddress.personID,
... EmailAddress.email == 'foo.bar@xxxxxxxxxxxxx').one()
>>> foo_bar = get_foo_bar_person()
- >>> print foo_bar.description
+ >>> print(foo_bar.description)
None
>>> foo_bar.description = 'Montreal'
@@ -953,7 +953,7 @@ be automatically reverted in a GET request.
>>> publication.afterCall(request, None)
>>> txn = transaction.begin()
>>> foo_bar = get_foo_bar_person()
- >>> print foo_bar.description
+ >>> print(foo_bar.description)
None
But not if the request uses POST, the changes will be preserved.
@@ -971,7 +971,7 @@ But not if the request uses POST, the changes will be preserved.
>>> request._publication_thread_start = None
>>> publication.afterCall(request, None)
>>> txn = transaction.begin()
- >>> print get_foo_bar_person().description
+ >>> print(get_foo_bar_person().description)
Darwin
@@ -988,7 +988,7 @@ Doomed transactions are aborted.
>>> bound_abort = txn.abort
>>> def faux_abort():
... bound_abort()
- ... print 'Aborted'
+ ... print('Aborted')
...
>>> txn.abort = faux_abort
@@ -1064,7 +1064,7 @@ In other cases, like a GET, the body would be unchanged.
>>> request._publication_start = 1.345
>>> request._publication_thread_start = None
>>> publication.afterCall(request, None)
- >>> print request.response.consumeBody()
+ >>> print(request.response.consumeBody())
Some boring content.
@@ -1107,7 +1107,7 @@ utility to setup the request.
>>> request, publication = get_request_and_publication(
... extra_environment=dict(HTTP_AUTHORIZATION=foo_bar_auth))
>>> principal = publication.getPrincipal(request)
- >>> print principal.title
+ >>> print(principal.title)
Foo Bar
The feeds implementation always returns the anonymous user.
@@ -1152,7 +1152,7 @@ token.
... extra_environment=dict(QUERY_STRING=urlencode(form)))
>>> test_request.processInputs()
>>> principal = publication.getPrincipal(test_request)
- >>> print principal.title
+ >>> print(principal.title)
Guilherme Salgado
>>> principal.access_level
<DBItem AccessLevel.WRITE_PUBLIC...
diff --git a/lib/lp/services/webapp/doc/zcmldirectives.txt b/lib/lp/services/webapp/doc/zcmldirectives.txt
index 71b14e4..e70ceed 100644
--- a/lib/lp/services/webapp/doc/zcmldirectives.txt
+++ b/lib/lp/services/webapp/doc/zcmldirectives.txt
@@ -101,14 +101,14 @@ its __launchpad_facetname__ attribute.
>>> cls = get_simplelaunchpadviewclass(context.actions)
>>> cls
<class 'zope.browserpage.metaconfigure.SimpleLaunchpadViewClass'>
- >>> cls.__launchpad_facetname__
- 'FACET'
+ >>> print(cls.__launchpad_facetname__)
+ FACET
Next, a functional/integration test of the overridden directive.
- >>> print queryMultiAdapter((fooobject, request), name='+whatever')
+ >>> print(queryMultiAdapter((fooobject, request), name='+whatever'))
None
- >>> print queryMultiAdapter((fooobject, request), name='+mandrill')
+ >>> print(queryMultiAdapter((fooobject, request), name='+mandrill'))
None
>>> from zope.configuration import xmlconfig
@@ -139,16 +139,16 @@ Next, a functional/integration test of the overridden directive.
>>> whatever_view = queryMultiAdapter(
... (fooobject, request), name='+whatever')
- >>> print whatever_view.__class__.__name__
+ >>> print(whatever_view.__class__.__name__)
FooView
- >>> print whatever_view.__launchpad_facetname__
+ >>> print(whatever_view.__launchpad_facetname__)
the_evil_facet
>>> mandrill_view = queryMultiAdapter(
... (fooobject, request), name='+mandrill')
- >>> print mandrill_view.__class__.__name__
+ >>> print(mandrill_view.__class__.__name__)
SimpleViewClass from ...base-layout.pt
- >>> print mandrill_view.__launchpad_facetname__
+ >>> print(mandrill_view.__launchpad_facetname__)
another-mister-lizard
@@ -184,17 +184,17 @@ its __launchpad_facetname__ attribute.
>>> cls = get_simplelaunchpadviewclass(context.actions)
>>> cls
<class 'zope.browserpage.metaconfigure.SimpleLaunchpadViewClass'>
- >>> cls.__launchpad_facetname__
- 'FACET'
+ >>> print(cls.__launchpad_facetname__)
+ FACET
>>> cls2 = context.actions[3][2][1]
>>> cls2
<class 'zope.browserpage.metaconfigure.SimpleLaunchpadViewClass'>
- >>> cls2.__launchpad_facetname__
- 'OUTERFACET'
+ >>> print(cls2.__launchpad_facetname__)
+ OUTERFACET
Next, a functional/integration test of the overridden directive.
- >>> print queryMultiAdapter((fooobject, request), name='+whatever2')
+ >>> print(queryMultiAdapter((fooobject, request), name='+whatever2'))
None
>>> zcmlcontext = xmlconfig.string("""
@@ -222,16 +222,16 @@ Next, a functional/integration test of the overridden directive.
>>> whatever2_view = queryMultiAdapter(
... (fooobject, request), name='+whatever2')
- >>> print whatever2_view.__class__.__name__
+ >>> print(whatever2_view.__class__.__name__)
FooView
- >>> print whatever2_view.__launchpad_facetname__
+ >>> print(whatever2_view.__launchpad_facetname__)
another_evil_facet
>>> whatever3_view = queryMultiAdapter(
... (fooobject, request), name='+whatever3')
- >>> print whatever3_view.__class__.__name__
+ >>> print(whatever3_view.__class__.__name__)
FooView
- >>> print whatever3_view.__launchpad_facetname__
+ >>> print(whatever3_view.__launchpad_facetname__)
outerspace
@@ -248,12 +248,12 @@ Name some variables to mirror the names used as arguments.
>>> facet = 'whole-file-facet'
>>> gc = GroupingFacet(context, facet=facet)
- >>> gc.facet
- 'whole-file-facet'
+ >>> print(gc.facet)
+ whole-file-facet
Next, a functional/integration test of the overridden directive.
- >>> print queryMultiAdapter((fooobject, request), name='+impliedfacet')
+ >>> print(queryMultiAdapter((fooobject, request), name='+impliedfacet'))
None
>>> zcmlcontext = xmlconfig.string("""
@@ -277,9 +277,9 @@ Next, a functional/integration test of the overridden directive.
>>> impliedfacet_view = queryMultiAdapter(
... (fooobject, request), name='+impliedfacet')
- >>> print impliedfacet_view.__class__.__name__
+ >>> print(impliedfacet_view.__class__.__name__)
FooView
- >>> print impliedfacet_view.__launchpad_facetname__
+ >>> print(impliedfacet_view.__launchpad_facetname__)
whole-facet
diff --git a/lib/lp/services/webapp/servers.py b/lib/lp/services/webapp/servers.py
index 0bd6152..d1e17fe 100644
--- a/lib/lp/services/webapp/servers.py
+++ b/lib/lp/services/webapp/servers.py
@@ -3,6 +3,8 @@
"""Definition of the internet servers that Launchpad uses."""
+from __future__ import absolute_import, print_function
+
__metaclass__ = type
import threading
@@ -137,19 +139,19 @@ class StepsToGo(six.Iterator):
False
>>> len(stepstogo)
3
- >>> print stepstogo.consume()
+ >>> print(stepstogo.consume())
foo
>>> request._traversed_names
['foo']
>>> request.stack
['baz', 'bar']
- >>> print stepstogo.consume()
+ >>> print(stepstogo.consume())
bar
>>> bool(stepstogo)
True
- >>> print stepstogo.consume()
+ >>> print(stepstogo.consume())
baz
- >>> print stepstogo.consume()
+ >>> print(stepstogo.consume())
None
>>> bool(stepstogo)
False
diff --git a/lib/lp/services/webapp/sorting.py b/lib/lp/services/webapp/sorting.py
index 6d34142..052c669 100644
--- a/lib/lp/services/webapp/sorting.py
+++ b/lib/lp/services/webapp/sorting.py
@@ -3,6 +3,8 @@
"""This module contains sorting utility functions."""
+from __future__ import absolute_import, print_function
+
__metaclass__ = type
__all__ = ['expand_numbers',
'sorted_version_numbers',
diff --git a/lib/lp/services/webapp/tests/cookie-authentication.txt b/lib/lp/services/webapp/tests/cookie-authentication.txt
index 503ba9d..9f73e5d 100644
--- a/lib/lp/services/webapp/tests/cookie-authentication.txt
+++ b/lib/lp/services/webapp/tests/cookie-authentication.txt
@@ -5,8 +5,8 @@ so it cannot tell that it will end up overwriting the existing cookie.
>>> from lp.testing.layers import BaseLayer
>>> feeds_root_url = BaseLayer.appserver_root_url('feeds')
>>> browser.open('%s/announcements.atom' % feeds_root_url)
- >>> browser.vhost
- 'http://feeds.launchpad.test'
+ >>> print(browser.vhost)
+ http://feeds.launchpad.test
>>> browser.urlpath
'/announcements.atom'
>>> len(browser.cookies)
@@ -21,14 +21,14 @@ are sent to other vhosts in the same domain.
# On a browser with JS support, this page would've been automatically
# submitted (thanks to the onload handler), but testbrowser doesn't
# support JS, so we have to submit the form manually.
- >>> print browser.contents
+ >>> print(browser.contents)
<html>...<body onload="document.forms[0].submit();"...
>>> browser.getControl('Continue').click()
>>> from lp.services.webapp.tests.test_login import (
... fill_login_form_and_submit)
>>> fill_login_form_and_submit(browser, 'foo.bar@xxxxxxxxxxxxx')
- >>> print extract_text(find_tag_by_id(browser.contents, 'logincontrol'))
+ >>> print(extract_text(find_tag_by_id(browser.contents, 'logincontrol')))
Foo Bar (name16) ...
# Open a page again so that we see the cookie for a launchpad.test request
@@ -46,11 +46,11 @@ If we visit another vhost in the domain, we remain logged in.
>>> root_url = BaseLayer.appserver_root_url()
>>> browser.open(root_url)
- >>> browser.vhost
- 'http://launchpad.test'
+ >>> print(browser.vhost)
+ http://launchpad.test
>>> browser.urlpath
'/'
- >>> print extract_text(find_tag_by_id(browser.contents, 'logincontrol'))
+ >>> print(extract_text(find_tag_by_id(browser.contents, 'logincontrol')))
Foo Bar (name16) ...
>>> browser.cookies.getinfo(session_cookie_name)['domain']
'.launchpad.test'
@@ -58,11 +58,11 @@ If we visit another vhost in the domain, we remain logged in.
Even if the browser passes in a cookie, the feeds vhost should not set one.
>>> browser.open('%s/announcements.atom' % feeds_root_url)
- >>> browser.vhost
- 'http://feeds.launchpad.test'
+ >>> print(browser.vhost)
+ http://feeds.launchpad.test
>>> browser.urlpath
'/announcements.atom'
- >>> print browser.headers.get('Set-Cookie')
+ >>> print(browser.headers.get('Set-Cookie'))
None
# XXX stub 20060816 bug=56601: We need to test that for https: URLs, the
diff --git a/lib/lp/services/webapp/tests/login.txt b/lib/lp/services/webapp/tests/login.txt
index 5b81348..156b5d2 100644
--- a/lib/lp/services/webapp/tests/login.txt
+++ b/lib/lp/services/webapp/tests/login.txt
@@ -20,13 +20,13 @@ link, they'll be sent to the OP to authenticate.
# On a browser with JS support, this page would've been automatically
# submitted (thanks to the onload handler), but testbrowser doesn't support
# JS, so we have to submit the form manually.
- >>> print browser.contents
+ >>> print(browser.contents)
<html>...<body onload="document.forms[0].submit();"...
>>> browser.getControl('Continue').click()
The OpenID Provider will ask us to authenticate.
- >>> print browser.title
+ >>> print(browser.title)
Login
>>> from lp.services.webapp.tests.test_login import (
... fill_login_form_and_submit)
@@ -35,19 +35,19 @@ The OpenID Provider will ask us to authenticate.
Once authenticated, we're redirected back to the page where we started, with
the query args preserved.
- >>> browser.vhost
- 'http://launchpad.test'
+ >>> print(browser.vhost)
+ http://launchpad.test
>>> browser.urlpath
'/people'
>>> import re
- >>> print sorted(re.sub('.*\?', '', browser.url).split('&'))
+ >>> print(pretty(sorted(re.sub('.*\?', '', browser.url).split('&'))))
['name=foo', 'searchfor=all']
If we load the +login page while already logged in, it will say we're already
logged in and ask us to log out if we're somebody else.
>>> browser.open('%s/+login' % root_url)
- >>> print extract_text(find_main_content(browser.contents))
+ >>> print(extract_text(find_main_content(browser.contents)))
You are already logged in...
The same thing works if the user has non-ASCII characters in their display
@@ -69,16 +69,16 @@ name.
>>> browser.open(
... '%s/people/?name=foo&searchfor=all' % root_url)
>>> browser.getLink('Log in / Register').click()
- >>> print browser.contents
+ >>> print(browser.contents)
<html>...<body onload="document.forms[0].submit();"...
>>> browser.getControl('Continue').click()
- >>> print browser.title
+ >>> print(browser.title)
Login
>>> fill_login_form_and_submit(browser, 'unicode@xxxxxxxxxxx')
- >>> browser.vhost
- 'http://launchpad.test'
+ >>> print(browser.vhost)
+ http://launchpad.test
>>> browser.urlpath
'/people'
>>> import re
- >>> print sorted(re.sub('.*\?', '', browser.url).split('&'))
+ >>> print(pretty(sorted(re.sub('.*\?', '', browser.url).split('&'))))
['name=foo', 'searchfor=all']
diff --git a/lib/lp/services/webapp/tests/no-anonymous-session-cookies.txt b/lib/lp/services/webapp/tests/no-anonymous-session-cookies.txt
index 441d5e9..a7d8df5 100644
--- a/lib/lp/services/webapp/tests/no-anonymous-session-cookies.txt
+++ b/lib/lp/services/webapp/tests/no-anonymous-session-cookies.txt
@@ -23,14 +23,14 @@ Now let's log in and show that the session cookie is set.
# On a browser with JS support, this page would've been automatically
# submitted (thanks to the onload handler), but testbrowser doesn't
# support JS, so we have to submit the form manually.
- >>> print browser.contents
+ >>> print(browser.contents)
<html>...<body onload="document.forms[0].submit();"...
>>> browser.getControl('Continue').click()
>>> from lp.services.webapp.tests.test_login import (
... fill_login_form_and_submit)
>>> fill_login_form_and_submit(browser, 'foo.bar@xxxxxxxxxxxxx')
- >>> print extract_text(find_tag_by_id(browser.contents, 'logincontrol'))
+ >>> print(extract_text(find_tag_by_id(browser.contents, 'logincontrol')))
Foo Bar (name16) ...
# Open a page again so that we see the cookie for a launchpad.test request
diff --git a/lib/lp/services/webapp/tests/test_authentication.py b/lib/lp/services/webapp/tests/test_authentication.py
index a348b0b..ff8036d 100644
--- a/lib/lp/services/webapp/tests/test_authentication.py
+++ b/lib/lp/services/webapp/tests/test_authentication.py
@@ -100,5 +100,6 @@ def test_suite():
suite = unittest.TestLoader().loadTestsFromName(__name__)
suite.addTest(LayeredDocFileSuite(
'test_launchpad_login_source.txt',
- layer=LaunchpadFunctionalLayer, setUp=setUp, tearDown=tearDown))
+ layer=LaunchpadFunctionalLayer,
+ setUp=lambda test: setUp(test, future=True), tearDown=tearDown))
return suite
diff --git a/lib/lp/services/webapp/tests/test_doc.py b/lib/lp/services/webapp/tests/test_doc.py
index 7af6c91..b4e50d8 100644
--- a/lib/lp/services/webapp/tests/test_doc.py
+++ b/lib/lp/services/webapp/tests/test_doc.py
@@ -29,7 +29,7 @@ here = os.path.dirname(os.path.realpath(__file__))
special = {
'canonical_url.txt': LayeredDocFileSuite(
'../doc/canonical_url.txt',
- setUp=setUp, tearDown=tearDown,
+ setUp=lambda test: setUp(test, future=True), tearDown=tearDown,
layer=FunctionalLayer,),
'notification-text-escape.txt': LayeredDocFileSuite(
'../doc/notification-text-escape.txt',
@@ -38,23 +38,27 @@ special = {
stdout_logging=False, layer=None),
'test_adapter.txt': LayeredDocFileSuite(
'../doc/test_adapter.txt',
- setUp=setGlobs, layer=LaunchpadFunctionalLayer),
+ setUp=lambda test: setGlobs(test, future=True),
+ layer=LaunchpadFunctionalLayer),
# XXX Julian 2009-05-13, bug=376171
# Temporarily disabled because of intermittent failures.
# 'test_adapter_timeout.txt': LayeredDocFileSuite(
# '../doc/test_adapter_timeout.txt',
-# setUp=setUp,
+# setUp=lambda test: setUp(test, future=True),
# tearDown=tearDown,
# layer=LaunchpadFunctionalLayer),
'test_adapter_permissions.txt': LayeredDocFileSuite(
'../doc/test_adapter_permissions.txt',
+ setUp=lambda test: setGlobs(test, future=True),
layer=LaunchpadFunctionalLayer),
'uri.txt': LayeredDocFileSuite(
'../doc/uri.txt',
- setUp=setUp, tearDown=tearDown,
+ setUp=lambda test: setUp(test, future=True), tearDown=tearDown,
layer=FunctionalLayer),
}
def test_suite():
- return build_test_suite(here, special, layer=LaunchpadFunctionalLayer)
+ return build_test_suite(
+ here, special, setUp=lambda test: setUp(test, future=True),
+ layer=LaunchpadFunctionalLayer)
diff --git a/lib/lp/services/webapp/tests/test_launchpad_login_source.txt b/lib/lp/services/webapp/tests/test_launchpad_login_source.txt
index 27a520c..b574c5d 100644
--- a/lib/lp/services/webapp/tests/test_launchpad_login_source.txt
+++ b/lib/lp/services/webapp/tests/test_launchpad_login_source.txt
@@ -8,7 +8,7 @@ person is found with the given email address, None is returned
>>> from lp.services.webapp.authentication import (
... LaunchpadLoginSource)
>>> login_source = LaunchpadLoginSource()
- >>> print login_source.getPrincipalByLogin('no-such-email@xxxxxxxxxxx')
+ >>> print(login_source.getPrincipalByLogin('no-such-email@xxxxxxxxxxx'))
None
Giving getPrincipalByLogin() an existing email address, returns a
diff --git a/lib/lp/services/webapp/tests/test_notifications.py b/lib/lp/services/webapp/tests/test_notifications.py
index d3f48ee..1b9b335 100644
--- a/lib/lp/services/webapp/tests/test_notifications.py
+++ b/lib/lp/services/webapp/tests/test_notifications.py
@@ -7,6 +7,7 @@ from __future__ import absolute_import, print_function
__metaclass__ = type
+import __future__
from doctest import DocTestSuite
import unittest
@@ -86,6 +87,8 @@ def setUp(test):
lambda x: mock_browser_request, (INotificationRequest,),
IBrowserRequest)
+ for future_item in 'absolute_import', 'print_function':
+ test.globs[future_item] = getattr(__future__, future_item)
test.globs['MockResponse'] = MockHTTPApplicationResponse
test.globs['structured'] = structured
diff --git a/lib/lp/services/webapp/tests/test_preferredcharsets.py b/lib/lp/services/webapp/tests/test_preferredcharsets.py
index 0c5f57e..a350a3b 100644
--- a/lib/lp/services/webapp/tests/test_preferredcharsets.py
+++ b/lib/lp/services/webapp/tests/test_preferredcharsets.py
@@ -5,9 +5,13 @@
__metaclass__ = type
-from lp.testing.systemdocs import LayeredDocFileSuite
+from lp.testing.systemdocs import (
+ LayeredDocFileSuite,
+ setGlobs,
+ )
def test_suite():
return LayeredDocFileSuite(
- 'test_preferredcharsets.txt')
+ 'test_preferredcharsets.txt',
+ setUp=lambda test: setGlobs(test, future=True))
diff --git a/lib/lp/testing/browser.py b/lib/lp/testing/browser.py
index 7bacfbe..aed02bc 100644
--- a/lib/lp/testing/browser.py
+++ b/lib/lp/testing/browser.py
@@ -9,11 +9,14 @@ child process. The Zope testing browser fakes its connections in-process, so
that's not good enough.
"""
+from __future__ import absolute_import, print_function, unicode_literals
+
__metaclass__ = type
__all__ = [
'setUp',
]
+import __future__
import ssl
from lazr.uri import URI
@@ -32,6 +35,7 @@ from lp.testing.pages import (
find_tag_by_id,
print_feedback_messages,
)
+from lp.testing.systemdocs import PrettyPrinter
class Browser(_Browser):
@@ -68,9 +72,12 @@ class Browser(_Browser):
def setUp(test):
"""Set up appserver tests."""
+ for future_item in 'absolute_import', 'print_function', 'unicode_literals':
+ test.globs[future_item] = getattr(__future__, future_item)
test.globs['Browser'] = Browser
test.globs['browser'] = Browser()
test.globs['find_tag_by_id'] = find_tag_by_id
test.globs['find_main_content'] = find_main_content
test.globs['print_feedback_messages'] = print_feedback_messages
test.globs['extract_text'] = extract_text
+ test.globs['pretty'] = PrettyPrinter(width=1).pformat