← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~cjwatson/launchpad/custom-widget-no-class-advice-4 into lp:launchpad

 

Colin Watson has proposed merging lp:~cjwatson/launchpad/custom-widget-no-class-advice-4 into lp:launchpad.

Commit message:
Remove Zope class advice from custom widget registration (part 4).

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/custom-widget-no-class-advice-4/+merge/354107

Next step after https://code.launchpad.net/~cjwatson/launchpad/custom-widget-no-class-advice-3/+merge/353872.
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~cjwatson/launchpad/custom-widget-no-class-advice-4 into lp:launchpad.
=== modified file 'lib/lp/registry/browser/person.py'
--- lib/lp/registry/browser/person.py	2018-05-18 14:07:28 +0000
+++ lib/lp/registry/browser/person.py	2018-08-31 11:41:19 +0000
@@ -74,6 +74,7 @@
 from zope.error.interfaces import IErrorReportingUtility
 from zope.formlib import form
 from zope.formlib.form import FormFields
+from zope.formlib.widget import CustomWidgetFactory
 from zope.formlib.widgets import (
     TextAreaWidget,
     TextWidget,
@@ -101,7 +102,6 @@
 from lp import _
 from lp.app.browser.launchpadform import (
     action,
-    custom_widget,
     LaunchpadEditFormView,
     LaunchpadFormView,
     )
@@ -1041,7 +1041,8 @@
 
     schema = DeactivateAccountSchema
     label = "Deactivate your Launchpad account"
-    custom_widget('comment', TextAreaWidget, height=5, width=60)
+    custom_widget_comment = CustomWidgetFactory(
+        TextAreaWidget, height=5, width=60)
 
     def validate(self, data):
         """See `LaunchpadFormView`."""
@@ -1238,8 +1239,8 @@
         'personal_standing', 'personal_standing_reason',
         'require_strong_email_authentication',
         ]
-    custom_widget(
-        'personal_standing_reason', TextAreaWidget, height=5, width=60)
+    custom_widget_personal_standing_reason = CustomWidgetFactory(
+        TextAreaWidget, height=5, width=60)
 
     @property
     def is_viewing_person(self):
@@ -1278,7 +1279,8 @@
     schema = IAccountAdministerSchema
     label = "Review person's account"
     field_names = ['status', 'comment']
-    custom_widget('comment', TextAreaWidget, height=5, width=60)
+    custom_widget_comment = CustomWidgetFactory(
+        TextAreaWidget, height=5, width=60)
 
     def __init__(self, context, request):
         """See `LaunchpadEditFormView`."""
@@ -1351,7 +1353,7 @@
 class PersonVouchersView(LaunchpadFormView):
     """Form for displaying and redeeming commercial subscription vouchers."""
 
-    custom_widget('voucher', LaunchpadDropdownWidget)
+    custom_widget_voucher = LaunchpadDropdownWidget
 
     @property
     def page_title(self):
@@ -2705,7 +2707,8 @@
                    'hide_email_addresses', 'verbose_bugnotifications',
                    'selfgenerated_bugnotifications',
                    'expanded_notification_footers']
-    custom_widget('mugshot', ImageChangeWidget, ImageChangeWidget.EDIT_STYLE)
+    custom_widget_mugshot = CustomWidgetFactory(
+        ImageChangeWidget, ImageChangeWidget.EDIT_STYLE)
 
     label = 'Change your personal details'
     page_title = label
@@ -2775,10 +2778,10 @@
 
     schema = IEmailAddress
 
-    custom_widget('VALIDATED_SELECTED', LaunchpadRadioWidget,
-                  orientation='vertical')
-    custom_widget('UNVALIDATED_SELECTED', LaunchpadRadioWidget,
-                  orientation='vertical')
+    custom_widget_VALIDATED_SELECTED = CustomWidgetFactory(
+        LaunchpadRadioWidget, orientation='vertical')
+    custom_widget_UNVALIDATED_SELECTED = CustomWidgetFactory(
+        LaunchpadRadioWidget, orientation='vertical')
 
     label = 'Change your email settings'
 
