launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #27756
[Merge] ~cjwatson/launchpad:pyupgrade-py3-answers into launchpad:master
Colin Watson has proposed merging ~cjwatson/launchpad:pyupgrade-py3-answers into launchpad:master.
Commit message:
lp.answers: Apply "pyupgrade --py3-plus"
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/+git/launchpad/+merge/412173
This is mostly a proof of concept in applying changes like this in a way that doesn't require changing the whole codebase at once, but it seems workable enough.
--
Your team Launchpad code reviewers is requested to review the proposed merge of ~cjwatson/launchpad:pyupgrade-py3-answers into launchpad:master.
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 4042766..34ba814 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -34,6 +34,11 @@ repos:
- id: pyupgrade
args: [--keep-percent-format]
exclude: ^lib/contrib/
+ - id: pyupgrade
+ alias: pyupgrade-py3
+ name: pyupgrade (--py3-plus)
+ args: [--keep-percent-format, --py3-plus]
+ files: ^lib/lp/answers/
- repo: https://github.com/PyCQA/isort
rev: 5.9.2
hooks:
diff --git a/lib/lp/answers/browser/faqcollection.py b/lib/lp/answers/browser/faqcollection.py
index 0c2734f..a32ebca 100644
--- a/lib/lp/answers/browser/faqcollection.py
+++ b/lib/lp/answers/browser/faqcollection.py
@@ -85,8 +85,8 @@ class SearchFAQsView(LaunchpadFormView):
displayname=self.context.displayname,
search_text=self.search_text)
if self.search_text:
- return _(u'FAQs matching \u201c${search_text}\u201d for '
- u'$displayname', mapping=replacements)
+ return _('FAQs matching \u201c${search_text}\u201d for '
+ '$displayname', mapping=replacements)
else:
return _('FAQs for $displayname', mapping=replacements)
@@ -99,8 +99,8 @@ class SearchFAQsView(LaunchpadFormView):
displayname=self.context.displayname,
search_text=self.search_text)
if self.search_text:
- return _(u'There are no FAQs for $displayname matching '
- u'\u201c${search_text}\u201d.', mapping=replacements)
+ return _('There are no FAQs for $displayname matching '
+ '\u201c${search_text}\u201d.', mapping=replacements)
else:
return _('There are no FAQs for $displayname.',
mapping=replacements)
diff --git a/lib/lp/answers/browser/question.py b/lib/lp/answers/browser/question.py
index 82560a8..a72083e 100644
--- a/lib/lp/answers/browser/question.py
+++ b/lib/lp/answers/browser/question.py
@@ -1251,7 +1251,7 @@ class SearchAllQuestionsView(SearchQuestionsView):
Saves the user submitted search parameters in an instance
attribute and redirects to questions when the term is a question id.
"""
- super(SearchAllQuestionsView, self).search_action.success(data)
+ super().search_action.success(data)
if not self.search_text:
return
@@ -1292,7 +1292,7 @@ class QuestionCreateFAQView(LinkFAQMixin, LaunchpadFormView):
Adds a message field to the form.
"""
- super(QuestionCreateFAQView, self).setUpFields()
+ super().setUpFields()
self.form_fields += form.Fields(
copy_field(IQuestionLinkFAQForm['message']))
self.form_fields['message'].field.title = _(
@@ -1341,7 +1341,7 @@ class SearchableFAQRadioWidget(LaunchpadRadioWidget):
def renderValue(self, value):
"""Render the widget with the value."""
- content = super(SearchableFAQRadioWidget, self).renderValue(value)
+ content = super().renderValue(value)
return "<br />".join([content, self.renderSearchWidget()])
def renderItemsWithValues(self, values):
@@ -1413,7 +1413,7 @@ class SearchableFAQRadioWidget(LaunchpadRadioWidget):
type='radio')
if selected:
attributes['checked'] = 'checked'
- input = renderElement(u'input', **attributes)
+ input = renderElement('input', **attributes)
button = structured(
'<label style="font-weight: normal">%s %s:</label>',
structured(input), term.token)
@@ -1472,7 +1472,7 @@ class QuestionLinkFAQView(LinkFAQMixin, LaunchpadFormView):
def setUpWidgets(self):
"""Set the query on the search widget to the question title."""
- super(QuestionLinkFAQView, self).setUpWidgets()
+ super().setUpWidgets()
self.widgets['faq'].default_query = self.context.title
def validate(self, data):
diff --git a/lib/lp/answers/browser/questiontarget.py b/lib/lp/answers/browser/questiontarget.py
index d039539..57d8caa 100644
--- a/lib/lp/answers/browser/questiontarget.py
+++ b/lib/lp/answers/browser/questiontarget.py
@@ -341,11 +341,11 @@ class SearchQuestionsView(UserSupportLanguagesMixin, LaunchpadFormView):
if len(language_counts) == 0:
return ''
url = canonical_url(self.context, rootsite='answers')
- format = (u'%s in <a href="' + url + u'/+by-language'
- u'?field.language=%s&field.status=Open">%s</a>')
+ format = ('%s in <a href="' + url + '/+by-language'
+ '?field.language=%s&field.status=Open">%s</a>')
links = [format % (language_counts[key], key.code, key.englishname)
for key in language_counts]
- return u', '.join(links)
+ return ', '.join(links)
@property
def empty_listing_message(self):
diff --git a/lib/lp/answers/browser/tests/test_breadcrumbs.py b/lib/lp/answers/browser/tests/test_breadcrumbs.py
index 070cb67..cca8dd6 100644
--- a/lib/lp/answers/browser/tests/test_breadcrumbs.py
+++ b/lib/lp/answers/browser/tests/test_breadcrumbs.py
@@ -17,8 +17,7 @@ class TestQuestionTargetProjectAndPersonBreadcrumbOnAnswersFacet(
"""
def setUp(self):
- super(TestQuestionTargetProjectAndPersonBreadcrumbOnAnswersFacet,
- self).setUp()
+ super().setUp()
self.person = self.factory.makePerson()
self.person_questions_url = canonical_url(
self.person, rootsite='answers')
@@ -54,7 +53,7 @@ class TestAnswersBreadcrumb(BaseBreadcrumbTestCase):
"""Test Breadcrumbs for answer module objects."""
def setUp(self):
- super(TestAnswersBreadcrumb, self).setUp()
+ super().setUp()
self.product = self.factory.makeProduct(name="mellon")
login_person(self.product.owner)
diff --git a/lib/lp/answers/browser/tests/test_question.py b/lib/lp/answers/browser/tests/test_question.py
index 7d7897d..9178619 100644
--- a/lib/lp/answers/browser/tests/test_question.py
+++ b/lib/lp/answers/browser/tests/test_question.py
@@ -26,7 +26,7 @@ class TestQuestionAddView(TestCaseWithFactory):
layer = DatabaseFunctionalLayer
def setUp(self):
- super(TestQuestionAddView, self).setUp()
+ super().setUp()
self.question_target = self.factory.makeProduct()
self.user = self.factory.makePerson()
login_person(self.user)
diff --git a/lib/lp/answers/browser/tests/test_questiontarget.py b/lib/lp/answers/browser/tests/test_questiontarget.py
index c0aefe0..307d038 100644
--- a/lib/lp/answers/browser/tests/test_questiontarget.py
+++ b/lib/lp/answers/browser/tests/test_questiontarget.py
@@ -10,7 +10,6 @@ from lazr.restful.interfaces import (
IJSONRequestCache,
IWebServiceClientRequest,
)
-import six
from six.moves.urllib.parse import quote
from zope.component import getUtility
from zope.security.proxy import removeSecurityProxy
@@ -196,7 +195,7 @@ class TestSearchQuestionsViewUnknown(TestCaseWithFactory):
hoary, sourcepackagename, product.owner)
def setUp(self):
- super(TestSearchQuestionsViewUnknown, self).setUp()
+ super().setUp()
self.product = self.factory.makeProduct()
self.view = create_initialized_view(self.product, '+questions')
@@ -246,7 +245,7 @@ class QuestionSetViewTestCase(TestCaseWithFactory):
target_widget = view.widgets['scope'].target_widget
self.assertIsNot(
None, content.find(True, id=target_widget.show_widget_id))
- text = six.text_type(content)
+ text = str(content)
picker_vocab = "DistributionOrProductOrProjectGroup"
self.assertIn(picker_vocab, text)
focus_script = "setFocusByName('field.search_text')"
diff --git a/lib/lp/answers/interfaces/question.py b/lib/lp/answers/interfaces/question.py
index 41efbf7..b7a0680 100644
--- a/lib/lp/answers/interfaces/question.py
+++ b/lib/lp/answers/interfaces/question.py
@@ -69,7 +69,7 @@ class IQuestion(IHasOwner):
description = exported(Text(
title=_('Description'), required=True, description=_(
"Include as much detail as possible: what "
- u"you\N{right single quotation mark}re trying to achieve, what steps "
+ "you\N{right single quotation mark}re trying to achieve, what steps "
"you take, what happens, and what you think should happen instead.")),
as_of="devel")
status = exported(Choice(
diff --git a/lib/lp/answers/model/faq.py b/lib/lp/answers/model/faq.py
index ac541ed..7c9945f 100644
--- a/lib/lp/answers/model/faq.py
+++ b/lib/lp/answers/model/faq.py
@@ -11,7 +11,6 @@ __all__ = [
from lazr.lifecycle.event import ObjectCreatedEvent
import pytz
-import six
from storm.expr import (
And,
Desc,
@@ -139,8 +138,8 @@ class FAQ(StormBase):
if date_created is None:
date_created = DEFAULT
faq = FAQ(
- owner=owner, title=six.text_type(title),
- content=six.text_type(content),
+ owner=owner, title=str(title),
+ content=str(content),
keywords=keywords,
date_created=date_created, product=product,
distribution=distribution)
@@ -218,7 +217,7 @@ class FAQSearch:
:param projectgroup: The project group in which to search for FAQs.
"""
if search_text is not None:
- assert isinstance(search_text, six.string_types), (
+ assert isinstance(search_text, str), (
'search_text should be a string, not %s' % type(search_text))
self.search_text = search_text
diff --git a/lib/lp/answers/model/question.py b/lib/lp/answers/model/question.py
index 61a534c..5d92043 100644
--- a/lib/lp/answers/model/question.py
+++ b/lib/lp/answers/model/question.py
@@ -29,7 +29,6 @@ from lazr.lifecycle.event import (
)
from lazr.lifecycle.snapshot import Snapshot
import pytz
-import six
from storm.expr import (
Alias,
LeftJoin,
@@ -702,7 +701,7 @@ class Question(StormBase, BugLinkTargetMixin):
from lp.bugs.model.bug import Bug
bug_ids = [
int(id) for _, id in getUtility(IXRefSet).findFrom(
- (u'question', six.text_type(self.id)), types=[u'bug'])]
+ ('question', str(self.id)), types=['bug'])]
return list(sorted(
bulk.load(Bug, bug_ids), key=operator.attrgetter('id')))
@@ -713,14 +712,12 @@ class Question(StormBase, BugLinkTargetMixin):
props = {}
# XXX: Should set creator.
getUtility(IXRefSet).create(
- {(u'question', six.text_type(self.id)):
- {(u'bug', six.text_type(bug.id)): props}})
+ {('question', str(self.id)): {('bug', str(bug.id)): props}})
def deleteBugLink(self, bug):
"""See BugLinkTargetMixin."""
getUtility(IXRefSet).delete(
- {(u'question', six.text_type(self.id)):
- [(u'bug', six.text_type(bug.id))]})
+ {('question', str(self.id)): [('bug', str(bug.id))]})
def setCommentVisibility(self, user, comment_number, visible):
"""See `IQuestion`."""
@@ -749,9 +746,9 @@ class QuestionSet:
origin = [
Question,
LeftJoin(XRef, And(
- XRef.from_type == u'question',
+ XRef.from_type == 'question',
XRef.from_id_int == Question.id,
- XRef.to_type == u'bug')),
+ XRef.to_type == 'bug')),
LeftJoin(BugTask, And(
BugTask.bug == XRef.to_id_int,
BugTask._status != BugTaskStatus.INVALID)),
diff --git a/lib/lp/answers/model/questionjob.py b/lib/lp/answers/model/questionjob.py
index 7a11475..39b9f73 100644
--- a/lib/lp/answers/model/questionjob.py
+++ b/lib/lp/answers/model/questionjob.py
@@ -76,7 +76,7 @@ class QuestionJob(StormBase):
:param metadata: The type-specific variables, as a JSON-compatible
dict.
"""
- super(QuestionJob, self).__init__()
+ super().__init__()
self.job = Job()
self.job_type = job_type
self.question = question
diff --git a/lib/lp/answers/notification.py b/lib/lp/answers/notification.py
index 42f04cd..59970e2 100644
--- a/lib/lp/answers/notification.py
+++ b/lib/lp/answers/notification.py
@@ -257,7 +257,7 @@ class QuestionModifiedDefaultNotification(QuestionNotification):
def getSubject(self):
"""The reply subject line."""
- line = super(QuestionModifiedDefaultNotification, self).getSubject()
+ line = super().getSubject()
return 'Re: %s' % line
def getHeaders(self):
diff --git a/lib/lp/answers/publisher.py b/lib/lp/answers/publisher.py
index 266d225..4805f4c 100644
--- a/lib/lp/answers/publisher.py
+++ b/lib/lp/answers/publisher.py
@@ -43,8 +43,7 @@ class AnswersBrowserRequest(LaunchpadBrowserRequest):
"""Instances of AnswersBrowserRequest provide `AnswersLayer`."""
def __init__(self, body_instream, environ, response=None):
- super(AnswersBrowserRequest, self).__init__(
- body_instream, environ, response)
+ super().__init__(body_instream, environ, response)
# Many of the responses from Answers vary based on language.
self.response.setHeader(
'Vary', 'Cookie, Authorization, Accept-Language')
diff --git a/lib/lp/answers/testing.py b/lib/lp/answers/testing.py
index 5ea8002..0bdc487 100644
--- a/lib/lp/answers/testing.py
+++ b/lib/lp/answers/testing.py
@@ -7,7 +7,6 @@ __all__ = [
'QuestionFactory',
]
-import six
from zope.component import getUtility
from lp.answers.interfaces.questiontarget import IQuestionTarget
@@ -25,7 +24,7 @@ class QuestionFactory:
It returns the pillar with the target_name and makes sure it
provides `IQuestionTarget`.
"""
- assert isinstance(target_name, six.string_types), (
+ assert isinstance(target_name, str), (
"expected a project name: %r", target_name)
target = getUtility(IPillarNameSet).getByName(target_name)
assert target is not None, (
diff --git a/lib/lp/answers/tests/test_faq.py b/lib/lp/answers/tests/test_faq.py
index 84e34e8..07ba82b 100644
--- a/lib/lp/answers/tests/test_faq.py
+++ b/lib/lp/answers/tests/test_faq.py
@@ -27,7 +27,7 @@ class TestFAQPermissions(TestCaseWithFactory):
layer = DatabaseFunctionalLayer
def setUp(self):
- super(TestFAQPermissions, self).setUp()
+ super().setUp()
target = self.factory.makeProduct()
self.owner = target.owner
with person_logged_in(self.owner):
diff --git a/lib/lp/answers/tests/test_faqtarget.py b/lib/lp/answers/tests/test_faqtarget.py
index d008ef9..82fafc1 100644
--- a/lib/lp/answers/tests/test_faqtarget.py
+++ b/lib/lp/answers/tests/test_faqtarget.py
@@ -73,7 +73,7 @@ class TestDistributionPermissions(BaseIFAQTargetTests, TestCaseWithFactory):
"""Test who can add FAQs to a distribution."""
def setUp(self):
- super(TestDistributionPermissions, self).setUp()
+ super().setUp()
self.target = self.factory.makeDistribution()
self.owner = self.target.owner
@@ -82,7 +82,7 @@ class TestProductPermissions(BaseIFAQTargetTests, TestCaseWithFactory):
"""Test who can add FAQs to a product."""
def setUp(self):
- super(TestProductPermissions, self).setUp()
+ super().setUp()
self.target = self.factory.makeProduct()
self.owner = self.target.owner
@@ -91,7 +91,7 @@ class TestDSPPermissions(BaseIFAQTargetTests, TestCaseWithFactory):
"""Test who can add FAQs for a distribution source package."""
def setUp(self):
- super(TestDSPPermissions, self).setUp()
+ super().setUp()
distribution = self.factory.makeDistribution()
self.owner = distribution.owner
self.target = self.factory.makeDistributionSourcePackage(
diff --git a/lib/lp/answers/tests/test_question_webservice.py b/lib/lp/answers/tests/test_question_webservice.py
index 53a05f3..30088ad 100644
--- a/lib/lp/answers/tests/test_question_webservice.py
+++ b/lib/lp/answers/tests/test_question_webservice.py
@@ -86,7 +86,7 @@ class TestQuestionRepresentation(TestCaseWithFactory):
layer = DatabaseFunctionalLayer
def setUp(self):
- super(TestQuestionRepresentation, self).setUp()
+ super().setUp()
with celebrity_logged_in('admin'):
self.question = self.factory.makeQuestion(
title="This is a question")
@@ -178,7 +178,7 @@ class TestSetCommentVisibility(TestCaseWithFactory):
layer = DatabaseFunctionalLayer
def setUp(self):
- super(TestSetCommentVisibility, self).setUp()
+ super().setUp()
self.commenter = self.factory.makePerson()
with person_logged_in(self.commenter):
self.question = self.factory.makeQuestion()
diff --git a/lib/lp/answers/tests/test_question_workflow.py b/lib/lp/answers/tests/test_question_workflow.py
index 1ec3999..cafe661 100644
--- a/lib/lp/answers/tests/test_question_workflow.py
+++ b/lib/lp/answers/tests/test_question_workflow.py
@@ -65,7 +65,7 @@ class BaseAnswerTrackerWorkflowTestCase(TestCase):
layer = DatabaseFunctionalLayer
def setUp(self):
- super(BaseAnswerTrackerWorkflowTestCase, self).setUp()
+ super().setUp()
self.now = datetime.now(UTC)
@@ -514,7 +514,7 @@ class LinkFAQTestCase(BaseAnswerTrackerWorkflowTestCase):
def setUp(self):
"""Create an additional FAQ."""
- super(LinkFAQTestCase, self).setUp()
+ super().setUp()
# Only admin can create FAQ on ubuntu.
login_person(self.admin)
diff --git a/lib/lp/answers/tests/test_questiontarget.py b/lib/lp/answers/tests/test_questiontarget.py
index e825d34..dbf5582 100644
--- a/lib/lp/answers/tests/test_questiontarget.py
+++ b/lib/lp/answers/tests/test_questiontarget.py
@@ -25,7 +25,7 @@ class QuestionTargetAnswerContactTestCase(TestCaseWithFactory):
layer = DatabaseFunctionalLayer
def setUp(self):
- super(QuestionTargetAnswerContactTestCase, self).setUp()
+ super().setUp()
self.project = self.factory.makeProduct()
self.user = self.factory.makePerson()
@@ -79,7 +79,7 @@ class TestQuestionTarget_answer_contacts_with_languages(TestCaseWithFactory):
layer = DatabaseFunctionalLayer
def setUp(self):
- super(TestQuestionTarget_answer_contacts_with_languages, self).setUp()
+ super().setUp()
self.answer_contact = self.factory.makePerson()
login_person(self.answer_contact)
lang_set = getUtility(ILanguageSet)
@@ -137,7 +137,7 @@ class TestQuestionTargetCreateQuestionFromBug(TestCaseWithFactory):
layer = DatabaseFunctionalLayer
def setUp(self):
- super(TestQuestionTargetCreateQuestionFromBug, self).setUp()
+ super().setUp()
self.bug = self.factory.makeBug(description="first comment")
self.target = self.bug.bugtasks[0].target
self.contributor = self.target.owner
diff --git a/lib/lp/answers/vocabulary.py b/lib/lp/answers/vocabulary.py
index ec3ab2d..20cea4c 100644
--- a/lib/lp/answers/vocabulary.py
+++ b/lib/lp/answers/vocabulary.py
@@ -93,8 +93,7 @@ class UsesAnswersProductVocabulary(ProductVocabulary):
vocab_filter = []
vocab_filter.append(
And(Product.official_answers == True))
- return super(UsesAnswersProductVocabulary, self).search(
- query, vocab_filter)
+ return super().search(query, vocab_filter)
class UsesAnswersDistributionVocabulary(DistributionVocabulary):
@@ -107,8 +106,7 @@ class UsesAnswersDistributionVocabulary(DistributionVocabulary):
"""
def __init__(self, context=None):
- super(UsesAnswersDistributionVocabulary, self).__init__(
- context=context)
+ super().__init__(context=context)
self.distribution = IDistribution(self.context, None)
@property