← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] ~cjwatson/launchpad:name-blocklist into launchpad:master

 

Colin Watson has proposed merging ~cjwatson/launchpad:name-blocklist into launchpad:master.

Commit message:
Rename NameBlacklist to NameBlocklist

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

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

`/+nameblacklist` is now `/+nameblocklist`, and I've left a redirection behind.
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of ~cjwatson/launchpad:name-blocklist into launchpad:master.
diff --git a/database/replication/helpers.py b/database/replication/helpers.py
index 5ab5b50..66c9fef 100644
--- a/database/replication/helpers.py
+++ b/database/replication/helpers.py
@@ -46,7 +46,7 @@ LPMAIN_SEED = frozenset(
         ("public", "person"),
         ("public", "databasereplicationlag"),
         ("public", "fticache"),
-        ("public", "nameblacklist"),
+        ("public", "nameblocklist"),
         ("public", "openidconsumerassociation"),
         ("public", "openidconsumernonce"),
         ("public", "codeimportmachine"),
diff --git a/database/sampledata/current-dev.sql b/database/sampledata/current-dev.sql
index 43507f2..2f4ef1b 100644
--- a/database/sampledata/current-dev.sql
+++ b/database/sampledata/current-dev.sql
@@ -5429,7 +5429,7 @@ ALTER TABLE public.mirrorproberecord ENABLE TRIGGER ALL;
 
 ALTER TABLE public.nameblocklist DISABLE TRIGGER ALL;
 
-INSERT INTO public.nameblocklist (id, regexp, comment, admin) VALUES (1, 'blacklist', 'For testing purposes', NULL);
+INSERT INTO public.nameblocklist (id, regexp, comment, admin) VALUES (1, 'blocklist', 'For testing purposes', NULL);
 INSERT INTO public.nameblocklist (id, regexp, comment, admin) VALUES (2, '^admin', NULL, NULL);
 
 
diff --git a/database/sampledata/current.sql b/database/sampledata/current.sql
index bf2b999..ff2880d 100644
--- a/database/sampledata/current.sql
+++ b/database/sampledata/current.sql
@@ -5343,7 +5343,7 @@ ALTER TABLE public.mirrorproberecord ENABLE TRIGGER ALL;
 
 ALTER TABLE public.nameblocklist DISABLE TRIGGER ALL;
 
-INSERT INTO public.nameblocklist (id, regexp, comment, admin) VALUES (1, 'blacklist', 'For testing purposes', NULL);
+INSERT INTO public.nameblocklist (id, regexp, comment, admin) VALUES (1, 'blocklist', 'For testing purposes', NULL);
 INSERT INTO public.nameblocklist (id, regexp, comment, admin) VALUES (2, '^admin', NULL, NULL);
 
 
diff --git a/lib/lp/app/browser/launchpad.py b/lib/lp/app/browser/launchpad.py
index 2621eba..a4eba0a 100644
--- a/lib/lp/app/browser/launchpad.py
+++ b/lib/lp/app/browser/launchpad.py
@@ -87,7 +87,7 @@ from lp.registry.interfaces.announcement import IAnnouncementSet
 from lp.registry.interfaces.codeofconduct import ICodeOfConductSet
 from lp.registry.interfaces.distribution import IDistributionSet
 from lp.registry.interfaces.karma import IKarmaActionSet
-from lp.registry.interfaces.nameblacklist import INameBlacklistSet
+from lp.registry.interfaces.nameblocklist import INameBlocklistSet
 from lp.registry.interfaces.person import IPersonSet
 from lp.registry.interfaces.pillar import IPillarNameSet
 from lp.registry.interfaces.poll import IPollSet
@@ -864,6 +864,10 @@ class LaunchpadRootNavigation(Navigation):
     def redirect_feature_changelog(self):
         return "/+feature-rules/changelog"
 
+    @redirection("+nameblacklist", status=301)  # wokeignore:rule=blacklist
+    def redirect_nameblacklist(self):  # wokeignore:rule=blacklist
+        return "+nameblocklist"
+
     # XXX cprov 2009-03-19 bug=345877: path segments starting with '+'
     # should never correspond to a valid traversal, they confuse the
     # hierarchical navigation model.
@@ -887,7 +891,7 @@ class LaunchpadRootNavigation(Navigation):
         "+imports": ITranslationImportQueue,
         "+languages": ILanguageSet,
         "livefses": ILiveFSSet,
-        "+nameblacklist": INameBlacklistSet,
+        "+nameblocklist": INameBlocklistSet,
         "package-sets": IPackagesetSet,
         "people": IPersonSet,
         "pillars": IPillarNameSet,
diff --git a/lib/lp/app/stories/basics/notfound-traversals.rst b/lib/lp/app/stories/basics/notfound-traversals.rst
index 01b859e..b154dc5 100644
--- a/lib/lp/app/stories/basics/notfound-traversals.rst
+++ b/lib/lp/app/stories/basics/notfound-traversals.rst
@@ -176,6 +176,10 @@ Check legacy URL redirects
     >>> check_redirect("/people/stub", status=301)
     http://launchpad.test/~stub
 
+    # wokeignore:rule=blacklist
+    >>> check_redirect("/+nameblacklist", auth=True, status=301)
+    +nameblocklist
+
 Check redirects of Unicode URLs works
 
     >>> check_not_found("/ubuntu/foo%C3%A9")
diff --git a/lib/lp/registry/browser/configure.zcml b/lib/lp/registry/browser/configure.zcml
index b90507b..80a57d0 100644
--- a/lib/lp/registry/browser/configure.zcml
+++ b/lib/lp/registry/browser/configure.zcml
@@ -1832,52 +1832,52 @@
         />
     <browser:page
         name="+edit"
-        for="lp.registry.interfaces.nameblacklist.INameBlacklist"
-        class="lp.registry.browser.nameblacklist.NameBlacklistEditView"
+        for="lp.registry.interfaces.nameblocklist.INameBlocklist"
+        class="lp.registry.browser.nameblocklist.NameBlocklistEditView"
         permission="launchpad.Edit"
         template="../../app/templates/generic-edit.pt"
         />
     <browser:url
-        for="lp.registry.interfaces.nameblacklist.INameBlacklistSet"
-        path_expression="string:+nameblacklist"
+        for="lp.registry.interfaces.nameblocklist.INameBlocklistSet"
+        path_expression="string:+nameblocklist"
         parent_utility="lp.services.webapp.interfaces.ILaunchpadRoot"
         />
     <browser:url
-        for="lp.registry.interfaces.nameblacklist.INameBlacklist"
+        for="lp.registry.interfaces.nameblocklist.INameBlocklist"
         path_expression="string:${id}"
-        parent_utility="lp.registry.interfaces.nameblacklist.INameBlacklistSet"
+        parent_utility="lp.registry.interfaces.nameblocklist.INameBlocklistSet"
         />
     <browser:defaultView
         name="+index"
-        for="lp.registry.interfaces.nameblacklist.INameBlacklistSet"
+        for="lp.registry.interfaces.nameblocklist.INameBlocklistSet"
         />
     <browser:page
         name="+index"
-        for="lp.registry.interfaces.nameblacklist.INameBlacklistSet"
-        class="lp.registry.browser.nameblacklist.NameBlacklistSetView"
+        for="lp.registry.interfaces.nameblocklist.INameBlocklistSet"
+        class="lp.registry.browser.nameblocklist.NameBlocklistSetView"
         permission="launchpad.View"
-        template="../templates/nameblacklists-index.pt"
+        template="../templates/nameblocklists-index.pt"
         />
     <browser:page
         name="+add"
-        for="lp.registry.interfaces.nameblacklist.INameBlacklistSet"
-        class="lp.registry.browser.nameblacklist.NameBlacklistAddView"
+        for="lp.registry.interfaces.nameblocklist.INameBlocklistSet"
+        class="lp.registry.browser.nameblocklist.NameBlocklistAddView"
         permission="launchpad.Edit"
         template="../../app/templates/generic-edit.pt"
         />
     <browser:navigation
-        module="lp.registry.browser.nameblacklist"
-        classes="NameBlacklistSetNavigation"
+        module="lp.registry.browser.nameblocklist"
+        classes="NameBlocklistSetNavigation"
         />
     <browser:menus
-        module="lp.registry.browser.nameblacklist"
+        module="lp.registry.browser.nameblocklist"
         classes="
-                 NameBlacklistNavigationMenu
-                 NameBlacklistSetNavigationMenu
+                 NameBlocklistNavigationMenu
+                 NameBlocklistSetNavigationMenu
                  "
         />
     <adapter
-        factory="lp.registry.browser.nameblacklist.NameBlacklistSetBreadcrumb"
+        factory="lp.registry.browser.nameblocklist.NameBlocklistSetBreadcrumb"
         />
     <browser:page
         name="+addseries"
diff --git a/lib/lp/registry/browser/nameblacklist.py b/lib/lp/registry/browser/nameblocklist.py
similarity index 61%
rename from lib/lp/registry/browser/nameblacklist.py
rename to lib/lp/registry/browser/nameblocklist.py
index 2c2e175..dad4965 100644
--- a/lib/lp/registry/browser/nameblacklist.py
+++ b/lib/lp/registry/browser/nameblocklist.py
@@ -2,11 +2,11 @@
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
 __all__ = [
-    "NameBlacklistAddView",
-    "NameBlacklistEditView",
-    "NameBlacklistNavigationMenu",
-    "NameBlacklistSetNavigationMenu",
-    "NameBlacklistSetView",
+    "NameBlocklistAddView",
+    "NameBlocklistEditView",
+    "NameBlocklistNavigationMenu",
+    "NameBlocklistSetNavigationMenu",
+    "NameBlocklistSetView",
 ]
 
 import re
@@ -18,9 +18,9 @@ from zope.interface import implementer
 
 from lp.app.browser.launchpadform import LaunchpadFormView, action
 from lp.registry.browser import RegistryEditFormView
-from lp.registry.interfaces.nameblacklist import (
-    INameBlacklist,
-    INameBlacklistSet,
+from lp.registry.interfaces.nameblocklist import (
+    INameBlocklist,
+    INameBlocklistSet,
 )
 from lp.services.webapp.breadcrumb import Breadcrumb
 from lp.services.webapp.interfaces import IBreadcrumb
@@ -37,7 +37,7 @@ from lp.services.webapp.publisher import (
 )
 
 
-class NameBlacklistValidationMixin:
+class NameBlocklistValidationMixin:
     """Validate regular expression when adding or editing."""
 
     def validate(self, data):
@@ -45,15 +45,15 @@ class NameBlacklistValidationMixin:
         regexp = data["regexp"]
         try:
             re.compile(regexp)
-            name_blacklist_set = getUtility(INameBlacklistSet)
+            name_blocklist_set = getUtility(INameBlocklistSet)
             if (
-                INameBlacklistSet.providedBy(self.context)
+                INameBlocklistSet.providedBy(self.context)
                 or self.context.regexp != regexp
             ):
                 # Check if the regular expression already exists if a
                 # new expression is being created or if an existing
                 # regular expression has been modified.
-                if name_blacklist_set.getByRegExp(regexp) is not None:
+                if name_blocklist_set.getByRegExp(regexp) is not None:
                     self.setFieldError(
                         "regexp", "This regular expression already exists."
                     )
@@ -61,29 +61,29 @@ class NameBlacklistValidationMixin:
             self.setFieldError("regexp", "Invalid regular expression: %s" % e)
 
 
-class NameBlacklistEditView(
-    NameBlacklistValidationMixin, RegistryEditFormView
+class NameBlocklistEditView(
+    NameBlocklistValidationMixin, RegistryEditFormView
 ):
-    """View for editing a blacklist expression."""
+    """View for editing a blocklist expression."""
 
-    schema = INameBlacklist
+    schema = INameBlocklist
     field_names = ["regexp", "admin", "comment"]
-    label = "Edit a blacklist expression"
+    label = "Edit a blocklist expression"
     page_title = label
 
     @property
     def cancel_url(self):
-        return canonical_url(getUtility(INameBlacklistSet))
+        return canonical_url(getUtility(INameBlocklistSet))
 
     next_url = cancel_url
 
 
-class NameBlacklistAddView(NameBlacklistValidationMixin, LaunchpadFormView):
-    """View for adding a blacklist expression."""
+class NameBlocklistAddView(NameBlocklistValidationMixin, LaunchpadFormView):
+    """View for adding a blocklist expression."""
 
-    schema = INameBlacklist
+    schema = INameBlocklist
     field_names = ["regexp", "admin", "comment"]
-    label = "Add a new blacklist expression"
+    label = "Add a new blocklist expression"
     page_title = label
 
     custom_widget_regexp = CustomWidgetFactory(TextWidget, displayWidth=60)
@@ -95,66 +95,66 @@ class NameBlacklistAddView(NameBlacklistValidationMixin, LaunchpadFormView):
 
     next_url = cancel_url
 
-    @action("Add to blacklist", name="add")
+    @action("Add to blocklist", name="add")
     def add_action(self, action, data):
-        name_blacklist_set = getUtility(INameBlacklistSet)
-        name_blacklist_set.create(
+        name_blocklist_set = getUtility(INameBlocklistSet)
+        name_blocklist_set.create(
             regexp=data["regexp"],
             comment=data["comment"],
             admin=data["admin"],
         )
         self.request.response.addInfoNotification(
-            'Regular expression "%s" has been added to the name blacklist.'
+            'Regular expression "%s" has been added to the name blocklist.'
             % data["regexp"]
         )
 
 
-class NameBlacklistSetView(LaunchpadView):
-    """View for /+nameblacklists top level collection."""
+class NameBlocklistSetView(LaunchpadView):
+    """View for /+nameblocklists top level collection."""
 
-    label = "Blacklist for names of Launchpad pillars and persons"
+    label = "Blocklist for names of Launchpad pillars and persons"
     page_title = label
 
 
-class NameBlacklistSetNavigation(Navigation):
+class NameBlocklistSetNavigation(Navigation):
 
-    usedfor = INameBlacklistSet
+    usedfor = INameBlocklistSet
 
     def traverse(self, name):
         return self.context.get(name)
 
 
-class NameBlacklistSetNavigationMenu(NavigationMenu):
-    """Action menu for NameBlacklistSet."""
+class NameBlocklistSetNavigationMenu(NavigationMenu):
+    """Action menu for NameBlocklistSet."""
 
-    usedfor = INameBlacklistSet
+    usedfor = INameBlocklistSet
     facet = "overview"
     links = [
-        "add_blacklist_expression",
+        "add_blocklist_expression",
     ]
 
     @enabled_with_permission("launchpad.Edit")
-    def add_blacklist_expression(self):
-        return Link("+add", "Add blacklist expression", icon="add")
+    def add_blocklist_expression(self):
+        return Link("+add", "Add blocklist expression", icon="add")
 
 
-class NameBlacklistNavigationMenu(ApplicationMenu):
-    """Action menu for NameBlacklist."""
+class NameBlocklistNavigationMenu(ApplicationMenu):
+    """Action menu for NameBlocklist."""
 
-    usedfor = INameBlacklist
+    usedfor = INameBlocklist
     facet = "overview"
     links = [
-        "edit_blacklist_expression",
+        "edit_blocklist_expression",
     ]
 
     @enabled_with_permission("launchpad.Edit")
-    def edit_blacklist_expression(self):
-        return Link("+edit", "Edit blacklist expression", icon="edit")
+    def edit_blocklist_expression(self):
+        return Link("+edit", "Edit blocklist expression", icon="edit")
 
 
-@adapter(INameBlacklistSet)
+@adapter(INameBlocklistSet)
 @implementer(IBreadcrumb)
-class NameBlacklistSetBreadcrumb(Breadcrumb):
-    """Return a breadcrumb for an `INameBlackListSet`."""
+class NameBlocklistSetBreadcrumb(Breadcrumb):
+    """Return a breadcrumb for an `INameBlockListSet`."""
 
-    text = "Name Blacklist"
+    text = "Name Blocklist"
diff --git a/lib/lp/registry/browser/tests/nameblacklist-views.rst b/lib/lp/registry/browser/tests/nameblocklist-views.rst
similarity index 78%
rename from lib/lp/registry/browser/tests/nameblacklist-views.rst
rename to lib/lp/registry/browser/tests/nameblocklist-views.rst
index 47d3d80..ef6bfeb 100644
--- a/lib/lp/registry/browser/tests/nameblacklist-views.rst
+++ b/lib/lp/registry/browser/tests/nameblocklist-views.rst
@@ -1,12 +1,12 @@
-NameBlacklist pages
+NameBlocklist pages
 ===================
 
     >>> import transaction
     >>> from zope.component import getUtility
     >>> from lp.testing.sampledata import ADMIN_EMAIL
     >>> from lp.app.interfaces.launchpad import ILaunchpadCelebrities
-    >>> from lp.registry.interfaces.nameblacklist import INameBlacklistSet
-    >>> name_blacklist_set = getUtility(INameBlacklistSet)
+    >>> from lp.registry.interfaces.nameblocklist import INameBlocklistSet
+    >>> name_blocklist_set = getUtility(INameBlocklistSet)
     >>> from lp.testing.pages import extract_text, find_tag_by_id
     >>> registry_experts = getUtility(ILaunchpadCelebrities).registry_experts
     >>> registry_expert = factory.makePerson()
@@ -18,24 +18,24 @@ NameBlacklist pages
 View all
 --------
 
-All the blacklisted regular expressions that filter pillar names and
-person names can be seen on the /+nameblacklist page.
+All the blocklisted regular expressions that filter pillar names and
+person names can be seen on the /+nameblocklist page.
 
     >>> ignored = login_person(registry_expert)
     >>> view = create_initialized_view(
-    ...     name_blacklist_set, "+index", principal=registry_expert
+    ...     name_blocklist_set, "+index", principal=registry_expert
     ... )
     >>> print(
     ...     extract_text(
-    ...         find_tag_by_id(view.render(), "blacklist"), formatter="html"
+    ...         find_tag_by_id(view.render(), "blocklist"), formatter="html"
     ...     )
     ... )
     Regular Expression                   Admin    Comment
-    ^admin Edit blacklist expression     &mdash;
-    blacklist Edit blacklist expression  &mdash;  For testing purposes
+    ^admin Edit blocklist expression     &mdash;
+    blocklist Edit blocklist expression  &mdash;  For testing purposes
 
 
-Add expression to blacklist
+Add expression to blocklist
 ---------------------------
 
 An invalid regular expression cannot be added.
@@ -44,9 +44,9 @@ An invalid regular expression cannot be added.
     ...     "field.regexp": "(",
     ...     "field.admin": registry_experts.name,
     ...     "field.comment": "old-comment",
-    ...     "field.actions.add": "Add to blacklist",
+    ...     "field.actions.add": "Add to blocklist",
     ... }
-    >>> view = create_initialized_view(name_blacklist_set, "+add", form=form)
+    >>> view = create_initialized_view(name_blocklist_set, "+add", form=form)
     >>> for error in view.errors:
     ...     print(error)
     ...
@@ -54,8 +54,8 @@ An invalid regular expression cannot be added.
 
 A duplicate regular expression cannot be added.
 
-    >>> form["field.regexp"] = "blacklist"
-    >>> view = create_initialized_view(name_blacklist_set, "+add", form=form)
+    >>> form["field.regexp"] = "blocklist"
+    >>> view = create_initialized_view(name_blocklist_set, "+add", form=form)
     >>> for error in view.errors:
     ...     print(error)
     ...
@@ -64,21 +64,21 @@ A duplicate regular expression cannot be added.
 After adding a regular expression, a notification will be displayed.
 
     >>> form["field.regexp"] = "foo"
-    >>> view = create_initialized_view(name_blacklist_set, "+add", form=form)
+    >>> view = create_initialized_view(name_blocklist_set, "+add", form=form)
     >>> for notification in view.request.response.notifications:
     ...     print(notification.message)
     ...
-    Regular expression &quot;foo&quot; has been added to the name blacklist.
+    Regular expression &quot;foo&quot; has been added to the name blocklist.
 
     >>> transaction.commit()
-    >>> foo_exp = name_blacklist_set.getByRegExp("foo")
+    >>> foo_exp = name_blocklist_set.getByRegExp("foo")
     >>> print(foo_exp.regexp)
     foo
     >>> print(foo_exp.admin.name)
     registry
 
 
-Edit expression in blacklist
+Edit expression in blocklist
 ----------------------------
 
 When a regular expression is edited, it still must be valid.
@@ -97,7 +97,7 @@ When a regular expression is edited, it still must be valid.
 
 It cannot changed to conflict with another regular expression.
 
-    >>> form["field.regexp"] = "blacklist"
+    >>> form["field.regexp"] = "blocklist"
     >>> view = create_initialized_view(foo_exp, "+edit", form=form)
     >>> for error in view.errors:
     ...     print(error)
diff --git a/lib/lp/registry/browser/tests/test_breadcrumbs.py b/lib/lp/registry/browser/tests/test_breadcrumbs.py
index 1ecb14a..635ea95 100644
--- a/lib/lp/registry/browser/tests/test_breadcrumbs.py
+++ b/lib/lp/registry/browser/tests/test_breadcrumbs.py
@@ -5,7 +5,7 @@ from zope.component import getUtility
 
 from lp.app.interfaces.launchpad import ILaunchpadCelebrities
 from lp.registry.browser.tests.test_pillar_sharing import SharingBaseTestCase
-from lp.registry.interfaces.nameblacklist import INameBlacklistSet
+from lp.registry.interfaces.nameblocklist import INameBlocklistSet
 from lp.services.webapp.publisher import canonical_url
 from lp.testing import login_person
 from lp.testing.breadcrumbs import BaseBreadcrumbTestCase
@@ -155,26 +155,26 @@ class TestPollBreadcrumb(BaseBreadcrumbTestCase):
         self.assertEqual(self.poll.title, last_crumb.text)
 
 
-class TestNameblacklistBreadcrumb(BaseBreadcrumbTestCase):
-    """Test breadcrumbs for +nameblacklist."""
+class TestNameblocklistBreadcrumb(BaseBreadcrumbTestCase):
+    """Test breadcrumbs for +nameblocklist."""
 
     def setUp(self):
         super().setUp()
-        self.name_blacklist_set = getUtility(INameBlacklistSet)
+        self.name_blocklist_set = getUtility(INameBlocklistSet)
         self.registry_expert = self.factory.makeRegistryExpert()
         login_person(self.registry_expert)
 
-    def test_nameblacklist(self):
-        expected = [("Name Blacklist", "http://launchpad.test/+nameblacklist";)]
-        self.assertBreadcrumbs(expected, self.name_blacklist_set)
+    def test_nameblocklist(self):
+        expected = [("Name Blocklist", "http://launchpad.test/+nameblocklist";)]
+        self.assertBreadcrumbs(expected, self.name_blocklist_set)
 
-    def test_nameblacklist_edit(self):
-        blacklist = self.name_blacklist_set.getByRegExp("blacklist")
+    def test_nameblocklist_edit(self):
+        blocklist = self.name_blocklist_set.getByRegExp("blocklist")
         expected = [
-            ("Name Blacklist", "http://launchpad.test/+nameblacklist";),
+            ("Name Blocklist", "http://launchpad.test/+nameblocklist";),
             (
-                "Edit a blacklist expression",
-                "http://launchpad.test/+nameblacklist/1/+edit";,
+                "Edit a blocklist expression",
+                "http://launchpad.test/+nameblocklist/1/+edit";,
             ),
         ]
-        self.assertBreadcrumbs(expected, blacklist, view_name="+edit")
+        self.assertBreadcrumbs(expected, blocklist, view_name="+edit")
diff --git a/lib/lp/registry/configure.zcml b/lib/lp/registry/configure.zcml
index 585bbf1..64cb8a2 100644
--- a/lib/lp/registry/configure.zcml
+++ b/lib/lp/registry/configure.zcml
@@ -203,27 +203,27 @@
       <allow interface=".interfaces.productjob.IThirtyDayCommercialExpirationJob"/>
     </class>
 
-    <!-- INameBlacklist -->
+    <!-- INameBlocklist -->
     <securedutility
-        class="lp.registry.model.nameblacklist.NameBlacklistSet"
-        provides="lp.registry.interfaces.nameblacklist.INameBlacklistSet">
+        class="lp.registry.model.nameblocklist.NameBlocklistSet"
+        provides="lp.registry.interfaces.nameblocklist.INameBlocklistSet">
         <allow
-            interface="lp.registry.interfaces.nameblacklist.INameBlacklistSet"/>
+            interface="lp.registry.interfaces.nameblocklist.INameBlocklistSet"/>
     </securedutility>
 
-    <class class="lp.registry.model.nameblacklist.NameBlacklistSet">
+    <class class="lp.registry.model.nameblocklist.NameBlocklistSet">
         <require
             permission="launchpad.Edit"
-            interface="lp.registry.interfaces.nameblacklist.INameBlacklistSet"/>
+            interface="lp.registry.interfaces.nameblocklist.INameBlocklistSet"/>
     </class>
 
-    <class class="lp.registry.model.nameblacklist.NameBlacklist">
+    <class class="lp.registry.model.nameblocklist.NameBlocklist">
         <require
             permission="launchpad.View"
-            interface="lp.registry.interfaces.nameblacklist.INameBlacklist"/>
+            interface="lp.registry.interfaces.nameblocklist.INameBlocklist"/>
         <require
             permission="launchpad.Edit"
-            set_schema="lp.registry.interfaces.nameblacklist.INameBlacklist"/>
+            set_schema="lp.registry.interfaces.nameblocklist.INameBlocklist"/>
     </class>
 
     <!-- Location -->
diff --git a/lib/lp/registry/doc/pillar-aliases-field.rst b/lib/lp/registry/doc/pillar-aliases-field.rst
index 9e0294a..e9176f6 100644
--- a/lib/lp/registry/doc/pillar-aliases-field.rst
+++ b/lib/lp/registry/doc/pillar-aliases-field.rst
@@ -71,10 +71,10 @@ Also, they must not be identical to the pillar's own name.
     ...
     lp.app.validators.LaunchpadValidationError: This is your name: firefox
 
-Black-listed names are not accepted as aliases either.
+Blocklisted names are not accepted as aliases either.
 
-    >>> bound_field.validate("blacklisted")
+    >>> bound_field.validate("blocklisted")
     Traceback (most recent call last):
     ...
     lp.app.validators.LaunchpadValidationError:
-    The name &#x27;blacklisted&#x27; has been blocked...
+    The name &#x27;blocklisted&#x27; has been blocked...
diff --git a/lib/lp/registry/interfaces/nameblacklist.py b/lib/lp/registry/interfaces/nameblocklist.py
similarity index 70%
rename from lib/lp/registry/interfaces/nameblacklist.py
rename to lib/lp/registry/interfaces/nameblocklist.py
index fcac7fc..d418362 100644
--- a/lib/lp/registry/interfaces/nameblacklist.py
+++ b/lib/lp/registry/interfaces/nameblocklist.py
@@ -1,11 +1,11 @@
 # Copyright 2010 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
-"""NameBlacklist interfaces."""
+"""NameBlocklist interfaces."""
 
 __all__ = [
-    "INameBlacklist",
-    "INameBlacklistSet",
+    "INameBlocklist",
+    "INameBlocklistSet",
 ]
 
 from zope.interface import Interface
@@ -14,15 +14,15 @@ from zope.schema import Choice, Int, Text, TextLine
 from lp import _
 
 
-class INameBlacklist(Interface):
-    """The interface for the NameBlacklist table."""
+class INameBlocklist(Interface):
+    """The interface for the NameBlocklist table."""
 
     id = Int(title=_("ID"), required=True, readonly=True)
     regexp = TextLine(title=_("Regular expression"), required=True)
     comment = Text(
         title=_("Comment"),
         description=_(
-            "Why is the name blacklisted? Does the namespace belong to an "
+            "Why is the name blocklisted? Does the namespace belong to an "
             "organization or is the namespace reserved by the application?"
         ),
         required=False,
@@ -38,17 +38,17 @@ class INameBlacklist(Interface):
     )
 
 
-class INameBlacklistSet(Interface):
-    """The set of INameBlacklist objects."""
+class INameBlocklistSet(Interface):
+    """The set of INameBlocklist objects."""
 
     def getAll():
-        """Return all the name blacklist expressions."""
+        """Return all the name blocklist expressions."""
 
     def create(regexp, comment=None):
-        """Create and return a new NameBlacklist with given arguments."""
+        """Create and return a new NameBlocklist with given arguments."""
 
     def get(id):
-        """Return the NameBlacklist with the given id or None."""
+        """Return the NameBlocklist with the given id or None."""
 
     def getByRegExp(regexp):
-        """Return the NameBlacklist with the given regexp or None."""
+        """Return the NameBlocklist with the given regexp or None."""
diff --git a/lib/lp/registry/interfaces/person.py b/lib/lp/registry/interfaces/person.py
index 228b8e4..d962b73 100644
--- a/lib/lp/registry/interfaces/person.py
+++ b/lib/lp/registry/interfaces/person.py
@@ -130,7 +130,7 @@ from lp.registry.interfaces.teammembership import (
 from lp.registry.interfaces.wikiname import IWikiName
 from lp.services.database.sqlbase import block_implicit_flushes
 from lp.services.fields import (
-    BlacklistableContentNameField,
+    BlocklistableContentNameField,
     IconImageUpload,
     LogoImageUpload,
     MugshotImageUpload,
@@ -469,11 +469,11 @@ class PersonCreationRationale(DBEnumeratedType):
     )
 
 
-class PersonNameField(BlacklistableContentNameField):
-    """A `Person` team name, which is unique and performs pseudo blacklisting.
+class PersonNameField(BlocklistableContentNameField):
+    """A `Person` team name, which is unique and performs pseudo blocklisting.
 
     If the team name is not unique, and the clash is with a private team,
-    return the blacklist message.  Also return the blacklist message if the
+    return the blocklist message.  Also return the blocklist message if the
     private prefix is used but the user is not privileged to create private
     teams.
     """
@@ -500,19 +500,19 @@ class PersonNameField(BlacklistableContentNameField):
             # private prefix.
 
             if input.startswith(PRIVATE_TEAM_PREFIX):
-                raise LaunchpadValidationError(self.blacklistmessage % input)
+                raise LaunchpadValidationError(self.blocklistmessage % input)
 
             # If a non-privileged user attempts to use an existing name AND
-            # the existing project is private, then return the blacklist
+            # the existing project is private, then return the blocklist
             # message rather than the message indicating the project exists.
             existing_object = self._getByAttribute(input)
             if (
                 existing_object is not None
                 and existing_object.visibility != PersonVisibility.PUBLIC
             ):
-                raise LaunchpadValidationError(self.blacklistmessage % input)
+                raise LaunchpadValidationError(self.blocklistmessage % input)
 
-        # Perform the normal validation, including the real blacklist checks.
+        # Perform the normal validation, including the real blocklist checks.
         super()._validate(input)
 
 
@@ -2466,12 +2466,12 @@ class IPersonSetPublic(Interface):
     def getTopContributors(limit=50):
         """Return the top contributors in Launchpad, up to the given limit."""
 
-    def isNameBlacklisted(name, user=None):
-        """Is the given name blacklisted by Launchpad Administrators?
+    def isNameBlocklisted(name, user=None):
+        """Is the given name blocklisted by Launchpad Administrators?
 
         :param name: The name to be checked.
         :param user: The `IPerson` that wants to use the name. If the user
-            is an admin for the nameblacklist expression, they can use the
+            is an admin for the nameblocklist expression, they can use the
             name.
         """
 
diff --git a/lib/lp/registry/model/nameblacklist.py b/lib/lp/registry/model/nameblacklist.py
deleted file mode 100644
index a35d78c..0000000
--- a/lib/lp/registry/model/nameblacklist.py
+++ /dev/null
@@ -1,68 +0,0 @@
-# Copyright 2010 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-"""Classes for managing the NameBlacklist table."""
-
-__all__ = [
-    "NameBlacklist",
-    "NameBlacklistSet",
-]
-
-
-from storm.locals import Int, Reference, Unicode
-from zope.interface import implementer
-
-from lp.registry.interfaces.nameblacklist import (
-    INameBlacklist,
-    INameBlacklistSet,
-)
-from lp.registry.model.person import Person
-from lp.services.database.interfaces import IStore
-from lp.services.database.stormbase import StormBase
-
-
-@implementer(INameBlacklist)
-class NameBlacklist(StormBase):
-    """Class for the NameBlacklist table."""
-
-    __storm_table__ = "NameBlacklist"
-
-    id = Int(primary=True)
-    regexp = Unicode(name="regexp", allow_none=False)
-    comment = Unicode(name="comment", allow_none=True)
-    admin_id = Int(name="admin", allow_none=True)
-    admin = Reference(admin_id, Person.id)
-
-
-@implementer(INameBlacklistSet)
-class NameBlacklistSet:
-    """Class for creating and retrieving NameBlacklist objects."""
-
-    def getAll(self):
-        """See `INameBlacklistSet`."""
-        store = IStore(NameBlacklist)
-        return store.find(NameBlacklist).order_by(NameBlacklist.regexp)
-
-    def create(self, regexp, comment=None, admin=None):
-        """See `INameBlacklistSet`."""
-        nameblacklist = NameBlacklist()
-        nameblacklist.regexp = regexp
-        nameblacklist.comment = comment
-        nameblacklist.admin = admin
-        store = IStore(NameBlacklist)
-        store.add(nameblacklist)
-        return nameblacklist
-
-    def get(self, id):
-        """See `INameBlacklistSet`."""
-        try:
-            id = int(id)
-        except ValueError:
-            return None
-        store = IStore(NameBlacklist)
-        return store.find(NameBlacklist, NameBlacklist.id == id).one()
-
-    def getByRegExp(self, regexp):
-        """See `INameBlacklistSet`."""
-        store = IStore(NameBlacklist)
-        return store.find(NameBlacklist, NameBlacklist.regexp == regexp).one()
diff --git a/lib/lp/registry/model/nameblocklist.py b/lib/lp/registry/model/nameblocklist.py
new file mode 100644
index 0000000..157726a
--- /dev/null
+++ b/lib/lp/registry/model/nameblocklist.py
@@ -0,0 +1,68 @@
+# Copyright 2010 Canonical Ltd.  This software is licensed under the
+# GNU Affero General Public License version 3 (see the file LICENSE).
+
+"""Classes for managing the NameBlocklist table."""
+
+__all__ = [
+    "NameBlocklist",
+    "NameBlocklistSet",
+]
+
+
+from storm.locals import Int, Reference, Unicode
+from zope.interface import implementer
+
+from lp.registry.interfaces.nameblocklist import (
+    INameBlocklist,
+    INameBlocklistSet,
+)
+from lp.registry.model.person import Person
+from lp.services.database.interfaces import IStore
+from lp.services.database.stormbase import StormBase
+
+
+@implementer(INameBlocklist)
+class NameBlocklist(StormBase):
+    """Class for the NameBlocklist table."""
+
+    __storm_table__ = "NameBlocklist"
+
+    id = Int(primary=True)
+    regexp = Unicode(name="regexp", allow_none=False)
+    comment = Unicode(name="comment", allow_none=True)
+    admin_id = Int(name="admin", allow_none=True)
+    admin = Reference(admin_id, Person.id)
+
+
+@implementer(INameBlocklistSet)
+class NameBlocklistSet:
+    """Class for creating and retrieving NameBlocklist objects."""
+
+    def getAll(self):
+        """See `INameBlocklistSet`."""
+        store = IStore(NameBlocklist)
+        return store.find(NameBlocklist).order_by(NameBlocklist.regexp)
+
+    def create(self, regexp, comment=None, admin=None):
+        """See `INameBlocklistSet`."""
+        nameblocklist = NameBlocklist()
+        nameblocklist.regexp = regexp
+        nameblocklist.comment = comment
+        nameblocklist.admin = admin
+        store = IStore(NameBlocklist)
+        store.add(nameblocklist)
+        return nameblocklist
+
+    def get(self, id):
+        """See `INameBlocklistSet`."""
+        try:
+            id = int(id)
+        except ValueError:
+            return None
+        store = IStore(NameBlocklist)
+        return store.find(NameBlocklist, NameBlocklist.id == id).one()
+
+    def getByRegExp(self, regexp):
+        """See `INameBlocklistSet`."""
+        store = IStore(NameBlocklist)
+        return store.find(NameBlocklist, NameBlocklist.regexp == regexp).one()
diff --git a/lib/lp/registry/model/person.py b/lib/lp/registry/model/person.py
index bfdee1a..175ccfc 100644
--- a/lib/lp/registry/model/person.py
+++ b/lib/lp/registry/model/person.py
@@ -3794,7 +3794,7 @@ class PersonSet:
     def __init__(self):
         self.title = "People registered with Launchpad"
 
-    def isNameBlacklisted(self, name, user=None):
+    def isNameBlocklisted(self, name, user=None):
         """See `IPersonSet`."""
         if user is None:
             user_id = 0
@@ -3802,7 +3802,7 @@ class PersonSet:
             user_id = user.id
         cur = cursor()
         cur.execute(
-            "SELECT is_blacklisted_name(%(name)s, %(user_id)s)",
+            "SELECT is_blocklisted_name(%(name)s, %(user_id)s)",
             {"name": name, "user_id": user_id},
         )
         return bool(cur.fetchone()[0])
@@ -5311,7 +5311,7 @@ def generate_nick(email_addr, is_registered=_is_nick_registered):
 
     It is technically possible for this function to raise a
     NicknameGenerationError, but this will only occur if an operator
-    has majorly screwed up the name blacklist.
+    has majorly screwed up the name blocklist.
     """
     email_addr = email_addr.strip().lower()
 
@@ -5330,7 +5330,7 @@ def generate_nick(email_addr, is_registered=_is_nick_registered):
             return False
         elif is_registered(nick):
             return False
-        elif person_set.isNameBlacklisted(nick):
+        elif person_set.isNameBlocklisted(nick):
             return False
         else:
             return True
@@ -5381,7 +5381,7 @@ def generate_nick(email_addr, is_registered=_is_nick_registered):
         raise NicknameGenerationError(
             "No nickname could be generated. "
             "This should be impossible to trigger unless some twonk has "
-            "registered a match everything regexp in the black list."
+            "registered a match everything regexp in the blocklist."
         )
 
     finally:
diff --git a/lib/lp/registry/scripts/closeaccount.py b/lib/lp/registry/scripts/closeaccount.py
index fce1289..505f4e8 100644
--- a/lib/lp/registry/scripts/closeaccount.py
+++ b/lib/lp/registry/scripts/closeaccount.py
@@ -86,7 +86,7 @@ def close_account(username, log):
     def table_notification(table):
         log.debug("Handling the %s table" % table)
 
-    # All names starting with 'removed' are blacklisted, so this will always
+    # All names starting with 'removed' are blocklisted, so this will always
     # succeed.
     new_name = "removed%d" % person.id
 
diff --git a/lib/lp/registry/security.py b/lib/lp/registry/security.py
index ad48865..17c201f 100644
--- a/lib/lp/registry/security.py
+++ b/lib/lp/registry/security.py
@@ -41,9 +41,9 @@ from lp.registry.interfaces.gpg import IGPGKey
 from lp.registry.interfaces.irc import IIrcID
 from lp.registry.interfaces.location import IPersonLocation
 from lp.registry.interfaces.milestone import IMilestone, IProjectGroupMilestone
-from lp.registry.interfaces.nameblacklist import (
-    INameBlacklist,
-    INameBlacklistSet,
+from lp.registry.interfaces.nameblocklist import (
+    INameBlocklist,
+    INameBlocklistSet,
 )
 from lp.registry.interfaces.ociproject import IOCIProject
 from lp.registry.interfaces.ociprojectseries import IOCIProjectSeries
@@ -1211,24 +1211,24 @@ class AddPOTemplate(OnlyRosettaExpertsAndAdmins):
     usedfor = IProductSeries
 
 
-class ViewNameBlacklist(EditByRegistryExpertsOrAdmins):
+class ViewNameBlocklist(EditByRegistryExpertsOrAdmins):
     permission = "launchpad.View"
-    usedfor = INameBlacklist
+    usedfor = INameBlocklist
 
 
-class EditNameBlacklist(EditByRegistryExpertsOrAdmins):
+class EditNameBlocklist(EditByRegistryExpertsOrAdmins):
     permission = "launchpad.Edit"
-    usedfor = INameBlacklist
+    usedfor = INameBlocklist
 
 
-class ViewNameBlacklistSet(EditByRegistryExpertsOrAdmins):
+class ViewNameBlocklistSet(EditByRegistryExpertsOrAdmins):
     permission = "launchpad.View"
-    usedfor = INameBlacklistSet
+    usedfor = INameBlocklistSet
 
 
-class EditNameBlacklistSet(EditByRegistryExpertsOrAdmins):
+class EditNameBlocklistSet(EditByRegistryExpertsOrAdmins):
     permission = "launchpad.Edit"
-    usedfor = INameBlacklistSet
+    usedfor = INameBlocklistSet
 
 
 class AdminDistroSeriesTranslations(AuthorizationBase):
diff --git a/lib/lp/registry/stories/object/xx-nameblacklist.rst b/lib/lp/registry/stories/object/xx-nameblocklist.rst
similarity index 73%
rename from lib/lp/registry/stories/object/xx-nameblacklist.rst
rename to lib/lp/registry/stories/object/xx-nameblocklist.rst
index d820568..9b05b9b 100644
--- a/lib/lp/registry/stories/object/xx-nameblacklist.rst
+++ b/lib/lp/registry/stories/object/xx-nameblocklist.rst
@@ -1,29 +1,29 @@
-The NameBlacklist table contains a central blacklist of disallowed names.
-For objects using this blacklist, it is impossible to create an object
-with a blacklisted name, or rename an object to a blacklisted name.
+The NameBlocklist table contains a central blocklist of disallowed names.
+For objects using this blocklist, it is impossible to create an object
+with a blocklisted name, or rename an object to a blocklisted name.
 
-Try creating a project with a blacklisted name:
+Try creating a project with a blocklisted name:
 
     >>> admin_browser.open("http://launchpad.test/projectgroups/+new";)
-    >>> admin_browser.getControl("Name", index=0).value = "blacklisted"
+    >>> admin_browser.getControl("Name", index=0).value = "blocklisted"
     >>> admin_browser.getControl("Display Name").value = "Whatever"
     >>> admin_browser.getControl("Project Group Summary").value = "Whatever"
     >>> admin_browser.getControl("Description").value = "Whatever"
     >>> admin_browser.getControl("Add").click()
     >>> (
-    ...     "The name &#x27;blacklisted&#x27; has been blocked"
+    ...     "The name &#x27;blocklisted&#x27; has been blocked"
     ...     in admin_browser.contents
     ... )
     True
 
-Try renaming a project to a blacklisted name:
+Try renaming a project to a blocklisted name:
 
     >>> admin_browser.open("http://launchpad.test/mozilla";)
     >>> admin_browser.getLink("Administer").click()
-    >>> admin_browser.getControl("Name", index=0).value = "blacklisted"
+    >>> admin_browser.getControl("Name", index=0).value = "blocklisted"
     >>> admin_browser.getControl("Change Details").click()
     >>> (
-    ...     "The name &#x27;blacklisted&#x27; has been blocked"
+    ...     "The name &#x27;blocklisted&#x27; has been blocked"
     ...     in admin_browser.contents
     ... )
     True
@@ -32,10 +32,10 @@ Same behaviour for products:
 
     >>> admin_browser.open("http://launchpad.test/firefox";)
     >>> admin_browser.getLink("Administer").click()
-    >>> admin_browser.getControl("Name").value = "blacklisted"
+    >>> admin_browser.getControl("Name").value = "blocklisted"
     >>> admin_browser.getControl("Change").click()
     >>> (
-    ...     "The name &#x27;blacklisted&#x27; has been blocked"
+    ...     "The name &#x27;blocklisted&#x27; has been blocked"
     ...     in admin_browser.contents
     ... )
     True
@@ -52,14 +52,14 @@ Same behaviour for people:
     ... )
     True
 
-Note that it is possible to have an object with a blacklisted name. These
-objects were either created before the blacklist was implemented, or have
+Note that it is possible to have an object with a blocklisted name. These
+objects were either created before the blocklist was implemented, or have
 been created or renamed manually by the DBA. Being able to manually set
-names to a blacklisted name is a desirable feature, as a use case of
-the black list is to prevent social engineering attacks by pretending to
+names to a blocklisted name is a desirable feature, as a use case of
+the blocklist is to prevent social engineering attacks by pretending to
 be a Launchpad Celebrity.
 
-We can edit the details of an object with a blacklisted name quite
+We can edit the details of an object with a blocklisted name quite
 happily without generating
 
     >>> admin_browser.open("http://launchpad.test/~admins";)
diff --git a/lib/lp/registry/templates/nameblacklists-index.pt b/lib/lp/registry/templates/nameblocklists-index.pt
similarity index 90%
rename from lib/lp/registry/templates/nameblacklists-index.pt
rename to lib/lp/registry/templates/nameblocklists-index.pt
index d9af3be..20f6472 100644
--- a/lib/lp/registry/templates/nameblacklists-index.pt
+++ b/lib/lp/registry/templates/nameblocklists-index.pt
@@ -17,19 +17,19 @@
 
     <div metal:fill-slot="main" class="main-portlet">
       <p>
-        There are two kinds of blacklisted names:
+        There are two kinds of blocklisted names:
       </p>
       <ul class="bulleted">
         <li>
-          Organisational blacklisted names have an administering team
+          Organisational blocklisted names have an administering team
           that is permitted to use the name for projects and teams.
          </li>
         <li>
-          Application blacklisted names cannot have an administering team.
+          Application blocklisted names cannot have an administering team.
           No one can override them.
          </li>
       </ul>
-      <table id="blacklist" class="listing sortable">
+      <table id="blocklist" class="listing sortable">
         <thead>
           <th>Regular Expression</th>
           <th>Admin</th>
@@ -41,7 +41,7 @@
               <tt tal:content="item/regexp"/>
               <tal:link replace="
                 structure
-                item/menu:overview/edit_blacklist_expression/fmt:icon"/>
+                item/menu:overview/edit_blocklist_expression/fmt:icon"/>
             </td>
             <td>
               <a
diff --git a/lib/lp/registry/tests/test_nameblacklist.py b/lib/lp/registry/tests/test_nameblacklist.py
deleted file mode 100644
index 3b41e88..0000000
--- a/lib/lp/registry/tests/test_nameblacklist.py
+++ /dev/null
@@ -1,214 +0,0 @@
-# Copyright 2009 Canonical Ltd.  This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-"""Test the person_sort_key stored procedure."""
-
-from zope.component import getUtility
-from zope.interface.verify import verifyObject
-
-from lp.app.interfaces.launchpad import ILaunchpadCelebrities
-from lp.registry.interfaces.nameblacklist import (
-    INameBlacklist,
-    INameBlacklistSet,
-)
-from lp.services.database.interfaces import IStore
-from lp.services.webapp.authorization import check_permission
-from lp.testing import ANONYMOUS, TestCaseWithFactory, login, login_celebrity
-from lp.testing.layers import DatabaseFunctionalLayer, ZopelessDatabaseLayer
-
-
-class TestNameBlacklist(TestCaseWithFactory):
-    layer = ZopelessDatabaseLayer
-
-    def setUp(self):
-        super().setUp()
-        self.name_blacklist_set = getUtility(INameBlacklistSet)
-        self.caret_foo_exp = self.name_blacklist_set.create("^foo")
-        self.foo_exp = self.name_blacklist_set.create("foo")
-        self.verbose_exp = self.name_blacklist_set.create("v e r b o s e")
-        team = self.factory.makeTeam()
-        self.admin_exp = self.name_blacklist_set.create("fnord", admin=team)
-        self.store = IStore(self.foo_exp)
-        self.store.flush()
-
-    def name_blacklist_match(self, name, user_id=None):
-        """Return the result of the name_blacklist_match stored procedure."""
-        user_id = user_id or 0
-        result = self.store.execute(
-            "SELECT name_blacklist_match(%s, %s)", (name, user_id)
-        )
-        return result.get_one()[0]
-
-    def is_blacklisted_name(self, name, user_id=None):
-        """Return the result of the is_blacklisted_name stored procedure."""
-        user_id = user_id or 0
-        result = self.store.execute(
-            "SELECT is_blacklisted_name(%s, %s)", (name, user_id)
-        )
-        blacklisted = result.get_one()[0]
-        self.assertIsNotNone(blacklisted, "is_blacklisted_name returned NULL")
-        return bool(blacklisted)
-
-    def test_name_blacklist_match(self):
-
-        # A name that is not blacklisted returns NULL/None
-        self.assertIsNone(self.name_blacklist_match("bar"))
-
-        # A name that is blacklisted returns the id of the row in the
-        # NameBlacklist table that matched. Rows are tried in order, and the
-        # first match is returned.
-        self.assertEqual(
-            self.name_blacklist_match("foobar"), self.caret_foo_exp.id
-        )
-        self.assertEqual(self.name_blacklist_match("barfoo"), self.foo_exp.id)
-
-    def test_name_blacklist_match_admin_does_not_match(self):
-        # A user in the expresssion's admin team is exempt from the
-        # backlisted name restriction.
-        user = self.admin_exp.admin.teamowner
-        self.assertEqual(None, self.name_blacklist_match("fnord", user.id))
-
-    def test_name_blacklist_match_launchpad_admin_can_change(self):
-        # A Launchpad admin is exempt from any backlisted name restriction
-        # that has an admin.
-        user = self.factory.makePerson()
-        admins = getUtility(ILaunchpadCelebrities).admin
-        admins.addMember(user, user)
-        self.assertEqual(None, self.name_blacklist_match("fnord", user.id))
-
-    def test_name_blacklist_match_launchpad_admin_cannot_change(self):
-        # A Launchpad admin cannot override backlisted names without admins.
-        user = self.factory.makePerson()
-        admins = getUtility(ILaunchpadCelebrities).admin
-        admins.addMember(user, user)
-        self.assertEqual(
-            self.foo_exp.id, self.name_blacklist_match("barfoo", user.id)
-        )
-
-    def test_name_blacklist_match_cache(self):
-        # If the blacklist is changed in the DB, these changes are noticed.
-        # This test is needed because the stored procedure keeps a cache
-        # of the compiled regular expressions.
-        self.assertEqual(
-            self.name_blacklist_match("foobar"), self.caret_foo_exp.id
-        )
-        self.caret_foo_exp.regexp = "nomatch"
-        self.assertEqual(self.name_blacklist_match("foobar"), self.foo_exp.id)
-        self.foo_exp.regexp = "nomatch2"
-        self.assertIsNone(self.name_blacklist_match("foobar"))
-
-    def test_is_blacklisted_name(self):
-        # is_blacklisted_name() is just a wrapper around name_blacklist_match
-        # that is friendlier to use in a boolean context.
-        self.assertFalse(self.is_blacklisted_name("bar"))
-        self.assertTrue(self.is_blacklisted_name("foo"))
-        self.caret_foo_exp.regexp = "bar"
-        self.foo_exp.regexp = "bar2"
-        self.assertFalse(self.is_blacklisted_name("foo"))
-
-    def test_is_blacklisted_name_admin_false(self):
-        # Users in the expression's admin team are will return False.
-        user = self.admin_exp.admin.teamowner
-        self.assertFalse(self.is_blacklisted_name("fnord", user.id))
-
-    def test_case_insensitive(self):
-        self.assertTrue(self.is_blacklisted_name("Foo"))
-
-    def test_verbose(self):
-        # Testing the VERBOSE flag is used when compiling the regexp
-        self.assertTrue(self.is_blacklisted_name("verbose"))
-
-
-class TestNameBlacklistSet(TestCaseWithFactory):
-
-    layer = DatabaseFunctionalLayer
-
-    def setUp(self):
-        super().setUp()
-        login_celebrity("registry_experts")
-        self.name_blacklist_set = getUtility(INameBlacklistSet)
-
-    def test_create_with_one_arg(self):
-        # Test NameBlacklistSet.create(regexp).
-        name_blacklist = self.name_blacklist_set.create("foo")
-        self.assertTrue(verifyObject(INameBlacklist, name_blacklist))
-        self.assertEqual("foo", name_blacklist.regexp)
-        self.assertIs(None, name_blacklist.comment)
-
-    def test_create_with_two_args(self):
-        # Test NameBlacklistSet.create(regexp, comment).
-        name_blacklist = self.name_blacklist_set.create("foo", "bar")
-        self.assertTrue(verifyObject(INameBlacklist, name_blacklist))
-        self.assertEqual("foo", name_blacklist.regexp)
-        self.assertEqual("bar", name_blacklist.comment)
-
-    def test_create_with_three_args(self):
-        # Test NameBlacklistSet.create(regexp, comment, admin).
-        team = self.factory.makeTeam()
-        name_blacklist = self.name_blacklist_set.create("foo", "bar", team)
-        self.assertTrue(verifyObject(INameBlacklist, name_blacklist))
-        self.assertEqual("foo", name_blacklist.regexp)
-        self.assertEqual("bar", name_blacklist.comment)
-        self.assertEqual(team, name_blacklist.admin)
-
-    def test_get_int(self):
-        # Test NameBlacklistSet.get() with int id.
-        name_blacklist = self.name_blacklist_set.create("foo", "bar")
-        store = IStore(name_blacklist)
-        store.flush()
-        retrieved = self.name_blacklist_set.get(name_blacklist.id)
-        self.assertEqual(name_blacklist, retrieved)
-
-    def test_get_string(self):
-        # Test NameBlacklistSet.get() with string id.
-        name_blacklist = self.name_blacklist_set.create("foo", "bar")
-        store = IStore(name_blacklist)
-        store.flush()
-        retrieved = self.name_blacklist_set.get(str(name_blacklist.id))
-        self.assertEqual(name_blacklist, retrieved)
-
-    def test_get_returns_None_instead_of_ValueError(self):
-        # Test that NameBlacklistSet.get() will return None instead of
-        # raising a ValueError when it tries to cast the id to an int,
-        # so that traversing an invalid url causes a Not Found error
-        # instead of an error that is recorded as an oops.
-        self.assertIs(None, self.name_blacklist_set.get("asdf"))
-
-    def test_getAll(self):
-        # Test NameBlacklistSet.getAll().
-        result = [
-            (item.regexp, item.comment)
-            for item in self.name_blacklist_set.getAll()
-        ]
-        expected = [
-            ("^admin", None),
-            ("blacklist", "For testing purposes"),
-        ]
-        self.assertEqual(expected, result)
-
-    def test_NameBlacklistSet_permissions(self):
-        # Verify that non-registry-experts do not have permission to
-        # access the NameBlacklistSet.
-        self.assertTrue(
-            check_permission("launchpad.View", self.name_blacklist_set)
-        )
-        self.assertTrue(
-            check_permission("launchpad.Edit", self.name_blacklist_set)
-        )
-        login(ANONYMOUS)
-        self.assertFalse(
-            check_permission("launchpad.View", self.name_blacklist_set)
-        )
-        self.assertFalse(
-            check_permission("launchpad.Edit", self.name_blacklist_set)
-        )
-
-    def test_NameBlacklist_permissions(self):
-        # Verify that non-registry-experts do not have permission to
-        # access the NameBlacklist.
-        name_blacklist = self.name_blacklist_set.create("foo")
-        self.assertTrue(check_permission("launchpad.View", name_blacklist))
-        self.assertTrue(check_permission("launchpad.Edit", name_blacklist))
-        login(ANONYMOUS)
-        self.assertFalse(check_permission("launchpad.View", name_blacklist))
-        self.assertFalse(check_permission("launchpad.Edit", name_blacklist))
diff --git a/lib/lp/registry/tests/test_nameblocklist.py b/lib/lp/registry/tests/test_nameblocklist.py
new file mode 100644
index 0000000..d92ee61
--- /dev/null
+++ b/lib/lp/registry/tests/test_nameblocklist.py
@@ -0,0 +1,214 @@
+# Copyright 2009 Canonical Ltd.  This software is licensed under the
+# GNU Affero General Public License version 3 (see the file LICENSE).
+
+"""Test the person_sort_key stored procedure."""
+
+from zope.component import getUtility
+from zope.interface.verify import verifyObject
+
+from lp.app.interfaces.launchpad import ILaunchpadCelebrities
+from lp.registry.interfaces.nameblocklist import (
+    INameBlocklist,
+    INameBlocklistSet,
+)
+from lp.services.database.interfaces import IStore
+from lp.services.webapp.authorization import check_permission
+from lp.testing import ANONYMOUS, TestCaseWithFactory, login, login_celebrity
+from lp.testing.layers import DatabaseFunctionalLayer, ZopelessDatabaseLayer
+
+
+class TestNameBlocklist(TestCaseWithFactory):
+    layer = ZopelessDatabaseLayer
+
+    def setUp(self):
+        super().setUp()
+        self.name_blocklist_set = getUtility(INameBlocklistSet)
+        self.caret_foo_exp = self.name_blocklist_set.create("^foo")
+        self.foo_exp = self.name_blocklist_set.create("foo")
+        self.verbose_exp = self.name_blocklist_set.create("v e r b o s e")
+        team = self.factory.makeTeam()
+        self.admin_exp = self.name_blocklist_set.create("fnord", admin=team)
+        self.store = IStore(self.foo_exp)
+        self.store.flush()
+
+    def name_blocklist_match(self, name, user_id=None):
+        """Return the result of the name_blocklist_match stored procedure."""
+        user_id = user_id or 0
+        result = self.store.execute(
+            "SELECT name_blocklist_match(%s, %s)", (name, user_id)
+        )
+        return result.get_one()[0]
+
+    def is_blocklisted_name(self, name, user_id=None):
+        """Return the result of the is_blocklisted_name stored procedure."""
+        user_id = user_id or 0
+        result = self.store.execute(
+            "SELECT is_blocklisted_name(%s, %s)", (name, user_id)
+        )
+        blocklisted = result.get_one()[0]
+        self.assertIsNotNone(blocklisted, "is_blocklisted_name returned NULL")
+        return bool(blocklisted)
+
+    def test_name_blocklist_match(self):
+
+        # A name that is not blocklisted returns NULL/None
+        self.assertIsNone(self.name_blocklist_match("bar"))
+
+        # A name that is blocklisted returns the id of the row in the
+        # NameBlocklist table that matched. Rows are tried in order, and the
+        # first match is returned.
+        self.assertEqual(
+            self.name_blocklist_match("foobar"), self.caret_foo_exp.id
+        )
+        self.assertEqual(self.name_blocklist_match("barfoo"), self.foo_exp.id)
+
+    def test_name_blocklist_match_admin_does_not_match(self):
+        # A user in the expresssion's admin team is exempt from the
+        # blocklisted name restriction.
+        user = self.admin_exp.admin.teamowner
+        self.assertEqual(None, self.name_blocklist_match("fnord", user.id))
+
+    def test_name_blocklist_match_launchpad_admin_can_change(self):
+        # A Launchpad admin is exempt from any blocklisted name restriction
+        # that has an admin.
+        user = self.factory.makePerson()
+        admins = getUtility(ILaunchpadCelebrities).admin
+        admins.addMember(user, user)
+        self.assertEqual(None, self.name_blocklist_match("fnord", user.id))
+
+    def test_name_blocklist_match_launchpad_admin_cannot_change(self):
+        # A Launchpad admin cannot override blocklisted names without admins.
+        user = self.factory.makePerson()
+        admins = getUtility(ILaunchpadCelebrities).admin
+        admins.addMember(user, user)
+        self.assertEqual(
+            self.foo_exp.id, self.name_blocklist_match("barfoo", user.id)
+        )
+
+    def test_name_blocklist_match_cache(self):
+        # If the blocklist is changed in the DB, these changes are noticed.
+        # This test is needed because the stored procedure keeps a cache
+        # of the compiled regular expressions.
+        self.assertEqual(
+            self.name_blocklist_match("foobar"), self.caret_foo_exp.id
+        )
+        self.caret_foo_exp.regexp = "nomatch"
+        self.assertEqual(self.name_blocklist_match("foobar"), self.foo_exp.id)
+        self.foo_exp.regexp = "nomatch2"
+        self.assertIsNone(self.name_blocklist_match("foobar"))
+
+    def test_is_blocklisted_name(self):
+        # is_blocklisted_name() is just a wrapper around name_blocklist_match
+        # that is friendlier to use in a boolean context.
+        self.assertFalse(self.is_blocklisted_name("bar"))
+        self.assertTrue(self.is_blocklisted_name("foo"))
+        self.caret_foo_exp.regexp = "bar"
+        self.foo_exp.regexp = "bar2"
+        self.assertFalse(self.is_blocklisted_name("foo"))
+
+    def test_is_blocklisted_name_admin_false(self):
+        # Users in the expression's admin team are will return False.
+        user = self.admin_exp.admin.teamowner
+        self.assertFalse(self.is_blocklisted_name("fnord", user.id))
+
+    def test_case_insensitive(self):
+        self.assertTrue(self.is_blocklisted_name("Foo"))
+
+    def test_verbose(self):
+        # Testing the VERBOSE flag is used when compiling the regexp
+        self.assertTrue(self.is_blocklisted_name("verbose"))
+
+
+class TestNameBlocklistSet(TestCaseWithFactory):
+
+    layer = DatabaseFunctionalLayer
+
+    def setUp(self):
+        super().setUp()
+        login_celebrity("registry_experts")
+        self.name_blocklist_set = getUtility(INameBlocklistSet)
+
+    def test_create_with_one_arg(self):
+        # Test NameBlocklistSet.create(regexp).
+        name_blocklist = self.name_blocklist_set.create("foo")
+        self.assertTrue(verifyObject(INameBlocklist, name_blocklist))
+        self.assertEqual("foo", name_blocklist.regexp)
+        self.assertIs(None, name_blocklist.comment)
+
+    def test_create_with_two_args(self):
+        # Test NameBlocklistSet.create(regexp, comment).
+        name_blocklist = self.name_blocklist_set.create("foo", "bar")
+        self.assertTrue(verifyObject(INameBlocklist, name_blocklist))
+        self.assertEqual("foo", name_blocklist.regexp)
+        self.assertEqual("bar", name_blocklist.comment)
+
+    def test_create_with_three_args(self):
+        # Test NameBlocklistSet.create(regexp, comment, admin).
+        team = self.factory.makeTeam()
+        name_blocklist = self.name_blocklist_set.create("foo", "bar", team)
+        self.assertTrue(verifyObject(INameBlocklist, name_blocklist))
+        self.assertEqual("foo", name_blocklist.regexp)
+        self.assertEqual("bar", name_blocklist.comment)
+        self.assertEqual(team, name_blocklist.admin)
+
+    def test_get_int(self):
+        # Test NameBlocklistSet.get() with int id.
+        name_blocklist = self.name_blocklist_set.create("foo", "bar")
+        store = IStore(name_blocklist)
+        store.flush()
+        retrieved = self.name_blocklist_set.get(name_blocklist.id)
+        self.assertEqual(name_blocklist, retrieved)
+
+    def test_get_string(self):
+        # Test NameBlocklistSet.get() with string id.
+        name_blocklist = self.name_blocklist_set.create("foo", "bar")
+        store = IStore(name_blocklist)
+        store.flush()
+        retrieved = self.name_blocklist_set.get(str(name_blocklist.id))
+        self.assertEqual(name_blocklist, retrieved)
+
+    def test_get_returns_None_instead_of_ValueError(self):
+        # Test that NameBlocklistSet.get() will return None instead of
+        # raising a ValueError when it tries to cast the id to an int,
+        # so that traversing an invalid url causes a Not Found error
+        # instead of an error that is recorded as an oops.
+        self.assertIs(None, self.name_blocklist_set.get("asdf"))
+
+    def test_getAll(self):
+        # Test NameBlocklistSet.getAll().
+        result = [
+            (item.regexp, item.comment)
+            for item in self.name_blocklist_set.getAll()
+        ]
+        expected = [
+            ("^admin", None),
+            ("blocklist", "For testing purposes"),
+        ]
+        self.assertEqual(expected, result)
+
+    def test_NameBlocklistSet_permissions(self):
+        # Verify that non-registry-experts do not have permission to
+        # access the NameBlocklistSet.
+        self.assertTrue(
+            check_permission("launchpad.View", self.name_blocklist_set)
+        )
+        self.assertTrue(
+            check_permission("launchpad.Edit", self.name_blocklist_set)
+        )
+        login(ANONYMOUS)
+        self.assertFalse(
+            check_permission("launchpad.View", self.name_blocklist_set)
+        )
+        self.assertFalse(
+            check_permission("launchpad.Edit", self.name_blocklist_set)
+        )
+
+    def test_NameBlocklist_permissions(self):
+        # Verify that non-registry-experts do not have permission to
+        # access the NameBlocklist.
+        name_blocklist = self.name_blocklist_set.create("foo")
+        self.assertTrue(check_permission("launchpad.View", name_blocklist))
+        self.assertTrue(check_permission("launchpad.Edit", name_blocklist))
+        login(ANONYMOUS)
+        self.assertFalse(check_permission("launchpad.View", name_blocklist))
+        self.assertFalse(check_permission("launchpad.Edit", name_blocklist))
diff --git a/lib/lp/registry/tests/test_personset.py b/lib/lp/registry/tests/test_personset.py
index 1469c89..9eb351d 100644
--- a/lib/lp/registry/tests/test_personset.py
+++ b/lib/lp/registry/tests/test_personset.py
@@ -27,7 +27,7 @@ from lp.registry.errors import (
     NoSuchAccount,
     NotPlaceholderAccount,
 )
-from lp.registry.interfaces.nameblacklist import INameBlacklistSet
+from lp.registry.interfaces.nameblocklist import INameBlocklistSet
 from lp.registry.interfaces.person import (
     IPerson,
     IPersonSet,
@@ -96,21 +96,21 @@ class TestPersonSet(TestCaseWithFactory):
         self.addCleanup(logout)
         self.person_set = getUtility(IPersonSet)
 
-    def test_isNameBlacklisted(self):
+    def test_isNameBlocklisted(self):
         cursor().execute(
-            "INSERT INTO NameBlacklist(id, regexp) VALUES (-100, 'foo')"
+            "INSERT INTO NameBlocklist(id, regexp) VALUES (-100, 'foo')"
         )
-        self.assertTrue(self.person_set.isNameBlacklisted("foo"))
-        self.assertFalse(self.person_set.isNameBlacklisted("bar"))
+        self.assertTrue(self.person_set.isNameBlocklisted("foo"))
+        self.assertFalse(self.person_set.isNameBlocklisted("bar"))
 
-    def test_isNameBlacklisted_user_is_admin(self):
+    def test_isNameBlocklisted_user_is_admin(self):
         team = self.factory.makeTeam()
-        name_blacklist_set = getUtility(INameBlacklistSet)
-        self.admin_exp = name_blacklist_set.create("fnord", admin=team)
+        name_blocklist_set = getUtility(INameBlocklistSet)
+        self.admin_exp = name_blocklist_set.create("fnord", admin=team)
         self.store = IStore(self.admin_exp)
         self.store.flush()
         user = team.teamowner
-        self.assertFalse(self.person_set.isNameBlacklisted("fnord", user))
+        self.assertFalse(self.person_set.isNameBlocklisted("fnord", user))
 
     def test_getByEmail_ignores_case_and_whitespace(self):
         person1_email = "foo.bar@xxxxxxxxxxxxx"
diff --git a/lib/lp/services/fields/__init__.py b/lib/lp/services/fields/__init__.py
index 1887615..1949b7a 100644
--- a/lib/lp/services/fields/__init__.py
+++ b/lib/lp/services/fields/__init__.py
@@ -4,7 +4,7 @@
 __all__ = [
     "AnnouncementDate",
     "BaseImageUpload",
-    "BlacklistableContentNameField",
+    "BlocklistableContentNameField",
     "BugField",
     "ContentNameField",
     "Description",
@@ -499,22 +499,22 @@ class ContentNameField(UniqueField):
         UniqueField._validate(self, name)
 
 
-class BlacklistableContentNameField(ContentNameField):
-    """ContentNameField that also checks that a name is not blacklisted"""
+class BlocklistableContentNameField(ContentNameField):
+    """ContentNameField that also checks that a name is not blocklisted"""
 
-    blacklistmessage = _(
+    blocklistmessage = _(
         "The name '%s' has been blocked by the Launchpad "
         "administrators. Contact Launchpad Support if you "
         "want to use this name."
     )
 
     def _validate(self, input):
-        """Check that the given name is valid, unique and not blacklisted."""
+        """Check that the given name is valid, unique and not blocklisted."""
         super()._validate(input)
 
         # Although this check is performed in UniqueField._validate(), we need
         # to do it here again to avoid checking whether or not the name is
-        # blacklisted when it hasn't been changed.
+        # blocklisted when it hasn't been changed.
         if self.unchanged(input):
             # The attribute wasn't changed.
             return
@@ -523,8 +523,8 @@ class BlacklistableContentNameField(ContentNameField):
         from lp.registry.interfaces.person import IPersonSet
 
         user = getUtility(ILaunchBag).user
-        if getUtility(IPersonSet).isNameBlacklisted(input, user):
-            raise LaunchpadValidationError(self.blacklistmessage % input)
+        if getUtility(IPersonSet).isNameBlocklisted(input, user):
+            raise LaunchpadValidationError(self.blocklistmessage % input)
 
 
 class PillarAliases(TextLine):
@@ -823,7 +823,7 @@ class MugshotImageUpload(BaseImageUpload):
     max_size = 100 * 1024
 
 
-class PillarNameField(BlacklistableContentNameField):
+class PillarNameField(BlocklistableContentNameField):
     """Base field used for names of distros/project groups/products."""
 
     errormessage = _("%s is already used by another project")
diff --git a/lib/lp/services/fields/tests/test_fields.py b/lib/lp/services/fields/tests/test_fields.py
index 665ce95..cbbaa9f 100644
--- a/lib/lp/services/fields/tests/test_fields.py
+++ b/lib/lp/services/fields/tests/test_fields.py
@@ -14,11 +14,11 @@ from zope.schema.interfaces import TooShort
 from lp.app.validators import LaunchpadValidationError
 from lp.blueprints.enums import SpecificationWorkItemStatus
 from lp.registry.enums import EXCLUSIVE_TEAM_POLICY, INCLUSIVE_TEAM_POLICY
-from lp.registry.interfaces.nameblacklist import INameBlacklistSet
+from lp.registry.interfaces.nameblocklist import INameBlocklistSet
 from lp.services.database.interfaces import IStore
 from lp.services.fields import (
     BaseImageUpload,
-    BlacklistableContentNameField,
+    BlocklistableContentNameField,
     FormattableDate,
     StrippableText,
     WorkItemsText,
@@ -536,15 +536,15 @@ class TestWorkItemsText(TestCase):
         )
 
 
-class TestBlacklistableContentNameField(TestCaseWithFactory):
+class TestBlocklistableContentNameField(TestCaseWithFactory):
 
     layer = DatabaseFunctionalLayer
 
     def setUp(self):
         super().setUp()
-        name_blacklist_set = getUtility(INameBlacklistSet)
+        name_blocklist_set = getUtility(INameBlocklistSet)
         self.team = self.factory.makeTeam()
-        admin_exp = name_blacklist_set.create("fnord", admin=self.team)
+        admin_exp = name_blocklist_set.create("fnord", admin=self.team)
         IStore(admin_exp).flush()
 
     def makeTestField(self):
@@ -553,7 +553,7 @@ class TestBlacklistableContentNameField(TestCaseWithFactory):
         class ITestInterface(Interface):
             pass
 
-        class TestField(BlacklistableContentNameField):
+        class TestField(BlocklistableContentNameField):
             _content_iface = ITestInterface
 
             def _getByName(self, name):
@@ -561,15 +561,15 @@ class TestBlacklistableContentNameField(TestCaseWithFactory):
 
         return TestField(__name__="test")
 
-    def test_validate_fails_with_blacklisted_name_anonymous(self):
+    def test_validate_fails_with_blocklisted_name_anonymous(self):
         # Anonymous users, processes, cannot create a name that matches
-        # a blacklisted name.
+        # a blocklisted name.
         field = self.makeTestField()
         date_value = "fnord"
         self.assertRaises(LaunchpadValidationError, field.validate, date_value)
 
-    def test_validate_fails_with_blacklisted_name_not_admin(self):
-        # Users who do not adminster a blacklisted name cannot create
+    def test_validate_fails_with_blocklisted_name_not_admin(self):
+        # Users who do not administer a blocklisted name cannot create
         # a matching name.
         field = self.makeTestField()
         date_value = "fnord"
@@ -577,7 +577,7 @@ class TestBlacklistableContentNameField(TestCaseWithFactory):
         self.assertRaises(LaunchpadValidationError, field.validate, date_value)
 
     def test_validate_passes_for_admin(self):
-        # Users in the team that adminsters a blacklisted name may create
+        # Users in the team that administers a blocklisted name may create
         # matching names.
         field = self.makeTestField()
         date_value = "fnord"