@@ -2840,8 +2843,7 @@
             Choice(__name__='VALIDATED_SELECTED',
                    title=_('These addresses are confirmed as being yours'),
                    source=SimpleVocabulary(terms),
-                   ),
-            custom_widget=self.custom_widgets['VALIDATED_SELECTED'])
+                   ))
 
     def _unvalidated_emails_field(self):
         """Create a field with a vocabulary of unvalidated and guessed emails.
@@ -2862,8 +2864,7 @@
 
         return FormFields(
             Choice(__name__='UNVALIDATED_SELECTED', title=title,
-                   source=SimpleVocabulary(terms)),
-            custom_widget=self.custom_widgets['UNVALIDATED_SELECTED'])
+                   source=SimpleVocabulary(terms)))
 
     def _validate_selected_address(self, data, field='VALIDATED_SELECTED'):
         """A generic validator for this view's actions.
@@ -3104,8 +3105,8 @@
 
     schema = IEmailAddress
 
-    custom_widget('mailing_list_auto_subscribe_policy',
-                  LaunchpadRadioWidgetWithDescription)
+    custom_widget_mailing_list_auto_subscribe_policy = (
+        LaunchpadRadioWidgetWithDescription)
 
     label = 'Change your mailing list subscriptions'
 
@@ -4016,7 +4017,7 @@
 
     schema = IEmailToPerson
     field_names = ['subject', 'message']
-    custom_widget('subject', TextWidget, displayWidth=60)
+    custom_widget_subject = CustomWidgetFactory(TextWidget, displayWidth=60)
 
     def initialize(self):
         """See `ILaunchpadFormView`."""

=== modified file 'lib/lp/registry/browser/poll.py'
--- lib/lp/registry/browser/poll.py	2016-01-26 15:47:37 +0000
+++ lib/lp/registry/browser/poll.py	2018-08-31 11:41:19 +0000
@@ -1,4 +1,4 @@
-# Copyright 2009 Canonical Ltd.  This software is licensed under the
+# Copyright 2009-2018 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
 __metaclass__ = type
@@ -21,6 +21,7 @@
 from z3c.ptcompat import ViewPageTemplateFile
 from zope.component import getUtility
 from zope.event import notify
+from zope.formlib.widget import CustomWidgetFactory
 from zope.formlib.widgets import TextWidget
 from zope.interface import (
     implementer,
@@ -30,7 +31,6 @@
 
 from lp.app.browser.launchpadform import (
     action,
-    custom_widget,
     LaunchpadEditFormView,
     LaunchpadFormView,
     )
@@ -443,7 +443,7 @@
     label = "Edit option details"
     page_title = 'Edit option'
     field_names = ["name", "title"]
-    custom_widget("title", TextWidget, displayWidth=30)
+    custom_widget_title = CustomWidgetFactory(TextWidget, displayWidth=30)
 
     @property
     def cancel_url(self):
@@ -463,7 +463,7 @@
     label = "Create new poll option"
     page_title = "New option"
     field_names = ["name", "title"]
-    custom_widget("title", TextWidget, displayWidth=30)
+    custom_widget_title = CustomWidgetFactory(TextWidget, displayWidth=30)
 
     @property
     def cancel_url(self):

=== modified file 'lib/lp/registry/browser/product.py'
--- lib/lp/registry/browser/product.py	2016-11-15 13:37:38 +0000
+++ lib/lp/registry/browser/product.py	2018-08-31 11:41:19 +0000
@@ -1,4 +1,4 @@
-# Copyright 2009-2016 Canonical Ltd.  This software is licensed under the
+# Copyright 2009-2018 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
 """Browser views for products."""
@@ -82,7 +82,6 @@
 from lp.answers.browser.questiontarget import QuestionTargetTraversalMixin
 from lp.app.browser.launchpadform import (
     action,
-    custom_widget,
     LaunchpadEditFormView,
     LaunchpadFormView,
     render_radio_widget_part,
@@ -1406,10 +1405,10 @@
         "licenses",
         "license_info",
         ]
-    custom_widget('licenses', LicenseWidget)
-    custom_widget('license_info', GhostWidget)
-    custom_widget(
-        'information_type', LaunchpadRadioWidgetWithDescription,
+    custom_widget_licenses = LicenseWidget
+    custom_widget_license_info = GhostWidget
+    custom_widget_information_type = CustomWidgetFactory(
+        LaunchpadRadioWidgetWithDescription,
         vocabulary=InformationTypeVocabulary(types=PILLAR_INFORMATION_TYPES))
 
     @property
@@ -1605,8 +1604,10 @@
 
     schema = IProductSeries
     field_names = ['name', 'summary', 'branch', 'releasefileglob']
-    custom_widget('summary', TextAreaWidget, height=7, width=62)
-    custom_widget('releasefileglob', StrippedTextWidget, displayWidth=40)
+    custom_widget_summary = CustomWidgetFactory(
+        TextAreaWidget, height=7, width=62)
+    custom_widget_releasefileglob = CustomWidgetFactory(
+        StrippedTextWidget, displayWidth=40)
 
     series = None
 
@@ -1765,10 +1766,10 @@
     # upon creation.
     for_input = True
 
-    custom_widget('rcs_type', LaunchpadRadioWidget)
-    custom_widget('branch_type', LaunchpadRadioWidget)
-    custom_widget('default_vcs', LaunchpadRadioWidget)
-    custom_widget('git_repository_type', LaunchpadRadioWidget)
+    custom_widget_rcs_type = LaunchpadRadioWidget
+    custom_widget_branch_type = LaunchpadRadioWidget
+    custom_widget_default_vcs = LaunchpadRadioWidget
+    custom_widget_git_repository_type = LaunchpadRadioWidget
 
     errors_in_action = False
     is_series = False
@@ -2219,23 +2220,22 @@
         ('subscription_modified_after', 'subscription_modified_before'),
         ]
 
-    custom_widget(
-        'licenses', CheckBoxMatrixWidget, column_count=4,
-        orientation='vertical')
-    custom_widget('active', LaunchpadRadioWidget,
-                  _messageNoValue="(do not filter)")
-    custom_widget('project_reviewed', LaunchpadRadioWidget,
-                  _messageNoValue="(do not filter)")
-    custom_widget('license_approved', LaunchpadRadioWidget,
-                  _messageNoValue="(do not filter)")
-    custom_widget('has_subscription', LaunchpadRadioWidget,
-                  _messageNoValue="(do not filter)")
-    custom_widget('created_after', DateWidget)
-    custom_widget('created_before', DateWidget)
-    custom_widget('subscription_expires_after', DateWidget)
-    custom_widget('subscription_expires_before', DateWidget)
-    custom_widget('subscription_modified_after', DateWidget)
-    custom_widget('subscription_modified_before', DateWidget)
+    custom_widget_licenses = CustomWidgetFactory(
+        CheckBoxMatrixWidget, column_count=4, orientation='vertical')
+    custom_widget_active = CustomWidgetFactory(
+        LaunchpadRadioWidget, _messageNoValue="(do not filter)")
+    custom_widget_project_reviewed = CustomWidgetFactory(
+        LaunchpadRadioWidget, _messageNoValue="(do not filter)")
+    custom_widget_license_approved = CustomWidgetFactory(
+        LaunchpadRadioWidget, _messageNoValue="(do not filter)")
+    custom_widget_has_subscription = CustomWidgetFactory(
+        LaunchpadRadioWidget, _messageNoValue="(do not filter)")
+    custom_widget_created_after = DateWidget
+    custom_widget_created_before = DateWidget
+    custom_widget_subscription_expires_after = DateWidget
+    custom_widget_subscription_expires_before = DateWidget
+    custom_widget_subscription_modified_after = DateWidget
+    custom_widget_subscription_modified_before = DateWidget
 
     @property
     def left_side_widgets(self):
@@ -2296,8 +2296,9 @@
     template = ViewPageTemplateFile('../templates/product-new.pt')
     page_title = "Register a project in Launchpad"
 
-    custom_widget('display_name', TextWidget, displayWidth=50, label='Name')
-    custom_widget('name', ProductNameWidget, label='URL')
+    custom_widget_display_name = CustomWidgetFactory(
+        TextWidget, displayWidth=50, label='Name')
+    custom_widget_name = CustomWidgetFactory(ProductNameWidget, label='URL')
 
     step_description = 'Project basics'
     search_results_count = 0
@@ -2355,27 +2356,28 @@
 
     product = None
 
-    custom_widget('display_name', TextWidget, displayWidth=50, label='Name')
-    custom_widget('name', ProductNameWidget, label='URL')
-    custom_widget('homepageurl', TextWidget, displayWidth=30)
-    custom_widget('licenses', LicenseWidget)
-    custom_widget('license_info', GhostWidget)
-    custom_widget(
-        'information_type',
+    custom_widget_display_name = CustomWidgetFactory(
+        TextWidget, displayWidth=50, label='Name')
+    custom_widget_name = CustomWidgetFactory(ProductNameWidget, label='URL')
+    custom_widget_homepageurl = CustomWidgetFactory(
+        TextWidget, displayWidth=30)
+    custom_widget_licenses = LicenseWidget
+    custom_widget_license_info = GhostWidget
+    custom_widget_information_type = CustomWidgetFactory(
         LaunchpadRadioWidgetWithDescription,
         vocabulary=InformationTypeVocabulary(types=PILLAR_INFORMATION_TYPES))
 
-    custom_widget(
-        'owner', PersonPickerWidget, header="Select the maintainer",
+    custom_widget_owner = CustomWidgetFactory(
+        PersonPickerWidget, header="Select the maintainer",
         show_create_team_link=True)
-    custom_widget(
-        'bug_supervisor', PersonPickerWidget, header="Set a bug supervisor",
-        required=True, show_create_team_link=True)
-    custom_widget(
-        'driver', PersonPickerWidget, header="Set a driver",
-        required=True, show_create_team_link=True)
-    custom_widget(
-        'disclaim_maintainer', CheckBoxWidget, cssClass="subordinate")
+    custom_widget_bug_supervisor = CustomWidgetFactory(
+        PersonPickerWidget, header="Set a bug supervisor",
+        required=True, show_create_team_link=True)
+    custom_widget_driver = CustomWidgetFactory(
+        PersonPickerWidget, header="Set a driver",
+        required=True, show_create_team_link=True)
+    custom_widget_disclaim_maintainer = CustomWidgetFactory(
+        CheckBoxWidget, cssClass="subordinate")
 
     def initialize(self):
         # The JSON cache must be populated before the super call, since
@@ -2656,12 +2658,14 @@
     # failing.
     initial_values = {'transfer_to_registry': False}
 
-    custom_widget('owner', PersonPickerWidget, header="Select the maintainer",
-                  show_create_team_link=True)
-    custom_widget('transfer_to_registry', CheckBoxWidget,
-                  widget_class='field subordinate')
-    custom_widget('driver', PersonPickerWidget, header="Select the driver",
-                  show_create_team_link=True)
+    custom_widget_owner = CustomWidgetFactory(
+        PersonPickerWidget, header="Select the maintainer",
+        show_create_team_link=True)
+    custom_widget_transfer_to_registry = CustomWidgetFactory(
+        CheckBoxWidget, widget_class='field subordinate')
+    custom_widget_driver = CustomWidgetFactory(
+        PersonPickerWidget, header="Select the driver",
+        show_create_team_link=True)
 
     @property
     def page_title(self):

=== modified file 'lib/lp/registry/browser/productrelease.py'
--- lib/lp/registry/browser/productrelease.py	2015-02-01 22:42:13 +0000
+++ lib/lp/registry/browser/productrelease.py	2018-08-31 11:41:19 +0000
@@ -1,4 +1,4 @@
-# Copyright 2009-2011 Canonical Ltd.  This software is licensed under the
+# Copyright 2009-2018 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
 __metaclass__ = type
@@ -21,6 +21,7 @@
 from z3c.ptcompat import ViewPageTemplateFile
 from zope.event import notify
 from zope.formlib.form import FormFields
+from zope.formlib.widget import CustomWidgetFactory
 from zope.formlib.widgets import (
     TextAreaWidget,
     TextWidget,
@@ -35,7 +36,6 @@
 from lp import _
 from lp.app.browser.launchpadform import (
     action,
-    custom_widget,
     LaunchpadEditFormView,
     LaunchpadFormView,
     )
@@ -107,9 +107,11 @@
     """
     schema = IProductRelease
 
-    custom_widget('datereleased', DateTimeWidget)
-    custom_widget('release_notes', TextAreaWidget, height=7, width=62)
-    custom_widget('changelog', TextAreaWidget, height=7, width=62)
+    custom_widget_datereleased = DateTimeWidget
+    custom_widget_release_notes = CustomWidgetFactory(
+        TextAreaWidget, height=7, width=62)
+    custom_widget_changelog = CustomWidgetFactory(
+        TextAreaWidget, height=7, width=62)
 
     def _prependKeepMilestoneActiveField(self):
         keep_milestone_active_checkbox = FormFields(
@@ -227,9 +229,11 @@
         "changelog",
         ]
 
-    custom_widget('datereleased', DateTimeWidget)
-    custom_widget('release_notes', TextAreaWidget, height=7, width=62)
-    custom_widget('changelog', TextAreaWidget, height=7, width=62)
+    custom_widget_datereleased = DateTimeWidget
+    custom_widget_release_notes = CustomWidgetFactory(
+        TextAreaWidget, height=7, width=62)
+    custom_widget_changelog = CustomWidgetFactory(
+        TextAreaWidget, height=7, width=62)
 
     @property
     def label(self):
@@ -265,7 +269,8 @@
     """A view for adding a file to an `IProductRelease`."""
     schema = IProductReleaseFileAddForm
 
-    custom_widget('description', TextWidget, displayWidth=60)
+    custom_widget_description = CustomWidgetFactory(
+        TextWidget, displayWidth=60)
 
     @property
     def label(self):

=== modified file 'lib/lp/registry/browser/productseries.py'
--- lib/lp/registry/browser/productseries.py	2016-09-19 13:44:28 +0000
+++ lib/lp/registry/browser/productseries.py	2018-08-31 11:41:19 +0000
@@ -1,4 +1,4 @@
-# Copyright 2009-2016 Canonical Ltd.  This software is licensed under the
+# Copyright 2009-2018 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
 """View classes for `IProductSeries`."""
@@ -32,6 +32,7 @@
 from z3c.ptcompat import ViewPageTemplateFile
 from zope.component import getUtility
 from zope.formlib import form
+from zope.formlib.widget import CustomWidgetFactory
 from zope.formlib.widgets import (
     TextAreaWidget,
     TextWidget,
@@ -50,7 +51,6 @@
 from lp.app.browser.informationtype import InformationTypePortletMixin
 from lp.app.browser.launchpadform import (
     action,
-    custom_widget,
     LaunchpadEditFormView,
     LaunchpadFormView,
     )
@@ -502,7 +502,7 @@
             return IPackaging
 
     field_names = ['sourcepackagename', 'distroseries']
-    custom_widget('sourcepackagename', UbuntuSourcePackageNameWidget)
+    custom_widget_sourcepackagename = UbuntuSourcePackageNameWidget
     page_title = 'Ubuntu source packaging'
     label = page_title
 
@@ -636,8 +636,10 @@
     schema = IProductSeries
     field_names = [
         'name', 'summary', 'status', 'branch', 'releasefileglob']
-    custom_widget('summary', TextAreaWidget, height=7, width=62)
-    custom_widget('releasefileglob', StrippedTextWidget, displayWidth=40)
+    custom_widget_summary = CustomWidgetFactory(
+        TextAreaWidget, height=7, width=62)
+    custom_widget_releasefileglob = CustomWidgetFactory(
+        StrippedTextWidget, displayWidth=40)
 
     @property
     def label(self):
@@ -797,7 +799,7 @@
     """A view to review and change the series `IProduct` and name."""
     schema = IProductSeries
     field_names = ['product', 'name']
-    custom_widget('name', TextWidget, displayWidth=20)
+    custom_widget_name = CustomWidgetFactory(TextWidget, displayWidth=20)
 
     @property
     def label(self):

=== modified file 'lib/lp/registry/browser/project.py'
--- lib/lp/registry/browser/project.py	2015-10-01 17:32:41 +0000
+++ lib/lp/registry/browser/project.py	2018-08-31 11:41:19 +0000
@@ -1,4 +1,4 @@
-# Copyright 2009-2011 Canonical Ltd.  This software is licensed under the
+# Copyright 2009-2018 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
 """Project-related View Classes"""
@@ -35,6 +35,7 @@
 from zope.component import getUtility
 from zope.event import notify
 from zope.formlib import form
+from zope.formlib.widget import CustomWidgetFactory
 from zope.formlib.widgets import TextWidget
 from zope.interface import (
     implementer,
@@ -48,7 +49,6 @@
 from lp.answers.browser.questiontarget import QuestionCollectionAnswersMenu
 from lp.app.browser.launchpadform import (
     action,
-    custom_widget,
     LaunchpadEditFormView,
     LaunchpadFormView,
     )
@@ -585,7 +585,8 @@
         'owner',
         'homepageurl',
         ]
-    custom_widget('homepageurl', TextWidget, displayWidth=30)
+    custom_widget_homepageurl = CustomWidgetFactory(
+        TextWidget, displayWidth=30)
     label = _('Register a project group with Launchpad')
     page_title = label
     projectgroup = None

=== modified file 'lib/lp/registry/browser/sourcepackage.py'
--- lib/lp/registry/browser/sourcepackage.py	2016-02-05 15:16:29 +0000
+++ lib/lp/registry/browser/sourcepackage.py	2018-08-31 11:41:19 +0000
@@ -1,4 +1,4 @@
-# Copyright 2009-2012 Canonical Ltd.  This software is licensed under the
+# Copyright 2009-2018 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
 """Browser views for sourcepackages."""
@@ -37,6 +37,7 @@
     )
 from zope.formlib.form import Fields
 from zope.formlib.interfaces import IInputWidget
+from zope.formlib.widget import CustomWidgetFactory
 from zope.formlib.widgets import DropdownWidget
 from zope.interface import Interface
 from zope.schema import (
@@ -52,7 +53,6 @@
 from lp import _
 from lp.app.browser.launchpadform import (
     action,
-    custom_widget,
     LaunchpadFormView,
     ReturnToReferrerMixin,
     )
@@ -316,8 +316,8 @@
     # The DropdownWidget is used, since the VocabularyPickerWidget
     # does not support visible=False to turn it into a hidden input
     # to continue passing the variable in the form.
-    custom_widget('product', DropdownWidget, visible=False)
-    custom_widget('productseries', LaunchpadRadioWidget)
+    custom_widget_product = CustomWidgetFactory(DropdownWidget, visible=False)
+    custom_widget_productseries = LaunchpadRadioWidget
 
     def setUpFields(self):
         super(SourcePackageChangeUpstreamStepTwo, self).setUpFields()
@@ -556,8 +556,8 @@
     """A view for linking to an upstream package."""
 
     schema = Interface
-    custom_widget(
-        'upstream', LaunchpadRadioWidget, orientation='vertical')
+    custom_widget_upstream = CustomWidgetFactory(
+        LaunchpadRadioWidget, orientation='vertical')
     product_suggestions = None
     initial_focus_widget = None
     max_suggestions = 9

=== modified file 'lib/lp/registry/browser/team.py'
--- lib/lp/registry/browser/team.py	2016-11-15 17:49:49 +0000
+++ lib/lp/registry/browser/team.py	2018-08-31 11:41:19 +0000
@@ -1,4 +1,4 @@
-# Copyright 2009-2016 Canonical Ltd.  This software is licensed under the
+# Copyright 2009-2018 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
 __metaclass__ = type
@@ -52,6 +52,7 @@
     FormFields,
     )
 from zope.formlib.textwidgets import IntWidget
+from zope.formlib.widget import CustomWidgetFactory
 from zope.formlib.widgets import TextAreaWidget
 from zope.interface import (
     classImplements,
@@ -76,7 +77,6 @@
 from lp.app.browser.badge import HasBadgeBase
 from lp.app.browser.launchpadform import (
     action,
-    custom_widget,
     LaunchpadFormView,
     )
 from lp.app.browser.tales import PersonFormatterAPI
@@ -299,14 +299,14 @@
 
     page_title = label
 
-    custom_widget(
-        'renewal_policy', LaunchpadRadioWidget, orientation='vertical')
-    custom_widget('defaultrenewalperiod', IntWidget,
-        widget_class='field subordinate')
-    custom_widget(
-        'membership_policy', LaunchpadRadioWidgetWithDescription,
-        orientation='vertical')
-    custom_widget('description', TextAreaWidget, height=10, width=30)
+    custom_widget_renewal_policy = CustomWidgetFactory(
+        LaunchpadRadioWidget, orientation='vertical')
+    custom_widget_defaultrenewalperiod = CustomWidgetFactory(
+        IntWidget, widget_class='field subordinate')
+    custom_widget_membership_policy = CustomWidgetFactory(
+        LaunchpadRadioWidgetWithDescription, orientation='vertical')
+    custom_widget_description = CustomWidgetFactory(
+        TextAreaWidget, height=10, width=30)
 
     def setUpFields(self):
         """See `LaunchpadViewForm`."""
@@ -442,8 +442,8 @@
 
     schema = ITeamContactAddressForm
 
-    custom_widget(
-        'contact_method', LaunchpadRadioWidget, orientation='vertical')
+    custom_widget_contact_method = CustomWidgetFactory(
+        LaunchpadRadioWidget, orientation='vertical')
 
     @property
     def label(self):
@@ -603,7 +603,8 @@
     schema = IMailingList
     field_names = ['welcome_message']
     label = "Mailing list configuration"
-    custom_widget('welcome_message', TextAreaWidget, width=72, height=10)
+    custom_widget_welcome_message = CustomWidgetFactory(
+        TextAreaWidget, width=72, height=10)
     page_title = label
 
     def __init__(self, context, request):
@@ -1001,14 +1002,13 @@
     page_title = 'Register a new team in Launchpad'
     label = page_title
 
-    custom_widget('teamowner', HiddenUserWidget)
-    custom_widget(
-        'renewal_policy', LaunchpadRadioWidget, orientation='vertical')
-    custom_widget(
-        'membership_policy', LaunchpadRadioWidgetWithDescription,
-        orientation='vertical')
-    custom_widget('defaultrenewalperiod', IntWidget,
-        widget_class='field subordinate')
+    custom_widget_teamowner = HiddenUserWidget
+    custom_widget_renewal_policy = CustomWidgetFactory(
+        LaunchpadRadioWidget, orientation='vertical')
+    custom_widget_membership_policy = CustomWidgetFactory(
+        LaunchpadRadioWidgetWithDescription, orientation='vertical')
+    custom_widget_defaultrenewalperiod = CustomWidgetFactory(
+        IntWidget, widget_class='field subordinate')
 
     def setUpFields(self):
         """See `LaunchpadViewForm`.
@@ -1073,9 +1073,8 @@
 
     # Use a dropdown - Javascript will be used to change this to a choice
     # popup widget.
-    custom_widget(
-        'membership_policy', LaunchpadDropdownWidget,
-        orientation='vertical')
+    custom_widget_membership_policy = CustomWidgetFactory(
+        LaunchpadDropdownWidget, orientation='vertical')
 
 
 class ProposedTeamMembersEditView(LaunchpadFormView):
@@ -1164,8 +1163,8 @@
     # below should be changed to the more appropriate False bool when we're
     # making use of the JSON cache to setup pickers, rather than assembling
     # javascript in a view macro.
-    custom_widget(
-        'newmember', PersonPickerWidget,
+    custom_widget_newmember = CustomWidgetFactory(
+        PersonPickerWidget,
         show_assign_me_button='false', show_remove_button='false')
 
     @property
@@ -1362,7 +1361,8 @@
     __name__ = '+invitation'
     schema = ITeamMembershipInvitationAcknowledgementForm
     field_names = ['acknowledger_comment']
-    custom_widget('acknowledger_comment', TextAreaWidget, height=5, width=60)
+    custom_widget_acknowledger_comment = CustomWidgetFactory(
+        TextAreaWidget, height=5, width=60)
     template = ViewPageTemplateFile(
         '../templates/teammembership-invitation.pt')
 
@@ -1893,7 +1893,7 @@
     """Propose/add to this team any team that you're an administrator of."""
 
     page_title = 'Propose/add one of your teams to another one'
-    custom_widget('teams', LabeledMultiCheckBoxWidget)
+    custom_widget_teams = LabeledMultiCheckBoxWidget
 
     def initialize(self):
         context = self.context

=== modified file 'lib/lp/registry/doc/product-widgets.txt'
--- lib/lp/registry/doc/product-widgets.txt	2017-10-21 18:14:14 +0000
+++ lib/lp/registry/doc/product-widgets.txt	2018-08-31 11:41:19 +0000
@@ -403,8 +403,7 @@
 
     >>> from lp.services.config import config
     >>> from z3c.ptcompat import ViewPageTemplateFile
-    >>> from lp.app.browser.launchpadform import (
-    ...     custom_widget, LaunchpadFormView)
+    >>> from lp.app.browser.launchpadform import LaunchpadFormView
 
     >>> class GhostWidgetView(LaunchpadFormView):
     ...     page_title = 'Test'
@@ -412,7 +411,7 @@
     ...         config.root + '/lib/lp/app/templates/generic-edit.pt')
     ...     schema = IProduct
     ...     field_names = ['license_info']
-    ...     custom_widget('license_info', GhostWidget)
+    ...     custom_widget_license_info = GhostWidget
 
     >>> request = LaunchpadTestRequest()
     >>> request.setPrincipal(factory.makePerson())


Follow ups